Live demo islands with highlighted source: SSR-safe effect, native component-source
- signals.sx: guard effect body with (when (client?) ...) so effects
are no-op during SSR — only 2 stubs needed (effect, register-in-scope)
- sx_primitives.ml: add resource SSR stub (returns signal {loading: true}),
remove 27 unnecessary browser primitive stubs
- sx_server.ml: native component-source that looks up Component/Island
from env and pretty-prints the definition (replaces broken Python helper)
- reactive-islands/index.sx: Examples section with all 15 live demos
inline + highlighted source via component-source
- reactive-islands/demo.sx: replace 14 hardcoded highlight strings with
(component-source "~name") calls for always-current source
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2015,6 +2015,30 @@ let http_setup_page_helpers env =
|
||||
Nil)
|
||||
| _ -> raise (Eval_error "helper: expected (helper \"name\" ...args)"));
|
||||
|
||||
(* component-source — look up component/island from env, pretty-print its definition *)
|
||||
bind "component-source" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
let lookup = if String.length name > 0 && name.[0] = '~'
|
||||
then name
|
||||
else "~" ^ name in
|
||||
(try
|
||||
let comp = env_get env lookup in
|
||||
match comp with
|
||||
| Component c ->
|
||||
let params = List (List.map (fun s -> Symbol s) c.c_params) in
|
||||
let form = List [Symbol "defcomp"; Symbol ("~" ^ c.c_name);
|
||||
params; c.c_body] in
|
||||
String (pretty_print_value form)
|
||||
| Island c ->
|
||||
let params = List (List.map (fun s -> Symbol s) c.i_params) in
|
||||
let form = List [Symbol "defisland"; Symbol ("~" ^ c.i_name);
|
||||
params; c.i_body] in
|
||||
String (pretty_print_value form)
|
||||
| _ -> String (";; " ^ name ^ ": not a component")
|
||||
with _ -> String (";; component " ^ name ^ " not found"))
|
||||
| _ -> raise (Eval_error "component-source: expected (name)"));
|
||||
|
||||
(* Stub remaining demo/action helpers that need real IO *)
|
||||
let stub name = bind name (fun _args -> Nil) in
|
||||
stub "run-spec-tests";
|
||||
|
||||
@@ -686,6 +686,11 @@ let () =
|
||||
| None -> raise (Eval_error ("Store not found: " ^ name)))
|
||||
| _ -> raise (Eval_error "use-store: expected (name)"));
|
||||
register "clear-stores" (fun _args -> Hashtbl.clear store_registry; Nil);
|
||||
(* SSR stubs — effect is no-op on server (signals.sx guards with client?),
|
||||
resource returns loading state. Other browser primitives only appear
|
||||
inside effect bodies which never execute during SSR. *)
|
||||
register "effect" (fun _args -> Nil);
|
||||
register "register-in-scope" (fun _args -> Nil);
|
||||
(* resource — SSR stub: return signal with {loading: true}, client hydrates real fetch *)
|
||||
register "resource" (fun _args ->
|
||||
let state = Hashtbl.create 8 in
|
||||
|
||||
Reference in New Issue
Block a user