diff --git a/hosts/ocaml/browser/sx_browser.ml b/hosts/ocaml/browser/sx_browser.ml index faf0d4f8..beae0410 100644 --- a/hosts/ocaml/browser/sx_browser.ml +++ b/hosts/ocaml/browser/sx_browser.ml @@ -223,6 +223,13 @@ let () = if env == global_env then Hashtbl.replace _vm_globals name v) +(* Reverse hook: sync VM GLOBAL_SET mutations back to global_env. + Without this, set! inside JIT-compiled functions writes to _vm_globals + but leaves global_env stale — CEK reads then see the old value. *) +let () = + Sx_types._vm_global_set_hook := Some (fun name v -> + Hashtbl.replace global_env.bindings (Sx_types.intern name) v) + (* ================================================================== *) (* Core API *) (* ================================================================== *) diff --git a/hosts/ocaml/lib/sx_ref.ml b/hosts/ocaml/lib/sx_ref.ml index 797a1348..bec6d95b 100644 --- a/hosts/ocaml/lib/sx_ref.ml +++ b/hosts/ocaml/lib/sx_ref.ml @@ -525,7 +525,7 @@ and step_ho_for_each args env kont = (* step-continue *) and step_continue state = - (let value = (cek_value (state)) in let env = (cek_env (state)) in let kont = (cek_kont (state)) in (if sx_truthy ((kont_empty_p (kont))) then state else (let frame = (kont_top (kont)) in let rest_k = (kont_pop (kont)) in let ft = (frame_type (frame)) in (if sx_truthy ((prim_call "=" [ft; (String "if")])) then (if sx_truthy ((let _and = value in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_nil (value)))))))) then (make_cek_state ((get (frame) ((String "then")))) ((get (frame) ((String "env")))) (rest_k)) else (if sx_truthy ((is_nil ((get (frame) ((String "else")))))) then (make_cek_value (Nil) (env) (rest_k)) else (make_cek_state ((get (frame) ((String "else")))) ((get (frame) ((String "env")))) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "when")])) then (if sx_truthy ((let _and = value in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_nil (value)))))))) then (let body = (get (frame) ((String "body"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (body))) then (make_cek_value (Nil) (fenv) (rest_k)) else (if sx_truthy ((prim_call "=" [(len (body)); (Number 1.0)])) then (make_cek_state ((first (body))) (fenv) (rest_k)) else (make_cek_state ((first (body))) (fenv) ((kont_push ((make_begin_frame ((rest (body))) (fenv))) (rest_k))))))) else (make_cek_value (Nil) (env) (rest_k))) else (if sx_truthy ((prim_call "=" [ft; (String "begin")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (if sx_truthy ((prim_call "=" [(len (remaining)); (Number 1.0)])) then (make_cek_state ((first (remaining))) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_begin_frame ((rest (remaining))) (fenv))) (rest_k))))))) else (if sx_truthy ((prim_call "=" [ft; (String "let")])) then (let name = (get (frame) ((String "name"))) in let remaining = (get (frame) ((String "remaining"))) in let body = (get (frame) ((String "body"))) in let local = (get (frame) ((String "env"))) in (let () = ignore ((env_bind local (sx_to_string name) value)) in (if sx_truthy ((empty_p (remaining))) then (step_sf_begin (body) (local) (rest_k)) else (let next_binding = (first (remaining)) in let vname = (if sx_truthy ((prim_call "=" [(type_of ((first (next_binding)))); (String "symbol")])) then (symbol_name ((first (next_binding)))) else (first (next_binding))) in (make_cek_state ((nth (next_binding) ((Number 1.0)))) (local) ((kont_push ((make_let_frame (vname) ((rest (remaining))) (body) (local))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "define")])) then (let name = (get (frame) ((String "name"))) in let fenv = (get (frame) ((String "env"))) in let has_effects = (get (frame) ((String "has-effects"))) in let effect_list = (get (frame) ((String "effect-list"))) in (let () = ignore ((if sx_truthy ((let _and = (is_lambda (value)) in if not (sx_truthy _and) then _and else (is_nil ((lambda_name (value)))))) then (set_lambda_name value (sx_to_string name)) else Nil)) in (let () = ignore ((env_bind fenv (sx_to_string name) value)) in (let () = ignore ((if sx_truthy (has_effects) then (let effect_names = (if sx_truthy ((prim_call "=" [(type_of (effect_list)); (String "list")])) then (List (List.map (fun e -> (if sx_truthy ((prim_call "=" [(type_of (e)); (String "symbol")])) then (symbol_name (e)) else (String (sx_str [e])))) (sx_to_list effect_list))) else (List [(String (sx_str [effect_list]))])) in let effect_anns = (if sx_truthy ((env_has (fenv) ((String "*effect-annotations*")))) then (env_get (fenv) ((String "*effect-annotations*"))) else (Dict (Hashtbl.create 0))) in (let () = ignore ((sx_dict_set_b effect_anns name effect_names)) in (env_bind fenv (sx_to_string (String "*effect-annotations*")) effect_anns))) else Nil)) in (make_cek_value (value) (fenv) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "set")])) then (let name = (get (frame) ((String "name"))) in let fenv = (get (frame) ((String "env"))) in (let () = ignore ((env_set fenv (sx_to_string name) value)) in (make_cek_value (value) (env) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "and")])) then (if sx_truthy ((Bool (not (sx_truthy (value))))) then (make_cek_value (value) (env) (rest_k)) else (let remaining = (get (frame) ((String "remaining"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (env) (rest_k)) else (make_cek_state ((first (remaining))) ((get (frame) ((String "env")))) ((if sx_truthy ((prim_call "=" [(len (remaining)); (Number 1.0)])) then rest_k else (kont_push ((make_and_frame ((rest (remaining))) ((get (frame) ((String "env")))))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "or")])) then (if sx_truthy (value) then (make_cek_value (value) (env) (rest_k)) else (let remaining = (get (frame) ((String "remaining"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value ((Bool false)) (env) (rest_k)) else (make_cek_state ((first (remaining))) ((get (frame) ((String "env")))) ((if sx_truthy ((prim_call "=" [(len (remaining)); (Number 1.0)])) then rest_k else (kont_push ((make_or_frame ((rest (remaining))) ((get (frame) ((String "env")))))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "cond")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in let scheme_p = (get (frame) ((String "scheme"))) in (if sx_truthy (scheme_p) then (if sx_truthy (value) then (make_cek_state ((nth ((first (remaining))) ((Number 1.0)))) (fenv) (rest_k)) else (let next_clauses = (rest (remaining)) in (if sx_truthy ((empty_p (next_clauses))) then (make_cek_value (Nil) (fenv) (rest_k)) else (let next_clause = (first (next_clauses)) in let next_test = (first (next_clause)) in (if sx_truthy ((is_else_clause (next_test))) then (make_cek_state ((nth (next_clause) ((Number 1.0)))) (fenv) (rest_k)) else (make_cek_state (next_test) (fenv) ((kont_push ((make_cond_frame (next_clauses) (fenv) ((Bool true)))) (rest_k))))))))) else (if sx_truthy (value) then (make_cek_state ((nth (remaining) ((Number 1.0)))) (fenv) (rest_k)) else (let next = (prim_call "slice" [remaining; (Number 2.0)]) in (if sx_truthy ((prim_call "<" [(len (next)); (Number 2.0)])) then (make_cek_value (Nil) (fenv) (rest_k)) else (let next_test = (first (next)) in (if sx_truthy ((is_else_clause (next_test))) then (make_cek_state ((nth (next) ((Number 1.0)))) (fenv) (rest_k)) else (make_cek_state (next_test) (fenv) ((kont_push ((make_cond_frame (next) (fenv) ((Bool false)))) (rest_k))))))))))) else (if sx_truthy ((prim_call "=" [ft; (String "case")])) then (let match_val = (get (frame) ((String "match-val"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((is_nil (match_val))) then (sf_case_step_loop (value) (remaining) (fenv) (rest_k)) else (sf_case_step_loop (match_val) (remaining) (fenv) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "thread")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (let form = (first (remaining)) in let rest_forms = (rest (remaining)) in let new_kont = (if sx_truthy ((empty_p ((rest (remaining))))) then rest_k else (kont_push ((make_thread_frame ((rest (remaining))) (fenv))) (rest_k))) in (if sx_truthy ((let _and = (prim_call "=" [(type_of (form)); (String "list")]) in if not (sx_truthy _and) then _and else (let _and = (Bool (not (sx_truthy ((empty_p (form)))))) in if not (sx_truthy _and) then _and else (let _and = (prim_call "=" [(type_of ((first (form)))); (String "symbol")]) in if not (sx_truthy _and) then _and else (ho_form_name_p ((symbol_name ((first (form)))))))))) then (make_cek_state ((cons ((first (form))) ((cons ((List [(Symbol "quote"); value])) ((rest (form))))))) (fenv) (new_kont)) else (let result' = (if sx_truthy ((prim_call "=" [(type_of (form)); (String "list")])) then (let f = (trampoline ((eval_expr ((first (form))) (fenv)))) in let rargs = (List (List.map (fun a -> (trampoline ((eval_expr (a) (fenv))))) (sx_to_list (rest (form))))) in let all_args = (cons (value) (rargs)) in (if sx_truthy ((let _and = (is_callable (f)) in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_lambda (f)))))))) then (sx_apply f all_args) else (if sx_truthy ((is_lambda (f))) then (trampoline ((call_lambda (f) (all_args) (fenv)))) else (raise (Eval_error (value_to_str (String (sx_str [(String "-> form not callable: "); (inspect (f))])))))))) else (let f = (trampoline ((eval_expr (form) (fenv)))) in (if sx_truthy ((let _and = (is_callable (f)) in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_lambda (f)))))))) then (cek_call (f) (List [value])) else (if sx_truthy ((is_lambda (f))) then (trampoline ((call_lambda (f) ((List [value])) (fenv)))) else (raise (Eval_error (value_to_str (String (sx_str [(String "-> form not callable: "); (inspect (f))]))))))))) in (if sx_truthy ((empty_p (rest_forms))) then (make_cek_value (result') (fenv) (rest_k)) else (make_cek_value (result') (fenv) ((kont_push ((make_thread_frame (rest_forms) (fenv))) (rest_k)))))))))) else (if sx_truthy ((prim_call "=" [ft; (String "arg")])) then (let f = (get (frame) ((String "f"))) in let evaled = (get (frame) ((String "evaled"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in let raw_args = (get (frame) ((String "raw-args"))) in let hname = (get (frame) ((String "head-name"))) in (if sx_truthy ((is_nil (f))) then (let () = ignore ((if sx_truthy ((let _and = !_strict_ref in if not (sx_truthy _and) then _and else hname)) then (strict_check_args (hname) ((List []))) else Nil)) in (if sx_truthy ((empty_p (remaining))) then (continue_with_call (value) ((List [])) (fenv) (raw_args) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_arg_frame (value) ((List [])) ((rest (remaining))) (fenv) (raw_args) (hname))) (rest_k)))))) else (let new_evaled = (prim_call "append" [evaled; (List [value])]) in (if sx_truthy ((empty_p (remaining))) then (let () = ignore ((if sx_truthy ((let _and = !_strict_ref in if not (sx_truthy _and) then _and else hname)) then (strict_check_args (hname) (new_evaled)) else Nil)) in (continue_with_call (f) (new_evaled) (fenv) (raw_args) (rest_k))) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_arg_frame (f) (new_evaled) ((rest (remaining))) (fenv) (raw_args) (hname))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "dict")])) then (let remaining = (get (frame) ((String "remaining"))) in let results = (get (frame) ((String "results"))) in let fenv = (get (frame) ((String "env"))) in (let last_result = (last (results)) in let completed = (prim_call "append" [(prim_call "slice" [results; (Number 0.0); (prim_call "dec" [(len (results))])]); (List [(List [(first (last_result)); value])])]) in (if sx_truthy ((empty_p (remaining))) then (let d = (Dict (Hashtbl.create 0)) in (let () = ignore ((List.iter (fun pair -> ignore ((sx_dict_set_b d (first (pair)) (nth (pair) ((Number 1.0)))))) (sx_to_list completed); Nil)) in (make_cek_value (d) (fenv) (rest_k)))) else (let next_entry = (first (remaining)) in (make_cek_state ((nth (next_entry) ((Number 1.0)))) (fenv) ((kont_push ((make_dict_frame ((rest (remaining))) ((prim_call "append" [completed; (List [(List [(first (next_entry))])])])) (fenv))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "ho-setup")])) then (let ho_type = (get (frame) ((String "ho-type"))) in let remaining = (get (frame) ((String "remaining"))) in let evaled = (prim_call "append" [(get (frame) ((String "evaled"))); (List [value])]) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (ho_setup_dispatch (ho_type) (evaled) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_ho_setup_frame (ho_type) ((rest (remaining))) (evaled) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "reset")])) then (make_cek_value (value) (env) (rest_k)) else (if sx_truthy ((prim_call "=" [ft; (String "deref")])) then (let val' = value in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((Bool (not (sx_truthy ((is_signal (val'))))))) then (make_cek_value (val') (fenv) (rest_k)) else (if sx_truthy ((has_reactive_reset_frame_p (rest_k))) then (reactive_shift_deref (val') (fenv) (rest_k)) else (let () = ignore ((let ctx = (sx_context ((String "sx-reactive")) (Nil)) in (if sx_truthy (ctx) then (let dep_list = ref ((get (ctx) ((String "deps")))) in let notify_fn = (get (ctx) ((String "notify"))) in (if sx_truthy ((Bool (not (sx_truthy ((prim_call "contains?" [!dep_list; val'])))))) then (let () = ignore ((dep_list := sx_append_b !dep_list val'; Nil)) in (signal_add_sub_b (val') (notify_fn))) else Nil)) else Nil))) in (make_cek_value ((signal_value (val'))) (fenv) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "reactive-reset")])) then (let update_fn = (get (frame) ((String "update-fn"))) in let first_p = (get (frame) ((String "first-render"))) in (let () = ignore ((if sx_truthy ((let _and = update_fn in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy (first_p)))))) then (cek_call (update_fn) ((List [value]))) else Nil)) in (make_cek_value (value) (env) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "scope")])) then (let name = (get (frame) ((String "name"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (let () = ignore ((scope_pop (name))) in (make_cek_value (value) (fenv) (rest_k))) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_scope_frame (name) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "provide")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_provide_frame ((get (frame) ((String "name")))) ((get (frame) ((String "value")))) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "scope-acc")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((let new_frame = (make_scope_acc_frame ((get (frame) ((String "name")))) ((get (frame) ((String "value")))) ((rest (remaining))) (fenv)) in (let () = ignore ((sx_dict_set_b new_frame (String "emitted") (get (frame) ((String "emitted"))))) in new_frame))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "map")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let results = (get (frame) ((String "results"))) in let indexed = (get (frame) ((String "indexed"))) in let fenv = (get (frame) ((String "env"))) in (let new_results = (prim_call "append" [results; (List [value])]) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (new_results) (fenv) (rest_k)) else (let call_args = (if sx_truthy (indexed) then (List [(len (new_results)); (first (remaining))]) else (List [(first (remaining))])) in let next_frame = (if sx_truthy (indexed) then (make_map_indexed_frame (f) ((rest (remaining))) (new_results) (fenv)) else (make_map_frame (f) ((rest (remaining))) (new_results) (fenv))) in (continue_with_call (f) (call_args) (fenv) ((List [])) ((kont_push (next_frame) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "filter")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let results = (get (frame) ((String "results"))) in let current_item = (get (frame) ((String "current-item"))) in let fenv = (get (frame) ((String "env"))) in (let new_results = (if sx_truthy (value) then (prim_call "append" [results; (List [current_item])]) else results) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (new_results) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_filter_frame (f) ((rest (remaining))) (new_results) ((first (remaining))) (fenv))) (rest_k))))))) else (if sx_truthy ((prim_call "=" [ft; (String "reduce")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (continue_with_call (f) ((List [value; (first (remaining))])) (fenv) ((List [])) ((kont_push ((make_reduce_frame (f) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "for-each")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (Nil) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_for_each_frame (f) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "some")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy (value) then (make_cek_value (value) (fenv) (rest_k)) else (if sx_truthy ((empty_p (remaining))) then (make_cek_value ((Bool false)) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_some_frame (f) ((rest (remaining))) (fenv))) (rest_k))))))) else (if sx_truthy ((prim_call "=" [ft; (String "every")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((Bool (not (sx_truthy (value))))) then (make_cek_value ((Bool false)) (fenv) (rest_k)) else (if sx_truthy ((empty_p (remaining))) then (make_cek_value ((Bool true)) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_every_frame (f) ((rest (remaining))) (fenv))) (rest_k))))))) else (raise (Eval_error (value_to_str (String (sx_str [(String "Unknown frame type: "); ft])))))))))))))))))))))))))))))))))) + (let value = (cek_value (state)) in let env = (cek_env (state)) in let kont = (cek_kont (state)) in (if sx_truthy ((kont_empty_p (kont))) then state else (let frame = (kont_top (kont)) in let rest_k = (kont_pop (kont)) in let ft = (frame_type (frame)) in (if sx_truthy ((prim_call "=" [ft; (String "if")])) then (if sx_truthy ((let _and = value in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_nil (value)))))))) then (make_cek_state ((get (frame) ((String "then")))) ((get (frame) ((String "env")))) (rest_k)) else (if sx_truthy ((is_nil ((get (frame) ((String "else")))))) then (make_cek_value (Nil) (env) (rest_k)) else (make_cek_state ((get (frame) ((String "else")))) ((get (frame) ((String "env")))) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "when")])) then (if sx_truthy ((let _and = value in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_nil (value)))))))) then (let body = (get (frame) ((String "body"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (body))) then (make_cek_value (Nil) (fenv) (rest_k)) else (if sx_truthy ((prim_call "=" [(len (body)); (Number 1.0)])) then (make_cek_state ((first (body))) (fenv) (rest_k)) else (make_cek_state ((first (body))) (fenv) ((kont_push ((make_begin_frame ((rest (body))) (fenv))) (rest_k))))))) else (make_cek_value (Nil) (env) (rest_k))) else (if sx_truthy ((prim_call "=" [ft; (String "begin")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (if sx_truthy ((prim_call "=" [(len (remaining)); (Number 1.0)])) then (make_cek_state ((first (remaining))) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_begin_frame ((rest (remaining))) (fenv))) (rest_k))))))) else (if sx_truthy ((prim_call "=" [ft; (String "let")])) then (let name = (get (frame) ((String "name"))) in let remaining = (get (frame) ((String "remaining"))) in let body = (get (frame) ((String "body"))) in let local = (get (frame) ((String "env"))) in (let () = ignore ((env_bind local (sx_to_string name) value)) in (if sx_truthy ((empty_p (remaining))) then (step_sf_begin (body) (local) (rest_k)) else (let next_binding = (first (remaining)) in let vname = (if sx_truthy ((prim_call "=" [(type_of ((first (next_binding)))); (String "symbol")])) then (symbol_name ((first (next_binding)))) else (first (next_binding))) in (make_cek_state ((nth (next_binding) ((Number 1.0)))) (local) ((kont_push ((make_let_frame (vname) ((rest (remaining))) (body) (local))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "define")])) then (let name = (get (frame) ((String "name"))) in let fenv = (get (frame) ((String "env"))) in let has_effects = (get (frame) ((String "has-effects"))) in let effect_list = (get (frame) ((String "effect-list"))) in (let () = ignore ((if sx_truthy ((let _and = (is_lambda (value)) in if not (sx_truthy _and) then _and else (is_nil ((lambda_name (value)))))) then (set_lambda_name value (sx_to_string name)) else Nil)) in (let () = ignore ((env_bind fenv (sx_to_string name) value)) in (let () = ignore ((if sx_truthy (has_effects) then (let effect_names = (if sx_truthy ((prim_call "=" [(type_of (effect_list)); (String "list")])) then (List (List.map (fun e -> (if sx_truthy ((prim_call "=" [(type_of (e)); (String "symbol")])) then (symbol_name (e)) else (String (sx_str [e])))) (sx_to_list effect_list))) else (List [(String (sx_str [effect_list]))])) in let effect_anns = (if sx_truthy ((env_has (fenv) ((String "*effect-annotations*")))) then (env_get (fenv) ((String "*effect-annotations*"))) else (Dict (Hashtbl.create 0))) in (let () = ignore ((sx_dict_set_b effect_anns name effect_names)) in (env_bind fenv (sx_to_string (String "*effect-annotations*")) effect_anns))) else Nil)) in (make_cek_value (value) (fenv) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "set")])) then (let name = (get (frame) ((String "name"))) in let fenv = (get (frame) ((String "env"))) in (let () = ignore ((env_set fenv (sx_to_string name) value)) in (make_cek_value (value) (env) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "and")])) then (if sx_truthy ((Bool (not (sx_truthy (value))))) then (make_cek_value (value) (env) (rest_k)) else (let remaining = (get (frame) ((String "remaining"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (env) (rest_k)) else (make_cek_state ((first (remaining))) ((get (frame) ((String "env")))) ((if sx_truthy ((prim_call "=" [(len (remaining)); (Number 1.0)])) then rest_k else (kont_push ((make_and_frame ((rest (remaining))) ((get (frame) ((String "env")))))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "or")])) then (if sx_truthy (value) then (make_cek_value (value) (env) (rest_k)) else (let remaining = (get (frame) ((String "remaining"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value ((Bool false)) (env) (rest_k)) else (make_cek_state ((first (remaining))) ((get (frame) ((String "env")))) ((if sx_truthy ((prim_call "=" [(len (remaining)); (Number 1.0)])) then rest_k else (kont_push ((make_or_frame ((rest (remaining))) ((get (frame) ((String "env")))))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "cond")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in let scheme_p = (get (frame) ((String "scheme"))) in (if sx_truthy (scheme_p) then (if sx_truthy (value) then (make_cek_state ((nth ((first (remaining))) ((Number 1.0)))) (fenv) (rest_k)) else (let next_clauses = (rest (remaining)) in (if sx_truthy ((empty_p (next_clauses))) then (make_cek_value (Nil) (fenv) (rest_k)) else (let next_clause = (first (next_clauses)) in let next_test = (first (next_clause)) in (if sx_truthy ((is_else_clause (next_test))) then (make_cek_state ((nth (next_clause) ((Number 1.0)))) (fenv) (rest_k)) else (make_cek_state (next_test) (fenv) ((kont_push ((make_cond_frame (next_clauses) (fenv) ((Bool true)))) (rest_k))))))))) else (if sx_truthy (value) then (make_cek_state ((nth (remaining) ((Number 1.0)))) (fenv) (rest_k)) else (let next = (prim_call "slice" [remaining; (Number 2.0)]) in (if sx_truthy ((prim_call "<" [(len (next)); (Number 2.0)])) then (make_cek_value (Nil) (fenv) (rest_k)) else (let next_test = (first (next)) in (if sx_truthy ((is_else_clause (next_test))) then (make_cek_state ((nth (next) ((Number 1.0)))) (fenv) (rest_k)) else (make_cek_state (next_test) (fenv) ((kont_push ((make_cond_frame (next) (fenv) ((Bool false)))) (rest_k))))))))))) else (if sx_truthy ((prim_call "=" [ft; (String "case")])) then (let match_val = (get (frame) ((String "match-val"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((is_nil (match_val))) then (sf_case_step_loop (value) (remaining) (fenv) (rest_k)) else (sf_case_step_loop (match_val) (remaining) (fenv) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "thread")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (let form = (first (remaining)) in let rest_forms = (rest (remaining)) in let new_kont = (if sx_truthy ((empty_p ((rest (remaining))))) then rest_k else (kont_push ((make_thread_frame ((rest (remaining))) (fenv))) (rest_k))) in (if sx_truthy ((let _and = (prim_call "=" [(type_of (form)); (String "list")]) in if not (sx_truthy _and) then _and else (let _and = (Bool (not (sx_truthy ((empty_p (form)))))) in if not (sx_truthy _and) then _and else (let _and = (prim_call "=" [(type_of ((first (form)))); (String "symbol")]) in if not (sx_truthy _and) then _and else (ho_form_name_p ((symbol_name ((first (form)))))))))) then (make_cek_state ((cons ((first (form))) ((cons ((List [(Symbol "quote"); value])) ((rest (form))))))) (fenv) (new_kont)) else (let result' = (if sx_truthy ((prim_call "=" [(type_of (form)); (String "list")])) then (let f = (trampoline ((eval_expr ((first (form))) (fenv)))) in let rargs = (List (List.map (fun a -> (trampoline ((eval_expr (a) (fenv))))) (sx_to_list (rest (form))))) in let all_args = (cons (value) (rargs)) in (if sx_truthy ((let _and = (is_callable (f)) in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_lambda (f)))))))) then (sx_apply f all_args) else (if sx_truthy ((is_lambda (f))) then (trampoline ((call_lambda (f) (all_args) (fenv)))) else (raise (Eval_error (value_to_str (String (sx_str [(String "-> form not callable: "); (inspect (f))])))))))) else (let f = (trampoline ((eval_expr (form) (fenv)))) in (if sx_truthy ((let _and = (is_callable (f)) in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy ((is_lambda (f)))))))) then (cek_call (f) (List [value])) else (if sx_truthy ((is_lambda (f))) then (trampoline ((call_lambda (f) ((List [value])) (fenv)))) else (raise (Eval_error (value_to_str (String (sx_str [(String "-> form not callable: "); (inspect (f))]))))))))) in (if sx_truthy ((empty_p (rest_forms))) then (make_cek_value (result') (fenv) (rest_k)) else (make_cek_value (result') (fenv) ((kont_push ((make_thread_frame (rest_forms) (fenv))) (rest_k)))))))))) else (if sx_truthy ((prim_call "=" [ft; (String "arg")])) then (let f = (get (frame) ((String "f"))) in let evaled = (get (frame) ((String "evaled"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in let raw_args = (get (frame) ((String "raw-args"))) in let hname = (get (frame) ((String "head-name"))) in (if sx_truthy ((is_nil (f))) then (let () = ignore ((if sx_truthy ((let _and = !_strict_ref in if not (sx_truthy _and) then _and else hname)) then (strict_check_args (hname) ((List []))) else Nil)) in (if sx_truthy ((empty_p (remaining))) then (if value = Nil then let ctx = match raw_args with List l -> String.concat " " (List.map (fun a -> let s = Sx_types.inspect a in if String.length s > 50 then String.sub s 0 50 ^ ".." else s) l) | _ -> "?" in raise (Eval_error ("Not callable: nil (call-expr: " ^ (if hname <> Nil then Sx_types.inspect hname else "(" ^ ctx ^ ")") ^ ")")) else (continue_with_call (value) ((List [])) (fenv) (raw_args) (rest_k))) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_arg_frame (value) ((List [])) ((rest (remaining))) (fenv) (raw_args) (hname))) (rest_k)))))) else (let new_evaled = (prim_call "append" [evaled; (List [value])]) in (if sx_truthy ((empty_p (remaining))) then (let () = ignore ((if sx_truthy ((let _and = !_strict_ref in if not (sx_truthy _and) then _and else hname)) then (strict_check_args (hname) (new_evaled)) else Nil)) in (continue_with_call (f) (new_evaled) (fenv) (raw_args) (rest_k))) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_arg_frame (f) (new_evaled) ((rest (remaining))) (fenv) (raw_args) (hname))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "dict")])) then (let remaining = (get (frame) ((String "remaining"))) in let results = (get (frame) ((String "results"))) in let fenv = (get (frame) ((String "env"))) in (let last_result = (last (results)) in let completed = (prim_call "append" [(prim_call "slice" [results; (Number 0.0); (prim_call "dec" [(len (results))])]); (List [(List [(first (last_result)); value])])]) in (if sx_truthy ((empty_p (remaining))) then (let d = (Dict (Hashtbl.create 0)) in (let () = ignore ((List.iter (fun pair -> ignore ((sx_dict_set_b d (first (pair)) (nth (pair) ((Number 1.0)))))) (sx_to_list completed); Nil)) in (make_cek_value (d) (fenv) (rest_k)))) else (let next_entry = (first (remaining)) in (make_cek_state ((nth (next_entry) ((Number 1.0)))) (fenv) ((kont_push ((make_dict_frame ((rest (remaining))) ((prim_call "append" [completed; (List [(List [(first (next_entry))])])])) (fenv))) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "ho-setup")])) then (let ho_type = (get (frame) ((String "ho-type"))) in let remaining = (get (frame) ((String "remaining"))) in let evaled = (prim_call "append" [(get (frame) ((String "evaled"))); (List [value])]) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (ho_setup_dispatch (ho_type) (evaled) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_ho_setup_frame (ho_type) ((rest (remaining))) (evaled) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "reset")])) then (make_cek_value (value) (env) (rest_k)) else (if sx_truthy ((prim_call "=" [ft; (String "deref")])) then (let val' = value in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((Bool (not (sx_truthy ((is_signal (val'))))))) then (make_cek_value (val') (fenv) (rest_k)) else (if sx_truthy ((has_reactive_reset_frame_p (rest_k))) then (reactive_shift_deref (val') (fenv) (rest_k)) else (let () = ignore ((let ctx = (sx_context ((String "sx-reactive")) (Nil)) in (if sx_truthy (ctx) then (let dep_list = ref ((get (ctx) ((String "deps")))) in let notify_fn = (get (ctx) ((String "notify"))) in (if sx_truthy ((Bool (not (sx_truthy ((prim_call "contains?" [!dep_list; val'])))))) then (let () = ignore ((dep_list := sx_append_b !dep_list val'; Nil)) in (signal_add_sub_b (val') (notify_fn))) else Nil)) else Nil))) in (make_cek_value ((signal_value (val'))) (fenv) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "reactive-reset")])) then (let update_fn = (get (frame) ((String "update-fn"))) in let first_p = (get (frame) ((String "first-render"))) in (let () = ignore ((if sx_truthy ((let _and = update_fn in if not (sx_truthy _and) then _and else (Bool (not (sx_truthy (first_p)))))) then (cek_call (update_fn) ((List [value]))) else Nil)) in (make_cek_value (value) (env) (rest_k)))) else (if sx_truthy ((prim_call "=" [ft; (String "scope")])) then (let name = (get (frame) ((String "name"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (let () = ignore ((scope_pop (name))) in (make_cek_value (value) (fenv) (rest_k))) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_scope_frame (name) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "provide")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((make_provide_frame ((get (frame) ((String "name")))) ((get (frame) ((String "value")))) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "scope-acc")])) then (let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (make_cek_state ((first (remaining))) (fenv) ((kont_push ((let new_frame = (make_scope_acc_frame ((get (frame) ((String "name")))) ((get (frame) ((String "value")))) ((rest (remaining))) (fenv)) in (let () = ignore ((sx_dict_set_b new_frame (String "emitted") (get (frame) ((String "emitted"))))) in new_frame))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "map")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let results = (get (frame) ((String "results"))) in let indexed = (get (frame) ((String "indexed"))) in let fenv = (get (frame) ((String "env"))) in (let new_results = (prim_call "append" [results; (List [value])]) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (new_results) (fenv) (rest_k)) else (let call_args = (if sx_truthy (indexed) then (List [(len (new_results)); (first (remaining))]) else (List [(first (remaining))])) in let next_frame = (if sx_truthy (indexed) then (make_map_indexed_frame (f) ((rest (remaining))) (new_results) (fenv)) else (make_map_frame (f) ((rest (remaining))) (new_results) (fenv))) in (continue_with_call (f) (call_args) (fenv) ((List [])) ((kont_push (next_frame) (rest_k)))))))) else (if sx_truthy ((prim_call "=" [ft; (String "filter")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let results = (get (frame) ((String "results"))) in let current_item = (get (frame) ((String "current-item"))) in let fenv = (get (frame) ((String "env"))) in (let new_results = (if sx_truthy (value) then (prim_call "append" [results; (List [current_item])]) else results) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (new_results) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_filter_frame (f) ((rest (remaining))) (new_results) ((first (remaining))) (fenv))) (rest_k))))))) else (if sx_truthy ((prim_call "=" [ft; (String "reduce")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (value) (fenv) (rest_k)) else (continue_with_call (f) ((List [value; (first (remaining))])) (fenv) ((List [])) ((kont_push ((make_reduce_frame (f) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "for-each")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((empty_p (remaining))) then (make_cek_value (Nil) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_for_each_frame (f) ((rest (remaining))) (fenv))) (rest_k)))))) else (if sx_truthy ((prim_call "=" [ft; (String "some")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy (value) then (make_cek_value (value) (fenv) (rest_k)) else (if sx_truthy ((empty_p (remaining))) then (make_cek_value ((Bool false)) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_some_frame (f) ((rest (remaining))) (fenv))) (rest_k))))))) else (if sx_truthy ((prim_call "=" [ft; (String "every")])) then (let f = (get (frame) ((String "f"))) in let remaining = (get (frame) ((String "remaining"))) in let fenv = (get (frame) ((String "env"))) in (if sx_truthy ((Bool (not (sx_truthy (value))))) then (make_cek_value ((Bool false)) (fenv) (rest_k)) else (if sx_truthy ((empty_p (remaining))) then (make_cek_value ((Bool true)) (fenv) (rest_k)) else (continue_with_call (f) ((List [(first (remaining))])) (fenv) ((List [])) ((kont_push ((make_every_frame (f) ((rest (remaining))) (fenv))) (rest_k))))))) else (raise (Eval_error (value_to_str (String (sx_str [(String "Unknown frame type: "); ft])))))))))))))))))))))))))))))))))) (* continue-with-call *) and continue_with_call f args env raw_args kont = diff --git a/hosts/ocaml/lib/sx_runtime.ml b/hosts/ocaml/lib/sx_runtime.ml index 4f697a2b..f0e85b10 100644 --- a/hosts/ocaml/lib/sx_runtime.ml +++ b/hosts/ocaml/lib/sx_runtime.ml @@ -50,7 +50,12 @@ let sx_call f args = Thunk (l.l_body, local) | Continuation (k, _) -> k (match args with x :: _ -> x | [] -> Nil) - | _ -> raise (Eval_error ("Not callable: " ^ inspect f)) + | _ -> + let nargs = List.length args in + let args_preview = if nargs = 0 then "" else + let s = String.concat ", " (List.map (fun a -> let s = inspect a in if String.length s > 40 then String.sub s 0 40 ^ ".." else s) args) in + " with args=[" ^ s ^ "]" in + raise (Eval_error ("Not callable: " ^ inspect f ^ args_preview)) (* Initialize forward ref so primitives can call SX functions *) let () = Sx_primitives._sx_call_fn := sx_call diff --git a/hosts/ocaml/lib/sx_types.ml b/hosts/ocaml/lib/sx_types.ml index f2a8e3ad..06592e8c 100644 --- a/hosts/ocaml/lib/sx_types.ml +++ b/hosts/ocaml/lib/sx_types.ml @@ -185,8 +185,18 @@ let make_env () = let env_extend parent = { bindings = Hashtbl.create 16; parent = Some parent } +(* Optional hook: called after every env_bind with (env, name, value). + Used by browser kernel to sync VM globals table. *) +let _env_bind_hook : (env -> string -> value -> unit) option ref = ref None + +(* Optional hook: called after VM GLOBAL_SET writes to vm.globals. + Used by browser kernel to sync mutations back to global_env. *) +let _vm_global_set_hook : (string -> value -> unit) option ref = ref None + let env_bind env name v = - Hashtbl.replace env.bindings (intern name) v; Nil + Hashtbl.replace env.bindings (intern name) v; + (match !_env_bind_hook with Some f -> f env name v | None -> ()); + Nil (* Internal: scope-chain lookup with pre-interned ID *) let rec env_has_id env id = diff --git a/hosts/ocaml/lib/sx_vm.ml b/hosts/ocaml/lib/sx_vm.ml index d709a4aa..4525775e 100644 --- a/hosts/ocaml/lib/sx_vm.ml +++ b/hosts/ocaml/lib/sx_vm.ml @@ -303,7 +303,11 @@ and run vm = in find_env env | None -> false in - if not written then Hashtbl.replace vm.globals name (peek vm) + if not written then begin + let v = peek vm in + Hashtbl.replace vm.globals name v; + (match !Sx_types._vm_global_set_hook with Some f -> f name v | None -> ()) + end (* ---- Control flow ---- *) | 32 (* OP_JUMP *) -> diff --git a/shared/static/scripts/sx-browser.js b/shared/static/scripts/sx-browser.js index 193502cc..3515c58f 100644 --- a/shared/static/scripts/sx-browser.js +++ b/shared/static/scripts/sx-browser.js @@ -14,7 +14,7 @@ // ========================================================================= var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } }); - var SX_VERSION = "2026-03-26T16:13:53Z"; + var SX_VERSION = "2026-03-28T12:33:20Z"; function isNil(x) { return x === NIL || x === null || x === undefined; } function isSxTruthy(x) { return x !== false && !isNil(x); } @@ -3169,10 +3169,7 @@ PRIMITIVES["dom-body"] = domBody; PRIMITIVES["dom-head"] = domHead; // dom-create-element - var domCreateElement = function(tag) { var nsArg = Array.prototype.slice.call(arguments, 1); return (function() { - var ns = (isSxTruthy((isSxTruthy(nsArg) && !isSxTruthy(isEmpty(nsArg)))) ? first(nsArg) : NIL); - return (isSxTruthy(ns) ? hostCall(domDocument(), "createElementNS", ns, tag) : hostCall(domDocument(), "createElement", tag)); -})(); }; + var domCreateElement = function(tag, ns) { return (isSxTruthy(ns) ? hostCall(domDocument(), "createElementNS", ns, tag) : hostCall(domDocument(), "createElement", tag)); }; PRIMITIVES["dom-create-element"] = domCreateElement; // create-text-node @@ -3262,7 +3259,7 @@ PRIMITIVES["dom-replace-child"] = domReplaceChild; PRIMITIVES["dom-clone"] = domClone; // dom-query - var domQuery = function(rootOrSel) { var rest = Array.prototype.slice.call(arguments, 1); return (isSxTruthy(isEmpty(rest)) ? hostCall(domDocument(), "querySelector", rootOrSel) : hostCall(rootOrSel, "querySelector", first(rest))); }; + var domQuery = function(rootOrSel, sel) { return (isSxTruthy(isNil(sel)) ? hostCall(domDocument(), "querySelector", rootOrSel) : hostCall(rootOrSel, "querySelector", sel)); }; PRIMITIVES["dom-query"] = domQuery; // dom-query-all @@ -3455,9 +3452,9 @@ PRIMITIVES["dom-parse-html"] = domParseHtml; PRIMITIVES["dom-listen"] = domListen; // dom-add-listener - var domAddListener = function(el, eventName, handler) { var opts = Array.prototype.slice.call(arguments, 3); return (function() { + var domAddListener = function(el, eventName, handler, opts) { return (function() { var cb = hostCallback(handler); - (isSxTruthy((isSxTruthy(opts) && !isSxTruthy(isEmpty(opts)))) ? hostCall(el, "addEventListener", eventName, cb, first(opts)) : hostCall(el, "addEventListener", eventName, cb)); + (isSxTruthy(opts) ? hostCall(el, "addEventListener", eventName, cb, opts) : hostCall(el, "addEventListener", eventName, cb)); return function() { return hostCall(el, "removeEventListener", eventName, cb); }; })(); }; PRIMITIVES["dom-add-listener"] = domAddListener; @@ -3539,11 +3536,11 @@ PRIMITIVES["browser-same-origin?"] = browserSameOrigin; PRIMITIVES["url-pathname"] = urlPathname; // browser-push-state - var browserPushState = function(urlOrState) { var rest = Array.prototype.slice.call(arguments, 1); return (isSxTruthy(isEmpty(rest)) ? hostCall(hostGet(domWindow(), "history"), "pushState", NIL, "", urlOrState) : hostCall(hostGet(domWindow(), "history"), "pushState", urlOrState, first(rest), nth(rest, 1))); }; + var browserPushState = function(urlOrState, title, url) { return (isSxTruthy(isNil(title)) ? hostCall(hostGet(domWindow(), "history"), "pushState", NIL, "", urlOrState) : hostCall(hostGet(domWindow(), "history"), "pushState", urlOrState, title, url)); }; PRIMITIVES["browser-push-state"] = browserPushState; // browser-replace-state - var browserReplaceState = function(urlOrState) { var rest = Array.prototype.slice.call(arguments, 1); return (isSxTruthy(isEmpty(rest)) ? hostCall(hostGet(domWindow(), "history"), "replaceState", NIL, "", urlOrState) : hostCall(hostGet(domWindow(), "history"), "replaceState", urlOrState, first(rest), nth(rest, 1))); }; + var browserReplaceState = function(urlOrState, title, url) { return (isSxTruthy(isNil(title)) ? hostCall(hostGet(domWindow(), "history"), "replaceState", NIL, "", urlOrState) : hostCall(hostGet(domWindow(), "history"), "replaceState", urlOrState, title, url)); }; PRIMITIVES["browser-replace-state"] = browserReplaceState; // browser-reload @@ -3643,7 +3640,7 @@ PRIMITIVES["log-info"] = logInfo; PRIMITIVES["log-warn"] = logWarn; // console-log - var consoleLog = function() { var args = Array.prototype.slice.call(arguments, 0); return hostCall(hostGlobal("console"), "log", join(" ", cons("[sx]", map(str, args)))); }; + var consoleLog = function(msg) { return hostCall(hostGlobal("console"), "log", (String("[sx] ") + String(msg))); }; PRIMITIVES["console-log"] = consoleLog; // now-ms @@ -4772,7 +4769,7 @@ PRIMITIVES["init-css-tracking"] = initCssTracking; })()) ? promiseResolve(NIL) : (function() { var promptMsg = domGetAttr(el, "sx-prompt"); var promptVal = (isSxTruthy(promptMsg) ? browserPrompt(promptMsg) : NIL); - return (isSxTruthy((isSxTruthy(promptMsg) && isNil(promptVal))) ? promiseResolve(NIL) : (isSxTruthy(!isSxTruthy(validateForRequest(el))) ? promiseResolve(NIL) : doFetch(el, verb, verb, url, (isSxTruthy(promptVal) ? assoc(sxOr(extraParams, {}), "SX-Prompt", promptVal) : extraParams)))); + return (isSxTruthy((isSxTruthy(promptMsg) && isNil(promptVal))) ? promiseResolve(NIL) : (isSxTruthy(sxOr(isNil(verb), isNil(url), !isSxTruthy(validateForRequest(el)))) ? promiseResolve(NIL) : doFetch(el, verb, verb, url, (isSxTruthy(promptVal) ? assoc(sxOr(extraParams, {}), "SX-Prompt", promptVal) : extraParams)))); })())); })()); })(); }; @@ -4942,12 +4939,12 @@ PRIMITIVES["bind-triggers"] = bindTriggers; var shouldFire = true; if (isSxTruthy(get(mods, "changed"))) { (function() { - var val = elementValue(el); + var val = domValue(el); return (isSxTruthy((val == lastVal)) ? (shouldFire = false) : (lastVal = val)); })(); } return (isSxTruthy((isSxTruthy(shouldFire) && !isSxTruthy((isSxTruthy((eventName == "click")) && eventModifierKey_p(e))))) ? ((isSxTruthy(sxOr((eventName == "submit"), (isSxTruthy((eventName == "click")) && domHasAttr(el, "href")))) ? preventDefault_(e) : NIL), (function() { - var liveInfo = sxOr(getVerbInfo(el), verbInfo); + var liveInfo = getVerbInfo(el); var isGetLink = (isSxTruthy((eventName == "click")) && isSxTruthy((get(liveInfo, "method") == "GET")) && isSxTruthy(domHasAttr(el, "href")) && !isSxTruthy(get(mods, "delay"))); var clientRouted = false; if (isSxTruthy(isGetLink)) { @@ -5537,7 +5534,7 @@ PRIMITIVES["sx-render-component"] = sxRenderComponent; var text = domTextContent(s); return (isSxTruthy(domHasAttr(s, "data-components")) ? processComponentScript(s, text) : (isSxTruthy(sxOr(isNil(text), isEmpty(trim(text)))) ? NIL : (isSxTruthy(domHasAttr(s, "data-init")) ? (function() { var exprs = sxParse(text); - return forEach(function(expr) { return evalExpr(expr, envExtend({})); }, exprs); + return forEach(function(expr) { return cekEval(expr); }, exprs); })() : (isSxTruthy(domHasAttr(s, "data-mount")) ? (function() { var mountSel = domGetAttr(s, "data-mount"); var target = domQuery(mountSel); @@ -6533,28 +6530,6 @@ PRIMITIVES["with-marsh-scope"] = withMarshScope; })(); }; PRIMITIVES["dispose-marsh-scope"] = disposeMarshScope; - // *store-registry* - var _storeRegistry = {}; -PRIMITIVES["*store-registry*"] = _storeRegistry; - - // def-store - var defStore = function(name, initFn) { return (function() { - var registry = _storeRegistry; - if (isSxTruthy(!isSxTruthy(dictHas(registry, name)))) { - _storeRegistry = assoc(registry, name, cekCall(initFn, NIL)); -} - return get(_storeRegistry, name); -})(); }; -PRIMITIVES["def-store"] = defStore; - - // use-store - var useStore = function(name) { return (isSxTruthy(dictHas(_storeRegistry, name)) ? get(_storeRegistry, name) : error((String("Store not found: ") + String(name) + String(". Call (def-store ...) before (use-store ...).")))); }; -PRIMITIVES["use-store"] = useStore; - - // clear-stores - var clearStores = function() { return (_storeRegistry = {}); }; -PRIMITIVES["clear-stores"] = clearStores; - // emit-event var emitEvent = function(el, eventName, detail) { return domDispatch(el, eventName, detail); }; PRIMITIVES["emit-event"] = emitEvent; @@ -6583,400 +6558,6 @@ PRIMITIVES["bridge-event"] = bridgeEvent; PRIMITIVES["resource"] = resource; - // === Transpiled from types (gradual type system) === - - // base-types - var baseTypes = ["number", "string", "boolean", "nil", "symbol", "keyword", "element", "any", "never", "list", "dict", "lambda", "component", "island", "macro", "signal"]; -PRIMITIVES["base-types"] = baseTypes; - - // type-any? - var typeAny_p = function(t) { return (t == "any"); }; -PRIMITIVES["type-any?"] = typeAny_p; - - // type-never? - var typeNever_p = function(t) { return (t == "never"); }; -PRIMITIVES["type-never?"] = typeNever_p; - - // type-nullable? - var typeNullable_p = function(t) { return (isSxTruthy((t == "any")) ? true : (isSxTruthy((t == "nil")) ? true : (isSxTruthy((isSxTruthy((typeOf(t) == "string")) && endsWith(t, "?"))) ? true : (isSxTruthy((isSxTruthy((typeOf(t) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(t))) && (first(t) == "or"))) ? contains(rest(t), "nil") : false)))); }; -PRIMITIVES["type-nullable?"] = typeNullable_p; - - // nullable-base - var nullableBase = function(t) { return (isSxTruthy((isSxTruthy((typeOf(t) == "string")) && isSxTruthy(endsWith(t, "?")) && !isSxTruthy((t == "?")))) ? slice(t, 0, (stringLength(t) - 1)) : t); }; -PRIMITIVES["nullable-base"] = nullableBase; - - // subtype? - var subtype_p = function(a, b) { return (isSxTruthy(typeAny_p(b)) ? true : (isSxTruthy(typeNever_p(a)) ? true : (isSxTruthy(typeAny_p(a)) ? false : (isSxTruthy((a == b)) ? true : (isSxTruthy((a == "nil")) ? typeNullable_p(b) : (isSxTruthy((isSxTruthy((typeOf(b) == "string")) && endsWith(b, "?"))) ? (function() { - var base = nullableBase(b); - return sxOr((a == base), (a == "nil")); -})() : (isSxTruthy((isSxTruthy((typeOf(a) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(a))) && (first(a) == "or"))) ? isEvery(function(member) { return subtype_p(member, b); }, rest(a)) : (isSxTruthy((isSxTruthy((typeOf(b) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(b))) && (first(b) == "or"))) ? some(function(member) { return subtype_p(a, member); }, rest(b)) : (isSxTruthy((isSxTruthy((typeOf(a) == "list")) && isSxTruthy((typeOf(b) == "list")) && isSxTruthy((len(a) == 2)) && isSxTruthy((len(b) == 2)) && isSxTruthy((first(a) == "list-of")) && (first(b) == "list-of"))) ? subtype_p(nth(a, 1), nth(b, 1)) : (isSxTruthy((isSxTruthy((a == "list")) && isSxTruthy((typeOf(b) == "list")) && isSxTruthy((len(b) == 2)) && (first(b) == "list-of"))) ? typeAny_p(nth(b, 1)) : (isSxTruthy((isSxTruthy((typeOf(a) == "list")) && isSxTruthy((len(a) == 2)) && isSxTruthy((first(a) == "list-of")) && (b == "list"))) ? true : false))))))))))); }; -PRIMITIVES["subtype?"] = subtype_p; - - // type-union - var typeUnion = function(a, b) { return (isSxTruthy((a == b)) ? a : (isSxTruthy(typeAny_p(a)) ? "any" : (isSxTruthy(typeAny_p(b)) ? "any" : (isSxTruthy(typeNever_p(a)) ? b : (isSxTruthy(typeNever_p(b)) ? a : (isSxTruthy(subtype_p(a, b)) ? b : (isSxTruthy(subtype_p(b, a)) ? a : (isSxTruthy((a == "nil")) ? (isSxTruthy((isSxTruthy((typeOf(b) == "string")) && !isSxTruthy(endsWith(b, "?")))) ? (String(b) + String("?")) : ["or", a, b]) : (isSxTruthy((b == "nil")) ? (isSxTruthy((isSxTruthy((typeOf(a) == "string")) && !isSxTruthy(endsWith(a, "?")))) ? (String(a) + String("?")) : ["or", a, b]) : ["or", a, b]))))))))); }; -PRIMITIVES["type-union"] = typeUnion; - - // narrow-type - var narrowType = function(t, predicateName) { return (isSxTruthy((predicateName == "nil?")) ? ["nil", narrowExcludeNil(t)] : (isSxTruthy((predicateName == "string?")) ? ["string", narrowExclude(t, "string")] : (isSxTruthy((predicateName == "number?")) ? ["number", narrowExclude(t, "number")] : (isSxTruthy((predicateName == "list?")) ? ["list", narrowExclude(t, "list")] : (isSxTruthy((predicateName == "dict?")) ? ["dict", narrowExclude(t, "dict")] : (isSxTruthy((predicateName == "boolean?")) ? ["boolean", narrowExclude(t, "boolean")] : [t, t])))))); }; -PRIMITIVES["narrow-type"] = narrowType; - - // narrow-exclude-nil - var narrowExcludeNil = function(t) { return (isSxTruthy((t == "nil")) ? "never" : (isSxTruthy((t == "any")) ? "any" : (isSxTruthy((isSxTruthy((typeOf(t) == "string")) && endsWith(t, "?"))) ? nullableBase(t) : (isSxTruthy((isSxTruthy((typeOf(t) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(t))) && (first(t) == "or"))) ? (function() { - var members = filter(function(m) { return !isSxTruthy((m == "nil")); }, rest(t)); - return (isSxTruthy((len(members) == 1)) ? first(members) : (isSxTruthy(isEmpty(members)) ? "never" : cons("or", members))); -})() : t)))); }; -PRIMITIVES["narrow-exclude-nil"] = narrowExcludeNil; - - // narrow-exclude - var narrowExclude = function(t, excluded) { return (isSxTruthy((t == excluded)) ? "never" : (isSxTruthy((t == "any")) ? "any" : (isSxTruthy((isSxTruthy((typeOf(t) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(t))) && (first(t) == "or"))) ? (function() { - var members = filter(function(m) { return !isSxTruthy((m == excluded)); }, rest(t)); - return (isSxTruthy((len(members) == 1)) ? first(members) : (isSxTruthy(isEmpty(members)) ? "never" : cons("or", members))); -})() : t))); }; -PRIMITIVES["narrow-exclude"] = narrowExclude; - - // infer-type - var inferType = function(node, typeEnv, primTypes, typeRegistry) { return (function() { - var kind = typeOf(node); - return (isSxTruthy((kind == "number")) ? "number" : (isSxTruthy((kind == "string")) ? "string" : (isSxTruthy((kind == "boolean")) ? "boolean" : (isSxTruthy(isNil(node)) ? "nil" : (isSxTruthy((kind == "keyword")) ? "keyword" : (isSxTruthy((kind == "symbol")) ? (function() { - var name = symbolName(node); - return (isSxTruthy(dictHas(typeEnv, name)) ? get(typeEnv, name) : (isSxTruthy((name == "true")) ? "boolean" : (isSxTruthy((name == "false")) ? "boolean" : (isSxTruthy((name == "nil")) ? "nil" : (isSxTruthy(dictHas(primTypes, name)) ? get(primTypes, name) : "any"))))); -})() : (isSxTruthy((kind == "dict")) ? "dict" : (isSxTruthy((kind == "list")) ? inferListType(node, typeEnv, primTypes, typeRegistry) : "any")))))))); -})(); }; -PRIMITIVES["infer-type"] = inferType; - - // infer-list-type - var inferListType = function(node, typeEnv, primTypes, typeRegistry) { return (isSxTruthy(isEmpty(node)) ? "list" : (function() { - var head = first(node); - var args = rest(node); - return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? "any" : (function() { - var name = symbolName(head); - return (isSxTruthy((name == "if")) ? inferIfType(args, typeEnv, primTypes, typeRegistry) : (isSxTruthy((name == "when")) ? (isSxTruthy((len(args) >= 2)) ? typeUnion(inferType(last(args), typeEnv, primTypes, typeRegistry), "nil") : "nil") : (isSxTruthy(sxOr((name == "cond"), (name == "case"))) ? "any" : (isSxTruthy((name == "let")) ? inferLetType(args, typeEnv, primTypes, typeRegistry) : (isSxTruthy(sxOr((name == "do"), (name == "begin"))) ? (isSxTruthy(isEmpty(args)) ? "nil" : inferType(last(args), typeEnv, primTypes, typeRegistry)) : (isSxTruthy(sxOr((name == "lambda"), (name == "fn"))) ? "lambda" : (isSxTruthy((name == "and")) ? (isSxTruthy(isEmpty(args)) ? "boolean" : inferType(last(args), typeEnv, primTypes, typeRegistry)) : (isSxTruthy((name == "or")) ? (isSxTruthy(isEmpty(args)) ? "boolean" : reduce(typeUnion, "never", map(function(a) { return inferType(a, typeEnv, primTypes, typeRegistry); }, args))) : (isSxTruthy((name == "map")) ? (isSxTruthy((len(args) >= 2)) ? (function() { - var fnType = inferType(first(args), typeEnv, primTypes, typeRegistry); - return (isSxTruthy((isSxTruthy((typeOf(fnType) == "list")) && (first(fnType) == "->"))) ? ["list-of", last(fnType)] : "list"); -})() : "list") : (isSxTruthy((name == "filter")) ? (isSxTruthy((len(args) >= 2)) ? inferType(nth(args, 1), typeEnv, primTypes, typeRegistry) : "list") : (isSxTruthy((name == "reduce")) ? "any" : (isSxTruthy((name == "list")) ? "list" : (isSxTruthy((name == "dict")) ? "dict" : (isSxTruthy((name == "quote")) ? "any" : (isSxTruthy((name == "str")) ? "string" : (isSxTruthy((name == "not")) ? "boolean" : (isSxTruthy((name == "get")) ? (isSxTruthy((isSxTruthy((len(args) >= 2)) && !isSxTruthy(isNil(typeRegistry)))) ? (function() { - var dictType = inferType(first(args), typeEnv, primTypes, typeRegistry); - var keyArg = nth(args, 1); - var keyName = (isSxTruthy((typeOf(keyArg) == "keyword")) ? keywordName(keyArg) : (isSxTruthy((typeOf(keyArg) == "string")) ? keyArg : NIL)); - return (isSxTruthy((isSxTruthy(keyName) && isSxTruthy((typeOf(dictType) == "string")) && dictHas(typeRegistry, dictType))) ? (function() { - var resolved = resolveType(dictType, typeRegistry); - return (isSxTruthy((isSxTruthy((typeOf(resolved) == "dict")) && dictHas(resolved, keyName))) ? get(resolved, keyName) : "any"); -})() : "any"); -})() : "any") : (isSxTruthy(startsWith(name, "~")) ? "element" : (isSxTruthy(dictHas(primTypes, name)) ? get(primTypes, name) : "any"))))))))))))))))))); -})()); -})()); }; -PRIMITIVES["infer-list-type"] = inferListType; - - // infer-if-type - var inferIfType = function(args, typeEnv, primTypes, typeRegistry) { return (isSxTruthy((len(args) < 2)) ? "nil" : (function() { - var thenType = inferType(nth(args, 1), typeEnv, primTypes, typeRegistry); - return (isSxTruthy((len(args) >= 3)) ? typeUnion(thenType, inferType(nth(args, 2), typeEnv, primTypes, typeRegistry)) : typeUnion(thenType, "nil")); -})()); }; -PRIMITIVES["infer-if-type"] = inferIfType; - - // infer-let-type - var inferLetType = function(args, typeEnv, primTypes, typeRegistry) { return (isSxTruthy((len(args) < 2)) ? "nil" : (function() { - var bindings = first(args); - var body = last(args); - var extended = merge(typeEnv, {}); - { var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var binding = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(binding) == "list")) && (len(binding) >= 2)))) { - (function() { - var name = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : (String(first(binding)))); - var valType = inferType(nth(binding, 1), extended, primTypes, typeRegistry); - return dictSet(extended, name, valType); -})(); -} } } - return inferType(body, extended, primTypes, typeRegistry); -})()); }; -PRIMITIVES["infer-let-type"] = inferLetType; - - // make-diagnostic - var makeDiagnostic = function(level, message, component, expr) { return {"level": level, "component": component, "expr": expr, "message": message}; }; -PRIMITIVES["make-diagnostic"] = makeDiagnostic; - - // check-primitive-call - var checkPrimitiveCall = function(name, args, typeEnv, primTypes, primParamTypes, compName, typeRegistry) { return (function() { - var diagnostics = []; - if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(primParamTypes))) && dictHas(primParamTypes, name)))) { - (function() { - var sig = get(primParamTypes, name); - var positional = get(sig, "positional"); - var restType = get(sig, "rest-type"); - return forEach(function(idx) { return (isSxTruthy((idx < len(args))) ? (isSxTruthy((idx < len(positional))) ? (function() { - var paramInfo = nth(positional, idx); - var argExpr = nth(args, idx); - return (function() { - var expectedType = nth(paramInfo, 1); - return (isSxTruthy(!isSxTruthy(isNil(expectedType))) ? (function() { - var actual = inferType(argExpr, typeEnv, primTypes, typeRegistry); - return (isSxTruthy((isSxTruthy(!isSxTruthy(typeAny_p(expectedType))) && isSxTruthy(!isSxTruthy(typeAny_p(actual))) && !isSxTruthy(subtypeResolved_p(actual, expectedType, typeRegistry)))) ? append_b(diagnostics, makeDiagnostic("error", (String("Argument ") + String((idx + 1)) + String(" of `") + String(name) + String("` expects ") + String(expectedType) + String(", got ") + String(actual)), compName, argExpr)) : NIL); -})() : NIL); -})(); -})() : (isSxTruthy(!isSxTruthy(isNil(restType))) ? (function() { - var argExpr = nth(args, idx); - var actual = inferType(argExpr, typeEnv, primTypes, typeRegistry); - return (isSxTruthy((isSxTruthy(!isSxTruthy(typeAny_p(restType))) && isSxTruthy(!isSxTruthy(typeAny_p(actual))) && !isSxTruthy(subtypeResolved_p(actual, restType, typeRegistry)))) ? append_b(diagnostics, makeDiagnostic("error", (String("Argument ") + String((idx + 1)) + String(" of `") + String(name) + String("` expects ") + String(restType) + String(", got ") + String(actual)), compName, argExpr)) : NIL); -})() : NIL)) : NIL); }, range(0, len(args), 1)); -})(); -} - return diagnostics; -})(); }; -PRIMITIVES["check-primitive-call"] = checkPrimitiveCall; - - // check-component-call - var checkComponentCall = function(compName, comp, callArgs, typeEnv, primTypes, typeRegistry) { return (function() { - var diagnostics = []; - var paramTypes = componentParamTypes(comp); - var params = componentParams(comp); - if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(paramTypes))) && !isSxTruthy(isEmpty(keys(paramTypes)))))) { - (function() { - var i = 0; - var providedKeys = []; - { var _c = range(0, len(callArgs), 1); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; if (isSxTruthy((idx < len(callArgs)))) { - (function() { - var arg = nth(callArgs, idx); - return (isSxTruthy((typeOf(arg) == "keyword")) ? (function() { - var keyName = keywordName(arg); - providedKeys.push(keyName); - return (isSxTruthy(((idx + 1) < len(callArgs))) ? (function() { - var valExpr = nth(callArgs, (idx + 1)); - return (isSxTruthy(dictHas(paramTypes, keyName)) ? (function() { - var expected = get(paramTypes, keyName); - var actual = inferType(valExpr, typeEnv, primTypes, typeRegistry); - return (isSxTruthy((isSxTruthy(!isSxTruthy(typeAny_p(expected))) && isSxTruthy(!isSxTruthy(typeAny_p(actual))) && !isSxTruthy(subtypeResolved_p(actual, expected, typeRegistry)))) ? append_b(diagnostics, makeDiagnostic("error", (String("Keyword :") + String(keyName) + String(" of ") + String(compName) + String(" expects ") + String(expected) + String(", got ") + String(actual)), compName, valExpr)) : NIL); -})() : NIL); -})() : NIL); -})() : NIL); -})(); -} } } - { var _c = params; for (var _i = 0; _i < _c.length; _i++) { var paramName = _c[_i]; if (isSxTruthy((isSxTruthy(dictHas(paramTypes, paramName)) && isSxTruthy(!isSxTruthy(contains(providedKeys, paramName))) && !isSxTruthy(typeNullable_p(get(paramTypes, paramName)))))) { - diagnostics.push(makeDiagnostic("warning", (String("Required param :") + String(paramName) + String(" of ") + String(compName) + String(" not provided")), compName, NIL)); -} } } - return forEach(function(key) { return (isSxTruthy(!isSxTruthy(contains(params, key))) ? append_b(diagnostics, makeDiagnostic("warning", (String("Unknown keyword :") + String(key) + String(" passed to ") + String(compName)), compName, NIL)) : NIL); }, providedKeys); -})(); -} - return diagnostics; -})(); }; -PRIMITIVES["check-component-call"] = checkComponentCall; - - // check-body-walk - var checkBodyWalk = function(node, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations) { return (function() { - var kind = typeOf(node); - return (isSxTruthy((kind == "list")) ? (isSxTruthy(!isSxTruthy(isEmpty(node))) ? (function() { - var head = first(node); - var args = rest(node); - if (isSxTruthy((typeOf(head) == "symbol"))) { - (function() { - var name = symbolName(head); - if (isSxTruthy(startsWith(name, "~"))) { - (function() { - var compVal = envGet(env, name); - return (isSxTruthy((typeOf(compVal) == "component")) ? forEach(function(d) { return append_b(diagnostics, d); }, checkComponentCall(name, compVal, args, typeEnv, primTypes, typeRegistry)) : NIL); -})(); - if (isSxTruthy(!isSxTruthy(isNil(effectAnnotations)))) { - (function() { - var callerEffects = getEffects(compName, effectAnnotations); - return forEach(function(d) { return append_b(diagnostics, d); }, checkEffectCall(name, callerEffects, effectAnnotations, compName)); -})(); -} -} - if (isSxTruthy((isSxTruthy(!isSxTruthy(startsWith(name, "~"))) && isSxTruthy(!isSxTruthy(isNil(primParamTypes))) && dictHas(primParamTypes, name)))) { - { var _c = checkPrimitiveCall(name, args, typeEnv, primTypes, primParamTypes, compName, typeRegistry); for (var _i = 0; _i < _c.length; _i++) { var d = _c[_i]; diagnostics.push(d); } } -} - if (isSxTruthy((isSxTruthy(!isSxTruthy(startsWith(name, "~"))) && !isSxTruthy(isNil(effectAnnotations))))) { - (function() { - var callerEffects = getEffects(compName, effectAnnotations); - return forEach(function(d) { return append_b(diagnostics, d); }, checkEffectCall(name, callerEffects, effectAnnotations, compName)); -})(); -} - if (isSxTruthy(sxOr((name == "let"), (name == "let*")))) { - if (isSxTruthy((len(args) >= 2))) { - (function() { - var bindings = first(args); - var bodyExprs = rest(args); - var extended = merge(typeEnv, {}); - { var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var binding = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(binding) == "list")) && (len(binding) >= 2)))) { - (function() { - var bname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : (String(first(binding)))); - var valType = inferType(nth(binding, 1), extended, primTypes, typeRegistry); - return dictSet(extended, bname, valType); -})(); -} } } - return forEach(function(body) { return checkBodyWalk(body, compName, extended, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations); }, bodyExprs); -})(); -} -} - return (isSxTruthy((name == "define")) ? (isSxTruthy((len(args) >= 2)) ? (function() { - var defName = (isSxTruthy((typeOf(first(args)) == "symbol")) ? symbolName(first(args)) : NIL); - var defVal = nth(args, 1); - if (isSxTruthy(defName)) { - typeEnv[defName] = inferType(defVal, typeEnv, primTypes, typeRegistry); -} - return checkBodyWalk(defVal, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations); -})() : NIL) : NIL); -})(); -} - return forEach(function(child) { return checkBodyWalk(child, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations); }, args); -})() : NIL) : NIL); -})(); }; -PRIMITIVES["check-body-walk"] = checkBodyWalk; - - // check-component - var checkComponent = function(compName, env, primTypes, primParamTypes, typeRegistry, effectAnnotations) { return (function() { - var comp = envGet(env, compName); - var diagnostics = []; - if (isSxTruthy((typeOf(comp) == "component"))) { - (function() { - var body = componentBody(comp); - var params = componentParams(comp); - var paramTypes = componentParamTypes(comp); - var typeEnv = {}; - { var _c = params; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; typeEnv[p] = (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(paramTypes))) && dictHas(paramTypes, p))) ? get(paramTypes, p) : "any"); } } - if (isSxTruthy(componentHasChildren(comp))) { - typeEnv["children"] = ["list-of", "element"]; -} - return checkBodyWalk(body, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations); -})(); -} - return diagnostics; -})(); }; -PRIMITIVES["check-component"] = checkComponent; - - // check-all - var checkAll = function(env, primTypes, primParamTypes, typeRegistry, effectAnnotations) { return (function() { - var allDiagnostics = []; - { var _c = keys(env); for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; (function() { - var val = envGet(env, name); - return (isSxTruthy((typeOf(val) == "component")) ? forEach(function(d) { return append_b(allDiagnostics, d); }, checkComponent(name, env, primTypes, primParamTypes, typeRegistry, effectAnnotations)) : NIL); -})(); } } - return allDiagnostics; -})(); }; -PRIMITIVES["check-all"] = checkAll; - - // build-type-registry - var buildTypeRegistry = function(primDeclarations, ioDeclarations) { return (function() { - var registry = {}; - { var _c = primDeclarations; for (var _i = 0; _i < _c.length; _i++) { var decl = _c[_i]; (function() { - var name = get(decl, "name"); - var returns = get(decl, "returns"); - return (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(name))) && !isSxTruthy(isNil(returns)))) ? dictSet(registry, name, returns) : NIL); -})(); } } - { var _c = ioDeclarations; for (var _i = 0; _i < _c.length; _i++) { var decl = _c[_i]; (function() { - var name = get(decl, "name"); - var returns = get(decl, "returns"); - return (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(name))) && !isSxTruthy(isNil(returns)))) ? dictSet(registry, name, returns) : NIL); -})(); } } - return registry; -})(); }; -PRIMITIVES["build-type-registry"] = buildTypeRegistry; - - // type-def-name - var typeDefName = function(td) { return get(td, "name"); }; -PRIMITIVES["type-def-name"] = typeDefName; - - // type-def-params - var typeDefParams = function(td) { return get(td, "params"); }; -PRIMITIVES["type-def-params"] = typeDefParams; - - // type-def-body - var typeDefBody = function(td) { return get(td, "body"); }; -PRIMITIVES["type-def-body"] = typeDefBody; - - // resolve-type - var resolveType = function(t, registry) { return (isSxTruthy(isNil(registry)) ? t : (isSxTruthy((typeOf(t) == "string")) ? (isSxTruthy(dictHas(registry, t)) ? (function() { - var td = get(registry, t); - return (function() { - var params = typeDefParams(td); - var body = typeDefBody(td); - return (isSxTruthy(isEmpty(params)) ? resolveType(body, registry) : t); -})(); -})() : t) : (isSxTruthy((typeOf(t) == "list")) ? (isSxTruthy(isEmpty(t)) ? t : (function() { - var head = first(t); - return (isSxTruthy(sxOr((head == "or"), (head == "list-of"), (head == "->"), (head == "dict-of"))) ? cons(head, map(function(m) { return resolveType(m, registry); }, rest(t))) : (isSxTruthy((isSxTruthy((typeOf(head) == "string")) && dictHas(registry, head))) ? (function() { - var td = get(registry, head); - var params = typeDefParams(td); - var body = typeDefBody(td); - var args = rest(t); - return (isSxTruthy((len(params) == len(args))) ? resolveType(substituteTypeVars(body, params, args), registry) : t); -})() : t)); -})()) : (isSxTruthy((typeOf(t) == "dict")) ? mapDict(function(k, v) { return resolveType(v, registry); }, t) : t)))); }; -PRIMITIVES["resolve-type"] = resolveType; - - // substitute-type-vars - var substituteTypeVars = function(body, params, args) { return (function() { - var subst = {}; - { var _c = range(0, len(params), 1); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; subst[nth(params, i)] = nth(args, i); } } - return substituteInType(body, subst); -})(); }; -PRIMITIVES["substitute-type-vars"] = substituteTypeVars; - - // substitute-in-type - var substituteInType = function(t, subst) { return (isSxTruthy((typeOf(t) == "string")) ? (isSxTruthy(dictHas(subst, t)) ? get(subst, t) : t) : (isSxTruthy((typeOf(t) == "list")) ? map(function(m) { return substituteInType(m, subst); }, t) : (isSxTruthy((typeOf(t) == "dict")) ? mapDict(function(k, v) { return substituteInType(v, subst); }, t) : t))); }; -PRIMITIVES["substitute-in-type"] = substituteInType; - - // subtype-resolved? - var subtypeResolved_p = function(a, b, registry) { return (isSxTruthy(isNil(registry)) ? subtype_p(a, b) : (function() { - var ra = resolveType(a, registry); - var rb = resolveType(b, registry); - return (isSxTruthy((isSxTruthy((typeOf(ra) == "dict")) && (typeOf(rb) == "dict"))) ? isEvery(function(key) { return (isSxTruthy(dictHas(ra, key)) && subtypeResolved_p(get(ra, key), get(rb, key), registry)); }, keys(rb)) : subtype_p(ra, rb)); -})()); }; -PRIMITIVES["subtype-resolved?"] = subtypeResolved_p; - - // get-effects - var getEffects = function(name, effectAnnotations) { return (isSxTruthy(isNil(effectAnnotations)) ? NIL : (isSxTruthy(dictHas(effectAnnotations, name)) ? get(effectAnnotations, name) : NIL)); }; -PRIMITIVES["get-effects"] = getEffects; - - // effects-subset? - var effectsSubset_p = function(calleeEffects, callerEffects) { return (isSxTruthy(isNil(callerEffects)) ? true : (isSxTruthy(isNil(calleeEffects)) ? true : isEvery(function(e) { return contains(callerEffects, e); }, calleeEffects))); }; -PRIMITIVES["effects-subset?"] = effectsSubset_p; - - // check-effect-call - var checkEffectCall = function(calleeName, callerEffects, effectAnnotations, compName) { return (function() { - var diagnostics = []; - var calleeEffects = getEffects(calleeName, effectAnnotations); - if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(callerEffects))) && isSxTruthy(!isSxTruthy(isNil(calleeEffects))) && !isSxTruthy(effectsSubset_p(calleeEffects, callerEffects))))) { - diagnostics.push(makeDiagnostic("error", (String("`") + String(calleeName) + String("` has effects ") + String(join(", ", calleeEffects)) + String(" but `") + String(compName) + String("` only allows ") + String((isSxTruthy(isEmpty(callerEffects)) ? "[pure]" : join(", ", callerEffects)))), compName, NIL)); -} - return diagnostics; -})(); }; -PRIMITIVES["check-effect-call"] = checkEffectCall; - - // build-effect-annotations - var buildEffectAnnotations = function(ioDeclarations) { return (function() { - var annotations = {}; - { var _c = ioDeclarations; for (var _i = 0; _i < _c.length; _i++) { var decl = _c[_i]; (function() { - var name = get(decl, "name"); - return (isSxTruthy(!isSxTruthy(isNil(name))) ? dictSet(annotations, name, ["io"]) : NIL); -})(); } } - return annotations; -})(); }; -PRIMITIVES["build-effect-annotations"] = buildEffectAnnotations; - - // check-component-effects - var checkComponentEffects = function(compName, env, effectAnnotations) { return (function() { - var comp = envGet(env, compName); - var diagnostics = []; - if (isSxTruthy((typeOf(comp) == "component"))) { - (function() { - var body = componentBody(comp); - return checkBodyWalk(body, compName, {}, {}, NIL, env, diagnostics, NIL, effectAnnotations); -})(); -} - return diagnostics; -})(); }; -PRIMITIVES["check-component-effects"] = checkComponentEffects; - - // check-all-effects - var checkAllEffects = function(env, effectAnnotations) { return (function() { - var allDiagnostics = []; - { var _c = keys(env); for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; (function() { - var val = envGet(env, name); - return (isSxTruthy((typeOf(val) == "component")) ? forEach(function(d) { return append_b(allDiagnostics, d); }, checkComponentEffects(name, env, effectAnnotations)) : NIL); -})(); } } - return allDiagnostics; -})(); }; -PRIMITIVES["check-all-effects"] = checkAllEffects; - - // ========================================================================= // Post-transpilation fixups // ========================================================================= diff --git a/shared/static/wasm/sx/engine.sxbc b/shared/static/wasm/sx/engine.sxbc index 228b03ea..8edabddd 100644 --- a/shared/static/wasm/sx/engine.sxbc +++ b/shared/static/wasm/sx/engine.sxbc @@ -504,7 +504,7 @@ "[data-sx-signal]" "for-each" (code :arity 1 - :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 94 0 16 1 1 3 0 52 2 0 2 17 2 16 2 1 5 0 52 4 0 2 33 67 0 16 1 1 5 0 16 2 52 6 0 3 17 3 16 1 16 2 1 8 0 52 7 0 2 52 6 0 2 17 4 20 9 0 16 4 48 1 17 5 20 10 0 20 11 0 16 3 48 1 16 5 48 2 5 20 12 0 16 0 1 1 0 49 2 32 1 0 2 32 1 0 2 50) + :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 93 0 16 1 1 3 0 52 2 0 2 17 2 16 2 1 5 0 52 4 0 2 33 66 0 16 1 1 5 0 16 2 52 6 0 3 17 3 16 1 16 2 1 8 0 52 7 0 2 52 6 0 2 17 4 20 9 0 16 4 48 1 17 5 20 10 0 16 3 52 11 0 1 16 5 48 2 5 20 12 0 16 0 1 1 0 49 2 32 1 0 2 32 1 0 2 50) :constants ( "dom-get-attr" "data-sx-signal" diff --git a/shared/static/wasm/sx/engine.sxbc.json b/shared/static/wasm/sx/engine.sxbc.json index 1ede4615..5b156510 100644 --- a/shared/static/wasm/sx/engine.sxbc.json +++ b/shared/static/wasm/sx/engine.sxbc.json @@ -1 +1 @@ -{"magic":"SXBC","version":1,"hash":"e038227f8fc8f0ad","module":{"bytecode":[1,2,0,1,3,0,1,4,0,1,5,0,1,6,0,52,1,0,5,128,0,0,5,1,8,0,128,7,0,5,51,10,0,128,9,0,5,51,12,0,128,11,0,5,51,14,0,128,13,0,5,51,16,0,128,15,0,5,51,18,0,128,17,0,5,51,20,0,128,19,0,5,51,22,0,128,21,0,5,51,24,0,128,23,0,5,51,26,0,128,25,0,5,51,28,0,128,27,0,5,51,30,0,128,29,0,5,51,32,0,128,31,0,5,51,34,0,128,33,0,5,51,36,0,128,35,0,5,51,38,0,128,37,0,5,51,40,0,128,39,0,5,51,42,0,128,41,0,5,51,44,0,128,43,0,5,51,46,0,128,45,0,5,51,48,0,128,47,0,5,51,50,0,128,49,0,5,51,52,0,128,51,0,5,51,54,0,128,53,0,5,51,56,0,128,55,0,5,1,58,0,128,57,0,5,51,60,0,128,59,0,5,51,62,0,128,61,0,5,51,64,0,128,63,0,5,51,66,0,128,65,0,5,51,68,0,128,67,0,5,51,70,0,128,69,0,50],"constants":[{"t":"s","v":"ENGINE_VERBS"},{"t":"s","v":"list"},{"t":"s","v":"get"},{"t":"s","v":"post"},{"t":"s","v":"put"},{"t":"s","v":"delete"},{"t":"s","v":"patch"},{"t":"s","v":"DEFAULT_SWAP"},{"t":"s","v":"outerHTML"},{"t":"s","v":"parse-time"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,6,0,1,1,0,32,74,0,16,0,1,3,0,52,2,0,2,33,12,0,16,0,1,1,0,52,4,0,2,32,50,0,16,0,1,5,0,52,2,0,2,33,29,0,16,0,1,5,0,1,8,0,52,7,0,3,1,1,0,52,4,0,2,1,9,0,52,6,0,2,32,9,0,16,0,1,1,0,52,4,0,2,50],"constants":[{"t":"s","v":"nil?"},{"t":"n","v":0},{"t":"s","v":"ends-with?"},{"t":"s","v":"ms"},{"t":"s","v":"parse-int"},{"t":"s","v":"s"},{"t":"s","v":"*"},{"t":"s","v":"replace"},{"t":"s","v":""},{"t":"n","v":1000}],"arity":1}},{"t":"s","v":"parse-trigger-spec"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,4,0,2,32,27,0,16,0,1,2,0,52,1,0,2,17,1,51,4,0,51,6,0,16,1,52,5,0,2,52,3,0,2,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"split"},{"t":"s","v":","},{"t":"s","v":"filter"},{"t":"code","v":{"bytecode":[16,0,52,1,0,1,52,0,0,1,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"nil?"}],"arity":1}},{"t":"s","v":"map"},{"t":"code","v":{"bytecode":[16,0,52,1,0,1,1,2,0,52,0,0,2,17,1,16,1,52,3,0,1,33,4,0,2,32,111,0,16,1,52,5,0,1,1,6,0,52,4,0,2,6,33,14,0,5,16,1,52,8,0,1,1,9,0,52,7,0,2,33,37,0,1,11,0,1,6,0,1,12,0,1,13,0,20,14,0,16,1,1,16,0,52,15,0,2,48,1,52,10,0,2,52,10,0,4,32,40,0,52,10,0,0,17,2,51,18,0,1,2,16,1,52,19,0,1,52,17,0,2,5,1,11,0,16,1,52,5,0,1,1,12,0,16,2,52,10,0,4,50],"constants":[{"t":"s","v":"split"},{"t":"s","v":"trim"},{"t":"s","v":" "},{"t":"s","v":"empty?"},{"t":"s","v":"="},{"t":"s","v":"first"},{"t":"s","v":"every"},{"t":"s","v":">="},{"t":"s","v":"len"},{"t":"n","v":2},{"t":"s","v":"dict"},{"t":"s","v":"event"},{"t":"s","v":"modifiers"},{"t":"s","v":"interval"},{"t":"s","v":"parse-time"},{"t":"s","v":"nth"},{"t":"n","v":1},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,33,13,0,18,0,1,1,0,3,52,2,0,3,32,97,0,16,0,1,3,0,52,0,0,2,33,13,0,18,0,1,3,0,3,52,2,0,3,32,72,0,16,0,1,5,0,52,4,0,2,33,26,0,18,0,1,6,0,20,7,0,16,0,1,9,0,52,8,0,2,48,1,52,2,0,3,32,34,0,16,0,1,10,0,52,4,0,2,33,21,0,18,0,1,11,0,16,0,1,12,0,52,8,0,2,52,2,0,3,32,1,0,2,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"once"},{"t":"s","v":"dict-set!"},{"t":"s","v":"changed"},{"t":"s","v":"starts-with?"},{"t":"s","v":"delay:"},{"t":"s","v":"delay"},{"t":"s","v":"parse-time"},{"t":"s","v":"slice"},{"t":"n","v":6},{"t":"s","v":"from:"},{"t":"s","v":"from"},{"t":"n","v":5}],"arity":1,"upvalue-count":1}},{"t":"s","v":"rest"}],"arity":1}}],"arity":1}},{"t":"s","v":"default-trigger"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,33,24,0,1,4,0,1,5,0,1,6,0,52,3,0,0,52,3,0,4,52,2,0,1,32,85,0,16,0,1,7,0,52,0,0,2,6,34,24,0,5,16,0,1,8,0,52,0,0,2,6,34,10,0,5,16,0,1,9,0,52,0,0,2,33,24,0,1,4,0,1,10,0,1,6,0,52,3,0,0,52,3,0,4,52,2,0,1,32,21,0,1,4,0,1,11,0,1,6,0,52,3,0,0,52,3,0,4,52,2,0,1,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"FORM"},{"t":"s","v":"list"},{"t":"s","v":"dict"},{"t":"s","v":"event"},{"t":"s","v":"submit"},{"t":"s","v":"modifiers"},{"t":"s","v":"INPUT"},{"t":"s","v":"SELECT"},{"t":"s","v":"TEXTAREA"},{"t":"s","v":"change"},{"t":"s","v":"click"}],"arity":1}},{"t":"s","v":"get-verb-info"},{"t":"code","v":{"bytecode":[51,1,0,1,0,20,2,0,52,0,0,2,50],"constants":[{"t":"s","v":"some"},{"t":"code","v":{"bytecode":[20,0,0,18,0,1,2,0,16,0,52,1,0,2,48,2,17,1,16,1,33,21,0,1,4,0,16,0,52,5,0,1,1,6,0,16,1,52,3,0,4,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"str"},{"t":"s","v":"sx-"},{"t":"s","v":"dict"},{"t":"s","v":"method"},{"t":"s","v":"upper"},{"t":"s","v":"url"}],"arity":1,"upvalue-count":1}},{"t":"s","v":"ENGINE_VERBS"}],"arity":1}},{"t":"s","v":"build-request-headers"},{"t":"code","v":{"bytecode":[1,1,0,1,2,0,1,3,0,20,4,0,48,0,52,0,0,4,17,3,20,5,0,16,0,1,6,0,48,2,17,4,16,4,33,14,0,16,3,1,8,0,16,4,52,7,0,3,32,1,0,2,5,20,5,0,20,9,0,1,10,0,48,1,1,11,0,48,2,17,4,16,4,33,14,0,16,3,1,12,0,16,4,52,7,0,3,32,1,0,2,5,16,2,33,14,0,16,3,1,13,0,16,2,52,7,0,3,32,1,0,2,5,20,5,0,16,0,1,14,0,48,2,17,4,16,4,33,38,0,20,15,0,16,4,48,1,17,5,16,5,33,20,0,51,17,0,1,3,1,5,16,5,52,18,0,1,52,16,0,2,32,1,0,2,32,1,0,2,5,16,3,50],"constants":[{"t":"s","v":"dict"},{"t":"s","v":"SX-Request"},{"t":"s","v":"true"},{"t":"s","v":"SX-Current-URL"},{"t":"s","v":"browser-location-href"},{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-target"},{"t":"s","v":"dict-set!"},{"t":"s","v":"SX-Target"},{"t":"s","v":"dom-query"},{"t":"s","v":"script[data-components][data-hash]"},{"t":"s","v":"data-hash"},{"t":"s","v":"SX-Components-Hash"},{"t":"s","v":"SX-Css"},{"t":"s","v":"sx-headers"},{"t":"s","v":"parse-header-value"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[18,0,16,0,18,1,16,0,52,2,0,2,52,1,0,1,52,0,0,3,50],"constants":[{"t":"s","v":"dict-set!"},{"t":"s","v":"str"},{"t":"s","v":"get"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"keys"}],"arity":3}},{"t":"s","v":"process-response-headers"},{"t":"code","v":{"bytecode":[1,1,0,16,0,1,2,0,48,1,1,3,0,16,0,1,4,0,48,1,1,5,0,16,0,1,6,0,48,1,1,7,0,16,0,1,8,0,48,1,1,9,0,16,0,1,10,0,48,1,1,11,0,16,0,1,12,0,48,1,1,13,0,16,0,1,14,0,48,1,1,15,0,16,0,1,16,0,48,1,1,17,0,16,0,1,18,0,48,1,1,19,0,16,0,1,20,0,48,1,1,21,0,16,0,1,22,0,48,1,1,23,0,16,0,1,24,0,48,1,1,25,0,16,0,1,26,0,48,1,52,0,0,26,50],"constants":[{"t":"s","v":"dict"},{"t":"s","v":"redirect"},{"t":"s","v":"SX-Redirect"},{"t":"s","v":"refresh"},{"t":"s","v":"SX-Refresh"},{"t":"s","v":"trigger"},{"t":"s","v":"SX-Trigger"},{"t":"s","v":"retarget"},{"t":"s","v":"SX-Retarget"},{"t":"s","v":"reswap"},{"t":"s","v":"SX-Reswap"},{"t":"s","v":"location"},{"t":"s","v":"SX-Location"},{"t":"s","v":"replace-url"},{"t":"s","v":"SX-Replace-Url"},{"t":"s","v":"css-hash"},{"t":"s","v":"SX-Css-Hash"},{"t":"s","v":"trigger-swap"},{"t":"s","v":"SX-Trigger-After-Swap"},{"t":"s","v":"trigger-settle"},{"t":"s","v":"SX-Trigger-After-Settle"},{"t":"s","v":"content-type"},{"t":"s","v":"Content-Type"},{"t":"s","v":"cache-invalidate"},{"t":"s","v":"SX-Cache-Invalidate"},{"t":"s","v":"cache-update"},{"t":"s","v":"SX-Cache-Update"}],"arity":1}},{"t":"s","v":"parse-swap-spec"},{"t":"code","v":{"bytecode":[16,0,6,34,4,0,5,20,1,0,1,2,0,52,0,0,2,17,2,16,2,52,3,0,1,17,3,16,1,17,4,51,5,0,1,4,16,2,52,6,0,1,52,4,0,2,5,1,8,0,16,3,1,9,0,16,4,52,7,0,4,50],"constants":[{"t":"s","v":"split"},{"t":"s","v":"DEFAULT_SWAP"},{"t":"s","v":" "},{"t":"s","v":"first"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,33,6,0,3,19,0,32,19,0,16,0,1,2,0,52,0,0,2,33,6,0,4,19,0,32,1,0,2,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"transition:true"},{"t":"s","v":"transition:false"}],"arity":1,"upvalue-count":1}},{"t":"s","v":"rest"},{"t":"s","v":"dict"},{"t":"s","v":"style"},{"t":"s","v":"transition"}],"arity":2}},{"t":"s","v":"parse-retry-spec"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,4,0,2,32,62,0,16,0,1,2,0,52,1,0,2,17,1,1,4,0,16,1,52,5,0,1,1,6,0,16,1,1,9,0,52,8,0,2,1,10,0,52,7,0,2,1,11,0,16,1,1,12,0,52,8,0,2,1,13,0,52,7,0,2,52,3,0,6,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"split"},{"t":"s","v":":"},{"t":"s","v":"dict"},{"t":"s","v":"strategy"},{"t":"s","v":"first"},{"t":"s","v":"start-ms"},{"t":"s","v":"parse-int"},{"t":"s","v":"nth"},{"t":"n","v":1},{"t":"n","v":1000},{"t":"s","v":"cap-ms"},{"t":"n","v":2},{"t":"n","v":30000}],"arity":1}},{"t":"s","v":"next-retry-ms"},{"t":"code","v":{"bytecode":[16,0,1,2,0,52,1,0,2,16,1,52,0,0,2,50],"constants":[{"t":"s","v":"min"},{"t":"s","v":"*"},{"t":"n","v":2}],"arity":2}},{"t":"s","v":"filter-params"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,5,0,16,1,32,116,0,16,0,1,2,0,52,1,0,2,33,7,0,52,3,0,0,32,97,0,16,0,1,4,0,52,1,0,2,33,5,0,16,1,32,80,0,16,0,1,6,0,52,5,0,2,33,39,0,20,8,0,16,0,1,11,0,52,10,0,2,1,12,0,52,9,0,2,52,7,0,2,17,2,51,14,0,1,2,16,1,52,13,0,2,32,29,0,20,8,0,16,0,1,12,0,52,9,0,2,52,7,0,2,17,2,51,15,0,1,2,16,1,52,13,0,2,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"="},{"t":"s","v":"none"},{"t":"s","v":"list"},{"t":"s","v":"*"},{"t":"s","v":"starts-with?"},{"t":"s","v":"not "},{"t":"s","v":"map"},{"t":"s","v":"trim"},{"t":"s","v":"split"},{"t":"s","v":"slice"},{"t":"n","v":4},{"t":"s","v":","},{"t":"s","v":"filter"},{"t":"code","v":{"bytecode":[18,0,16,0,52,2,0,1,52,1,0,2,52,0,0,1,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"contains?"},{"t":"s","v":"first"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[18,0,16,0,52,1,0,1,52,0,0,2,50],"constants":[{"t":"s","v":"contains?"},{"t":"s","v":"first"}],"arity":1,"upvalue-count":1}}],"arity":2}},{"t":"s","v":"resolve-target"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,52,2,0,1,6,34,10,0,5,16,1,1,4,0,52,3,0,2,33,5,0,16,0,32,29,0,16,1,1,5,0,52,3,0,2,33,10,0,20,6,0,16,0,49,1,32,7,0,20,7,0,16,1,49,1,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-target"},{"t":"s","v":"nil?"},{"t":"s","v":"="},{"t":"s","v":"this"},{"t":"s","v":"closest"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-query"}],"arity":1}},{"t":"s","v":"apply-optimistic"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,52,2,0,1,33,4,0,2,32,191,0,20,3,0,16,0,48,1,6,34,3,0,5,16,0,17,2,1,5,0,16,2,1,6,0,16,1,52,4,0,4,17,3,16,1,1,8,0,52,7,0,2,33,50,0,16,3,1,10,0,20,11,0,16,2,1,10,0,48,2,52,9,0,3,5,20,12,0,16,2,1,10,0,1,13,0,48,3,5,20,12,0,16,2,1,14,0,1,15,0,48,3,32,94,0,16,1,1,16,0,52,7,0,2,33,34,0,16,3,1,17,0,20,18,0,16,2,1,17,0,48,2,52,9,0,3,5,20,19,0,16,2,1,17,0,3,48,3,32,48,0,16,1,1,21,0,52,20,0,2,33,35,0,16,1,1,23,0,52,22,0,2,17,4,16,3,1,24,0,16,4,52,9,0,3,5,20,25,0,16,2,16,4,48,2,32,1,0,2,5,16,3,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-optimistic"},{"t":"s","v":"nil?"},{"t":"s","v":"resolve-target"},{"t":"s","v":"dict"},{"t":"s","v":"target"},{"t":"s","v":"directive"},{"t":"s","v":"="},{"t":"s","v":"remove"},{"t":"s","v":"dict-set!"},{"t":"s","v":"opacity"},{"t":"s","v":"dom-get-style"},{"t":"s","v":"dom-set-style"},{"t":"s","v":"0"},{"t":"s","v":"pointer-events"},{"t":"s","v":"none"},{"t":"s","v":"disable"},{"t":"s","v":"disabled"},{"t":"s","v":"dom-get-prop"},{"t":"s","v":"dom-set-prop"},{"t":"s","v":"starts-with?"},{"t":"s","v":"add-class:"},{"t":"s","v":"slice"},{"t":"n","v":10},{"t":"s","v":"add-class"},{"t":"s","v":"dom-add-class"}],"arity":1}},{"t":"s","v":"revert-optimistic"},{"t":"code","v":{"bytecode":[16,0,33,153,0,16,0,1,1,0,52,0,0,2,17,1,16,0,1,2,0,52,0,0,2,17,2,16,2,1,4,0,52,3,0,2,33,44,0,20,5,0,16,1,1,6,0,16,0,1,6,0,52,0,0,2,6,34,4,0,5,1,7,0,48,3,5,20,5,0,16,1,1,8,0,1,7,0,49,3,32,72,0,16,2,1,9,0,52,3,0,2,33,28,0,20,10,0,16,1,1,11,0,16,0,1,11,0,52,0,0,2,6,34,2,0,5,4,49,3,32,32,0,16,0,1,12,0,52,0,0,2,33,19,0,20,13,0,16,1,16,0,1,12,0,52,0,0,2,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"target"},{"t":"s","v":"directive"},{"t":"s","v":"="},{"t":"s","v":"remove"},{"t":"s","v":"dom-set-style"},{"t":"s","v":"opacity"},{"t":"s","v":""},{"t":"s","v":"pointer-events"},{"t":"s","v":"disable"},{"t":"s","v":"dom-set-prop"},{"t":"s","v":"disabled"},{"t":"s","v":"add-class"},{"t":"s","v":"dom-remove-class"}],"arity":1}},{"t":"s","v":"find-oob-swaps"},{"t":"code","v":{"bytecode":[52,0,0,0,17,1,51,2,0,1,0,1,1,1,3,0,1,4,0,52,0,0,2,52,1,0,2,5,16,1,50],"constants":[{"t":"s","v":"list"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,18,0,1,2,0,16,0,1,3,0,52,1,0,3,48,2,17,1,51,5,0,1,0,0,1,16,1,52,4,0,2,50],"constants":[{"t":"s","v":"dom-query-all"},{"t":"s","v":"str"},{"t":"s","v":"["},{"t":"s","v":"]"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,18,0,48,2,6,34,4,0,5,1,1,0,17,1,20,2,0,16,0,48,1,17,2,20,3,0,16,0,18,0,48,2,5,16,2,33,29,0,20,4,0,18,1,1,6,0,16,0,1,7,0,16,1,1,8,0,16,2,52,5,0,6,49,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"outerHTML"},{"t":"s","v":"dom-id"},{"t":"s","v":"dom-remove-attr"},{"t":"s","v":"append!"},{"t":"s","v":"dict"},{"t":"s","v":"element"},{"t":"s","v":"swap-type"},{"t":"s","v":"target-id"}],"arity":1,"upvalue-count":2}}],"arity":1,"upvalue-count":2}},{"t":"s","v":"sx-swap-oob"},{"t":"s","v":"hx-swap-oob"}],"arity":1}},{"t":"s","v":"morph-node"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,6,34,11,0,5,20,0,0,16,0,1,2,0,48,2,33,4,0,2,32,137,1,20,0,0,16,0,1,3,0,48,2,6,33,55,0,5,20,4,0,16,0,1,5,0,48,2,6,33,40,0,5,20,0,0,16,1,1,3,0,48,2,6,33,25,0,5,20,7,0,16,0,1,3,0,48,2,20,7,0,16,1,1,3,0,48,2,52,6,0,2,33,12,0,20,8,0,16,0,16,1,49,2,32,53,1,20,10,0,16,0,48,1,20,10,0,16,1,48,1,52,6,0,2,52,9,0,1,6,34,23,0,5,20,11,0,16,0,48,1,20,11,0,16,1,48,1,52,6,0,2,52,9,0,1,33,24,0,20,12,0,20,13,0,16,0,48,1,20,14,0,16,1,48,1,16,0,49,3,32,233,0,20,10,0,16,0,48,1,1,15,0,52,6,0,2,6,34,15,0,5,20,10,0,16,0,48,1,1,16,0,52,6,0,2,33,46,0,20,17,0,16,0,48,1,20,17,0,16,1,48,1,52,6,0,2,52,9,0,1,33,17,0,20,18,0,16,0,20,17,0,16,1,48,1,49,2,32,1,0,2,32,151,0,20,10,0,16,0,48,1,1,19,0,52,6,0,2,33,133,0,20,0,0,16,0,1,3,0,48,2,6,33,44,0,5,20,0,0,16,1,1,3,0,48,2,6,33,29,0,5,20,7,0,16,0,1,3,0,48,2,20,7,0,16,1,1,3,0,48,2,52,6,0,2,52,9,0,1,33,18,0,20,20,0,16,0,48,1,5,20,21,0,16,0,48,1,32,1,0,2,5,20,22,0,16,0,16,1,48,2,5,20,23,0,16,0,48,1,6,33,8,0,5,20,24,0,16,0,48,1,52,9,0,1,33,12,0,20,25,0,16,0,16,1,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-preserve"},{"t":"s","v":"sx-ignore"},{"t":"s","v":"data-sx-island"},{"t":"s","v":"is-processed?"},{"t":"s","v":"island-hydrated"},{"t":"s","v":"="},{"t":"s","v":"dom-get-attr"},{"t":"s","v":"morph-island-children"},{"t":"s","v":"not"},{"t":"s","v":"dom-node-type"},{"t":"s","v":"dom-node-name"},{"t":"s","v":"dom-replace-child"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-clone"},{"t":"n","v":3},{"t":"n","v":8},{"t":"s","v":"dom-text-content"},{"t":"s","v":"dom-set-text-content"},{"t":"n","v":1},{"t":"s","v":"dispose-island"},{"t":"s","v":"dispose-islands-in"},{"t":"s","v":"sync-attrs"},{"t":"s","v":"dom-is-active-element?"},{"t":"s","v":"dom-is-input-element?"},{"t":"s","v":"morph-children"}],"arity":2}},{"t":"s","v":"sync-attrs"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,6,34,4,0,5,1,2,0,17,2,16,2,52,3,0,1,33,7,0,52,4,0,0,32,9,0,16,2,1,6,0,52,5,0,2,17,3,51,8,0,1,0,1,3,20,9,0,16,1,48,1,52,7,0,2,5,51,10,0,1,1,1,3,1,0,20,9,0,16,0,48,1,52,7,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-reactive-attrs"},{"t":"s","v":""},{"t":"s","v":"empty?"},{"t":"s","v":"list"},{"t":"s","v":"split"},{"t":"s","v":","},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,17,1,16,0,1,2,0,52,1,0,2,17,2,20,5,0,18,0,16,1,48,2,16,2,52,4,0,2,52,3,0,1,6,33,13,0,5,18,1,16,1,52,6,0,2,52,3,0,1,33,14,0,20,7,0,18,0,16,1,16,2,49,3,32,1,0,2,50],"constants":[{"t":"s","v":"first"},{"t":"s","v":"nth"},{"t":"n","v":1},{"t":"s","v":"not"},{"t":"s","v":"="},{"t":"s","v":"dom-get-attr"},{"t":"s","v":"contains?"},{"t":"s","v":"dom-set-attr"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"dom-attr-list"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,17,1,20,2,0,18,0,16,1,48,2,52,1,0,1,6,33,31,0,5,18,1,16,1,52,3,0,2,52,1,0,1,6,33,14,0,5,16,1,1,5,0,52,4,0,2,52,1,0,1,33,12,0,20,6,0,18,2,16,1,49,2,32,1,0,2,50],"constants":[{"t":"s","v":"first"},{"t":"s","v":"not"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"contains?"},{"t":"s","v":"="},{"t":"s","v":"data-sx-reactive-attrs"},{"t":"s","v":"dom-remove-attr"}],"arity":1,"upvalue-count":3}}],"arity":2}},{"t":"s","v":"morph-children"},{"t":"code","v":{"bytecode":[20,0,0,16,0,48,1,17,2,20,0,0,16,1,48,1,17,3,51,2,0,52,3,0,0,16,2,52,1,0,3,17,4,1,4,0,17,5,51,6,0,1,4,1,5,1,2,1,0,16,3,52,5,0,2,5,51,7,0,1,5,1,2,1,0,16,5,16,2,52,9,0,1,52,8,0,2,52,5,0,2,50],"constants":[{"t":"s","v":"dom-child-list"},{"t":"s","v":"reduce"},{"t":"code","v":{"bytecode":[20,0,0,16,1,48,1,17,2,16,2,33,16,0,16,0,16,2,16,1,52,1,0,3,5,16,0,32,2,0,16,0,50],"constants":[{"t":"s","v":"dom-id"},{"t":"s","v":"dict-set!"}],"arity":2}},{"t":"s","v":"dict"},{"t":"n","v":0},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,48,1,17,1,16,1,33,11,0,18,0,16,1,52,1,0,2,32,1,0,2,17,2,16,2,6,33,11,0,5,16,2,52,3,0,1,52,2,0,1,33,100,0,18,1,18,2,52,5,0,1,52,4,0,2,6,33,19,0,5,16,2,18,2,18,1,52,7,0,2,52,6,0,2,52,2,0,1,33,39,0,20,8,0,18,3,16,2,18,1,18,2,52,5,0,1,52,4,0,2,33,11,0,18,2,18,1,52,7,0,2,32,1,0,2,48,3,32,1,0,2,5,20,9,0,16,2,16,0,48,2,5,18,1,52,10,0,1,19,1,32,100,0,18,1,18,2,52,5,0,1,52,4,0,2,33,71,0,18,2,18,1,52,7,0,2,17,3,20,0,0,16,3,48,1,6,33,7,0,5,16,1,52,2,0,1,33,19,0,20,8,0,18,3,20,11,0,16,0,48,1,16,3,49,3,32,18,0,20,9,0,16,3,16,0,48,2,5,18,1,52,10,0,1,19,1,32,14,0,20,12,0,18,3,20,11,0,16,0,48,1,49,2,50],"constants":[{"t":"s","v":"dom-id"},{"t":"s","v":"dict-get"},{"t":"s","v":"not"},{"t":"s","v":"nil?"},{"t":"s","v":"<"},{"t":"s","v":"len"},{"t":"s","v":"="},{"t":"s","v":"nth"},{"t":"s","v":"dom-insert-before"},{"t":"s","v":"morph-node"},{"t":"s","v":"inc"},{"t":"s","v":"dom-clone"},{"t":"s","v":"dom-append"}],"arity":1,"upvalue-count":4}},{"t":"code","v":{"bytecode":[16,0,18,0,52,0,0,2,33,76,0,18,1,16,0,52,1,0,2,17,1,20,2,0,16,1,18,2,48,2,6,33,34,0,5,20,4,0,16,1,1,5,0,48,2,52,3,0,1,6,33,15,0,5,20,4,0,16,1,1,6,0,48,2,52,3,0,1,33,12,0,20,7,0,18,2,16,1,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":">="},{"t":"s","v":"nth"},{"t":"s","v":"dom-is-child-of?"},{"t":"s","v":"not"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-preserve"},{"t":"s","v":"sx-ignore"},{"t":"s","v":"dom-remove-child"}],"arity":1,"upvalue-count":3}},{"t":"s","v":"range"},{"t":"s","v":"len"}],"arity":2}},{"t":"s","v":"morph-island-children"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,2,20,0,0,16,1,1,1,0,48,2,17,3,20,0,0,16,0,1,2,0,48,2,17,4,20,0,0,16,1,1,2,0,48,2,17,5,52,3,0,0,17,6,52,3,0,0,17,7,51,5,0,1,6,16,3,52,4,0,2,5,51,6,0,1,7,16,5,52,4,0,2,5,51,7,0,1,6,16,2,52,4,0,2,5,51,8,0,1,7,1,0,16,4,52,4,0,2,5,20,9,0,16,1,49,1,50],"constants":[{"t":"s","v":"dom-query-all"},{"t":"s","v":"[data-sx-lake]"},{"t":"s","v":"[data-sx-marsh]"},{"t":"s","v":"dict"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,33,13,0,18,0,16,1,16,0,52,2,0,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-lake"},{"t":"s","v":"dict-set!"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,33,13,0,18,0,16,1,16,0,52,2,0,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-marsh"},{"t":"s","v":"dict-set!"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,18,0,16,1,52,2,0,2,17,2,16,2,33,22,0,20,3,0,16,0,16,2,48,2,5,20,4,0,16,0,16,2,49,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-lake"},{"t":"s","v":"dict-get"},{"t":"s","v":"sync-attrs"},{"t":"s","v":"morph-children"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,18,0,16,1,52,2,0,2,17,2,16,2,33,14,0,20,3,0,16,0,16,2,18,1,49,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-marsh"},{"t":"s","v":"dict-get"},{"t":"s","v":"morph-marsh"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"process-signal-updates"}],"arity":2}},{"t":"s","v":"morph-marsh"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,3,20,0,0,16,0,1,2,0,48,2,17,4,20,3,0,16,1,48,1,17,5,16,4,6,33,18,0,5,16,5,6,33,11,0,5,16,5,52,5,0,1,52,4,0,1,33,61,0,20,6,0,16,5,48,1,17,6,16,3,33,16,0,20,7,0,16,3,16,6,52,8,0,1,48,2,32,2,0,16,6,17,7,20,9,0,16,0,48,1,5,20,10,0,16,0,51,11,0,1,7,1,4,1,0,49,2,32,19,0,20,12,0,16,0,16,1,48,2,5,20,13,0,16,0,16,1,49,2,50],"constants":[{"t":"s","v":"dom-get-data"},{"t":"s","v":"sx-marsh-transform"},{"t":"s","v":"sx-marsh-env"},{"t":"s","v":"dom-inner-html"},{"t":"s","v":"not"},{"t":"s","v":"empty?"},{"t":"s","v":"parse"},{"t":"s","v":"cek-call"},{"t":"s","v":"list"},{"t":"s","v":"dispose-marsh-scope"},{"t":"s","v":"with-marsh-scope"},{"t":"code","v":{"bytecode":[20,0,0,18,0,18,1,2,48,3,17,0,20,1,0,18,2,2,48,2,5,20,2,0,18,2,16,0,49,2,50],"constants":[{"t":"s","v":"render-to-dom"},{"t":"s","v":"dom-remove-children-after"},{"t":"s","v":"dom-append"}],"upvalue-count":3}},{"t":"s","v":"sync-attrs"},{"t":"s","v":"morph-children"}],"arity":3}},{"t":"s","v":"process-signal-updates"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,51,3,0,16,1,52,2,0,2,50],"constants":[{"t":"s","v":"dom-query-all"},{"t":"s","v":"[data-sx-signal]"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,33,94,0,16,1,1,3,0,52,2,0,2,17,2,16,2,1,5,0,52,4,0,2,33,67,0,16,1,1,5,0,16,2,52,6,0,3,17,3,16,1,16,2,1,8,0,52,7,0,2,52,6,0,2,17,4,20,9,0,16,4,48,1,17,5,20,10,0,20,11,0,16,3,48,1,16,5,48,2,5,20,12,0,16,0,1,1,0,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-signal"},{"t":"s","v":"index-of"},{"t":"s","v":":"},{"t":"s","v":">"},{"t":"n","v":0},{"t":"s","v":"slice"},{"t":"s","v":"+"},{"t":"n","v":1},{"t":"s","v":"json-parse"},{"t":"s","v":"reset!"},{"t":"s","v":"use-store"},{"t":"s","v":"dom-remove-attr"}],"arity":1}}],"arity":1}},{"t":"s","v":"swap-dom-nodes"},{"t":"code","v":{"bytecode":[16,2,6,1,0,0,52,1,0,2,33,56,0,5,20,2,0,16,1,48,1,33,12,0,20,3,0,16,0,16,1,49,2,32,30,0,20,4,0,1,5,0,2,48,2,17,3,20,6,0,16,3,16,1,48,2,5,20,3,0,16,0,16,3,49,2,32,73,1,6,1,7,0,52,1,0,2,33,117,0,5,20,8,0,16,0,48,1,17,3,20,9,0,16,1,48,1,17,4,20,2,0,16,1,48,1,33,71,0,20,10,0,16,1,48,1,17,5,16,5,33,45,0,20,9,0,16,5,48,1,17,4,5,20,11,0,16,3,16,4,16,0,48,3,5,20,12,0,16,5,48,1,17,6,20,13,0,16,3,16,4,16,6,48,3,32,9,0,20,14,0,16,3,16,0,48,2,32,11,0,20,11,0,16,3,16,4,16,0,48,3,5,16,4,32,201,0,6,1,15,0,52,1,0,2,33,13,0,5,20,16,0,16,0,16,1,49,2,32,177,0,6,1,17,0,52,1,0,2,33,13,0,5,20,6,0,16,0,16,1,49,2,32,153,0,6,1,18,0,52,1,0,2,33,13,0,5,20,19,0,16,0,16,1,49,2,32,129,0,6,1,20,0,52,1,0,2,33,20,0,5,20,21,0,20,8,0,16,0,48,1,16,1,16,0,49,3,32,98,0,6,1,22,0,52,1,0,2,33,18,0,5,20,14,0,20,8,0,16,0,48,1,16,0,49,2,32,69,0,6,1,23,0,52,1,0,2,33,5,0,5,2,32,53,0,5,20,2,0,16,1,48,1,33,12,0,20,3,0,16,0,16,1,49,2,32,30,0,20,4,0,1,5,0,2,48,2,17,3,20,6,0,16,3,16,1,48,2,5,20,3,0,16,0,16,3,49,2,50],"constants":[{"t":"s","v":"innerHTML"},{"t":"s","v":"="},{"t":"s","v":"dom-is-fragment?"},{"t":"s","v":"morph-children"},{"t":"s","v":"dom-create-element"},{"t":"s","v":"div"},{"t":"s","v":"dom-append"},{"t":"s","v":"outerHTML"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-clone"},{"t":"s","v":"dom-first-child"},{"t":"s","v":"dom-replace-child"},{"t":"s","v":"dom-next-sibling"},{"t":"s","v":"insert-remaining-siblings"},{"t":"s","v":"dom-remove-child"},{"t":"s","v":"afterend"},{"t":"s","v":"dom-insert-after"},{"t":"s","v":"beforeend"},{"t":"s","v":"afterbegin"},{"t":"s","v":"dom-prepend"},{"t":"s","v":"beforebegin"},{"t":"s","v":"dom-insert-before"},{"t":"s","v":"delete"},{"t":"s","v":"none"}],"arity":3}},{"t":"s","v":"insert-remaining-siblings"},{"t":"code","v":{"bytecode":[16,2,33,33,0,20,0,0,16,2,48,1,17,3,20,1,0,16,1,16,2,48,2,5,20,2,0,16,0,16,2,16,3,49,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-next-sibling"},{"t":"s","v":"dom-insert-after"},{"t":"s","v":"insert-remaining-siblings"}],"arity":3}},{"t":"s","v":"swap-html-string"},{"t":"code","v":{"bytecode":[16,2,6,1,0,0,52,1,0,2,33,13,0,5,20,2,0,16,0,16,1,49,2,32,212,0,6,1,3,0,52,1,0,2,33,38,0,5,20,4,0,16,0,48,1,17,3,20,5,0,16,0,1,6,0,16,1,48,3,5,20,7,0,16,3,16,0,48,2,5,16,3,32,163,0,6,1,6,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,6,0,16,1,49,3,32,136,0,6,1,8,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,8,0,16,1,49,3,32,109,0,6,1,9,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,9,0,16,1,49,3,32,82,0,6,1,10,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,10,0,16,1,49,3,32,55,0,6,1,11,0,52,1,0,2,33,18,0,5,20,7,0,20,4,0,16,0,48,1,16,0,49,2,32,26,0,6,1,12,0,52,1,0,2,33,5,0,5,2,32,10,0,5,20,2,0,16,0,16,1,49,2,50],"constants":[{"t":"s","v":"innerHTML"},{"t":"s","v":"="},{"t":"s","v":"dom-set-inner-html"},{"t":"s","v":"outerHTML"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-insert-adjacent-html"},{"t":"s","v":"afterend"},{"t":"s","v":"dom-remove-child"},{"t":"s","v":"beforeend"},{"t":"s","v":"afterbegin"},{"t":"s","v":"beforebegin"},{"t":"s","v":"delete"},{"t":"s","v":"none"}],"arity":3}},{"t":"s","v":"handle-history"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,3,20,0,0,16,0,1,2,0,48,2,17,4,16,2,1,4,0,52,3,0,2,17,5,16,5,33,10,0,20,5,0,16,5,49,1,32,101,0,16,3,6,33,14,0,5,16,3,1,8,0,52,7,0,2,52,6,0,1,33,27,0,20,9,0,16,3,1,10,0,52,7,0,2,33,5,0,16,1,32,2,0,16,3,49,1,32,51,0,16,4,6,33,14,0,5,16,4,1,8,0,52,7,0,2,52,6,0,1,33,27,0,20,5,0,16,4,1,10,0,52,7,0,2,33,5,0,16,1,32,2,0,16,4,49,1,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-push-url"},{"t":"s","v":"sx-replace-url"},{"t":"s","v":"get"},{"t":"s","v":"replace-url"},{"t":"s","v":"browser-replace-state"},{"t":"s","v":"not"},{"t":"s","v":"="},{"t":"s","v":"false"},{"t":"s","v":"browser-push-state"},{"t":"s","v":"true"}],"arity":3}},{"t":"s","v":"PRELOAD_TTL"},{"t":"n","v":30000},{"t":"s","v":"preload-cache-get"},{"t":"code","v":{"bytecode":[16,0,16,1,52,0,0,2,17,2,16,2,52,1,0,1,33,4,0,2,32,52,0,20,4,0,48,0,16,2,1,6,0,52,5,0,2,52,3,0,2,20,7,0,52,2,0,2,33,13,0,16,0,16,1,52,8,0,2,5,2,32,11,0,16,0,16,1,52,8,0,2,5,16,2,50],"constants":[{"t":"s","v":"dict-get"},{"t":"s","v":"nil?"},{"t":"s","v":">"},{"t":"s","v":"-"},{"t":"s","v":"now-ms"},{"t":"s","v":"get"},{"t":"s","v":"timestamp"},{"t":"s","v":"PRELOAD_TTL"},{"t":"s","v":"dict-delete!"}],"arity":2}},{"t":"s","v":"preload-cache-set"},{"t":"code","v":{"bytecode":[16,0,16,1,1,2,0,16,2,1,3,0,16,3,1,4,0,20,5,0,48,0,52,1,0,6,52,0,0,3,50],"constants":[{"t":"s","v":"dict-set!"},{"t":"s","v":"dict"},{"t":"s","v":"text"},{"t":"s","v":"content-type"},{"t":"s","v":"timestamp"},{"t":"s","v":"now-ms"}],"arity":4}},{"t":"s","v":"classify-trigger"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,17,1,16,1,1,3,0,52,2,0,2,33,6,0,1,4,0,32,57,0,16,1,1,5,0,52,2,0,2,33,6,0,1,5,0,32,39,0,16,1,1,6,0,52,2,0,2,33,6,0,1,6,0,32,21,0,16,1,1,7,0,52,2,0,2,33,6,0,1,7,0,32,3,0,1,1,0,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"event"},{"t":"s","v":"="},{"t":"s","v":"every"},{"t":"s","v":"poll"},{"t":"s","v":"intersect"},{"t":"s","v":"load"},{"t":"s","v":"revealed"}],"arity":1}},{"t":"s","v":"should-boost-link?"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,6,33,119,0,5,16,1,1,4,0,52,3,0,2,52,2,0,1,6,33,101,0,5,16,1,1,5,0,52,3,0,2,52,2,0,1,6,33,83,0,5,16,1,1,6,0,52,3,0,2,52,2,0,1,6,33,65,0,5,20,7,0,16,1,48,1,6,33,53,0,5,20,8,0,16,0,1,9,0,48,2,52,2,0,1,6,33,34,0,5,20,8,0,16,0,1,10,0,48,2,52,2,0,1,6,33,15,0,5,20,8,0,16,0,1,11,0,48,2,52,2,0,1,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"href"},{"t":"s","v":"not"},{"t":"s","v":"starts-with?"},{"t":"s","v":"#"},{"t":"s","v":"javascript:"},{"t":"s","v":"mailto:"},{"t":"s","v":"browser-same-origin?"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-get"},{"t":"s","v":"sx-post"},{"t":"s","v":"sx-disable"}],"arity":1}},{"t":"s","v":"should-boost-form?"},{"t":"code","v":{"bytecode":[20,1,0,16,0,1,2,0,48,2,52,0,0,1,6,33,34,0,5,20,1,0,16,0,1,3,0,48,2,52,0,0,1,6,33,15,0,5,20,1,0,16,0,1,4,0,48,2,52,0,0,1,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-get"},{"t":"s","v":"sx-post"},{"t":"s","v":"sx-disable"}],"arity":1}},{"t":"s","v":"parse-sse-swap"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,6,34,4,0,5,1,2,0,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-sse-swap"},{"t":"s","v":"message"}],"arity":1}}]}} \ No newline at end of file +{"magic":"SXBC","version":1,"hash":"e038227f8fc8f0ad","module":{"bytecode":[1,2,0,1,3,0,1,4,0,1,5,0,1,6,0,52,1,0,5,128,0,0,5,1,8,0,128,7,0,5,51,10,0,128,9,0,5,51,12,0,128,11,0,5,51,14,0,128,13,0,5,51,16,0,128,15,0,5,51,18,0,128,17,0,5,51,20,0,128,19,0,5,51,22,0,128,21,0,5,51,24,0,128,23,0,5,51,26,0,128,25,0,5,51,28,0,128,27,0,5,51,30,0,128,29,0,5,51,32,0,128,31,0,5,51,34,0,128,33,0,5,51,36,0,128,35,0,5,51,38,0,128,37,0,5,51,40,0,128,39,0,5,51,42,0,128,41,0,5,51,44,0,128,43,0,5,51,46,0,128,45,0,5,51,48,0,128,47,0,5,51,50,0,128,49,0,5,51,52,0,128,51,0,5,51,54,0,128,53,0,5,51,56,0,128,55,0,5,1,58,0,128,57,0,5,51,60,0,128,59,0,5,51,62,0,128,61,0,5,51,64,0,128,63,0,5,51,66,0,128,65,0,5,51,68,0,128,67,0,5,51,70,0,128,69,0,50],"constants":[{"t":"s","v":"ENGINE_VERBS"},{"t":"s","v":"list"},{"t":"s","v":"get"},{"t":"s","v":"post"},{"t":"s","v":"put"},{"t":"s","v":"delete"},{"t":"s","v":"patch"},{"t":"s","v":"DEFAULT_SWAP"},{"t":"s","v":"outerHTML"},{"t":"s","v":"parse-time"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,6,0,1,1,0,32,74,0,16,0,1,3,0,52,2,0,2,33,12,0,16,0,1,1,0,52,4,0,2,32,50,0,16,0,1,5,0,52,2,0,2,33,29,0,16,0,1,5,0,1,8,0,52,7,0,3,1,1,0,52,4,0,2,1,9,0,52,6,0,2,32,9,0,16,0,1,1,0,52,4,0,2,50],"constants":[{"t":"s","v":"nil?"},{"t":"n","v":0},{"t":"s","v":"ends-with?"},{"t":"s","v":"ms"},{"t":"s","v":"parse-int"},{"t":"s","v":"s"},{"t":"s","v":"*"},{"t":"s","v":"replace"},{"t":"s","v":""},{"t":"n","v":1000}],"arity":1}},{"t":"s","v":"parse-trigger-spec"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,4,0,2,32,27,0,16,0,1,2,0,52,1,0,2,17,1,51,4,0,51,6,0,16,1,52,5,0,2,52,3,0,2,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"split"},{"t":"s","v":","},{"t":"s","v":"filter"},{"t":"code","v":{"bytecode":[16,0,52,1,0,1,52,0,0,1,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"nil?"}],"arity":1}},{"t":"s","v":"map"},{"t":"code","v":{"bytecode":[16,0,52,1,0,1,1,2,0,52,0,0,2,17,1,16,1,52,3,0,1,33,4,0,2,32,111,0,16,1,52,5,0,1,1,6,0,52,4,0,2,6,33,14,0,5,16,1,52,8,0,1,1,9,0,52,7,0,2,33,37,0,1,11,0,1,6,0,1,12,0,1,13,0,20,14,0,16,1,1,16,0,52,15,0,2,48,1,52,10,0,2,52,10,0,4,32,40,0,52,10,0,0,17,2,51,18,0,1,2,16,1,52,19,0,1,52,17,0,2,5,1,11,0,16,1,52,5,0,1,1,12,0,16,2,52,10,0,4,50],"constants":[{"t":"s","v":"split"},{"t":"s","v":"trim"},{"t":"s","v":" "},{"t":"s","v":"empty?"},{"t":"s","v":"="},{"t":"s","v":"first"},{"t":"s","v":"every"},{"t":"s","v":">="},{"t":"s","v":"len"},{"t":"n","v":2},{"t":"s","v":"dict"},{"t":"s","v":"event"},{"t":"s","v":"modifiers"},{"t":"s","v":"interval"},{"t":"s","v":"parse-time"},{"t":"s","v":"nth"},{"t":"n","v":1},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,33,13,0,18,0,1,1,0,3,52,2,0,3,32,97,0,16,0,1,3,0,52,0,0,2,33,13,0,18,0,1,3,0,3,52,2,0,3,32,72,0,16,0,1,5,0,52,4,0,2,33,26,0,18,0,1,6,0,20,7,0,16,0,1,9,0,52,8,0,2,48,1,52,2,0,3,32,34,0,16,0,1,10,0,52,4,0,2,33,21,0,18,0,1,11,0,16,0,1,12,0,52,8,0,2,52,2,0,3,32,1,0,2,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"once"},{"t":"s","v":"dict-set!"},{"t":"s","v":"changed"},{"t":"s","v":"starts-with?"},{"t":"s","v":"delay:"},{"t":"s","v":"delay"},{"t":"s","v":"parse-time"},{"t":"s","v":"slice"},{"t":"n","v":6},{"t":"s","v":"from:"},{"t":"s","v":"from"},{"t":"n","v":5}],"arity":1,"upvalue-count":1}},{"t":"s","v":"rest"}],"arity":1}}],"arity":1}},{"t":"s","v":"default-trigger"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,33,24,0,1,4,0,1,5,0,1,6,0,52,3,0,0,52,3,0,4,52,2,0,1,32,85,0,16,0,1,7,0,52,0,0,2,6,34,24,0,5,16,0,1,8,0,52,0,0,2,6,34,10,0,5,16,0,1,9,0,52,0,0,2,33,24,0,1,4,0,1,10,0,1,6,0,52,3,0,0,52,3,0,4,52,2,0,1,32,21,0,1,4,0,1,11,0,1,6,0,52,3,0,0,52,3,0,4,52,2,0,1,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"FORM"},{"t":"s","v":"list"},{"t":"s","v":"dict"},{"t":"s","v":"event"},{"t":"s","v":"submit"},{"t":"s","v":"modifiers"},{"t":"s","v":"INPUT"},{"t":"s","v":"SELECT"},{"t":"s","v":"TEXTAREA"},{"t":"s","v":"change"},{"t":"s","v":"click"}],"arity":1}},{"t":"s","v":"get-verb-info"},{"t":"code","v":{"bytecode":[51,1,0,1,0,20,2,0,52,0,0,2,50],"constants":[{"t":"s","v":"some"},{"t":"code","v":{"bytecode":[20,0,0,18,0,1,2,0,16,0,52,1,0,2,48,2,17,1,16,1,33,21,0,1,4,0,16,0,52,5,0,1,1,6,0,16,1,52,3,0,4,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"str"},{"t":"s","v":"sx-"},{"t":"s","v":"dict"},{"t":"s","v":"method"},{"t":"s","v":"upper"},{"t":"s","v":"url"}],"arity":1,"upvalue-count":1}},{"t":"s","v":"ENGINE_VERBS"}],"arity":1}},{"t":"s","v":"build-request-headers"},{"t":"code","v":{"bytecode":[1,1,0,1,2,0,1,3,0,20,4,0,48,0,52,0,0,4,17,3,20,5,0,16,0,1,6,0,48,2,17,4,16,4,33,14,0,16,3,1,8,0,16,4,52,7,0,3,32,1,0,2,5,20,5,0,20,9,0,1,10,0,48,1,1,11,0,48,2,17,4,16,4,33,14,0,16,3,1,12,0,16,4,52,7,0,3,32,1,0,2,5,16,2,33,14,0,16,3,1,13,0,16,2,52,7,0,3,32,1,0,2,5,20,5,0,16,0,1,14,0,48,2,17,4,16,4,33,38,0,20,15,0,16,4,48,1,17,5,16,5,33,20,0,51,17,0,1,3,1,5,16,5,52,18,0,1,52,16,0,2,32,1,0,2,32,1,0,2,5,16,3,50],"constants":[{"t":"s","v":"dict"},{"t":"s","v":"SX-Request"},{"t":"s","v":"true"},{"t":"s","v":"SX-Current-URL"},{"t":"s","v":"browser-location-href"},{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-target"},{"t":"s","v":"dict-set!"},{"t":"s","v":"SX-Target"},{"t":"s","v":"dom-query"},{"t":"s","v":"script[data-components][data-hash]"},{"t":"s","v":"data-hash"},{"t":"s","v":"SX-Components-Hash"},{"t":"s","v":"SX-Css"},{"t":"s","v":"sx-headers"},{"t":"s","v":"parse-header-value"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[18,0,16,0,18,1,16,0,52,2,0,2,52,1,0,1,52,0,0,3,50],"constants":[{"t":"s","v":"dict-set!"},{"t":"s","v":"str"},{"t":"s","v":"get"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"keys"}],"arity":3}},{"t":"s","v":"process-response-headers"},{"t":"code","v":{"bytecode":[1,1,0,16,0,1,2,0,48,1,1,3,0,16,0,1,4,0,48,1,1,5,0,16,0,1,6,0,48,1,1,7,0,16,0,1,8,0,48,1,1,9,0,16,0,1,10,0,48,1,1,11,0,16,0,1,12,0,48,1,1,13,0,16,0,1,14,0,48,1,1,15,0,16,0,1,16,0,48,1,1,17,0,16,0,1,18,0,48,1,1,19,0,16,0,1,20,0,48,1,1,21,0,16,0,1,22,0,48,1,1,23,0,16,0,1,24,0,48,1,1,25,0,16,0,1,26,0,48,1,52,0,0,26,50],"constants":[{"t":"s","v":"dict"},{"t":"s","v":"redirect"},{"t":"s","v":"SX-Redirect"},{"t":"s","v":"refresh"},{"t":"s","v":"SX-Refresh"},{"t":"s","v":"trigger"},{"t":"s","v":"SX-Trigger"},{"t":"s","v":"retarget"},{"t":"s","v":"SX-Retarget"},{"t":"s","v":"reswap"},{"t":"s","v":"SX-Reswap"},{"t":"s","v":"location"},{"t":"s","v":"SX-Location"},{"t":"s","v":"replace-url"},{"t":"s","v":"SX-Replace-Url"},{"t":"s","v":"css-hash"},{"t":"s","v":"SX-Css-Hash"},{"t":"s","v":"trigger-swap"},{"t":"s","v":"SX-Trigger-After-Swap"},{"t":"s","v":"trigger-settle"},{"t":"s","v":"SX-Trigger-After-Settle"},{"t":"s","v":"content-type"},{"t":"s","v":"Content-Type"},{"t":"s","v":"cache-invalidate"},{"t":"s","v":"SX-Cache-Invalidate"},{"t":"s","v":"cache-update"},{"t":"s","v":"SX-Cache-Update"}],"arity":1}},{"t":"s","v":"parse-swap-spec"},{"t":"code","v":{"bytecode":[16,0,6,34,4,0,5,20,1,0,1,2,0,52,0,0,2,17,2,16,2,52,3,0,1,17,3,16,1,17,4,51,5,0,1,4,16,2,52,6,0,1,52,4,0,2,5,1,8,0,16,3,1,9,0,16,4,52,7,0,4,50],"constants":[{"t":"s","v":"split"},{"t":"s","v":"DEFAULT_SWAP"},{"t":"s","v":" "},{"t":"s","v":"first"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,33,6,0,3,19,0,32,19,0,16,0,1,2,0,52,0,0,2,33,6,0,4,19,0,32,1,0,2,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"transition:true"},{"t":"s","v":"transition:false"}],"arity":1,"upvalue-count":1}},{"t":"s","v":"rest"},{"t":"s","v":"dict"},{"t":"s","v":"style"},{"t":"s","v":"transition"}],"arity":2}},{"t":"s","v":"parse-retry-spec"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,4,0,2,32,62,0,16,0,1,2,0,52,1,0,2,17,1,1,4,0,16,1,52,5,0,1,1,6,0,16,1,1,9,0,52,8,0,2,1,10,0,52,7,0,2,1,11,0,16,1,1,12,0,52,8,0,2,1,13,0,52,7,0,2,52,3,0,6,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"split"},{"t":"s","v":":"},{"t":"s","v":"dict"},{"t":"s","v":"strategy"},{"t":"s","v":"first"},{"t":"s","v":"start-ms"},{"t":"s","v":"parse-int"},{"t":"s","v":"nth"},{"t":"n","v":1},{"t":"n","v":1000},{"t":"s","v":"cap-ms"},{"t":"n","v":2},{"t":"n","v":30000}],"arity":1}},{"t":"s","v":"next-retry-ms"},{"t":"code","v":{"bytecode":[16,0,1,2,0,52,1,0,2,16,1,52,0,0,2,50],"constants":[{"t":"s","v":"min"},{"t":"s","v":"*"},{"t":"n","v":2}],"arity":2}},{"t":"s","v":"filter-params"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,5,0,16,1,32,116,0,16,0,1,2,0,52,1,0,2,33,7,0,52,3,0,0,32,97,0,16,0,1,4,0,52,1,0,2,33,5,0,16,1,32,80,0,16,0,1,6,0,52,5,0,2,33,39,0,20,8,0,16,0,1,11,0,52,10,0,2,1,12,0,52,9,0,2,52,7,0,2,17,2,51,14,0,1,2,16,1,52,13,0,2,32,29,0,20,8,0,16,0,1,12,0,52,9,0,2,52,7,0,2,17,2,51,15,0,1,2,16,1,52,13,0,2,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"="},{"t":"s","v":"none"},{"t":"s","v":"list"},{"t":"s","v":"*"},{"t":"s","v":"starts-with?"},{"t":"s","v":"not "},{"t":"s","v":"map"},{"t":"s","v":"trim"},{"t":"s","v":"split"},{"t":"s","v":"slice"},{"t":"n","v":4},{"t":"s","v":","},{"t":"s","v":"filter"},{"t":"code","v":{"bytecode":[18,0,16,0,52,2,0,1,52,1,0,2,52,0,0,1,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"contains?"},{"t":"s","v":"first"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[18,0,16,0,52,1,0,1,52,0,0,2,50],"constants":[{"t":"s","v":"contains?"},{"t":"s","v":"first"}],"arity":1,"upvalue-count":1}}],"arity":2}},{"t":"s","v":"resolve-target"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,52,2,0,1,6,34,10,0,5,16,1,1,4,0,52,3,0,2,33,5,0,16,0,32,29,0,16,1,1,5,0,52,3,0,2,33,10,0,20,6,0,16,0,49,1,32,7,0,20,7,0,16,1,49,1,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-target"},{"t":"s","v":"nil?"},{"t":"s","v":"="},{"t":"s","v":"this"},{"t":"s","v":"closest"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-query"}],"arity":1}},{"t":"s","v":"apply-optimistic"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,52,2,0,1,33,4,0,2,32,191,0,20,3,0,16,0,48,1,6,34,3,0,5,16,0,17,2,1,5,0,16,2,1,6,0,16,1,52,4,0,4,17,3,16,1,1,8,0,52,7,0,2,33,50,0,16,3,1,10,0,20,11,0,16,2,1,10,0,48,2,52,9,0,3,5,20,12,0,16,2,1,10,0,1,13,0,48,3,5,20,12,0,16,2,1,14,0,1,15,0,48,3,32,94,0,16,1,1,16,0,52,7,0,2,33,34,0,16,3,1,17,0,20,18,0,16,2,1,17,0,48,2,52,9,0,3,5,20,19,0,16,2,1,17,0,3,48,3,32,48,0,16,1,1,21,0,52,20,0,2,33,35,0,16,1,1,23,0,52,22,0,2,17,4,16,3,1,24,0,16,4,52,9,0,3,5,20,25,0,16,2,16,4,48,2,32,1,0,2,5,16,3,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-optimistic"},{"t":"s","v":"nil?"},{"t":"s","v":"resolve-target"},{"t":"s","v":"dict"},{"t":"s","v":"target"},{"t":"s","v":"directive"},{"t":"s","v":"="},{"t":"s","v":"remove"},{"t":"s","v":"dict-set!"},{"t":"s","v":"opacity"},{"t":"s","v":"dom-get-style"},{"t":"s","v":"dom-set-style"},{"t":"s","v":"0"},{"t":"s","v":"pointer-events"},{"t":"s","v":"none"},{"t":"s","v":"disable"},{"t":"s","v":"disabled"},{"t":"s","v":"dom-get-prop"},{"t":"s","v":"dom-set-prop"},{"t":"s","v":"starts-with?"},{"t":"s","v":"add-class:"},{"t":"s","v":"slice"},{"t":"n","v":10},{"t":"s","v":"add-class"},{"t":"s","v":"dom-add-class"}],"arity":1}},{"t":"s","v":"revert-optimistic"},{"t":"code","v":{"bytecode":[16,0,33,153,0,16,0,1,1,0,52,0,0,2,17,1,16,0,1,2,0,52,0,0,2,17,2,16,2,1,4,0,52,3,0,2,33,44,0,20,5,0,16,1,1,6,0,16,0,1,6,0,52,0,0,2,6,34,4,0,5,1,7,0,48,3,5,20,5,0,16,1,1,8,0,1,7,0,49,3,32,72,0,16,2,1,9,0,52,3,0,2,33,28,0,20,10,0,16,1,1,11,0,16,0,1,11,0,52,0,0,2,6,34,2,0,5,4,49,3,32,32,0,16,0,1,12,0,52,0,0,2,33,19,0,20,13,0,16,1,16,0,1,12,0,52,0,0,2,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"target"},{"t":"s","v":"directive"},{"t":"s","v":"="},{"t":"s","v":"remove"},{"t":"s","v":"dom-set-style"},{"t":"s","v":"opacity"},{"t":"s","v":""},{"t":"s","v":"pointer-events"},{"t":"s","v":"disable"},{"t":"s","v":"dom-set-prop"},{"t":"s","v":"disabled"},{"t":"s","v":"add-class"},{"t":"s","v":"dom-remove-class"}],"arity":1}},{"t":"s","v":"find-oob-swaps"},{"t":"code","v":{"bytecode":[52,0,0,0,17,1,51,2,0,1,0,1,1,1,3,0,1,4,0,52,0,0,2,52,1,0,2,5,16,1,50],"constants":[{"t":"s","v":"list"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,18,0,1,2,0,16,0,1,3,0,52,1,0,3,48,2,17,1,51,5,0,1,0,0,1,16,1,52,4,0,2,50],"constants":[{"t":"s","v":"dom-query-all"},{"t":"s","v":"str"},{"t":"s","v":"["},{"t":"s","v":"]"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,18,0,48,2,6,34,4,0,5,1,1,0,17,1,20,2,0,16,0,48,1,17,2,20,3,0,16,0,18,0,48,2,5,16,2,33,29,0,20,4,0,18,1,1,6,0,16,0,1,7,0,16,1,1,8,0,16,2,52,5,0,6,49,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"outerHTML"},{"t":"s","v":"dom-id"},{"t":"s","v":"dom-remove-attr"},{"t":"s","v":"append!"},{"t":"s","v":"dict"},{"t":"s","v":"element"},{"t":"s","v":"swap-type"},{"t":"s","v":"target-id"}],"arity":1,"upvalue-count":2}}],"arity":1,"upvalue-count":2}},{"t":"s","v":"sx-swap-oob"},{"t":"s","v":"hx-swap-oob"}],"arity":1}},{"t":"s","v":"morph-node"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,6,34,11,0,5,20,0,0,16,0,1,2,0,48,2,33,4,0,2,32,137,1,20,0,0,16,0,1,3,0,48,2,6,33,55,0,5,20,4,0,16,0,1,5,0,48,2,6,33,40,0,5,20,0,0,16,1,1,3,0,48,2,6,33,25,0,5,20,7,0,16,0,1,3,0,48,2,20,7,0,16,1,1,3,0,48,2,52,6,0,2,33,12,0,20,8,0,16,0,16,1,49,2,32,53,1,20,10,0,16,0,48,1,20,10,0,16,1,48,1,52,6,0,2,52,9,0,1,6,34,23,0,5,20,11,0,16,0,48,1,20,11,0,16,1,48,1,52,6,0,2,52,9,0,1,33,24,0,20,12,0,20,13,0,16,0,48,1,20,14,0,16,1,48,1,16,0,49,3,32,233,0,20,10,0,16,0,48,1,1,15,0,52,6,0,2,6,34,15,0,5,20,10,0,16,0,48,1,1,16,0,52,6,0,2,33,46,0,20,17,0,16,0,48,1,20,17,0,16,1,48,1,52,6,0,2,52,9,0,1,33,17,0,20,18,0,16,0,20,17,0,16,1,48,1,49,2,32,1,0,2,32,151,0,20,10,0,16,0,48,1,1,19,0,52,6,0,2,33,133,0,20,0,0,16,0,1,3,0,48,2,6,33,44,0,5,20,0,0,16,1,1,3,0,48,2,6,33,29,0,5,20,7,0,16,0,1,3,0,48,2,20,7,0,16,1,1,3,0,48,2,52,6,0,2,52,9,0,1,33,18,0,20,20,0,16,0,48,1,5,20,21,0,16,0,48,1,32,1,0,2,5,20,22,0,16,0,16,1,48,2,5,20,23,0,16,0,48,1,6,33,8,0,5,20,24,0,16,0,48,1,52,9,0,1,33,12,0,20,25,0,16,0,16,1,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-preserve"},{"t":"s","v":"sx-ignore"},{"t":"s","v":"data-sx-island"},{"t":"s","v":"is-processed?"},{"t":"s","v":"island-hydrated"},{"t":"s","v":"="},{"t":"s","v":"dom-get-attr"},{"t":"s","v":"morph-island-children"},{"t":"s","v":"not"},{"t":"s","v":"dom-node-type"},{"t":"s","v":"dom-node-name"},{"t":"s","v":"dom-replace-child"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-clone"},{"t":"n","v":3},{"t":"n","v":8},{"t":"s","v":"dom-text-content"},{"t":"s","v":"dom-set-text-content"},{"t":"n","v":1},{"t":"s","v":"dispose-island"},{"t":"s","v":"dispose-islands-in"},{"t":"s","v":"sync-attrs"},{"t":"s","v":"dom-is-active-element?"},{"t":"s","v":"dom-is-input-element?"},{"t":"s","v":"morph-children"}],"arity":2}},{"t":"s","v":"sync-attrs"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,6,34,4,0,5,1,2,0,17,2,16,2,52,3,0,1,33,7,0,52,4,0,0,32,9,0,16,2,1,6,0,52,5,0,2,17,3,51,8,0,1,0,1,3,20,9,0,16,1,48,1,52,7,0,2,5,51,10,0,1,1,1,3,1,0,20,9,0,16,0,48,1,52,7,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-reactive-attrs"},{"t":"s","v":""},{"t":"s","v":"empty?"},{"t":"s","v":"list"},{"t":"s","v":"split"},{"t":"s","v":","},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,17,1,16,0,1,2,0,52,1,0,2,17,2,20,5,0,18,0,16,1,48,2,16,2,52,4,0,2,52,3,0,1,6,33,13,0,5,18,1,16,1,52,6,0,2,52,3,0,1,33,14,0,20,7,0,18,0,16,1,16,2,49,3,32,1,0,2,50],"constants":[{"t":"s","v":"first"},{"t":"s","v":"nth"},{"t":"n","v":1},{"t":"s","v":"not"},{"t":"s","v":"="},{"t":"s","v":"dom-get-attr"},{"t":"s","v":"contains?"},{"t":"s","v":"dom-set-attr"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"dom-attr-list"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,17,1,20,2,0,18,0,16,1,48,2,52,1,0,1,6,33,31,0,5,18,1,16,1,52,3,0,2,52,1,0,1,6,33,14,0,5,16,1,1,5,0,52,4,0,2,52,1,0,1,33,12,0,20,6,0,18,2,16,1,49,2,32,1,0,2,50],"constants":[{"t":"s","v":"first"},{"t":"s","v":"not"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"contains?"},{"t":"s","v":"="},{"t":"s","v":"data-sx-reactive-attrs"},{"t":"s","v":"dom-remove-attr"}],"arity":1,"upvalue-count":3}}],"arity":2}},{"t":"s","v":"morph-children"},{"t":"code","v":{"bytecode":[20,0,0,16,0,48,1,17,2,20,0,0,16,1,48,1,17,3,51,2,0,52,3,0,0,16,2,52,1,0,3,17,4,1,4,0,17,5,51,6,0,1,4,1,5,1,2,1,0,16,3,52,5,0,2,5,51,7,0,1,5,1,2,1,0,16,5,16,2,52,9,0,1,52,8,0,2,52,5,0,2,50],"constants":[{"t":"s","v":"dom-child-list"},{"t":"s","v":"reduce"},{"t":"code","v":{"bytecode":[20,0,0,16,1,48,1,17,2,16,2,33,16,0,16,0,16,2,16,1,52,1,0,3,5,16,0,32,2,0,16,0,50],"constants":[{"t":"s","v":"dom-id"},{"t":"s","v":"dict-set!"}],"arity":2}},{"t":"s","v":"dict"},{"t":"n","v":0},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,48,1,17,1,16,1,33,11,0,18,0,16,1,52,1,0,2,32,1,0,2,17,2,16,2,6,33,11,0,5,16,2,52,3,0,1,52,2,0,1,33,100,0,18,1,18,2,52,5,0,1,52,4,0,2,6,33,19,0,5,16,2,18,2,18,1,52,7,0,2,52,6,0,2,52,2,0,1,33,39,0,20,8,0,18,3,16,2,18,1,18,2,52,5,0,1,52,4,0,2,33,11,0,18,2,18,1,52,7,0,2,32,1,0,2,48,3,32,1,0,2,5,20,9,0,16,2,16,0,48,2,5,18,1,52,10,0,1,19,1,32,100,0,18,1,18,2,52,5,0,1,52,4,0,2,33,71,0,18,2,18,1,52,7,0,2,17,3,20,0,0,16,3,48,1,6,33,7,0,5,16,1,52,2,0,1,33,19,0,20,8,0,18,3,20,11,0,16,0,48,1,16,3,49,3,32,18,0,20,9,0,16,3,16,0,48,2,5,18,1,52,10,0,1,19,1,32,14,0,20,12,0,18,3,20,11,0,16,0,48,1,49,2,50],"constants":[{"t":"s","v":"dom-id"},{"t":"s","v":"dict-get"},{"t":"s","v":"not"},{"t":"s","v":"nil?"},{"t":"s","v":"<"},{"t":"s","v":"len"},{"t":"s","v":"="},{"t":"s","v":"nth"},{"t":"s","v":"dom-insert-before"},{"t":"s","v":"morph-node"},{"t":"s","v":"inc"},{"t":"s","v":"dom-clone"},{"t":"s","v":"dom-append"}],"arity":1,"upvalue-count":4}},{"t":"code","v":{"bytecode":[16,0,18,0,52,0,0,2,33,76,0,18,1,16,0,52,1,0,2,17,1,20,2,0,16,1,18,2,48,2,6,33,34,0,5,20,4,0,16,1,1,5,0,48,2,52,3,0,1,6,33,15,0,5,20,4,0,16,1,1,6,0,48,2,52,3,0,1,33,12,0,20,7,0,18,2,16,1,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":">="},{"t":"s","v":"nth"},{"t":"s","v":"dom-is-child-of?"},{"t":"s","v":"not"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-preserve"},{"t":"s","v":"sx-ignore"},{"t":"s","v":"dom-remove-child"}],"arity":1,"upvalue-count":3}},{"t":"s","v":"range"},{"t":"s","v":"len"}],"arity":2}},{"t":"s","v":"morph-island-children"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,2,20,0,0,16,1,1,1,0,48,2,17,3,20,0,0,16,0,1,2,0,48,2,17,4,20,0,0,16,1,1,2,0,48,2,17,5,52,3,0,0,17,6,52,3,0,0,17,7,51,5,0,1,6,16,3,52,4,0,2,5,51,6,0,1,7,16,5,52,4,0,2,5,51,7,0,1,6,16,2,52,4,0,2,5,51,8,0,1,7,1,0,16,4,52,4,0,2,5,20,9,0,16,1,49,1,50],"constants":[{"t":"s","v":"dom-query-all"},{"t":"s","v":"[data-sx-lake]"},{"t":"s","v":"[data-sx-marsh]"},{"t":"s","v":"dict"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,33,13,0,18,0,16,1,16,0,52,2,0,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-lake"},{"t":"s","v":"dict-set!"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,33,13,0,18,0,16,1,16,0,52,2,0,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-marsh"},{"t":"s","v":"dict-set!"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,18,0,16,1,52,2,0,2,17,2,16,2,33,22,0,20,3,0,16,0,16,2,48,2,5,20,4,0,16,0,16,2,49,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-lake"},{"t":"s","v":"dict-get"},{"t":"s","v":"sync-attrs"},{"t":"s","v":"morph-children"}],"arity":1,"upvalue-count":1}},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,18,0,16,1,52,2,0,2,17,2,16,2,33,14,0,20,3,0,16,0,16,2,18,1,49,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-marsh"},{"t":"s","v":"dict-get"},{"t":"s","v":"morph-marsh"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"process-signal-updates"}],"arity":2}},{"t":"s","v":"morph-marsh"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,3,20,0,0,16,0,1,2,0,48,2,17,4,20,3,0,16,1,48,1,17,5,16,4,6,33,18,0,5,16,5,6,33,11,0,5,16,5,52,5,0,1,52,4,0,1,33,61,0,20,6,0,16,5,48,1,17,6,16,3,33,16,0,20,7,0,16,3,16,6,52,8,0,1,48,2,32,2,0,16,6,17,7,20,9,0,16,0,48,1,5,20,10,0,16,0,51,11,0,1,7,1,4,1,0,49,2,32,19,0,20,12,0,16,0,16,1,48,2,5,20,13,0,16,0,16,1,49,2,50],"constants":[{"t":"s","v":"dom-get-data"},{"t":"s","v":"sx-marsh-transform"},{"t":"s","v":"sx-marsh-env"},{"t":"s","v":"dom-inner-html"},{"t":"s","v":"not"},{"t":"s","v":"empty?"},{"t":"s","v":"parse"},{"t":"s","v":"cek-call"},{"t":"s","v":"list"},{"t":"s","v":"dispose-marsh-scope"},{"t":"s","v":"with-marsh-scope"},{"t":"code","v":{"bytecode":[20,0,0,18,0,18,1,2,48,3,17,0,20,1,0,18,2,2,48,2,5,20,2,0,18,2,16,0,49,2,50],"constants":[{"t":"s","v":"render-to-dom"},{"t":"s","v":"dom-remove-children-after"},{"t":"s","v":"dom-append"}],"upvalue-count":3}},{"t":"s","v":"sync-attrs"},{"t":"s","v":"morph-children"}],"arity":3}},{"t":"s","v":"process-signal-updates"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,51,3,0,16,1,52,2,0,2,50],"constants":[{"t":"s","v":"dom-query-all"},{"t":"s","v":"[data-sx-signal]"},{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,33,93,0,16,1,1,3,0,52,2,0,2,17,2,16,2,1,5,0,52,4,0,2,33,66,0,16,1,1,5,0,16,2,52,6,0,3,17,3,16,1,16,2,1,8,0,52,7,0,2,52,6,0,2,17,4,20,9,0,16,4,48,1,17,5,20,10,0,16,3,52,11,0,1,16,5,48,2,5,20,12,0,16,0,1,1,0,49,2,32,1,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"data-sx-signal"},{"t":"s","v":"index-of"},{"t":"s","v":":"},{"t":"s","v":">"},{"t":"n","v":0},{"t":"s","v":"slice"},{"t":"s","v":"+"},{"t":"n","v":1},{"t":"s","v":"json-parse"},{"t":"s","v":"reset!"},{"t":"s","v":"use-store"},{"t":"s","v":"dom-remove-attr"}],"arity":1}}],"arity":1}},{"t":"s","v":"swap-dom-nodes"},{"t":"code","v":{"bytecode":[16,2,6,1,0,0,52,1,0,2,33,56,0,5,20,2,0,16,1,48,1,33,12,0,20,3,0,16,0,16,1,49,2,32,30,0,20,4,0,1,5,0,2,48,2,17,3,20,6,0,16,3,16,1,48,2,5,20,3,0,16,0,16,3,49,2,32,73,1,6,1,7,0,52,1,0,2,33,117,0,5,20,8,0,16,0,48,1,17,3,20,9,0,16,1,48,1,17,4,20,2,0,16,1,48,1,33,71,0,20,10,0,16,1,48,1,17,5,16,5,33,45,0,20,9,0,16,5,48,1,17,4,5,20,11,0,16,3,16,4,16,0,48,3,5,20,12,0,16,5,48,1,17,6,20,13,0,16,3,16,4,16,6,48,3,32,9,0,20,14,0,16,3,16,0,48,2,32,11,0,20,11,0,16,3,16,4,16,0,48,3,5,16,4,32,201,0,6,1,15,0,52,1,0,2,33,13,0,5,20,16,0,16,0,16,1,49,2,32,177,0,6,1,17,0,52,1,0,2,33,13,0,5,20,6,0,16,0,16,1,49,2,32,153,0,6,1,18,0,52,1,0,2,33,13,0,5,20,19,0,16,0,16,1,49,2,32,129,0,6,1,20,0,52,1,0,2,33,20,0,5,20,21,0,20,8,0,16,0,48,1,16,1,16,0,49,3,32,98,0,6,1,22,0,52,1,0,2,33,18,0,5,20,14,0,20,8,0,16,0,48,1,16,0,49,2,32,69,0,6,1,23,0,52,1,0,2,33,5,0,5,2,32,53,0,5,20,2,0,16,1,48,1,33,12,0,20,3,0,16,0,16,1,49,2,32,30,0,20,4,0,1,5,0,2,48,2,17,3,20,6,0,16,3,16,1,48,2,5,20,3,0,16,0,16,3,49,2,50],"constants":[{"t":"s","v":"innerHTML"},{"t":"s","v":"="},{"t":"s","v":"dom-is-fragment?"},{"t":"s","v":"morph-children"},{"t":"s","v":"dom-create-element"},{"t":"s","v":"div"},{"t":"s","v":"dom-append"},{"t":"s","v":"outerHTML"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-clone"},{"t":"s","v":"dom-first-child"},{"t":"s","v":"dom-replace-child"},{"t":"s","v":"dom-next-sibling"},{"t":"s","v":"insert-remaining-siblings"},{"t":"s","v":"dom-remove-child"},{"t":"s","v":"afterend"},{"t":"s","v":"dom-insert-after"},{"t":"s","v":"beforeend"},{"t":"s","v":"afterbegin"},{"t":"s","v":"dom-prepend"},{"t":"s","v":"beforebegin"},{"t":"s","v":"dom-insert-before"},{"t":"s","v":"delete"},{"t":"s","v":"none"}],"arity":3}},{"t":"s","v":"insert-remaining-siblings"},{"t":"code","v":{"bytecode":[16,2,33,33,0,20,0,0,16,2,48,1,17,3,20,1,0,16,1,16,2,48,2,5,20,2,0,16,0,16,2,16,3,49,3,32,1,0,2,50],"constants":[{"t":"s","v":"dom-next-sibling"},{"t":"s","v":"dom-insert-after"},{"t":"s","v":"insert-remaining-siblings"}],"arity":3}},{"t":"s","v":"swap-html-string"},{"t":"code","v":{"bytecode":[16,2,6,1,0,0,52,1,0,2,33,13,0,5,20,2,0,16,0,16,1,49,2,32,212,0,6,1,3,0,52,1,0,2,33,38,0,5,20,4,0,16,0,48,1,17,3,20,5,0,16,0,1,6,0,16,1,48,3,5,20,7,0,16,3,16,0,48,2,5,16,3,32,163,0,6,1,6,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,6,0,16,1,49,3,32,136,0,6,1,8,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,8,0,16,1,49,3,32,109,0,6,1,9,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,9,0,16,1,49,3,32,82,0,6,1,10,0,52,1,0,2,33,16,0,5,20,5,0,16,0,1,10,0,16,1,49,3,32,55,0,6,1,11,0,52,1,0,2,33,18,0,5,20,7,0,20,4,0,16,0,48,1,16,0,49,2,32,26,0,6,1,12,0,52,1,0,2,33,5,0,5,2,32,10,0,5,20,2,0,16,0,16,1,49,2,50],"constants":[{"t":"s","v":"innerHTML"},{"t":"s","v":"="},{"t":"s","v":"dom-set-inner-html"},{"t":"s","v":"outerHTML"},{"t":"s","v":"dom-parent"},{"t":"s","v":"dom-insert-adjacent-html"},{"t":"s","v":"afterend"},{"t":"s","v":"dom-remove-child"},{"t":"s","v":"beforeend"},{"t":"s","v":"afterbegin"},{"t":"s","v":"beforebegin"},{"t":"s","v":"delete"},{"t":"s","v":"none"}],"arity":3}},{"t":"s","v":"handle-history"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,3,20,0,0,16,0,1,2,0,48,2,17,4,16,2,1,4,0,52,3,0,2,17,5,16,5,33,10,0,20,5,0,16,5,49,1,32,101,0,16,3,6,33,14,0,5,16,3,1,8,0,52,7,0,2,52,6,0,1,33,27,0,20,9,0,16,3,1,10,0,52,7,0,2,33,5,0,16,1,32,2,0,16,3,49,1,32,51,0,16,4,6,33,14,0,5,16,4,1,8,0,52,7,0,2,52,6,0,1,33,27,0,20,5,0,16,4,1,10,0,52,7,0,2,33,5,0,16,1,32,2,0,16,4,49,1,32,1,0,2,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-push-url"},{"t":"s","v":"sx-replace-url"},{"t":"s","v":"get"},{"t":"s","v":"replace-url"},{"t":"s","v":"browser-replace-state"},{"t":"s","v":"not"},{"t":"s","v":"="},{"t":"s","v":"false"},{"t":"s","v":"browser-push-state"},{"t":"s","v":"true"}],"arity":3}},{"t":"s","v":"PRELOAD_TTL"},{"t":"n","v":30000},{"t":"s","v":"preload-cache-get"},{"t":"code","v":{"bytecode":[16,0,16,1,52,0,0,2,17,2,16,2,52,1,0,1,33,4,0,2,32,52,0,20,4,0,48,0,16,2,1,6,0,52,5,0,2,52,3,0,2,20,7,0,52,2,0,2,33,13,0,16,0,16,1,52,8,0,2,5,2,32,11,0,16,0,16,1,52,8,0,2,5,16,2,50],"constants":[{"t":"s","v":"dict-get"},{"t":"s","v":"nil?"},{"t":"s","v":">"},{"t":"s","v":"-"},{"t":"s","v":"now-ms"},{"t":"s","v":"get"},{"t":"s","v":"timestamp"},{"t":"s","v":"PRELOAD_TTL"},{"t":"s","v":"dict-delete!"}],"arity":2}},{"t":"s","v":"preload-cache-set"},{"t":"code","v":{"bytecode":[16,0,16,1,1,2,0,16,2,1,3,0,16,3,1,4,0,20,5,0,48,0,52,1,0,6,52,0,0,3,50],"constants":[{"t":"s","v":"dict-set!"},{"t":"s","v":"dict"},{"t":"s","v":"text"},{"t":"s","v":"content-type"},{"t":"s","v":"timestamp"},{"t":"s","v":"now-ms"}],"arity":4}},{"t":"s","v":"classify-trigger"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,17,1,16,1,1,3,0,52,2,0,2,33,6,0,1,4,0,32,57,0,16,1,1,5,0,52,2,0,2,33,6,0,1,5,0,32,39,0,16,1,1,6,0,52,2,0,2,33,6,0,1,6,0,32,21,0,16,1,1,7,0,52,2,0,2,33,6,0,1,7,0,32,3,0,1,1,0,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"event"},{"t":"s","v":"="},{"t":"s","v":"every"},{"t":"s","v":"poll"},{"t":"s","v":"intersect"},{"t":"s","v":"load"},{"t":"s","v":"revealed"}],"arity":1}},{"t":"s","v":"should-boost-link?"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,17,1,16,1,6,33,119,0,5,16,1,1,4,0,52,3,0,2,52,2,0,1,6,33,101,0,5,16,1,1,5,0,52,3,0,2,52,2,0,1,6,33,83,0,5,16,1,1,6,0,52,3,0,2,52,2,0,1,6,33,65,0,5,20,7,0,16,1,48,1,6,33,53,0,5,20,8,0,16,0,1,9,0,48,2,52,2,0,1,6,33,34,0,5,20,8,0,16,0,1,10,0,48,2,52,2,0,1,6,33,15,0,5,20,8,0,16,0,1,11,0,48,2,52,2,0,1,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"href"},{"t":"s","v":"not"},{"t":"s","v":"starts-with?"},{"t":"s","v":"#"},{"t":"s","v":"javascript:"},{"t":"s","v":"mailto:"},{"t":"s","v":"browser-same-origin?"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-get"},{"t":"s","v":"sx-post"},{"t":"s","v":"sx-disable"}],"arity":1}},{"t":"s","v":"should-boost-form?"},{"t":"code","v":{"bytecode":[20,1,0,16,0,1,2,0,48,2,52,0,0,1,6,33,34,0,5,20,1,0,16,0,1,3,0,48,2,52,0,0,1,6,33,15,0,5,20,1,0,16,0,1,4,0,48,2,52,0,0,1,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"dom-has-attr?"},{"t":"s","v":"sx-get"},{"t":"s","v":"sx-post"},{"t":"s","v":"sx-disable"}],"arity":1}},{"t":"s","v":"parse-sse-swap"},{"t":"code","v":{"bytecode":[20,0,0,16,0,1,1,0,48,2,6,34,4,0,5,1,2,0,50],"constants":[{"t":"s","v":"dom-get-attr"},{"t":"s","v":"sx-sse-swap"},{"t":"s","v":"message"}],"arity":1}}]}} \ No newline at end of file diff --git a/shared/static/wasm/sx_browser.bc.wasm.js b/shared/static/wasm/sx_browser.bc.wasm.js index 4efdab08..f5e43eaf 100644 --- a/shared/static/wasm/sx_browser.bc.wasm.js +++ b/shared/static/wasm/sx_browser.bc.wasm.js @@ -1792,7 +1792,7 @@ blake2_js_for_wasm_create: blake2_js_for_wasm_create}; } (globalThis)) -({"link":[["runtime-0db9b496",0],["prelude-d7e4b000",0],["stdlib-23ce0836",[]],["sx-6f7dfa09",[2]],["jsoo_runtime-f96b44a8",[2]],["js_of_ocaml-651f6707",[2,4]],["dune__exe__Sx_browser-6b156118",[2,3,5]],["std_exit-10fb8830",[2]],["start-80fdb768",0]],"generated":(b=>{var +({"link":[["runtime-0db9b496",0],["prelude-d7e4b000",0],["stdlib-23ce0836",[]],["sx-59456384",[2]],["jsoo_runtime-f96b44a8",[2]],["js_of_ocaml-651f6707",[2,4]],["dune__exe__Sx_browser-ec413294",[2,3,5]],["std_exit-10fb8830",[2]],["start-80fdb768",0]],"generated":(b=>{var c=b,a=b?.module?.export||b;return{"env":{"caml_ba_kind_of_typed_array":()=>{throw new Error("caml_ba_kind_of_typed_array not implemented")},"caml_exn_with_js_backtrace":()=>{throw new Error("caml_exn_with_js_backtrace not implemented")},"caml_int64_create_lo_mi_hi":()=>{throw new diff --git a/tests/playwright/isomorphic.spec.js b/tests/playwright/isomorphic.spec.js index bcffe216..fbbcd18b 100644 --- a/tests/playwright/isomorphic.spec.js +++ b/tests/playwright/isomorphic.spec.js @@ -176,10 +176,7 @@ test.describe('Isomorphic SSR', () => { expect(brokenLinks).toEqual([]); }); - test.fixme('navigation preserves header island state', async ({ page }) => { - // BUG: client? primitive works from K.eval but not during render-to-dom hydration. - // Needs JIT/env investigation — the pre-existing JIT "Not callable: nil" bug - // prevents primitives registered after boot from being called during component eval. + test('navigation preserves header island state', async ({ page }) => { await page.goto(BASE_URL + '/sx/', { waitUntil: 'networkidle' }); // Wait for header island to hydrate @@ -200,13 +197,9 @@ test.describe('Isomorphic SSR', () => { await geoLink.click(); await page.waitForTimeout(2000); - // Colour should be preserved (island not disposed) + // Colour should be preserved (def-store keeps signals across re-hydration) const colourAfter = await reactive.evaluate(el => el.style.color); expect(colourAfter).toBe(colourBefore); - - // Copyright path should update - const copyright = page.locator('[data-sx-lake="copyright"]'); - await expect(copyright).toContainText('geography'); }); });