From 89ffb02b20df8f6058b198e9db2579d55fecddaa Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 10 Apr 2026 11:21:57 +0000 Subject: [PATCH] =?UTF-8?q?Revert=20WIP=20hydration=20commit=20=E2=80=94?= =?UTF-8?q?=20undefined=20hydrate-start!/stop!=20broke=20all=20islands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WIP commit (0044f17e) added calls to hydrate-start!, hydrate-stop!, hydrate-push!, hydrate-pop!, and hydrate-next-*! — none of which were ever defined. This crashed hydrate-island silently (cek-try swallowed the error), preventing event listener attachment on every island. Co-Authored-By: Claude Opus 4.6 (1M context) --- shared/static/wasm/sx/adapter-dom.sx | 2607 ++++++++++++------------ shared/static/wasm/sx/adapter-dom.sxbc | 4 +- shared/static/wasm/sx/boot.sx | 13 +- shared/static/wasm/sx/boot.sxbc | 4 +- web/adapter-dom.sx | 2607 ++++++++++++------------ web/boot.sx | 13 +- 6 files changed, 2568 insertions(+), 2680 deletions(-) diff --git a/shared/static/wasm/sx/adapter-dom.sx b/shared/static/wasm/sx/adapter-dom.sx index af0b1708..8be3ae23 100644 --- a/shared/static/wasm/sx/adapter-dom.sx +++ b/shared/static/wasm/sx/adapter-dom.sx @@ -1,453 +1,220 @@ (import (sx dom)) (import (sx render)) -(define-library - (web adapter-dom) - (export - SVG_NS - MATH_NS - island-scope? - contains-deref? - dom-on - render-to-dom - render-dom-list - render-dom-element - render-dom-component - render-dom-fragment - render-dom-raw - render-dom-unknown-component - RENDER_DOM_FORMS - render-dom-form? - dispatch-render-form - render-lambda-dom - render-dom-island - render-dom-lake - render-dom-marsh - reactive-text - reactive-attr - reactive-spread - reactive-fragment - render-list-item - extract-key - reactive-list - bind-input - *use-cek-reactive* - enable-cek-reactive! - cek-reactive-text - cek-reactive-attr - render-dom-portal - render-dom-error-boundary) +(define-library (web adapter-dom) + (export SVG_NS MATH_NS island-scope? contains-deref? dom-on render-to-dom render-dom-list render-dom-element render-dom-component render-dom-fragment render-dom-raw render-dom-unknown-component RENDER_DOM_FORMS render-dom-form? dispatch-render-form render-lambda-dom render-dom-island render-dom-lake render-dom-marsh reactive-text reactive-attr reactive-spread reactive-fragment render-list-item extract-key reactive-list bind-input *use-cek-reactive* enable-cek-reactive! cek-reactive-text cek-reactive-attr render-dom-portal render-dom-error-boundary) (begin - (define SVG_NS "http://www.w3.org/2000/svg") - (define MATH_NS "http://www.w3.org/1998/Math/MathML") - (define - island-scope? - (fn () (not (nil? (scope-peek "sx-island-scope"))))) - (begin - (define *memo-cache* (dict)) - (define *cyst-counter* 0) - (define - next-cyst-id - (fn - () - (set! *cyst-counter* (+ *cyst-counter* 1)) - (str "sx-cyst-" *cyst-counter*)))) - (define - contains-deref? - (fn - (expr) + +(define SVG_NS "http://www.w3.org/2000/svg") + +(define MATH_NS "http://www.w3.org/1998/Math/MathML") + +(define island-scope? (fn () (not (nil? (scope-peek "sx-island-scope"))))) + +(begin + (define *memo-cache* (dict)) + (define *cyst-counter* 0) + (define + next-cyst-id + (fn + () + (set! *cyst-counter* (+ *cyst-counter* 1)) + (str "sx-cyst-" *cyst-counter*)))) + +(define + contains-deref? + (fn + (expr) + (if + (not (list? expr)) + false + (if + (empty? expr) + false (if - (not (list? expr)) - false - (if - (empty? expr) - false + (and + (= (type-of (first expr)) "symbol") + (= (symbol-name (first expr)) "deref")) + true + (some contains-deref? expr)))))) + +(define + dom-on + :effects (io) + (fn + (el name handler) + (dom-listen + el + name + (if + (lambda? handler) + (if + (= 0 (len (lambda-params handler))) + (fn + (_e) + (trampoline (call-lambda handler (list))) + (run-post-render-hooks)) + (fn + (e) + (trampoline (call-lambda handler (list e))) + (run-post-render-hooks))) + handler)))) + +(define + render-to-dom + :effects (render) + (fn + (expr (env :as dict) (ns :as string)) + (set-render-active! true) + (case + (type-of expr) + "nil" + (create-fragment) + "boolean" + (create-fragment) + "raw-html" + (dom-parse-html (raw-html-content expr)) + "string" + (create-text-node expr) + "number" + (create-text-node (str expr)) + "symbol" + (render-to-dom (trampoline (eval-expr expr env)) env ns) + "keyword" + (create-text-node (keyword-name expr)) + "dom-node" + expr + "spread" + (do + (when + (not (island-scope?)) + (scope-emit! "element-attrs" (spread-attrs expr))) + expr) + "dict" + (if (has-key? expr "__host_handle") expr (create-fragment)) + "list" + (if (empty? expr) (create-fragment) (render-dom-list expr env ns)) + :else (if + (signal? expr) + (if + (island-scope?) + (reactive-text expr) + (create-text-node (str (deref expr)))) + (create-text-node (str expr)))))) + +(define + render-dom-list + :effects (render) + (fn + (expr (env :as dict) (ns :as string)) + (let + ((head (first expr))) + (cond + (= (type-of head) "symbol") + (let + ((name (symbol-name head)) (args (rest expr))) + (cond + (= name "raw!") + (render-dom-raw args env) + (= name "<>") + (render-dom-fragment args env ns) + (= name "lake") + (render-dom-lake args env ns) + (= name "marsh") + (render-dom-marsh args env ns) + (starts-with? name "html:") + (render-dom-element (slice name 5) args env ns) + (render-dom-form? name) (if (and - (= (type-of (first expr)) "symbol") - (= (symbol-name (first expr)) "deref")) - true - (some contains-deref? expr)))))) - (define - dom-on - :effects (io) - (fn - (el name handler) - (dom-listen - el - name - (if - (lambda? handler) - (if - (= 0 (len (lambda-params handler))) - (fn - (_e) - (trampoline (call-lambda handler (list))) - (run-post-render-hooks)) - (fn - (e) - (trampoline (call-lambda handler (list e))) - (run-post-render-hooks))) - handler)))) - (define - render-to-dom - :effects (render) - (fn - (expr (env :as dict) (ns :as string)) - (set-render-active! true) - (case - (type-of expr) - "nil" - (create-fragment) - "boolean" - (create-fragment) - "raw-html" - (dom-parse-html (raw-html-content expr)) - "string" - (if - *hydrating* - (or (hydrate-next-text!) (create-text-node expr)) - (create-text-node expr)) - "number" - (if - *hydrating* - (or (hydrate-next-text!) (create-text-node (str expr))) - (create-text-node (str expr))) - "symbol" - (render-to-dom (trampoline (eval-expr expr env)) env ns) - "keyword" - (create-text-node (keyword-name expr)) - "dom-node" - expr - "spread" - (do - (when - (not (island-scope?)) - (scope-emit! "element-attrs" (spread-attrs expr))) - expr) - "dict" - (if (has-key? expr "__host_handle") expr (create-fragment)) - "list" - (if (empty? expr) (create-fragment) (render-dom-list expr env ns)) - :else (if - (signal? expr) - (if - (island-scope?) - (reactive-text expr) - (create-text-node (str (deref expr)))) - (create-text-node (str expr)))))) - (define - render-dom-list - :effects (render) - (fn - (expr (env :as dict) (ns :as string)) - (let - ((head (first expr))) - (cond - (= (type-of head) "symbol") - (let - ((name (symbol-name head)) (args (rest expr))) - (cond - (= name "raw!") - (render-dom-raw args env) - (= name "<>") - (render-dom-fragment args env ns) - (= name "lake") - (render-dom-lake args env ns) - (= name "marsh") - (render-dom-marsh args env ns) - (starts-with? name "html:") - (render-dom-element (slice name 5) args env ns) - (render-dom-form? name) - (if - (and - (contains? HTML_TAGS name) - (or - (and - (> (len args) 0) - (= (type-of (first args)) "keyword")) - ns)) - (render-dom-element name args env ns) - (dispatch-render-form name expr env ns)) - (and (env-has? env name) (macro? (env-get env name))) - (render-to-dom - (expand-macro (env-get env name) args env) - env - ns) (contains? HTML_TAGS name) - (render-dom-element name args env ns) - (and - (starts-with? name "~") - (env-has? env name) - (island? (env-get env name))) - (if - (scope-peek "sx-render-markers") - (let - ((island (env-get env name)) - (marker (dom-create-element "span" nil)) - (kw-state (dict))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip + (or + (and + (> (len args) 0) + (= (type-of (first args)) "keyword")) + ns)) + (render-dom-element name args env ns) + (dispatch-render-form name expr env ns)) + (and (env-has? env name) (macro? (env-get env name))) + (render-to-dom (expand-macro (env-get env name) args env) env ns) + (contains? HTML_TAGS name) + (render-dom-element name args env ns) + (and + (starts-with? name "~") + (env-has? env name) + (island? (env-get env name))) + (if + (scope-peek "sx-render-markers") + (let + ((island (env-get env name)) + (marker (dom-create-element "span" nil)) + (kw-state (dict))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((kname (keyword-name arg)) + (kval + (trampoline + (eval-expr + (nth args (inc (get state "i"))) + env)))) + (dict-set! kw-state kname kval) (assoc state "skip" - false + true "i" - (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((kname (keyword-name arg)) - (kval - (trampoline - (eval-expr - (nth args (inc (get state "i"))) - env)))) - (dict-set! kw-state kname kval) - (assoc - state - "skip" - true - "i" - (inc (get state "i")))) - (assoc state "i" (inc (get state "i"))))))) - (dict "i" 0 "skip" false) - args) - (dom-set-attr - marker - "data-sx-island" - (component-name island)) - (when - (not (empty-dict? kw-state)) - (dom-set-attr - marker - "data-sx-state" - (sx-serialize kw-state))) - marker) - (render-dom-island (env-get env name) args env ns)) - (starts-with? name "~") - (let - ((comp (env-get env name))) - (if - (component? comp) - (render-dom-component comp args env ns) - (render-dom-unknown-component name))) - (and - (> (index-of name "-") 0) - (> (len args) 0) - (= (type-of (first args)) "keyword")) - (render-dom-element name args env ns) - ns - (render-dom-element name args env ns) - (and (= name "deref") (island-scope?)) - (let - ((sig-or-val (trampoline (eval-expr (first args) env)))) - (if - (signal? sig-or-val) - (reactive-text sig-or-val) - (create-text-node (str (deref sig-or-val))))) - (and (island-scope?) (contains-deref? expr)) - (reactive-text - (computed (fn () (trampoline (eval-expr expr env))))) - :else (render-to-dom (trampoline (eval-expr expr env)) env ns))) - (or (lambda? head) (= (type-of head) "list")) - (render-to-dom (trampoline (eval-expr expr env)) env ns) - :else (let - ((frag (create-fragment))) - (for-each - (fn - (x) - (let - ((result (render-to-dom x env ns))) - (when (not (spread? result)) (dom-append frag result)))) - expr) - frag))))) - (define - render-dom-element - :effects (render) - (fn - ((tag :as string) (args :as list) (env :as dict) (ns :as string)) - (let - ((new-ns (if (= tag "svg") SVG_NS (if (= tag "math") MATH_NS ns))) - (el + (inc (get state "i")))) + (assoc state "i" (inc (get state "i"))))))) + (dict "i" 0 "skip" false) + args) + (dom-set-attr marker "data-sx-island" (component-name island)) + (when + (not (empty-dict? kw-state)) + (dom-set-attr + marker + "data-sx-state" + (sx-serialize kw-state))) + marker) + (render-dom-island (env-get env name) args env ns)) + (starts-with? name "~") + (let + ((comp (env-get env name))) (if - *hydrating* - (let - ((existing (hydrate-next-element!))) - (when existing (hydrate-push! existing)) - (or existing (dom-create-element tag new-ns))) - (dom-create-element tag new-ns)))) - (scope-push! "element-attrs" nil) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((attr-name (keyword-name arg)) - (attr-expr (nth args (inc (get state "i"))))) - (cond - (starts-with? attr-name "on-") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (when - (callable? attr-val) - (dom-on el (slice attr-name 3) attr-val))) - (= attr-name "bind") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (when (signal? attr-val) (bind-input el attr-val))) - (= attr-name "ref") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (dict-set! attr-val "current" el)) - (= attr-name "key") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (dom-set-attr el "key" (str attr-val))) - (island-scope?) - (reactive-attr - el - attr-name - (fn () (trampoline (eval-expr attr-expr env)))) - :else (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (cond - (or (nil? attr-val) (= attr-val false)) - nil - (contains? BOOLEAN_ATTRS attr-name) - (when attr-val (dom-set-attr el attr-name "")) - (= attr-val true) - (dom-set-attr el attr-name "") - :else (dom-set-attr el attr-name (str attr-val))))) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (when - (not (contains? VOID_ELEMENTS tag)) - (let - ((child (render-to-dom arg env new-ns))) - (cond - (and (spread? child) (island-scope?)) - (reactive-spread - el - (fn () (render-to-dom arg env new-ns))) - (spread? child) - nil - :else (when (not *hydrating*) (dom-append el child))))) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (for-each - (fn - (spread-dict) - (for-each - (fn - ((key :as string)) - (let - ((val (dict-get spread-dict key))) - (if - (= key "class") - (let - ((existing (dom-get-attr el "class"))) - (dom-set-attr - el - "class" - (if - (and existing (not (= existing ""))) - (str existing " " val) - val))) - (if - (= key "style") - (let - ((existing (dom-get-attr el "style"))) - (dom-set-attr - el - "style" - (if - (and existing (not (= existing ""))) - (str existing ";" val) - val))) - (dom-set-attr el key (str val)))))) - (keys spread-dict))) - (scope-emitted "element-attrs")) - (scope-pop! "element-attrs") - (do (when *hydrating* (hydrate-pop!)) el)))) - (define - render-dom-component - :effects (render) - (fn - ((comp :as component) - (args :as list) - (env :as dict) - (ns :as string)) - (let - ((kwargs (dict)) (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) - (dict-set! kwargs (keyword-name arg) val) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((local (env-merge (component-closure comp) env))) - (for-each - (fn - (p) - (env-bind! - local - p - (if (dict-has? kwargs p) (dict-get kwargs p) nil))) - (component-params comp)) - (when - (component-has-children? comp) - (let - ((child-frag (create-fragment))) - (for-each - (fn - (c) - (let - ((result (render-to-dom c env ns))) - (when - (not (spread? result)) - (dom-append child-frag result)))) - children) - (env-bind! local "children" child-frag))) - (render-to-dom (component-body comp) local ns))))) - (define - render-dom-fragment - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let + (component? comp) + (render-dom-component comp args env ns) + (render-dom-unknown-component name))) + (and + (> (index-of name "-") 0) + (> (len args) 0) + (= (type-of (first args)) "keyword")) + (render-dom-element name args env ns) + ns + (render-dom-element name args env ns) + (and (= name "deref") (island-scope?)) + (let + ((sig-or-val (trampoline (eval-expr (first args) env)))) + (if + (signal? sig-or-val) + (reactive-text sig-or-val) + (create-text-node (str (deref sig-or-val))))) + (and (island-scope?) (contains-deref? expr)) + (reactive-text + (computed (fn () (trampoline (eval-expr expr env))))) + :else (render-to-dom (trampoline (eval-expr expr env)) env ns))) + (or (lambda? head) (= (type-of head) "list")) + (render-to-dom (trampoline (eval-expr expr env)) env ns) + :else (let ((frag (create-fragment))) (for-each (fn @@ -455,320 +222,490 @@ (let ((result (render-to-dom x env ns))) (when (not (spread? result)) (dom-append frag result)))) - args) - frag))) - (define - render-dom-raw - :effects (render) - (fn - ((args :as list) (env :as dict)) - (let - ((frag (create-fragment))) + expr) + frag))))) + +(define + render-dom-element + :effects (render) + (fn + ((tag :as string) (args :as list) (env :as dict) (ns :as string)) + (let + ((new-ns (cond (= tag "svg") SVG_NS (= tag "math") MATH_NS :else ns)) + (el (dom-create-element tag new-ns))) + (scope-push! "element-attrs" nil) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((attr-name (keyword-name arg)) + (attr-expr (nth args (inc (get state "i"))))) + (cond + (starts-with? attr-name "on-") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (when + (callable? attr-val) + (dom-on el (slice attr-name 3) attr-val))) + (= attr-name "bind") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (when (signal? attr-val) (bind-input el attr-val))) + (= attr-name "ref") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (dict-set! attr-val "current" el)) + (= attr-name "key") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (dom-set-attr el "key" (str attr-val))) + (island-scope?) + (reactive-attr + el + attr-name + (fn () (trampoline (eval-expr attr-expr env)))) + :else (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (cond + (or (nil? attr-val) (= attr-val false)) + nil + (contains? BOOLEAN_ATTRS attr-name) + (when attr-val (dom-set-attr el attr-name "")) + (= attr-val true) + (dom-set-attr el attr-name "") + :else (dom-set-attr el attr-name (str attr-val))))) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (when + (not (contains? VOID_ELEMENTS tag)) + (let + ((child (render-to-dom arg env new-ns))) + (cond + (and (spread? child) (island-scope?)) + (reactive-spread + el + (fn () (render-to-dom arg env new-ns))) + (spread? child) + nil + :else (dom-append el child)))) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (for-each + (fn + (spread-dict) (for-each (fn - (arg) + ((key :as string)) (let - ((val (trampoline (eval-expr arg env)))) - (cond - (= (type-of val) "string") - (dom-append frag (dom-parse-html val)) - (= (type-of val) "dom-node") - (dom-append frag (dom-clone val)) - (not (nil? val)) - (dom-append frag (create-text-node (str val)))))) - args) - frag))) - (define - render-dom-unknown-component - :effects (render) - (fn ((name :as string)) (error (str "Unknown component: " name)))) - (define - RENDER_DOM_FORMS - (list - "if" - "when" - "cond" - "case" - "let" - "let*" - "letrec" - "begin" - "do" - "define" - "defcomp" - "defisland" - "defmacro" - "defstyle" - "map" - "map-indexed" - "filter" - "for-each" - "portal" - "error-boundary" - "scope" - "provide" - "cyst")) - (define - render-dom-form? - :effects () - (fn ((name :as string)) (contains? RENDER_DOM_FORMS name))) - (define - dispatch-render-form - :effects (render) - (fn - ((name :as string) expr (env :as dict) (ns :as string)) - (cond - (= name "if") - (if - (island-scope?) - (let - ((marker (create-comment "r-if")) - (current-nodes (list)) - (initial-result nil)) - (effect - (fn - () + ((val (dict-get spread-dict key))) + (if + (= key "class") (let - ((result (let ((cond-val (trampoline (eval-expr (nth expr 1) env)))) (if cond-val (render-to-dom (nth expr 2) env ns) (if (> (len expr) 3) (render-to-dom (nth expr 3) env ns) (create-fragment)))))) - (if - (dom-parent marker) - (do - (for-each (fn (n) (dom-remove n)) current-nodes) + ((existing (dom-get-attr el "class"))) + (dom-set-attr + el + "class" + (if + (and existing (not (= existing ""))) + (str existing " " val) + val))) + (if + (= key "style") + (let + ((existing (dom-get-attr el "style"))) + (dom-set-attr + el + "style" + (if + (and existing (not (= existing ""))) + (str existing ";" val) + val))) + (dom-set-attr el key (str val)))))) + (keys spread-dict))) + (scope-emitted "element-attrs")) + (scope-pop! "element-attrs") + el))) + +(define + render-dom-component + :effects (render) + (fn + ((comp :as component) (args :as list) (env :as dict) (ns :as string)) + (let + ((kwargs (dict)) (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) + (dict-set! kwargs (keyword-name arg) val) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((local (env-merge (component-closure comp) env))) + (for-each + (fn + (p) + (env-bind! + local + p + (if (dict-has? kwargs p) (dict-get kwargs p) nil))) + (component-params comp)) + (when + (component-has-children? comp) + (let + ((child-frag (create-fragment))) + (for-each + (fn + (c) + (let + ((result (render-to-dom c env ns))) + (when + (not (spread? result)) + (dom-append child-frag result)))) + children) + (env-bind! local "children" child-frag))) + (render-to-dom (component-body comp) local ns))))) + +(define + render-dom-fragment + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((frag (create-fragment))) + (for-each + (fn + (x) + (let + ((result (render-to-dom x env ns))) + (when (not (spread? result)) (dom-append frag result)))) + args) + frag))) + +(define + render-dom-raw + :effects (render) + (fn + ((args :as list) (env :as dict)) + (let + ((frag (create-fragment))) + (for-each + (fn + (arg) + (let + ((val (trampoline (eval-expr arg env)))) + (cond + (= (type-of val) "string") + (dom-append frag (dom-parse-html val)) + (= (type-of val) "dom-node") + (dom-append frag (dom-clone val)) + (not (nil? val)) + (dom-append frag (create-text-node (str val)))))) + args) + frag))) + +(define + render-dom-unknown-component + :effects (render) + (fn ((name :as string)) (error (str "Unknown component: " name)))) + +(define + RENDER_DOM_FORMS + (list + "if" + "when" + "cond" + "case" + "let" + "let*" + "letrec" + "begin" + "do" + "define" + "defcomp" + "defisland" + "defmacro" + "defstyle" + "map" + "map-indexed" + "filter" + "for-each" + "portal" + "error-boundary" + "scope" + "provide" + "cyst")) + +(define + render-dom-form? + :effects () + (fn ((name :as string)) (contains? RENDER_DOM_FORMS name))) + +(define + dispatch-render-form + :effects (render) + (fn + ((name :as string) expr (env :as dict) (ns :as string)) + (cond + (= name "if") + (if + (island-scope?) + (let + ((marker (create-comment "r-if")) + (current-nodes (list)) + (initial-result nil)) + (effect + (fn + () + (let + ((result (let ((cond-val (trampoline (eval-expr (nth expr 1) env)))) (if cond-val (render-to-dom (nth expr 2) env ns) (if (> (len expr) 3) (render-to-dom (nth expr 3) env ns) (create-fragment)))))) + (if + (dom-parent marker) + (do + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! + current-nodes + (if + (dom-is-fragment? result) + (dom-child-nodes result) + (list result))) + (dom-insert-after marker result)) + (set! initial-result result))))) + (if + (spread? initial-result) + initial-result + (let + ((frag (create-fragment))) + (dom-append frag marker) + (when + initial-result + (set! + current-nodes + (if + (dom-is-fragment? initial-result) + (dom-child-nodes initial-result) + (list initial-result))) + (dom-append frag initial-result)) + frag))) + (let + ((cond-val (trampoline (eval-expr (nth expr 1) env)))) + (if + cond-val + (render-to-dom (nth expr 2) env ns) + (if + (> (len expr) 3) + (render-to-dom (nth expr 3) env ns) + (create-fragment))))) + (= name "when") + (if + (island-scope?) + (let + ((marker (create-comment "r-when")) + (current-nodes (list)) + (initial-result nil)) + (effect + (fn + () + (if + (dom-parent marker) + (do + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! current-nodes (list)) + (when + (trampoline (eval-expr (nth expr 1) env)) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (dom-append + frag + (render-to-dom (nth expr i) env ns))) + (range 2 (len expr))) + (set! current-nodes (dom-child-nodes frag)) + (dom-insert-after marker frag)))) + (when + (trampoline (eval-expr (nth expr 1) env)) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (dom-append frag (render-to-dom (nth expr i) env ns))) + (range 2 (len expr))) + (set! current-nodes (dom-child-nodes frag)) + (set! initial-result frag)))))) + (if + (spread? initial-result) + initial-result + (let + ((frag (create-fragment))) + (dom-append frag marker) + (when initial-result (dom-append frag initial-result)) + frag))) + (if + (not (trampoline (eval-expr (nth expr 1) env))) + (create-fragment) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (dom-append frag (render-to-dom (nth expr i) env ns))) + (range 2 (len expr))) + frag))) + (= name "cond") + (if + (island-scope?) + (let + ((marker (create-comment "r-cond")) + (current-nodes (list)) + (initial-result nil)) + (effect + (fn + () + (let + ((branch (eval-cond (rest expr) env))) + (if + (dom-parent marker) + (do + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! current-nodes (list)) + (when + branch + (let + ((result (render-to-dom branch env ns))) (set! current-nodes (if (dom-is-fragment? result) (dom-child-nodes result) (list result))) - (dom-insert-after marker result)) - (set! initial-result result))))) - (if - (spread? initial-result) - initial-result - (let - ((frag (create-fragment))) - (dom-append frag marker) + (dom-insert-after marker result)))) (when - initial-result - (set! - current-nodes - (if - (dom-is-fragment? initial-result) - (dom-child-nodes initial-result) - (list initial-result))) - (dom-append frag initial-result)) - frag))) - (let - ((cond-val (trampoline (eval-expr (nth expr 1) env)))) - (if - cond-val - (render-to-dom (nth expr 2) env ns) - (if - (> (len expr) 3) - (render-to-dom (nth expr 3) env ns) - (create-fragment))))) - (= name "when") - (if - (island-scope?) - (let - ((marker (create-comment "r-when")) - (current-nodes (list)) - (initial-result nil)) - (effect - (fn - () - (if - (dom-parent marker) - (do - (for-each (fn (n) (dom-remove n)) current-nodes) - (set! current-nodes (list)) - (when - (trampoline (eval-expr (nth expr 1) env)) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) - (dom-append - frag - (render-to-dom (nth expr i) env ns))) - (range 2 (len expr))) - (set! current-nodes (dom-child-nodes frag)) - (dom-insert-after marker frag)))) - (when - (trampoline (eval-expr (nth expr 1) env)) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) - (dom-append - frag - (render-to-dom (nth expr i) env ns))) - (range 2 (len expr))) - (set! current-nodes (dom-child-nodes frag)) - (set! initial-result frag)))))) - (if - (spread? initial-result) - initial-result - (let - ((frag (create-fragment))) - (dom-append frag marker) - (when initial-result (dom-append frag initial-result)) - frag))) - (if - (not (trampoline (eval-expr (nth expr 1) env))) - (create-fragment) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) - (dom-append frag (render-to-dom (nth expr i) env ns))) - (range 2 (len expr))) - frag))) - (= name "cond") - (if - (island-scope?) - (let - ((marker (create-comment "r-cond")) - (current-nodes (list)) - (initial-result nil)) - (effect - (fn - () - (let - ((branch (eval-cond (rest expr) env))) - (if - (dom-parent marker) - (do - (for-each (fn (n) (dom-remove n)) current-nodes) - (set! current-nodes (list)) - (when - branch - (let - ((result (render-to-dom branch env ns))) - (set! - current-nodes - (if - (dom-is-fragment? result) - (dom-child-nodes result) - (list result))) - (dom-insert-after marker result)))) - (when - branch - (let - ((result (render-to-dom branch env ns))) - (set! - current-nodes - (if - (dom-is-fragment? result) - (dom-child-nodes result) - (list result))) - (set! initial-result result))))))) - (if - (spread? initial-result) - initial-result - (let - ((frag (create-fragment))) - (dom-append frag marker) - (when initial-result (dom-append frag initial-result)) - frag))) - (let - ((branch (eval-cond (rest expr) env))) - (if branch (render-to-dom branch env ns) (create-fragment)))) - (= name "case") - (render-to-dom (trampoline (eval-expr expr env)) env ns) - (or (= name "let") (= name "let*")) - (let - ((local (process-bindings (nth expr 1) env))) - (if - (= (len expr) 3) - (render-to-dom (nth expr 2) local ns) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) + branch (let - ((result (render-to-dom (nth expr i) local ns))) - (when (not (spread? result)) (dom-append frag result)))) - (range 2 (len expr))) - frag))) - (= name "letrec") - (let - ((bindings (nth expr 1)) - (body (slice expr 2)) - (local (env-extend env))) - (for-each - (fn - (pair) - (let - ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) - (env-bind! local pname nil))) - bindings) - (for-each - (fn - (pair) - (let - ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) - (env-set! - local - pname - (trampoline (eval-expr (nth pair 1) local))))) - bindings) - (when - (> (len body) 1) - (for-each - (fn (e) (trampoline (eval-expr e local))) - (init body))) - (render-to-dom (last body) local ns)) - (or (= name "begin") (= name "do")) + ((result (render-to-dom branch env ns))) + (set! + current-nodes + (if + (dom-is-fragment? result) + (dom-child-nodes result) + (list result))) + (set! initial-result result))))))) (if - (= (len expr) 2) - (render-to-dom (nth expr 1) env ns) + (spread? initial-result) + initial-result (let ((frag (create-fragment))) - (for-each - (fn - (i) - (let - ((result (render-to-dom (nth expr i) env ns))) - (when (not (spread? result)) (dom-append frag result)))) - (range 1 (len expr))) - frag)) - (definition-form? name) - (do (trampoline (eval-expr expr env)) (create-fragment)) - (= name "map") + (dom-append frag marker) + (when initial-result (dom-append frag initial-result)) + frag))) + (let + ((branch (eval-cond (rest expr) env))) + (if branch (render-to-dom branch env ns) (create-fragment)))) + (= name "case") + (render-to-dom (trampoline (eval-expr expr env)) env ns) + (or (= name "let") (= name "let*")) + (let + ((local (process-bindings (nth expr 1) env))) + (if + (= (len expr) 3) + (render-to-dom (nth expr 2) local ns) (let - ((coll-expr (nth expr 2))) + ((frag (create-fragment))) + (for-each + (fn + (i) + (let + ((result (render-to-dom (nth expr i) local ns))) + (when (not (spread? result)) (dom-append frag result)))) + (range 2 (len expr))) + frag))) + (= name "letrec") + (let + ((bindings (nth expr 1)) + (body (slice expr 2)) + (local (env-extend env))) + (for-each + (fn + (pair) + (let + ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) + (env-bind! local pname nil))) + bindings) + (for-each + (fn + (pair) + (let + ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) + (env-set! + local + pname + (trampoline (eval-expr (nth pair 1) local))))) + bindings) + (when + (> (len body) 1) + (for-each (fn (e) (trampoline (eval-expr e local))) (init body))) + (render-to-dom (last body) local ns)) + (or (= name "begin") (= name "do")) + (if + (= (len expr) 2) + (render-to-dom (nth expr 1) env ns) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (let + ((result (render-to-dom (nth expr i) env ns))) + (when (not (spread? result)) (dom-append frag result)))) + (range 1 (len expr))) + frag)) + (definition-form? name) + (do (trampoline (eval-expr expr env)) (create-fragment)) + (= name "map") + (let + ((coll-expr (nth expr 2))) + (if + (and + (island-scope?) + (= (type-of coll-expr) "list") + (> (len coll-expr) 1) + (= (type-of (first coll-expr)) "symbol") + (= (symbol-name (first coll-expr)) "deref")) + (let + ((f (trampoline (eval-expr (nth expr 1) env))) + (sig (trampoline (eval-expr (nth coll-expr 1) env)))) (if - (and - (island-scope?) - (= (type-of coll-expr) "list") - (> (len coll-expr) 1) - (= (type-of (first coll-expr)) "symbol") - (= (symbol-name (first coll-expr)) "deref")) + (signal? sig) + (reactive-list f sig env ns) (let - ((f (trampoline (eval-expr (nth expr 1) env))) - (sig (trampoline (eval-expr (nth coll-expr 1) env)))) - (if - (signal? sig) - (reactive-list f sig env ns) - (let - ((coll (deref sig)) (frag (create-fragment))) - (for-each - (fn - (item) - (let - ((val (if (lambda? f) (render-lambda-dom f (list item) env ns) (render-to-dom (apply f (list item)) env ns)))) - (dom-append frag val))) - coll) - frag))) - (let - ((f (trampoline (eval-expr (nth expr 1) env))) - (coll (trampoline (eval-expr (nth expr 2) env))) - (frag (create-fragment))) + ((coll (deref sig)) (frag (create-fragment))) (for-each (fn (item) @@ -777,26 +714,6 @@ (dom-append frag val))) coll) frag))) - (= name "map-indexed") - (let - ((f (trampoline (eval-expr (nth expr 1) env))) - (coll (trampoline (eval-expr (nth expr 2) env))) - (frag (create-fragment))) - (for-each-indexed - (fn - (i item) - (let - ((val (if (lambda? f) (render-lambda-dom f (list i item) env ns) (render-to-dom (apply f (list i item)) env ns)))) - (dom-append frag val))) - coll) - frag) - (= name "filter") - (render-to-dom (trampoline (eval-expr expr env)) env ns) - (= name "portal") - (render-dom-portal (rest expr) env ns) - (= name "error-boundary") - (render-dom-error-boundary (rest expr) env ns) - (= name "for-each") (let ((f (trampoline (eval-expr (nth expr 1) env))) (coll (trampoline (eval-expr (nth expr 2) env))) @@ -808,593 +725,627 @@ ((val (if (lambda? f) (render-lambda-dom f (list item) env ns) (render-to-dom (apply f (list item)) env ns)))) (dom-append frag val))) coll) - frag) - (= name "scope") - (let - ((scope-name (trampoline (eval-expr (nth expr 1) env))) - (rest-args (slice expr 2)) - (scope-val nil) - (body-exprs nil) - (frag (create-fragment))) - (if - (and - (>= (len rest-args) 2) - (= (type-of (first rest-args)) "keyword") - (= (keyword-name (first rest-args)) "value")) - (do - (set! - scope-val - (trampoline (eval-expr (nth rest-args 1) env))) - (set! body-exprs (slice rest-args 2))) - (set! body-exprs rest-args)) - (scope-push! scope-name scope-val) - (for-each - (fn (e) (dom-append frag (render-to-dom e env ns))) - body-exprs) - (scope-pop! scope-name) - frag) - (= name "provide") - (let - ((prov-name (trampoline (eval-expr (nth expr 1) env))) - (prov-val (trampoline (eval-expr (nth expr 2) env))) - (frag (create-fragment))) - (scope-push! prov-name prov-val) - (for-each - (fn - (i) - (dom-append frag (render-to-dom (nth expr i) env ns))) - (range 3 (len expr))) - (scope-pop! prov-name) - frag) - (= name "cyst") - (let - ((cyst-key (if (and (> (len expr) 2) (= (type-of (nth expr 1)) "keyword") (= (keyword-name (nth expr 1)) "key")) (str (trampoline (eval-expr (nth expr 2) env))) (next-cyst-id))) - (cached (get *memo-cache* cyst-key))) - (if - (and cached (host-get cached "isConnected")) - cached - (let - ((container (dom-create-element "div" nil)) - (disposers (list)) - (body-exprs - (if - (and - (> (len expr) 2) - (= (type-of (nth expr 1)) "keyword") - (= (keyword-name (nth expr 1)) "key")) - (slice expr 3) - (slice expr 1)))) - (dom-set-attr container "data-sx-cyst" cyst-key) - (let - ((body-dom (with-island-scope (fn (d) (append! disposers d)) (fn () (let ((frag (create-fragment))) (for-each (fn (child) (dom-append frag (render-to-dom child env ns))) body-exprs) frag))))) - (dom-append container body-dom) - (dom-set-data container "sx-disposers" disposers) - (dict-set! *memo-cache* cyst-key container) - container)))) - :else (render-to-dom (trampoline (eval-expr expr env)) env ns)))) - (define - render-lambda-dom - :effects (render) - (fn - ((f :as lambda) (args :as list) (env :as dict) (ns :as string)) - (let - ((local (env-merge (lambda-closure f) env))) - (for-each-indexed - (fn (i p) (env-bind! local p (nth args i))) - (lambda-params f)) - (render-to-dom (lambda-body f) local ns)))) - (define - render-dom-island - :effects (render mutation) - (fn - ((island :as island) - (args :as list) - (env :as dict) - (ns :as string)) - (let - ((kwargs (dict)) (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) - (dict-set! kwargs (keyword-name arg) val) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((local (env-merge (component-closure island) env)) - (island-name (component-name island))) - (for-each - (fn - (p) - (env-bind! - local - p - (if (dict-has? kwargs p) (dict-get kwargs p) nil))) - (component-params island)) - (when - (component-has-children? island) - (let - ((child-frag (create-fragment))) - (for-each - (fn (c) (dom-append child-frag (render-to-dom c env ns))) - children) - (env-bind! local "children" child-frag))) - (let - ((container (dom-create-element "span" nil)) - (disposers (list))) - (begin - (dom-set-attr container "data-sx-island" island-name) - (when - (not (empty-dict? kwargs)) - (dom-set-attr - container - "data-sx-state" - (sx-serialize kwargs)))) - (mark-processed! container "island-hydrated") - (let - ((body-dom (with-island-scope (fn (disposable) (append! disposers disposable)) (fn () (render-to-dom (component-body island) local ns))))) - (dom-append container body-dom) - (dom-set-data container "sx-disposers" disposers) - container)))))) - (define - render-dom-lake - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let - ((lake-id nil) (lake-tag "div") (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((kname (keyword-name arg)) - (kval - (trampoline - (eval-expr (nth args (inc (get state "i"))) env)))) - (cond - (= kname "id") - (set! lake-id kval) - (= kname "tag") - (set! lake-tag kval)) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((el (dom-create-element lake-tag nil))) - (dom-set-attr el "data-sx-lake" (or lake-id "")) - (for-each - (fn (c) (dom-append el (render-to-dom c env ns))) - children) - el)))) - (define - render-dom-marsh - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let - ((marsh-id nil) - (marsh-tag "div") - (marsh-transform nil) - (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((kname (keyword-name arg)) - (kval - (trampoline - (eval-expr (nth args (inc (get state "i"))) env)))) - (cond - (= kname "id") - (set! marsh-id kval) - (= kname "tag") - (set! marsh-tag kval) - (= kname "transform") - (set! marsh-transform kval)) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((el (dom-create-element marsh-tag nil))) - (dom-set-attr el "data-sx-marsh" (or marsh-id "")) - (when - marsh-transform - (dom-set-data el "sx-marsh-transform" marsh-transform)) - (dom-set-data el "sx-marsh-env" env) - (for-each - (fn (c) (dom-append el (render-to-dom c env ns))) - children) - el)))) - (define - reactive-text - :effects (render mutation) - (fn - (sig) - (let - ((node (if *hydrating* (or (hydrate-next-text!) (create-text-node (str (deref sig)))) (create-text-node (str (deref sig)))))) - (effect (fn () (dom-set-text-content node (str (deref sig))))) - node))) - (define - reactive-attr - :effects (render mutation) - (fn - (el (attr-name :as string) (compute-fn :as lambda)) - (let - ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) - (updated - (if (empty? existing) attr-name (str existing "," attr-name)))) - (dom-set-attr el "data-sx-reactive-attrs" updated)) - (effect + frag))) + (= name "map-indexed") + (let + ((f (trampoline (eval-expr (nth expr 1) env))) + (coll (trampoline (eval-expr (nth expr 2) env))) + (frag (create-fragment))) + (for-each-indexed (fn - () + (i item) (let - ((raw (compute-fn))) - (let - ((val (if (signal? raw) (deref raw) raw))) - (cond - (or (nil? val) (= val false)) - (dom-remove-attr el attr-name) - (= val true) - (dom-set-attr el attr-name "") - :else (dom-set-attr el attr-name (str val))))))))) - (define - reactive-spread - :effects (render mutation) - (fn - (el (render-fn :as lambda)) - (let - ((prev-classes (list)) (prev-extra-keys (list))) - (let - ((existing (or (dom-get-attr el "data-sx-reactive-attrs") ""))) - (dom-set-attr - el - "data-sx-reactive-attrs" - (if (empty? existing) "_spread" (str existing ",_spread")))) - (effect - (fn - () - (when - (not (empty? prev-classes)) - (let - ((current (or (dom-get-attr el "class") "")) - (tokens - (filter (fn (c) (not (= c ""))) (split current " "))) - (kept - (filter - (fn - (c) - (not (some (fn (pc) (= pc c)) prev-classes))) - tokens))) - (if - (empty? kept) - (dom-remove-attr el "class") - (dom-set-attr el "class" (join " " kept))))) - (for-each (fn (k) (dom-remove-attr el k)) prev-extra-keys) - (let - ((result (render-fn))) - (if - (spread? result) - (let - ((attrs (spread-attrs result)) - (cls-str (or (dict-get attrs "class") "")) - (new-classes - (filter - (fn (c) (not (= c ""))) - (split cls-str " "))) - (extra-keys - (filter (fn (k) (not (= k "class"))) (keys attrs)))) - (set! prev-classes new-classes) - (set! prev-extra-keys extra-keys) - (when - (not (empty? new-classes)) - (let - ((current (or (dom-get-attr el "class") ""))) - (dom-set-attr - el - "class" - (if - (and current (not (= current ""))) - (str current " " cls-str) - cls-str)))) - (for-each - (fn (k) (dom-set-attr el k (str (dict-get attrs k)))) - extra-keys) - (run-post-render-hooks)) - (do - (set! prev-classes (list)) - (set! prev-extra-keys (list)))))))))) - (define - reactive-fragment - :effects (render mutation) - (fn - ((test-fn :as lambda) - (render-fn :as lambda) - (env :as dict) - (ns :as string)) - (let - ((marker (create-comment "island-fragment")) - (current-nodes (list))) - (effect - (fn - () - (for-each (fn (n) (dom-remove n)) current-nodes) - (set! current-nodes (list)) - (when - (test-fn) - (let - ((frag (render-fn))) - (set! current-nodes (dom-child-nodes frag)) - (dom-insert-after marker frag))))) - marker))) - (define - render-list-item - :effects (render) - (fn - ((map-fn :as lambda) item (env :as dict) (ns :as string)) + ((val (if (lambda? f) (render-lambda-dom f (list i item) env ns) (render-to-dom (apply f (list i item)) env ns)))) + (dom-append frag val))) + coll) + frag) + (= name "filter") + (render-to-dom (trampoline (eval-expr expr env)) env ns) + (= name "portal") + (render-dom-portal (rest expr) env ns) + (= name "error-boundary") + (render-dom-error-boundary (rest expr) env ns) + (= name "for-each") + (let + ((f (trampoline (eval-expr (nth expr 1) env))) + (coll (trampoline (eval-expr (nth expr 2) env))) + (frag (create-fragment))) + (for-each + (fn + (item) + (let + ((val (if (lambda? f) (render-lambda-dom f (list item) env ns) (render-to-dom (apply f (list item)) env ns)))) + (dom-append frag val))) + coll) + frag) + (= name "scope") + (let + ((scope-name (trampoline (eval-expr (nth expr 1) env))) + (rest-args (slice expr 2)) + (scope-val nil) + (body-exprs nil) + (frag (create-fragment))) (if - (lambda? map-fn) - (render-lambda-dom map-fn (list item) env ns) - (render-to-dom (apply map-fn (list item)) env ns)))) - (define - extract-key - :effects (render) - (fn - (node (index :as number)) - (let - ((k (dom-get-attr node "key"))) - (if - k - (do (dom-remove-attr node "key") k) - (let - ((dk (dom-get-data node "key"))) - (if dk (str dk) (str "__idx_" index))))))) - (define - reactive-list - :effects (render mutation) - (fn - ((map-fn :as lambda) - (items-sig :as signal) - (env :as dict) - (ns :as string)) - (let - ((container (create-fragment)) - (marker (create-comment "island-list")) - (key-map (dict)) - (key-order (list))) - (dom-append container marker) - (effect - (fn - () - (let - ((items (deref items-sig))) + (and + (>= (len rest-args) 2) + (= (type-of (first rest-args)) "keyword") + (= (keyword-name (first rest-args)) "value")) + (do + (set! scope-val (trampoline (eval-expr (nth rest-args 1) env))) + (set! body-exprs (slice rest-args 2))) + (set! body-exprs rest-args)) + (scope-push! scope-name scope-val) + (for-each + (fn (e) (dom-append frag (render-to-dom e env ns))) + body-exprs) + (scope-pop! scope-name) + frag) + (= name "provide") + (let + ((prov-name (trampoline (eval-expr (nth expr 1) env))) + (prov-val (trampoline (eval-expr (nth expr 2) env))) + (frag (create-fragment))) + (scope-push! prov-name prov-val) + (for-each + (fn (i) (dom-append frag (render-to-dom (nth expr i) env ns))) + (range 3 (len expr))) + (scope-pop! prov-name) + frag) + (= name "cyst") + (let + ((cyst-key (if (and (> (len expr) 2) (= (type-of (nth expr 1)) "keyword") (= (keyword-name (nth expr 1)) "key")) (str (trampoline (eval-expr (nth expr 2) env))) (next-cyst-id))) + (cached (get *memo-cache* cyst-key))) + (if + (and cached (host-get cached "isConnected")) + cached + (let + ((container (dom-create-element "div" nil)) + (disposers (list)) + (body-exprs (if - (dom-parent marker) - (let - ((new-map (dict)) (new-keys (list)) (has-keys false)) - (for-each-indexed - (fn - (idx item) - (let - ((rendered (render-list-item map-fn item env ns)) - (key (extract-key rendered idx))) - (when - (and - (not has-keys) - (not (starts-with? key "__idx_"))) - (set! has-keys true)) - (if - (dict-has? key-map key) - (dict-set! new-map key (dict-get key-map key)) - (dict-set! new-map key rendered)) - (append! new-keys key))) - items) - (if - (not has-keys) - (do - (dom-remove-children-after marker) - (let - ((frag (create-fragment))) - (for-each - (fn (k) (dom-append frag (dict-get new-map k))) - new-keys) - (dom-insert-after marker frag))) - (do - (for-each - (fn - (old-key) - (when - (not (dict-has? new-map old-key)) - (dom-remove (dict-get key-map old-key)))) - key-order) - (let - ((cursor marker)) - (for-each - (fn - (k) - (let - ((node (dict-get new-map k)) - (next (dom-next-sibling cursor))) - (when - (not (identical? node next)) - (dom-insert-after cursor node)) - (set! cursor node))) - new-keys)))) - (set! key-map new-map) - (set! key-order new-keys)) - (for-each-indexed - (fn - (idx item) - (let - ((rendered (render-list-item map-fn item env ns)) - (key (extract-key rendered idx))) - (dict-set! key-map key rendered) - (append! key-order key) - (dom-append container rendered))) - items))))) - container))) - (define - bind-input - :effects (render mutation) - (fn - (el (sig :as signal)) + (and + (> (len expr) 2) + (= (type-of (nth expr 1)) "keyword") + (= (keyword-name (nth expr 1)) "key")) + (slice expr 3) + (slice expr 1)))) + (dom-set-attr container "data-sx-cyst" cyst-key) + (let + ((body-dom (with-island-scope (fn (d) (append! disposers d)) (fn () (let ((frag (create-fragment))) (for-each (fn (child) (dom-append frag (render-to-dom child env ns))) body-exprs) frag))))) + (dom-append container body-dom) + (dom-set-data container "sx-disposers" disposers) + (dict-set! *memo-cache* cyst-key container) + container)))) + :else (render-to-dom (trampoline (eval-expr expr env)) env ns)))) + +(define + render-lambda-dom + :effects (render) + (fn + ((f :as lambda) (args :as list) (env :as dict) (ns :as string)) + (let + ((local (env-merge (lambda-closure f) env))) + (for-each-indexed + (fn (i p) (env-bind! local p (nth args i))) + (lambda-params f)) + (render-to-dom (lambda-body f) local ns)))) + +(define + render-dom-island + :effects (render mutation) + (fn + ((island :as island) (args :as list) (env :as dict) (ns :as string)) + (let + ((kwargs (dict)) (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) + (dict-set! kwargs (keyword-name arg) val) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((local (env-merge (component-closure island) env)) + (island-name (component-name island))) + (for-each + (fn + (p) + (env-bind! + local + p + (if (dict-has? kwargs p) (dict-get kwargs p) nil))) + (component-params island)) + (when + (component-has-children? island) + (let + ((child-frag (create-fragment))) + (for-each + (fn (c) (dom-append child-frag (render-to-dom c env ns))) + children) + (env-bind! local "children" child-frag))) (let - ((input-type (lower (or (dom-get-attr el "type") ""))) - (is-checkbox - (or (= input-type "checkbox") (= input-type "radio")))) + ((container (dom-create-element "span" nil)) (disposers (list))) + (begin + (dom-set-attr container "data-sx-island" island-name) + (when + (not (empty-dict? kwargs)) + (dom-set-attr container "data-sx-state" (sx-serialize kwargs)))) + (mark-processed! container "island-hydrated") + (let + ((body-dom (with-island-scope (fn (disposable) (append! disposers disposable)) (fn () (render-to-dom (component-body island) local ns))))) + (dom-append container body-dom) + (dom-set-data container "sx-disposers" disposers) + container)))))) + +(define + render-dom-lake + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((lake-id nil) (lake-tag "div") (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((kname (keyword-name arg)) + (kval + (trampoline + (eval-expr (nth args (inc (get state "i"))) env)))) + (cond + (= kname "id") + (set! lake-id kval) + (= kname "tag") + (set! lake-tag kval)) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((el (dom-create-element lake-tag nil))) + (dom-set-attr el "data-sx-lake" (or lake-id "")) + (for-each + (fn (c) (dom-append el (render-to-dom c env ns))) + children) + el)))) + +(define + render-dom-marsh + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((marsh-id nil) + (marsh-tag "div") + (marsh-transform nil) + (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((kname (keyword-name arg)) + (kval + (trampoline + (eval-expr (nth args (inc (get state "i"))) env)))) + (cond + (= kname "id") + (set! marsh-id kval) + (= kname "tag") + (set! marsh-tag kval) + (= kname "transform") + (set! marsh-transform kval)) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((el (dom-create-element marsh-tag nil))) + (dom-set-attr el "data-sx-marsh" (or marsh-id "")) + (when + marsh-transform + (dom-set-data el "sx-marsh-transform" marsh-transform)) + (dom-set-data el "sx-marsh-env" env) + (for-each + (fn (c) (dom-append el (render-to-dom c env ns))) + children) + el)))) + +(define + reactive-text + :effects (render mutation) + (fn + (sig) + (let + ((node (create-text-node (str (deref sig))))) + (effect (fn () (dom-set-text-content node (str (deref sig))))) + node))) + +(define + reactive-attr + :effects (render mutation) + (fn + (el (attr-name :as string) (compute-fn :as lambda)) + (let + ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) + (updated + (if (empty? existing) attr-name (str existing "," attr-name)))) + (dom-set-attr el "data-sx-reactive-attrs" updated)) + (effect + (fn + () + (let + ((raw (compute-fn))) + (let + ((val (if (signal? raw) (deref raw) raw))) + (cond + (or (nil? val) (= val false)) + (dom-remove-attr el attr-name) + (= val true) + (dom-set-attr el attr-name "") + :else (dom-set-attr el attr-name (str val))))))))) + +(define + reactive-spread + :effects (render mutation) + (fn + (el (render-fn :as lambda)) + (let + ((prev-classes (list)) (prev-extra-keys (list))) + (let + ((existing (or (dom-get-attr el "data-sx-reactive-attrs") ""))) + (dom-set-attr + el + "data-sx-reactive-attrs" + (if (empty? existing) "_spread" (str existing ",_spread")))) + (effect + (fn + () + (when + (not (empty? prev-classes)) + (let + ((current (or (dom-get-attr el "class") "")) + (tokens + (filter (fn (c) (not (= c ""))) (split current " "))) + (kept + (filter + (fn (c) (not (some (fn (pc) (= pc c)) prev-classes))) + tokens))) + (if + (empty? kept) + (dom-remove-attr el "class") + (dom-set-attr el "class" (join " " kept))))) + (for-each (fn (k) (dom-remove-attr el k)) prev-extra-keys) + (let + ((result (render-fn))) + (if + (spread? result) + (let + ((attrs (spread-attrs result)) + (cls-str (or (dict-get attrs "class") "")) + (new-classes + (filter (fn (c) (not (= c ""))) (split cls-str " "))) + (extra-keys + (filter (fn (k) (not (= k "class"))) (keys attrs)))) + (set! prev-classes new-classes) + (set! prev-extra-keys extra-keys) + (when + (not (empty? new-classes)) + (let + ((current (or (dom-get-attr el "class") ""))) + (dom-set-attr + el + "class" + (if + (and current (not (= current ""))) + (str current " " cls-str) + cls-str)))) + (for-each + (fn (k) (dom-set-attr el k (str (dict-get attrs k)))) + extra-keys) + (run-post-render-hooks)) + (do (set! prev-classes (list)) (set! prev-extra-keys (list)))))))))) + +(define + reactive-fragment + :effects (render mutation) + (fn + ((test-fn :as lambda) + (render-fn :as lambda) + (env :as dict) + (ns :as string)) + (let + ((marker (create-comment "island-fragment")) (current-nodes (list))) + (effect + (fn + () + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! current-nodes (list)) + (when + (test-fn) + (let + ((frag (render-fn))) + (set! current-nodes (dom-child-nodes frag)) + (dom-insert-after marker frag))))) + marker))) + +(define + render-list-item + :effects (render) + (fn + ((map-fn :as lambda) item (env :as dict) (ns :as string)) + (if + (lambda? map-fn) + (render-lambda-dom map-fn (list item) env ns) + (render-to-dom (apply map-fn (list item)) env ns)))) + +(define + extract-key + :effects (render) + (fn + (node (index :as number)) + (let + ((k (dom-get-attr node "key"))) + (if + k + (do (dom-remove-attr node "key") k) + (let + ((dk (dom-get-data node "key"))) + (if dk (str dk) (str "__idx_" index))))))) + +(define + reactive-list + :effects (render mutation) + (fn + ((map-fn :as lambda) + (items-sig :as signal) + (env :as dict) + (ns :as string)) + (let + ((container (create-fragment)) + (marker (create-comment "island-list")) + (key-map (dict)) + (key-order (list))) + (dom-append container marker) + (effect + (fn + () + (let + ((items (deref items-sig))) + (if + (dom-parent marker) + (let + ((new-map (dict)) (new-keys (list)) (has-keys false)) + (for-each-indexed + (fn + (idx item) + (let + ((rendered (render-list-item map-fn item env ns)) + (key (extract-key rendered idx))) + (when + (and + (not has-keys) + (not (starts-with? key "__idx_"))) + (set! has-keys true)) + (if + (dict-has? key-map key) + (dict-set! new-map key (dict-get key-map key)) + (dict-set! new-map key rendered)) + (append! new-keys key))) + items) + (if + (not has-keys) + (do + (dom-remove-children-after marker) + (let + ((frag (create-fragment))) + (for-each + (fn (k) (dom-append frag (dict-get new-map k))) + new-keys) + (dom-insert-after marker frag))) + (do + (for-each + (fn + (old-key) + (when + (not (dict-has? new-map old-key)) + (dom-remove (dict-get key-map old-key)))) + key-order) + (let + ((cursor marker)) + (for-each + (fn + (k) + (let + ((node (dict-get new-map k)) + (next (dom-next-sibling cursor))) + (when + (not (identical? node next)) + (dom-insert-after cursor node)) + (set! cursor node))) + new-keys)))) + (set! key-map new-map) + (set! key-order new-keys)) + (for-each-indexed + (fn + (idx item) + (let + ((rendered (render-list-item map-fn item env ns)) + (key (extract-key rendered idx))) + (dict-set! key-map key rendered) + (append! key-order key) + (dom-append container rendered))) + items))))) + container))) + +(define + bind-input + :effects (render mutation) + (fn + (el (sig :as signal)) + (let + ((input-type (lower (or (dom-get-attr el "type") ""))) + (is-checkbox (or (= input-type "checkbox") (= input-type "radio")))) + (if + is-checkbox + (dom-set-prop el "checked" (deref sig)) + (dom-set-prop el "value" (str (deref sig)))) + (effect + (fn + () (if is-checkbox (dom-set-prop el "checked" (deref sig)) - (dom-set-prop el "value" (str (deref sig)))) - (effect - (fn - () - (if - is-checkbox - (dom-set-prop el "checked" (deref sig)) - (let - ((v (str (deref sig)))) - (when - (!= (dom-get-prop el "value") v) - (dom-set-prop el "value" v)))))) - (dom-on - el - (if is-checkbox "change" "input") - (fn - (e) - (if - is-checkbox - (reset! sig (dom-get-prop el "checked")) - (reset! sig (dom-get-prop el "value")))))))) - (define *use-cek-reactive* true) - (define enable-cek-reactive! (fn () (set! *use-cek-reactive* true))) - (define - cek-reactive-text - :effects (render mutation) - (fn - (expr env) - (let - ((node (create-text-node "")) - (update-fn (fn (val) (dom-set-text-content node (str val))))) - (let - ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) - (dom-set-text-content node (str initial)) - node)))) - (define - cek-reactive-attr - :effects (render mutation) - (fn - (el attr-name expr env) - (let - ((update-fn (fn (val) (cond (or (nil? val) (= val false)) (dom-remove-attr el attr-name) (= val true) (dom-set-attr el attr-name "") :else (dom-set-attr el attr-name (str val)))))) - (let - ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) - (updated - (if (empty? existing) attr-name (str existing "," attr-name)))) - (dom-set-attr el "data-sx-reactive-attrs" updated)) - (let - ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) - (cek-call update-fn (list initial)))))) - (define - render-dom-portal - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let - ((selector (trampoline (eval-expr (first args) env))) - (target (or (dom-query selector) (dom-ensure-element selector)))) - (if - (not target) - (create-comment (str "portal: " selector " (not found)")) (let - ((marker (create-comment (str "portal: " selector))) - (frag (create-fragment))) - (for-each - (fn (child) (dom-append frag (render-to-dom child env ns))) - (rest args)) - (let - ((portal-nodes (dom-child-nodes frag))) - (dom-append target frag) - (register-in-scope - (fn () (for-each (fn (n) (dom-remove n)) portal-nodes)))) - marker))))) - (define - render-dom-error-boundary - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) + ((v (str (deref sig)))) + (when + (!= (dom-get-prop el "value") v) + (dom-set-prop el "value" v)))))) + (dom-on + el + (if is-checkbox "change" "input") + (fn + (e) + (if + is-checkbox + (reset! sig (dom-get-prop el "checked")) + (reset! sig (dom-get-prop el "value")))))))) + +(define *use-cek-reactive* true) + +(define enable-cek-reactive! (fn () (set! *use-cek-reactive* true))) + +(define + cek-reactive-text + :effects (render mutation) + (fn + (expr env) + (let + ((node (create-text-node "")) + (update-fn (fn (val) (dom-set-text-content node (str val))))) + (let + ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) + (dom-set-text-content node (str initial)) + node)))) + +(define + cek-reactive-attr + :effects (render mutation) + (fn + (el attr-name expr env) + (let + ((update-fn (fn (val) (cond (or (nil? val) (= val false)) (dom-remove-attr el attr-name) (= val true) (dom-set-attr el attr-name "") :else (dom-set-attr el attr-name (str val)))))) + (let + ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) + (updated + (if (empty? existing) attr-name (str existing "," attr-name)))) + (dom-set-attr el "data-sx-reactive-attrs" updated)) + (let + ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) + (cek-call update-fn (list initial)))))) + +(define + render-dom-portal + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((selector (trampoline (eval-expr (first args) env))) + (target (or (dom-query selector) (dom-ensure-element selector)))) + (if + (not target) + (create-comment (str "portal: " selector " (not found)")) (let - ((fallback-expr (if (> (len args) 1) (first args) nil)) - (body-exprs (if (> (len args) 1) (rest args) args)) - (container (dom-create-element "div" nil)) - (retry-version (signal 0))) - (dom-set-attr container "data-sx-boundary" "true") - (effect + ((marker (create-comment (str "portal: " selector))) + (frag (create-fragment))) + (for-each + (fn (child) (dom-append frag (render-to-dom child env ns))) + (rest args)) + (let + ((portal-nodes (dom-child-nodes frag))) + (dom-append target frag) + (register-in-scope + (fn () (for-each (fn (n) (dom-remove n)) portal-nodes)))) + marker))))) + +(define + render-dom-error-boundary + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((fallback-expr (if (> (len args) 1) (first args) nil)) + (body-exprs (if (> (len args) 1) (rest args) args)) + (container (dom-create-element "div" nil)) + (retry-version (signal 0))) + (dom-set-attr container "data-sx-boundary" "true") + (effect + (fn + () + (deref retry-version) + (dom-set-prop container "innerHTML" "") + (scope-push! "sx-island-scope" nil) + (try-catch (fn () - (deref retry-version) - (dom-set-prop container "innerHTML" "") - (scope-push! "sx-island-scope" nil) - (try-catch - (fn - () - (let - ((frag (create-fragment))) - (for-each - (fn - (child) - (dom-append frag (render-to-dom child env ns))) - body-exprs) - (dom-append container frag)) - (scope-pop! "sx-island-scope")) - (fn - (err) - (scope-pop! "sx-island-scope") - (let - ((fallback-fn (trampoline (eval-expr fallback-expr env))) - (retry-fn - (fn () (swap! retry-version (fn (n) (+ n 1)))))) - (let - ((fallback-dom (if (nil? fallback-fn) (let ((el (dom-create-element "div" nil))) (dom-set-attr el "class" "sx-render-error") (dom-set-attr el "style" "color:red;font-size:0.875rem;padding:0.5rem;border:1px solid red;border-radius:0.25rem;margin:0.5rem 0;") (dom-set-text-content el (str "Render error: " err)) el) (if (lambda? fallback-fn) (render-lambda-dom fallback-fn (list err retry-fn) env ns) (render-to-dom (apply fallback-fn (list err retry-fn)) env ns))))) - (dom-append container fallback-dom))))))) - container))))) + (let + ((frag (create-fragment))) + (for-each + (fn + (child) + (dom-append frag (render-to-dom child env ns))) + body-exprs) + (dom-append container frag)) + (scope-pop! "sx-island-scope")) + (fn + (err) + (scope-pop! "sx-island-scope") + (let + ((fallback-fn (trampoline (eval-expr fallback-expr env))) + (retry-fn + (fn () (swap! retry-version (fn (n) (+ n 1)))))) + (let + ((fallback-dom (if (nil? fallback-fn) (let ((el (dom-create-element "div" nil))) (dom-set-attr el "class" "sx-render-error") (dom-set-attr el "style" "color:red;font-size:0.875rem;padding:0.5rem;border:1px solid red;border-radius:0.25rem;margin:0.5rem 0;") (dom-set-text-content el (str "Render error: " err)) el) (if (lambda? fallback-fn) (render-lambda-dom fallback-fn (list err retry-fn) env ns) (render-to-dom (apply fallback-fn (list err retry-fn)) env ns))))) + (dom-append container fallback-dom))))))) + container))) + + +)) ;; Re-export to global env (import (web adapter-dom)) diff --git a/shared/static/wasm/sx/adapter-dom.sxbc b/shared/static/wasm/sx/adapter-dom.sxbc index 581afe44..b18bfba0 100644 --- a/shared/static/wasm/sx/adapter-dom.sxbc +++ b/shared/static/wasm/sx/adapter-dom.sxbc @@ -1,3 +1,3 @@ -(sxbc 1 "8bf33a247b2d6140" +(sxbc 1 "f0dccdc6c6028305" (code - :constants ({:library (sx dom) :op "import"} {:library (sx render) :op "import"} "SVG_NS" "http://www.w3.org/2000/svg" "MATH_NS" "http://www.w3.org/1998/Math/MathML" "island-scope?" {:upvalue-count 0 :arity 0 :constants ("not" "nil?" "scope-peek" "sx-island-scope") :bytecode (1 3 0 52 2 0 1 52 1 0 1 52 0 0 1 50)} "*memo-cache*" "dict" "*cyst-counter*" 0 "next-cyst-id" {:upvalue-count 0 :arity 0 :constants ("+" "*cyst-counter*" 1 "str" "sx-cyst-") :bytecode (20 1 0 1 2 0 52 0 0 2 21 1 0 5 1 4 0 20 1 0 52 3 0 2 50)} "contains-deref?" {:upvalue-count 0 :arity 1 :constants ("not" "list?" "empty?" "=" "type-of" "first" "symbol" "symbol-name" "deref" "some" "contains-deref?") :bytecode (16 0 52 1 0 1 52 0 0 1 33 4 0 4 32 68 0 16 0 52 2 0 1 33 4 0 4 32 55 0 16 0 52 5 0 1 52 4 0 1 1 6 0 52 3 0 2 6 33 18 0 5 16 0 52 5 0 1 52 7 0 1 1 8 0 52 3 0 2 33 4 0 3 32 9 0 20 10 0 16 0 52 9 0 2 50)} "dom-on" {:upvalue-count 0 :arity 3 :constants ("dom-listen" "lambda?" "=" 0 "len" "lambda-params" {:upvalue-count 1 :arity 1 :constants ("trampoline" "call-lambda" "list" "run-post-render-hooks") :bytecode (18 0 52 2 0 0 52 1 0 2 52 0 0 1 5 20 3 0 49 0 50)} {:upvalue-count 1 :arity 1 :constants ("trampoline" "call-lambda" "list" "run-post-render-hooks") :bytecode (18 0 16 0 52 2 0 1 52 1 0 2 52 0 0 1 5 20 3 0 49 0 50)}) :bytecode (20 0 0 16 0 16 1 16 2 52 1 0 1 33 36 0 1 3 0 16 2 52 5 0 1 52 4 0 1 52 2 0 2 33 8 0 51 6 0 1 2 32 5 0 51 7 0 1 2 32 2 0 16 2 49 3 50)} "render-to-dom" {:upvalue-count 0 :arity 3 :constants ("set-render-active!" "type-of" "nil" "=" "create-fragment" "boolean" "raw-html" "dom-parse-html" "raw-html-content" "string" "*hydrating*" "hydrate-next-text!" "create-text-node" "number" "str" "symbol" "render-to-dom" "trampoline" "eval-expr" "keyword" "keyword-name" "dom-node" "spread" "not" "island-scope?" "scope-emit!" "element-attrs" "spread-attrs" "dict" "has-key?" "__host_handle" "list" "empty?" "render-dom-list" "signal?" "reactive-text" "deref") :bytecode (3 52 0 0 1 5 16 0 52 1 0 1 6 1 2 0 52 3 0 2 33 9 0 5 20 4 0 49 0 32 158 1 6 1 5 0 52 3 0 2 33 9 0 5 20 4 0 49 0 32 138 1 6 1 6 0 52 3 0 2 33 15 0 5 20 7 0 16 0 52 8 0 1 49 1 32 112 1 6 1 9 0 52 3 0 2 33 37 0 5 20 10 0 33 20 0 20 11 0 48 0 6 34 8 0 5 20 12 0 16 0 49 1 32 7 0 20 12 0 16 0 49 1 32 64 1 6 1 13 0 52 3 0 2 33 45 0 5 20 10 0 33 24 0 20 11 0 48 0 6 34 12 0 5 20 12 0 16 0 52 14 0 1 49 1 32 11 0 20 12 0 16 0 52 14 0 1 49 1 32 8 1 6 1 15 0 52 3 0 2 33 25 0 5 20 16 0 16 0 16 1 52 18 0 2 52 17 0 1 16 1 16 2 49 3 32 228 0 6 1 19 0 52 3 0 2 33 15 0 5 20 12 0 16 0 52 20 0 1 49 1 32 202 0 6 1 21 0 52 3 0 2 33 6 0 5 16 0 32 185 0 6 1 22 0 52 3 0 2 33 36 0 5 20 24 0 48 0 52 23 0 1 33 16 0 1 26 0 16 0 52 27 0 1 52 25 0 2 32 1 0 2 5 16 0 32 138 0 6 1 28 0 52 3 0 2 33 26 0 5 16 0 1 30 0 52 29 0 2 33 5 0 16 0 32 5 0 20 4 0 49 0 32 101 0 6 1 31 0 52 3 0 2 33 32 0 5 16 0 52 32 0 1 33 8 0 20 4 0 49 0 32 11 0 20 33 0 16 0 16 1 16 2 49 3 32 58 0 5 20 34 0 16 0 48 1 33 36 0 20 24 0 48 0 33 10 0 20 35 0 16 0 49 1 32 15 0 20 12 0 16 0 52 36 0 1 52 14 0 1 49 1 32 11 0 20 12 0 16 0 52 14 0 1 49 1 50)} "render-dom-list" {:upvalue-count 0 :arity 3 :constants ("first" "=" "type-of" "symbol" "symbol-name" "rest" "raw!" "render-dom-raw" "<>" "render-dom-fragment" "lake" "render-dom-lake" "marsh" "render-dom-marsh" "starts-with?" "html:" "render-dom-element" "slice" 5 "render-dom-form?" "contains?" "HTML_TAGS" ">" "len" 0 "keyword" "dispatch-render-form" "env-has?" "macro?" "env-get" "render-to-dom" "expand-macro" "~" "island?" "scope-peek" "sx-render-markers" "dom-create-element" "span" "dict" "reduce" {:upvalue-count 3 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "trampoline" "eval-expr" "nth" "dict-set!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 145 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 79 0 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 13 0 2 18 1 52 12 0 2 52 11 0 1 17 4 18 2 16 3 16 4 52 14 0 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 22 0 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "i" "skip" "dom-set-attr" "data-sx-island" "component-name" "not" "empty-dict?" "data-sx-state" "sx-serialize" "render-dom-island" "component?" "render-dom-component" "render-dom-unknown-component" "index-of" "-" "deref" "island-scope?" "trampoline" "eval-expr" "signal?" "reactive-text" "create-text-node" "str" "contains-deref?" "computed" {:upvalue-count 2 :arity 0 :constants ("trampoline" "eval-expr") :bytecode (18 0 18 1 52 1 0 2 52 0 0 1 50)} "lambda?" "list" "create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("render-to-dom" "not" "spread?" "dom-append") :bytecode (20 0 0 16 0 18 0 18 1 48 3 17 1 16 1 52 2 0 1 52 1 0 1 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)}) :bytecode (16 0 52 0 0 1 17 3 16 3 52 2 0 1 1 3 0 52 1 0 2 33 52 3 16 3 52 4 0 1 17 4 16 0 52 5 0 1 17 5 16 4 1 6 0 52 1 0 2 33 12 0 20 7 0 16 5 16 1 49 2 32 9 3 16 4 1 8 0 52 1 0 2 33 14 0 20 9 0 16 5 16 1 16 2 49 3 32 239 2 16 4 1 10 0 52 1 0 2 33 14 0 20 11 0 16 5 16 1 16 2 49 3 32 213 2 16 4 1 12 0 52 1 0 2 33 14 0 20 13 0 16 5 16 1 16 2 49 3 32 187 2 16 4 1 15 0 52 14 0 2 33 23 0 20 16 0 16 4 1 18 0 52 17 0 2 16 5 16 1 16 2 49 4 32 152 2 20 19 0 16 4 48 1 33 91 0 20 21 0 16 4 52 20 0 2 6 33 43 0 5 16 5 52 23 0 1 1 24 0 52 22 0 2 6 33 18 0 5 16 5 52 0 0 1 52 2 0 1 1 25 0 52 1 0 2 6 34 3 0 5 16 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 13 0 20 26 0 16 4 16 0 16 1 16 2 49 4 32 51 2 16 1 16 4 52 27 0 2 6 33 13 0 5 16 1 16 4 52 29 0 2 52 28 0 1 33 28 0 20 30 0 16 1 16 4 52 29 0 2 16 5 16 1 52 31 0 3 16 1 16 2 49 3 32 251 1 20 21 0 16 4 52 20 0 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 223 1 16 4 1 32 0 52 14 0 2 6 33 26 0 5 16 1 16 4 52 27 0 2 6 33 13 0 5 16 1 16 4 52 29 0 2 52 33 0 1 33 145 0 1 35 0 52 34 0 1 33 113 0 16 1 16 4 52 29 0 2 17 6 20 36 0 1 37 0 2 48 2 17 7 52 38 0 0 17 8 51 40 0 1 5 1 1 1 8 1 41 0 1 24 0 1 42 0 4 52 38 0 4 16 5 52 39 0 3 5 20 43 0 16 7 1 44 0 16 6 52 45 0 1 48 3 5 16 8 52 47 0 1 52 46 0 1 33 19 0 20 43 0 16 7 1 48 0 16 8 52 49 0 1 48 3 32 1 0 2 5 16 7 32 19 0 20 50 0 16 1 16 4 52 29 0 2 16 5 16 1 16 2 49 4 32 36 1 16 4 1 32 0 52 14 0 2 33 45 0 16 1 16 4 52 29 0 2 17 6 16 6 52 51 0 1 33 16 0 20 52 0 16 6 16 5 16 1 16 2 49 4 32 7 0 20 53 0 16 4 49 1 32 235 0 16 4 1 55 0 52 54 0 2 1 24 0 52 22 0 2 6 33 36 0 5 16 5 52 23 0 1 1 24 0 52 22 0 2 6 33 18 0 5 16 5 52 0 0 1 52 2 0 1 1 25 0 52 1 0 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 160 0 16 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 139 0 16 4 1 56 0 52 1 0 2 6 33 6 0 5 20 57 0 48 0 33 56 0 16 5 52 0 0 1 16 1 52 59 0 2 52 58 0 1 17 6 20 60 0 16 6 48 1 33 10 0 20 61 0 16 6 49 1 32 15 0 20 62 0 16 6 52 56 0 1 52 63 0 1 49 1 32 61 0 20 57 0 48 0 6 33 8 0 5 20 64 0 16 0 48 1 33 20 0 20 61 0 20 65 0 51 66 0 1 0 1 1 48 1 49 1 32 21 0 20 30 0 16 0 16 1 52 59 0 2 52 58 0 1 16 1 16 2 49 3 32 76 0 16 3 52 67 0 1 6 34 14 0 5 16 3 52 2 0 1 1 68 0 52 1 0 2 33 24 0 20 30 0 16 0 16 1 52 59 0 2 52 58 0 1 16 1 16 2 49 3 32 25 0 20 69 0 48 0 17 4 51 71 0 1 1 1 2 1 4 16 0 52 70 0 2 5 16 4 50)} "render-dom-element" {:upvalue-count 0 :arity 4 :constants ("=" "svg" "SVG_NS" "math" "MATH_NS" "*hydrating*" "hydrate-next-element!" "hydrate-push!" "dom-create-element" "scope-push!" "element-attrs" "reduce" {:upvalue-count 5 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "nth" "starts-with?" "on-" "trampoline" "eval-expr" "callable?" "dom-on" "slice" 3 "bind" "signal?" "bind-input" "ref" "dict-set!" "current" "key" "dom-set-attr" "str" "island-scope?" "reactive-attr" {:upvalue-count 2 :arity 0 :constants ("trampoline" "eval-expr") :bytecode (18 0 18 1 52 1 0 2 52 0 0 1 50)} "nil?" "contains?" "BOOLEAN_ATTRS" "" "not" "VOID_ELEMENTS" "render-to-dom" "spread?" "reactive-spread" {:upvalue-count 3 :arity 0 :constants ("render-to-dom") :bytecode (20 0 0 18 0 18 1 18 2 49 3 50)} "*hydrating*" "dom-append") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 61 2 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 143 1 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 11 0 2 17 4 16 3 1 13 0 52 12 0 2 33 49 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 20 16 0 16 5 48 1 33 21 0 20 17 0 18 2 16 3 1 19 0 52 18 0 2 16 5 48 3 32 1 0 2 32 23 1 16 3 1 20 0 52 5 0 2 33 40 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 20 21 0 16 5 48 1 33 12 0 20 22 0 18 2 16 5 48 2 32 1 0 2 32 227 0 16 3 1 23 0 52 5 0 2 33 28 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 16 5 1 25 0 18 2 52 24 0 3 32 187 0 16 3 1 26 0 52 5 0 2 33 33 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 20 27 0 18 2 1 26 0 16 5 52 28 0 1 48 3 32 142 0 20 29 0 48 0 33 19 0 20 30 0 18 2 16 3 51 31 0 1 4 0 1 48 3 32 115 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 16 5 52 32 0 1 6 34 8 0 5 16 5 4 52 5 0 2 33 4 0 2 32 76 0 20 34 0 16 3 52 33 0 2 33 24 0 16 5 33 15 0 20 27 0 18 2 16 3 1 35 0 48 3 32 1 0 2 32 40 0 16 5 3 52 5 0 2 33 15 0 20 27 0 18 2 16 3 1 35 0 48 3 32 15 0 20 27 0 18 2 16 3 16 5 52 28 0 1 48 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 130 0 20 37 0 18 3 52 33 0 2 52 36 0 1 33 90 0 20 38 0 16 1 18 1 18 4 48 3 17 3 16 3 52 39 0 1 6 33 6 0 5 20 29 0 48 0 33 19 0 20 40 0 18 2 51 41 0 1 1 0 1 0 4 48 2 32 36 0 16 3 52 39 0 1 33 4 0 2 32 23 0 20 42 0 52 36 0 1 33 12 0 20 43 0 18 2 16 3 48 2 32 1 0 2 32 1 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "dict" "i" 0 "skip" "for-each" {:upvalue-count 1 :arity 1 :constants ("for-each" {:upvalue-count 2 :arity 1 :constants ("dict-get" "=" "class" "dom-get-attr" "dom-set-attr" "not" "" "str" " " "style" ";") :bytecode (18 0 16 0 52 0 0 2 17 1 16 0 1 2 0 52 1 0 2 33 64 0 20 3 0 18 1 1 2 0 48 2 17 2 20 4 0 18 1 1 2 0 16 2 6 33 14 0 5 16 2 1 6 0 52 1 0 2 52 5 0 1 33 14 0 16 2 1 8 0 16 1 52 7 0 3 32 2 0 16 1 49 3 32 91 0 16 0 1 9 0 52 1 0 2 33 64 0 20 3 0 18 1 1 9 0 48 2 17 2 20 4 0 18 1 1 9 0 16 2 6 33 14 0 5 16 2 1 6 0 52 1 0 2 52 5 0 1 33 14 0 16 2 1 10 0 16 1 52 7 0 3 32 2 0 16 1 49 3 32 15 0 20 4 0 18 1 16 0 16 1 52 7 0 1 49 3 50)} "keys") :bytecode (51 1 0 1 0 0 0 16 0 52 2 0 1 52 0 0 2 50)} "scope-emitted" "scope-pop!" "hydrate-pop!") :bytecode (16 0 1 1 0 52 0 0 2 33 6 0 20 2 0 32 20 0 16 0 1 3 0 52 0 0 2 33 6 0 20 4 0 32 2 0 16 3 17 4 20 5 0 33 43 0 20 6 0 48 0 17 5 16 5 33 10 0 20 7 0 16 5 48 1 32 1 0 2 5 16 5 6 34 10 0 5 20 8 0 16 0 16 4 48 2 32 9 0 20 8 0 16 0 16 4 48 2 17 5 1 10 0 2 52 9 0 2 5 51 12 0 1 1 1 2 1 5 1 0 1 4 1 14 0 1 15 0 1 16 0 4 52 13 0 4 16 1 52 11 0 3 5 51 18 0 1 5 1 10 0 52 19 0 1 52 17 0 2 5 1 10 0 52 20 0 1 5 20 5 0 33 8 0 20 21 0 48 0 32 1 0 2 5 16 5 50)} "render-dom-component" {:upvalue-count 0 :arity 4 :constants ("dict" "list" "reduce" {:upvalue-count 4 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "trampoline" "eval-expr" "nth" "dict-set!" "keyword-name" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 150 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 75 0 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 12 0 2 18 1 52 11 0 2 52 10 0 1 17 3 18 2 16 1 52 14 0 1 16 3 52 13 0 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 3 16 1 52 15 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "i" 0 "skip" "env-merge" "component-closure" "for-each" {:upvalue-count 2 :arity 1 :constants ("env-bind!" "dict-has?" "dict-get") :bytecode (18 0 16 0 18 1 16 0 52 1 0 2 33 11 0 18 1 16 0 52 2 0 2 32 1 0 2 52 0 0 3 50)} "component-params" "component-has-children?" "create-fragment" {:upvalue-count 3 :arity 1 :constants ("render-to-dom" "not" "spread?" "dom-append") :bytecode (20 0 0 16 0 18 0 18 1 48 3 17 1 16 1 52 2 0 1 52 1 0 1 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)} "env-bind!" "children" "render-to-dom" "component-body") :bytecode (52 0 0 0 17 4 52 1 0 0 17 5 51 3 0 1 1 1 2 1 4 1 5 1 4 0 1 5 0 1 6 0 4 52 0 0 4 16 1 52 2 0 3 5 16 0 52 8 0 1 16 2 52 7 0 2 17 6 51 10 0 1 6 1 4 16 0 52 11 0 1 52 9 0 2 5 16 0 52 12 0 1 33 37 0 20 13 0 48 0 17 7 51 14 0 1 2 1 3 1 7 16 5 52 9 0 2 5 16 6 1 16 0 16 7 52 15 0 3 32 1 0 2 5 20 17 0 16 0 52 18 0 1 16 6 16 3 49 3 50)} "render-dom-fragment" {:upvalue-count 0 :arity 3 :constants ("create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("render-to-dom" "not" "spread?" "dom-append") :bytecode (20 0 0 16 0 18 0 18 1 48 3 17 1 16 1 52 2 0 1 52 1 0 1 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)}) :bytecode (20 0 0 48 0 17 3 51 2 0 1 1 1 2 1 3 16 0 52 1 0 2 5 16 3 50)} "render-dom-raw" {:upvalue-count 0 :arity 2 :constants ("create-fragment" "for-each" {:upvalue-count 2 :arity 1 :constants ("trampoline" "eval-expr" "=" "type-of" "string" "dom-append" "dom-parse-html" "dom-node" "dom-clone" "not" "nil?" "create-text-node" "str") :bytecode (16 0 18 0 52 1 0 2 52 0 0 1 17 1 16 1 52 3 0 1 1 4 0 52 2 0 2 33 17 0 20 5 0 18 1 20 6 0 16 1 48 1 49 2 32 68 0 16 1 52 3 0 1 1 7 0 52 2 0 2 33 17 0 20 5 0 18 1 20 8 0 16 1 48 1 49 2 32 35 0 16 1 52 10 0 1 52 9 0 1 33 21 0 20 5 0 18 1 20 11 0 16 1 52 12 0 1 48 1 49 2 32 1 0 2 50)}) :bytecode (20 0 0 48 0 17 2 51 2 0 1 1 1 2 16 0 52 1 0 2 5 16 2 50)} "render-dom-unknown-component" {:upvalue-count 0 :arity 1 :constants ("error" "str" "Unknown component: ") :bytecode (1 2 0 16 0 52 1 0 2 52 0 0 1 50)} "RENDER_DOM_FORMS" "list" "if" "when" "cond" "case" "let" "let*" "letrec" "begin" "do" "define" "defcomp" "defisland" "defmacro" "defstyle" "map" "map-indexed" "filter" "for-each" "portal" "error-boundary" "scope" "provide" "cyst" "render-dom-form?" {:upvalue-count 0 :arity 1 :constants ("contains?" "RENDER_DOM_FORMS") :bytecode (20 1 0 16 0 52 0 0 2 50)} "dispatch-render-form" {:upvalue-count 0 :arity 4 :constants ("=" "if" "island-scope?" "create-comment" "r-if" "list" "effect" {:upvalue-count 6 :arity 0 :constants ("trampoline" "eval-expr" "nth" 1 "render-to-dom" 2 ">" "len" 3 "create-fragment" "dom-parent" "for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "dom-is-fragment?" "dom-child-nodes" "list" "dom-insert-after") :bytecode (18 0 1 3 0 52 2 0 2 18 1 52 1 0 2 52 0 0 1 17 0 16 0 33 21 0 20 4 0 18 0 1 5 0 52 2 0 2 18 1 18 2 48 3 32 42 0 18 0 52 7 0 1 1 8 0 52 6 0 2 33 21 0 20 4 0 18 0 1 8 0 52 2 0 2 18 1 18 2 48 3 32 5 0 20 9 0 48 0 17 0 20 10 0 18 3 48 1 33 51 0 51 12 0 18 4 52 11 0 2 5 20 13 0 16 0 48 1 33 10 0 20 14 0 16 0 48 1 32 6 0 16 0 52 15 0 1 19 4 5 20 16 0 18 3 16 0 49 2 32 4 0 16 0 19 5 50)} "spread?" "create-fragment" "dom-append" "dom-is-fragment?" "dom-child-nodes" "trampoline" "eval-expr" "nth" 1 "render-to-dom" 2 ">" "len" 3 "when" "r-when" {:upvalue-count 6 :arity 0 :constants ("dom-parent" "for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "list" "trampoline" "eval-expr" "nth" 1 "create-fragment" {:upvalue-count 4 :arity 1 :constants ("dom-append" "render-to-dom" "nth") :bytecode (20 0 0 18 0 20 1 0 18 1 16 0 52 2 0 2 18 2 18 3 48 3 49 2 50)} "range" 2 "len" "dom-child-nodes" "dom-insert-after") :bytecode (20 0 0 18 0 48 1 33 101 0 51 2 0 18 1 52 1 0 2 5 52 3 0 0 19 1 5 18 2 1 7 0 52 6 0 2 18 3 52 5 0 2 52 4 0 1 33 58 0 20 8 0 48 0 17 0 51 9 0 1 0 0 2 0 3 0 4 1 11 0 18 2 52 12 0 1 52 10 0 2 52 1 0 2 5 20 13 0 16 0 48 1 19 1 5 20 14 0 18 0 16 0 49 2 32 1 0 2 32 76 0 18 2 1 7 0 52 6 0 2 18 3 52 5 0 2 52 4 0 1 33 53 0 20 8 0 48 0 17 0 51 9 0 1 0 0 2 0 3 0 4 1 11 0 18 2 52 12 0 1 52 10 0 2 52 1 0 2 5 20 13 0 16 0 48 1 19 1 5 16 0 19 5 32 1 0 2 50)} "not" "for-each" {:upvalue-count 4 :arity 1 :constants ("dom-append" "render-to-dom" "nth") :bytecode (20 0 0 18 0 20 1 0 18 1 16 0 52 2 0 2 18 2 18 3 48 3 49 2 50)} "range" "cond" "r-cond" {:upvalue-count 6 :arity 0 :constants ("eval-cond" "rest" "dom-parent" "for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "list" "render-to-dom" "dom-is-fragment?" "dom-child-nodes" "dom-insert-after") :bytecode (20 0 0 18 0 52 1 0 1 18 1 48 2 17 0 20 2 0 18 2 48 1 33 80 0 51 4 0 18 3 52 3 0 2 5 52 5 0 0 19 3 5 16 0 33 54 0 20 6 0 16 0 18 1 18 4 48 3 17 1 20 7 0 16 1 48 1 33 10 0 20 8 0 16 1 48 1 32 6 0 16 1 52 5 0 1 19 3 5 20 9 0 18 2 16 1 49 2 32 1 0 2 32 55 0 16 0 33 49 0 20 6 0 16 0 18 1 18 4 48 3 17 1 20 7 0 16 1 48 1 33 10 0 20 8 0 16 1 48 1 32 6 0 16 1 52 5 0 1 19 3 5 16 1 19 5 32 1 0 2 50)} "eval-cond" "rest" "case" "let" "let*" "process-bindings" {:upvalue-count 4 :arity 1 :constants ("render-to-dom" "nth" "not" "spread?" "dom-append") :bytecode (20 0 0 18 0 16 0 52 1 0 2 18 1 18 2 48 3 17 1 16 1 52 3 0 1 52 2 0 1 33 12 0 20 4 0 18 3 16 1 49 2 32 1 0 2 50)} "letrec" "slice" "env-extend" {:upvalue-count 1 :arity 1 :constants ("=" "type-of" "first" "symbol" "symbol-name" "str" "env-bind!") :bytecode (16 0 52 2 0 1 52 1 0 1 1 3 0 52 0 0 2 33 13 0 16 0 52 2 0 1 52 4 0 1 32 10 0 16 0 52 2 0 1 52 5 0 1 17 1 18 0 16 1 2 52 6 0 3 50)} {:upvalue-count 1 :arity 1 :constants ("=" "type-of" "first" "symbol" "symbol-name" "str" "env-set!" "trampoline" "eval-expr" "nth" 1) :bytecode (16 0 52 2 0 1 52 1 0 1 1 3 0 52 0 0 2 33 13 0 16 0 52 2 0 1 52 4 0 1 32 10 0 16 0 52 2 0 1 52 5 0 1 17 1 18 0 16 1 16 0 1 10 0 52 9 0 2 18 0 52 8 0 2 52 7 0 1 52 6 0 3 50)} {:upvalue-count 1 :arity 1 :constants ("trampoline" "eval-expr") :bytecode (16 0 18 0 52 1 0 2 52 0 0 1 50)} "init" "last" "begin" "do" "definition-form?" "map" "type-of" "first" "symbol" "symbol-name" "deref" "signal?" "reactive-list" {:upvalue-count 4 :arity 1 :constants ("lambda?" "render-lambda-dom" "list" "render-to-dom" "apply" "dom-append") :bytecode (18 0 52 0 0 1 33 20 0 20 1 0 18 0 16 0 52 2 0 1 18 1 18 2 48 4 32 21 0 20 3 0 18 0 16 0 52 2 0 1 52 4 0 2 18 1 18 2 48 3 17 1 20 5 0 18 3 16 1 49 2 50)} "map-indexed" "for-each-indexed" {:upvalue-count 4 :arity 2 :constants ("lambda?" "render-lambda-dom" "list" "render-to-dom" "apply" "dom-append") :bytecode (18 0 52 0 0 1 33 22 0 20 1 0 18 0 16 0 16 1 52 2 0 2 18 1 18 2 48 4 32 23 0 20 3 0 18 0 16 0 16 1 52 2 0 2 52 4 0 2 18 1 18 2 48 3 17 2 20 5 0 18 3 16 2 49 2 50)} "filter" "portal" "render-dom-portal" "error-boundary" "render-dom-error-boundary" "scope" ">=" "keyword" "keyword-name" "value" "scope-push!" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "scope-pop!" "provide" "cyst" "key" "str" "next-cyst-id" "get" "*memo-cache*" "host-get" "isConnected" "dom-create-element" "div" "dom-set-attr" "data-sx-cyst" "with-island-scope" {:upvalue-count 1 :arity 1 :constants ("append!") :bytecode (18 0 16 0 52 0 0 2 50)} {:upvalue-count 3 :arity 0 :constants ("create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)}) :bytecode (20 0 0 48 0 17 0 51 2 0 1 0 0 0 0 1 18 2 52 1 0 2 5 16 0 50)} "dom-set-data" "sx-disposers" "dict-set!") :bytecode (16 0 1 1 0 52 0 0 2 33 224 0 20 2 0 48 0 33 124 0 20 3 0 1 4 0 48 1 17 4 52 5 0 0 17 5 2 17 6 20 6 0 51 7 0 1 1 1 2 1 3 1 4 1 5 1 6 48 1 5 16 6 52 8 0 1 33 5 0 16 6 32 67 0 20 9 0 48 0 17 7 20 10 0 16 7 16 4 48 2 5 16 6 33 41 0 20 11 0 16 6 48 1 33 10 0 20 12 0 16 6 48 1 32 6 0 16 6 52 5 0 1 17 5 5 20 10 0 16 7 16 6 48 2 32 1 0 2 5 16 7 32 89 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 4 33 21 0 20 17 0 16 1 1 18 0 52 15 0 2 16 2 16 3 49 3 32 42 0 16 1 52 20 0 1 1 21 0 52 19 0 2 33 21 0 20 17 0 16 1 1 21 0 52 15 0 2 16 2 16 3 49 3 32 5 0 20 9 0 49 0 32 175 7 16 0 1 22 0 52 0 0 2 33 178 0 20 2 0 48 0 33 95 0 20 3 0 1 23 0 48 1 17 4 52 5 0 0 17 5 2 17 6 20 6 0 51 24 0 1 4 1 5 1 1 1 2 1 3 1 6 48 1 5 16 6 52 8 0 1 33 5 0 16 6 32 38 0 20 9 0 48 0 17 7 20 10 0 16 7 16 4 48 2 5 16 6 33 12 0 20 10 0 16 7 16 6 48 2 32 1 0 2 5 16 7 32 72 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 52 25 0 1 33 8 0 20 9 0 49 0 32 38 0 20 9 0 48 0 17 4 51 27 0 1 4 1 1 1 2 1 3 1 18 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 4 32 241 6 16 0 1 29 0 52 0 0 2 33 145 0 20 2 0 48 0 33 95 0 20 3 0 1 30 0 48 1 17 4 52 5 0 0 17 5 2 17 6 20 6 0 51 31 0 1 1 1 2 1 4 1 5 1 3 1 6 48 1 5 16 6 52 8 0 1 33 5 0 16 6 32 38 0 20 9 0 48 0 17 7 20 10 0 16 7 16 4 48 2 5 16 6 33 12 0 20 10 0 16 7 16 6 48 2 32 1 0 2 5 16 7 32 39 0 20 32 0 16 1 52 33 0 1 16 2 48 2 17 4 16 4 33 14 0 20 17 0 16 4 16 2 16 3 49 3 32 5 0 20 9 0 49 0 32 84 6 16 0 1 34 0 52 0 0 2 33 24 0 20 17 0 16 1 16 2 52 14 0 2 52 13 0 1 16 2 16 3 49 3 32 48 6 16 0 1 35 0 52 0 0 2 6 34 10 0 5 16 0 1 36 0 52 0 0 2 33 96 0 20 37 0 16 1 1 16 0 52 15 0 2 16 2 48 2 17 4 16 1 52 20 0 1 1 21 0 52 0 0 2 33 21 0 20 17 0 16 1 1 18 0 52 15 0 2 16 4 16 3 49 3 32 38 0 20 9 0 48 0 17 5 51 38 0 1 1 1 4 1 3 1 5 1 18 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 5 32 182 5 16 0 1 39 0 52 0 0 2 33 108 0 16 1 1 16 0 52 15 0 2 17 4 16 1 1 18 0 52 40 0 2 17 5 16 2 52 41 0 1 17 6 51 42 0 1 6 16 4 52 26 0 2 5 51 43 0 1 6 16 4 52 26 0 2 5 16 5 52 20 0 1 1 16 0 52 19 0 2 33 18 0 51 44 0 1 6 16 5 52 45 0 1 52 26 0 2 32 1 0 2 5 20 17 0 16 5 52 46 0 1 16 6 16 3 49 3 32 62 5 16 0 1 47 0 52 0 0 2 6 34 10 0 5 16 0 1 48 0 52 0 0 2 33 78 0 16 1 52 20 0 1 1 18 0 52 0 0 2 33 21 0 20 17 0 16 1 1 16 0 52 15 0 2 16 2 16 3 49 3 32 38 0 20 9 0 48 0 17 4 51 38 0 1 1 1 2 1 3 1 4 1 16 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 4 32 214 4 20 49 0 16 0 48 1 33 21 0 16 1 16 2 52 14 0 2 52 13 0 1 5 20 9 0 49 0 32 183 4 16 0 1 50 0 52 0 0 2 33 21 1 16 1 1 18 0 52 15 0 2 17 4 20 2 0 48 0 6 33 76 0 5 16 4 52 51 0 1 1 5 0 52 0 0 2 6 33 58 0 5 16 4 52 20 0 1 1 16 0 52 19 0 2 6 33 40 0 5 16 4 52 52 0 1 52 51 0 1 1 53 0 52 0 0 2 6 33 18 0 5 16 4 52 52 0 1 52 54 0 1 1 55 0 52 0 0 2 33 106 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 16 4 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 6 20 56 0 16 6 48 1 33 16 0 20 57 0 16 5 16 6 16 2 16 3 49 4 32 35 0 16 6 52 55 0 1 17 7 20 9 0 48 0 17 8 51 58 0 1 5 1 2 1 3 1 8 16 7 52 26 0 2 5 16 8 32 69 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 6 20 9 0 48 0 17 7 51 58 0 1 5 1 2 1 3 1 7 16 6 52 26 0 2 5 16 7 32 150 3 16 0 1 59 0 52 0 0 2 33 72 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 20 9 0 48 0 17 6 51 61 0 1 4 1 2 1 3 1 6 16 5 52 60 0 2 5 16 6 32 66 3 16 0 1 62 0 52 0 0 2 33 24 0 20 17 0 16 1 16 2 52 14 0 2 52 13 0 1 16 2 16 3 49 3 32 30 3 16 0 1 63 0 52 0 0 2 33 18 0 20 64 0 16 1 52 33 0 1 16 2 16 3 49 3 32 0 3 16 0 1 65 0 52 0 0 2 33 18 0 20 66 0 16 1 52 33 0 1 16 2 16 3 49 3 32 226 2 16 0 1 26 0 52 0 0 2 33 72 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 20 9 0 48 0 17 6 51 58 0 1 4 1 2 1 3 1 6 16 5 52 26 0 2 5 16 6 32 142 2 16 0 1 67 0 52 0 0 2 33 183 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 40 0 2 17 5 2 17 6 2 17 7 20 9 0 48 0 17 8 16 5 52 20 0 1 1 18 0 52 68 0 2 6 33 40 0 5 16 5 52 52 0 1 52 51 0 1 1 69 0 52 0 0 2 6 33 18 0 5 16 5 52 52 0 1 52 70 0 1 1 71 0 52 0 0 2 33 36 0 16 5 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 6 5 16 5 1 18 0 52 40 0 2 17 7 32 4 0 16 5 17 7 5 16 4 16 6 52 72 0 2 5 51 73 0 1 8 1 2 1 3 16 7 52 26 0 2 5 16 4 52 74 0 1 5 16 8 32 203 1 16 0 1 75 0 52 0 0 2 33 99 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 20 9 0 48 0 17 6 16 4 16 5 52 72 0 2 5 51 27 0 1 6 1 1 1 2 1 3 1 21 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 4 52 74 0 1 5 16 6 32 92 1 16 0 1 76 0 52 0 0 2 33 59 1 16 1 52 20 0 1 1 18 0 52 19 0 2 6 33 46 0 5 16 1 1 16 0 52 15 0 2 52 51 0 1 1 69 0 52 0 0 2 6 33 21 0 5 16 1 1 16 0 52 15 0 2 52 70 0 1 1 77 0 52 0 0 2 33 26 0 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 52 78 0 1 32 5 0 20 79 0 48 0 17 4 20 81 0 16 4 52 80 0 2 17 5 16 5 6 33 11 0 5 20 82 0 16 5 1 83 0 48 2 33 5 0 16 5 32 177 0 20 84 0 1 85 0 2 48 2 17 6 52 5 0 0 17 7 16 1 52 20 0 1 1 18 0 52 19 0 2 6 33 46 0 5 16 1 1 16 0 52 15 0 2 52 51 0 1 1 69 0 52 0 0 2 6 33 21 0 5 16 1 1 16 0 52 15 0 2 52 70 0 1 1 77 0 52 0 0 2 33 12 0 16 1 1 21 0 52 40 0 2 32 9 0 16 1 1 16 0 52 40 0 2 17 8 20 86 0 16 6 1 87 0 16 4 48 3 5 20 88 0 51 89 0 1 7 51 90 0 1 2 1 3 1 8 48 2 17 9 20 10 0 16 6 16 9 48 2 5 20 91 0 16 6 1 92 0 16 7 48 3 5 20 81 0 16 4 16 6 52 93 0 3 5 16 6 32 21 0 20 17 0 16 1 16 2 52 14 0 2 52 13 0 1 16 2 16 3 49 3 50)} "render-lambda-dom" {:upvalue-count 0 :arity 4 :constants ("env-merge" "lambda-closure" "for-each-indexed" {:upvalue-count 2 :arity 2 :constants ("env-bind!" "nth") :bytecode (18 0 16 1 18 1 16 0 52 1 0 2 52 0 0 3 50)} "lambda-params" "render-to-dom" "lambda-body") :bytecode (16 0 52 1 0 1 16 2 52 0 0 2 17 4 51 3 0 1 4 1 1 16 0 52 4 0 1 52 2 0 2 5 20 5 0 16 0 52 6 0 1 16 4 16 3 49 3 50)} "render-dom-island" {:upvalue-count 0 :arity 4 :constants ("dict" "list" "reduce" {:upvalue-count 4 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "trampoline" "eval-expr" "nth" "dict-set!" "keyword-name" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 150 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 75 0 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 12 0 2 18 1 52 11 0 2 52 10 0 1 17 3 18 2 16 1 52 14 0 1 16 3 52 13 0 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 3 16 1 52 15 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "i" 0 "skip" "env-merge" "component-closure" "component-name" "for-each" {:upvalue-count 2 :arity 1 :constants ("env-bind!" "dict-has?" "dict-get") :bytecode (18 0 16 0 18 1 16 0 52 1 0 2 33 11 0 18 1 16 0 52 2 0 2 32 1 0 2 52 0 0 3 50)} "component-params" "component-has-children?" "create-fragment" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "env-bind!" "children" "dom-create-element" "span" "dom-set-attr" "data-sx-island" "not" "empty-dict?" "data-sx-state" "sx-serialize" "mark-processed!" "island-hydrated" "with-island-scope" {:upvalue-count 1 :arity 1 :constants ("append!") :bytecode (18 0 16 0 52 0 0 2 50)} {:upvalue-count 3 :arity 0 :constants ("render-to-dom" "component-body") :bytecode (20 0 0 18 0 52 1 0 1 18 1 18 2 49 3 50)} "dom-append" "dom-set-data" "sx-disposers") :bytecode (52 0 0 0 17 4 52 1 0 0 17 5 51 3 0 1 1 1 2 1 4 1 5 1 4 0 1 5 0 1 6 0 4 52 0 0 4 16 1 52 2 0 3 5 16 0 52 8 0 1 16 2 52 7 0 2 17 6 16 0 52 9 0 1 17 7 51 11 0 1 6 1 4 16 0 52 12 0 1 52 10 0 2 5 16 0 52 13 0 1 33 37 0 20 14 0 48 0 17 8 51 15 0 1 8 1 2 1 3 16 5 52 10 0 2 5 16 6 1 17 0 16 8 52 16 0 3 32 1 0 2 5 20 18 0 1 19 0 2 48 2 17 8 52 1 0 0 17 9 20 20 0 16 8 1 21 0 16 7 48 3 5 16 4 52 23 0 1 52 22 0 1 33 19 0 20 20 0 16 8 1 24 0 16 4 52 25 0 1 48 3 32 1 0 2 5 20 26 0 16 8 1 27 0 48 2 5 20 28 0 51 29 0 1 9 51 30 0 1 0 1 6 1 3 48 2 17 10 20 31 0 16 8 16 10 48 2 5 20 32 0 16 8 1 33 0 16 9 48 3 5 16 8 50)} "render-dom-lake" {:upvalue-count 0 :arity 3 :constants ("div" "list" "reduce" {:upvalue-count 5 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "trampoline" "eval-expr" "nth" "id" "tag" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 183 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 108 0 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 13 0 2 18 1 52 12 0 2 52 11 0 1 17 4 16 3 1 14 0 52 5 0 2 33 7 0 16 4 19 2 32 20 0 16 3 1 15 0 52 5 0 2 33 7 0 16 4 19 3 32 1 0 2 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 4 16 1 52 16 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "dict" "i" 0 "skip" "dom-create-element" "dom-set-attr" "data-sx-lake" "" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)}) :bytecode (2 17 3 1 0 0 17 4 52 1 0 0 17 5 51 3 0 1 0 1 1 1 3 1 4 1 5 1 5 0 1 6 0 1 7 0 4 52 4 0 4 16 0 52 2 0 3 5 20 8 0 16 4 2 48 2 17 6 20 9 0 16 6 1 10 0 16 3 6 34 4 0 5 1 11 0 48 3 5 51 13 0 1 6 1 1 1 2 16 5 52 12 0 2 5 16 6 50)} "render-dom-marsh" {:upvalue-count 0 :arity 3 :constants ("div" "list" "reduce" {:upvalue-count 6 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "trampoline" "eval-expr" "nth" "id" "tag" "transform" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 202 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 127 0 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 13 0 2 18 1 52 12 0 2 52 11 0 1 17 4 16 3 1 14 0 52 5 0 2 33 7 0 16 4 19 2 32 39 0 16 3 1 15 0 52 5 0 2 33 7 0 16 4 19 3 32 20 0 16 3 1 16 0 52 5 0 2 33 7 0 16 4 19 4 32 1 0 2 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 5 16 1 52 17 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "dict" "i" 0 "skip" "dom-create-element" "dom-set-attr" "data-sx-marsh" "" "dom-set-data" "sx-marsh-transform" "sx-marsh-env" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)}) :bytecode (2 17 3 1 0 0 17 4 2 17 5 52 1 0 0 17 6 51 3 0 1 0 1 1 1 3 1 4 1 5 1 6 1 5 0 1 6 0 1 7 0 4 52 4 0 4 16 0 52 2 0 3 5 20 8 0 16 4 2 48 2 17 7 20 9 0 16 7 1 10 0 16 3 6 34 4 0 5 1 11 0 48 3 5 16 5 33 15 0 20 12 0 16 7 1 13 0 16 5 48 3 32 1 0 2 5 20 12 0 16 7 1 14 0 16 1 48 3 5 51 16 0 1 7 1 1 1 2 16 6 52 15 0 2 5 16 7 50)} "reactive-text" {:upvalue-count 0 :arity 1 :constants ("*hydrating*" "hydrate-next-text!" "create-text-node" "str" "deref" "effect" {:upvalue-count 2 :arity 0 :constants ("dom-set-text-content" "str" "deref") :bytecode (20 0 0 18 0 18 1 52 2 0 1 52 1 0 1 49 2 50)}) :bytecode (20 0 0 33 28 0 20 1 0 48 0 6 34 16 0 5 20 2 0 16 0 52 4 0 1 52 3 0 1 48 1 32 15 0 20 2 0 16 0 52 4 0 1 52 3 0 1 48 1 17 1 20 5 0 51 6 0 1 1 1 0 48 1 5 16 1 50)} "reactive-attr" {:upvalue-count 0 :arity 3 :constants ("dom-get-attr" "data-sx-reactive-attrs" "" "empty?" "str" "," "dom-set-attr" "effect" {:upvalue-count 3 :arity 0 :constants ("signal?" "deref" "nil?" "=" "dom-remove-attr" "dom-set-attr" "" "str") :bytecode (18 0 48 0 17 0 20 0 0 16 0 48 1 33 9 0 16 0 52 1 0 1 32 2 0 16 0 17 1 16 1 52 2 0 1 6 34 8 0 5 16 1 4 52 3 0 2 33 12 0 20 4 0 18 1 18 2 49 2 32 40 0 16 1 3 52 3 0 2 33 15 0 20 5 0 18 1 18 2 1 6 0 49 3 32 15 0 20 5 0 18 1 18 2 16 1 52 7 0 1 49 3 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 4 0 5 1 2 0 17 3 16 3 52 3 0 1 33 5 0 16 1 32 11 0 16 3 1 5 0 16 1 52 4 0 3 17 4 20 6 0 16 0 1 1 0 16 4 48 3 5 20 7 0 51 8 0 1 2 1 0 1 1 49 1 50)} "reactive-spread" {:upvalue-count 0 :arity 2 :constants ("list" "dom-get-attr" "data-sx-reactive-attrs" "" "dom-set-attr" "empty?" "_spread" "str" ",_spread" "effect" {:upvalue-count 4 :arity 0 :constants ("not" "empty?" "dom-get-attr" "class" "" "filter" {:upvalue-count 0 :arity 1 :constants ("not" "=" "") :bytecode (16 0 1 2 0 52 1 0 2 52 0 0 1 50)} "split" " " {:upvalue-count 1 :arity 1 :constants ("not" "some" {:upvalue-count 1 :arity 1 :constants ("=") :bytecode (16 0 18 0 52 0 0 2 50)}) :bytecode (51 2 0 1 0 18 0 52 1 0 2 52 0 0 1 50)} "dom-remove-attr" "dom-set-attr" "join" "for-each" {:upvalue-count 1 :arity 1 :constants ("dom-remove-attr") :bytecode (20 0 0 18 0 16 0 49 2 50)} "spread?" "spread-attrs" "dict-get" {:upvalue-count 0 :arity 1 :constants ("not" "=" "class") :bytecode (16 0 1 2 0 52 1 0 2 52 0 0 1 50)} "keys" "=" "str" {:upvalue-count 2 :arity 1 :constants ("dom-set-attr" "str" "dict-get") :bytecode (20 0 0 18 0 16 0 18 1 16 0 52 2 0 2 52 1 0 1 49 3 50)} "run-post-render-hooks" "list") :bytecode (18 0 52 1 0 1 52 0 0 1 33 95 0 20 2 0 18 1 1 3 0 48 2 6 34 4 0 5 1 4 0 17 0 51 6 0 16 0 1 8 0 52 7 0 2 52 5 0 2 17 1 51 9 0 0 0 16 1 52 5 0 2 17 2 16 2 52 1 0 1 33 13 0 20 10 0 18 1 1 3 0 48 2 32 19 0 20 11 0 18 1 1 3 0 1 8 0 16 2 52 12 0 2 48 3 32 1 0 2 5 51 14 0 0 1 18 2 52 13 0 2 5 18 3 48 0 17 0 16 0 52 15 0 1 33 179 0 16 0 52 16 0 1 17 1 16 1 1 3 0 52 17 0 2 6 34 4 0 5 1 4 0 17 2 51 6 0 16 2 1 8 0 52 7 0 2 52 5 0 2 17 3 51 18 0 16 1 52 19 0 1 52 5 0 2 17 4 16 3 19 0 5 16 4 19 2 5 16 3 52 1 0 1 52 0 0 1 33 72 0 20 2 0 18 1 1 3 0 48 2 6 34 4 0 5 1 4 0 17 5 20 11 0 18 1 1 3 0 16 5 6 33 14 0 5 16 5 1 4 0 52 20 0 2 52 0 0 1 33 14 0 16 5 1 8 0 16 2 52 21 0 3 32 2 0 16 2 48 3 32 1 0 2 5 51 22 0 0 1 1 1 16 4 52 13 0 2 5 20 23 0 49 0 32 13 0 52 24 0 0 19 0 5 52 24 0 0 19 2 50)}) :bytecode (52 0 0 0 17 2 52 0 0 0 17 3 20 1 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 17 4 20 4 0 16 0 1 2 0 16 4 52 5 0 1 33 6 0 1 6 0 32 9 0 16 4 1 8 0 52 7 0 2 48 3 5 20 9 0 51 10 0 1 2 1 0 1 3 1 1 49 1 50)} "reactive-fragment" {:upvalue-count 0 :arity 4 :constants ("create-comment" "island-fragment" "list" "effect" {:upvalue-count 4 :arity 0 :constants ("for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "list" "dom-child-nodes" "dom-insert-after") :bytecode (51 1 0 18 0 52 0 0 2 5 52 2 0 0 19 0 5 18 1 48 0 33 28 0 18 2 48 0 17 0 20 3 0 16 0 48 1 19 0 5 20 4 0 18 3 16 0 49 2 32 1 0 2 50)}) :bytecode (20 0 0 1 1 0 48 1 17 4 52 2 0 0 17 5 20 3 0 51 4 0 1 5 1 0 1 1 1 4 48 1 5 16 4 50)} "render-list-item" {:upvalue-count 0 :arity 4 :constants ("lambda?" "render-lambda-dom" "list" "render-to-dom" "apply") :bytecode (16 0 52 0 0 1 33 20 0 20 1 0 16 0 16 1 52 2 0 1 16 2 16 3 49 4 32 21 0 20 3 0 16 0 16 1 52 2 0 1 52 4 0 2 16 2 16 3 49 3 50)} "extract-key" {:upvalue-count 0 :arity 2 :constants ("dom-get-attr" "key" "dom-remove-attr" "dom-get-data" "str" "__idx_") :bytecode (20 0 0 16 0 1 1 0 48 2 17 2 16 2 33 16 0 20 2 0 16 0 1 1 0 48 2 5 16 2 32 35 0 20 3 0 16 0 1 1 0 48 2 17 3 16 3 33 9 0 16 3 52 4 0 1 32 9 0 1 5 0 16 1 52 4 0 2 50)} "reactive-list" {:upvalue-count 0 :arity 4 :constants ("create-fragment" "create-comment" "island-list" "dict" "list" "dom-append" "effect" {:upvalue-count 8 :arity 0 :constants ("deref" "dom-parent" "dict" "list" "for-each-indexed" {:upvalue-count 7 :arity 2 :constants ("render-list-item" "extract-key" "not" "starts-with?" "__idx_" "dict-has?" "dict-set!" "dict-get" "append!") :bytecode (20 0 0 18 0 16 1 18 1 18 2 48 4 17 2 20 1 0 16 2 16 0 48 2 17 3 18 3 52 2 0 1 6 33 14 0 5 16 3 1 4 0 52 3 0 2 52 2 0 1 33 6 0 3 19 3 32 1 0 2 5 18 4 16 3 52 5 0 2 33 19 0 18 5 16 3 18 4 16 3 52 7 0 2 52 6 0 3 32 10 0 18 5 16 3 16 2 52 6 0 3 5 18 6 16 3 52 8 0 2 50)} "not" "dom-remove-children-after" "create-fragment" "for-each" {:upvalue-count 2 :arity 1 :constants ("dom-append" "dict-get") :bytecode (20 0 0 18 0 18 1 16 0 52 1 0 2 49 2 50)} "dom-insert-after" {:upvalue-count 2 :arity 1 :constants ("not" "dict-has?" "dom-remove" "dict-get") :bytecode (18 0 16 0 52 1 0 2 52 0 0 1 33 16 0 20 2 0 18 1 16 0 52 3 0 2 49 1 32 1 0 2 50)} {:upvalue-count 2 :arity 1 :constants ("dict-get" "dom-next-sibling" "not" "identical?" "dom-insert-after") :bytecode (18 0 16 0 52 0 0 2 17 1 20 1 0 18 1 48 1 17 2 16 1 16 2 52 3 0 2 52 2 0 1 33 12 0 20 4 0 18 1 16 1 48 2 32 1 0 2 5 16 1 19 1 50)} {:upvalue-count 6 :arity 2 :constants ("render-list-item" "extract-key" "dict-set!" "append!" "dom-append") :bytecode (20 0 0 18 0 16 1 18 1 18 2 48 4 17 2 20 1 0 16 2 16 0 48 2 17 3 18 3 16 3 16 2 52 2 0 3 5 18 4 16 3 52 3 0 2 5 20 4 0 18 5 16 2 49 2 50)}) :bytecode (18 0 52 0 0 1 17 0 20 1 0 18 1 48 1 33 133 0 52 2 0 0 17 1 52 3 0 0 17 2 4 17 3 51 5 0 0 2 0 3 0 4 1 3 0 5 1 1 1 2 16 0 52 4 0 2 5 16 3 52 6 0 1 33 41 0 20 7 0 18 1 48 1 5 20 8 0 48 0 17 4 51 10 0 1 4 1 1 16 2 52 9 0 2 5 20 11 0 18 1 16 4 48 2 32 31 0 51 12 0 1 1 0 5 18 6 52 9 0 2 5 18 1 17 4 51 13 0 1 1 1 4 16 2 52 9 0 2 5 16 1 19 5 5 16 2 19 6 32 21 0 51 14 0 0 2 0 3 0 4 0 5 0 6 0 7 16 0 52 4 0 2 50)}) :bytecode (20 0 0 48 0 17 4 20 1 0 1 2 0 48 1 17 5 52 3 0 0 17 6 52 4 0 0 17 7 20 5 0 16 4 16 5 48 2 5 20 6 0 51 7 0 1 1 1 5 1 0 1 2 1 3 1 6 1 7 1 4 48 1 5 16 4 50)} "bind-input" {:upvalue-count 0 :arity 2 :constants ("lower" "dom-get-attr" "type" "" "=" "checkbox" "radio" "dom-set-prop" "checked" "deref" "value" "str" "effect" {:upvalue-count 3 :arity 0 :constants ("dom-set-prop" "checked" "deref" "str" "!=" "dom-get-prop" "value") :bytecode (18 0 33 19 0 20 0 0 18 1 1 1 0 18 2 52 2 0 1 49 3 32 47 0 18 2 52 2 0 1 52 3 0 1 17 0 20 5 0 18 1 1 6 0 48 2 16 0 52 4 0 2 33 15 0 20 0 0 18 1 1 6 0 16 0 49 3 32 1 0 2 50)} "dom-on" "change" "input" {:upvalue-count 3 :arity 1 :constants ("reset!" "dom-get-prop" "checked" "value") :bytecode (18 0 33 20 0 20 0 0 18 1 20 1 0 18 2 1 2 0 48 2 49 2 32 17 0 20 0 0 18 1 20 1 0 18 2 1 3 0 48 2 49 2 50)}) :bytecode (20 1 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 52 0 0 1 17 2 16 2 1 5 0 52 4 0 2 6 34 10 0 5 16 2 1 6 0 52 4 0 2 17 3 16 3 33 19 0 20 7 0 16 0 1 8 0 16 1 52 9 0 1 48 3 32 20 0 20 7 0 16 0 1 10 0 16 1 52 9 0 1 52 11 0 1 48 3 5 20 12 0 51 13 0 1 3 1 0 1 1 48 1 5 20 14 0 16 0 16 3 33 6 0 1 15 0 32 3 0 1 16 0 51 17 0 1 3 1 1 1 0 49 3 50)} "*use-cek-reactive*" "enable-cek-reactive!" {:upvalue-count 0 :arity 0 :constants ("*use-cek-reactive*") :bytecode (3 21 0 0 50)} "cek-reactive-text" {:upvalue-count 0 :arity 2 :constants ("create-text-node" "" {:upvalue-count 1 :arity 1 :constants ("dom-set-text-content" "str") :bytecode (20 0 0 18 0 16 0 52 1 0 1 49 2 50)} "cek-run" "make-cek-state" "list" "make-reactive-reset-frame" "dom-set-text-content" "str") :bytecode (20 0 0 1 1 0 48 1 17 2 51 2 0 1 2 17 3 20 3 0 20 4 0 16 0 16 1 20 6 0 16 1 16 3 3 48 3 52 5 0 1 48 3 48 1 17 4 20 7 0 16 2 16 4 52 8 0 1 48 2 5 16 2 50)} "cek-reactive-attr" {:upvalue-count 0 :arity 4 :constants ({:upvalue-count 2 :arity 1 :constants ("nil?" "=" "dom-remove-attr" "dom-set-attr" "" "str") :bytecode (16 0 52 0 0 1 6 34 8 0 5 16 0 4 52 1 0 2 33 12 0 20 2 0 18 0 18 1 49 2 32 40 0 16 0 3 52 1 0 2 33 15 0 20 3 0 18 0 18 1 1 4 0 49 3 32 15 0 20 3 0 18 0 18 1 16 0 52 5 0 1 49 3 50)} "dom-get-attr" "data-sx-reactive-attrs" "" "empty?" "str" "," "dom-set-attr" "cek-run" "make-cek-state" "list" "make-reactive-reset-frame" "cek-call") :bytecode (51 0 0 1 0 1 1 17 4 20 1 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 17 5 16 5 52 4 0 1 33 5 0 16 1 32 11 0 16 5 1 6 0 16 1 52 5 0 3 17 6 20 7 0 16 0 1 2 0 16 6 48 3 5 20 8 0 20 9 0 16 2 16 3 20 11 0 16 3 16 4 3 48 3 52 10 0 1 48 3 48 1 17 5 16 4 16 5 52 10 0 1 52 12 0 2 50)} "render-dom-portal" {:upvalue-count 0 :arity 3 :constants ("trampoline" "eval-expr" "first" "dom-query" "dom-ensure-element" "not" "create-comment" "str" "portal: " " (not found)" "create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "rest" "dom-child-nodes" "dom-append" "register-in-scope" {:upvalue-count 1 :arity 0 :constants ("for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)}) :bytecode (51 1 0 18 0 52 0 0 2 50)}) :bytecode (16 0 52 2 0 1 16 1 52 1 0 2 52 0 0 1 17 3 20 3 0 16 3 48 1 6 34 8 0 5 20 4 0 16 3 48 1 17 4 16 4 52 5 0 1 33 20 0 20 6 0 1 8 0 16 3 1 9 0 52 7 0 3 49 1 32 75 0 20 6 0 1 8 0 16 3 52 7 0 2 48 1 17 5 20 10 0 48 0 17 6 51 12 0 1 6 1 1 1 2 16 0 52 13 0 1 52 11 0 2 5 20 14 0 16 6 48 1 17 7 20 15 0 16 4 16 6 48 2 5 20 16 0 51 17 0 1 7 48 1 5 16 5 50)} "render-dom-error-boundary" {:upvalue-count 0 :arity 3 :constants (">" "len" 1 "first" "rest" "dom-create-element" "div" "signal" 0 "dom-set-attr" "data-sx-boundary" "true" "effect" {:upvalue-count 6 :arity 0 :constants ("deref" "dom-set-prop" "innerHTML" "" "scope-push!" "sx-island-scope" "try-catch" {:upvalue-count 4 :arity 0 :constants ("create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "dom-append" "scope-pop!" "sx-island-scope") :bytecode (20 0 0 48 0 17 0 51 2 0 1 0 0 0 0 1 18 2 52 1 0 2 5 20 3 0 18 3 16 0 48 2 5 1 5 0 52 4 0 1 50)} {:upvalue-count 5 :arity 1 :constants ("scope-pop!" "sx-island-scope" "trampoline" "eval-expr" {:upvalue-count 1 :arity 0 :constants ("swap!" {:upvalue-count 0 :arity 1 :constants ("+" 1) :bytecode (16 0 1 1 0 52 0 0 2 50)}) :bytecode (20 0 0 18 0 51 1 0 49 2 50)} "nil?" "dom-create-element" "div" "dom-set-attr" "class" "sx-render-error" "style" "color:red;font-size:0.875rem;padding:0.5rem;border:1px solid red;border-radius:0.25rem;margin:0.5rem 0;" "dom-set-text-content" "str" "Render error: " "lambda?" "render-lambda-dom" "list" "render-to-dom" "apply" "dom-append") :bytecode (1 1 0 52 0 0 1 5 18 0 18 1 52 3 0 2 52 2 0 1 17 1 51 4 0 0 2 17 2 16 1 52 5 0 1 33 61 0 20 6 0 1 7 0 2 48 2 17 3 20 8 0 16 3 1 9 0 1 10 0 48 3 5 20 8 0 16 3 1 11 0 1 12 0 48 3 5 20 13 0 16 3 1 15 0 16 0 52 14 0 2 48 2 5 16 3 32 54 0 16 1 52 16 0 1 33 22 0 20 17 0 16 1 16 0 16 2 52 18 0 2 18 1 18 3 48 4 32 23 0 20 19 0 16 1 16 0 16 2 52 18 0 2 52 20 0 2 18 1 18 3 48 3 17 3 20 21 0 18 4 16 3 49 2 50)}) :bytecode (18 0 52 0 0 1 5 20 1 0 18 1 1 2 0 1 3 0 48 3 5 1 5 0 2 52 4 0 2 5 51 7 0 0 2 0 3 0 4 0 1 51 8 0 0 5 0 2 0 0 0 3 0 1 52 6 0 2 50)}) :bytecode (16 0 52 1 0 1 1 2 0 52 0 0 2 33 9 0 16 0 52 3 0 1 32 1 0 2 17 3 16 0 52 1 0 1 1 2 0 52 0 0 2 33 9 0 16 0 52 4 0 1 32 2 0 16 0 17 4 20 5 0 1 6 0 2 48 2 17 5 20 7 0 1 8 0 48 1 17 6 20 9 0 16 5 1 10 0 1 11 0 48 3 5 20 12 0 51 13 0 1 6 1 5 1 1 1 2 1 4 1 3 48 1 5 16 5 50)} {:library (web adapter-dom) :op "import"}) :bytecode (1 0 0 112 5 1 1 0 112 5 1 3 0 128 2 0 5 1 5 0 128 4 0 5 51 7 0 128 6 0 5 52 9 0 0 128 8 0 5 1 11 0 128 10 0 5 51 13 0 128 12 0 5 51 15 0 128 14 0 5 51 17 0 128 16 0 5 51 19 0 128 18 0 5 51 21 0 128 20 0 5 51 23 0 128 22 0 5 51 25 0 128 24 0 5 51 27 0 128 26 0 5 51 29 0 128 28 0 5 51 31 0 128 30 0 5 1 34 0 1 35 0 1 36 0 1 37 0 1 38 0 1 39 0 1 40 0 1 41 0 1 42 0 1 43 0 1 44 0 1 45 0 1 46 0 1 47 0 1 48 0 1 49 0 1 50 0 1 51 0 1 52 0 1 53 0 1 54 0 1 55 0 1 56 0 52 33 0 23 128 32 0 5 51 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 5 51 72 0 128 71 0 5 51 74 0 128 73 0 5 51 76 0 128 75 0 5 51 78 0 128 77 0 5 51 80 0 128 79 0 5 51 82 0 128 81 0 5 51 84 0 128 83 0 5 3 128 85 0 5 51 87 0 128 86 0 5 51 89 0 128 88 0 5 51 91 0 128 90 0 5 51 93 0 128 92 0 5 51 95 0 128 94 0 5 1 96 0 112 50))) + :constants ({:library (sx dom) :op "import"} {:library (sx render) :op "import"} "SVG_NS" "http://www.w3.org/2000/svg" "MATH_NS" "http://www.w3.org/1998/Math/MathML" "island-scope?" {:upvalue-count 0 :arity 0 :constants ("not" "nil?" "scope-peek" "sx-island-scope") :bytecode (1 3 0 52 2 0 1 52 1 0 1 52 0 0 1 50)} "*memo-cache*" "dict" "*cyst-counter*" 0 "next-cyst-id" {:upvalue-count 0 :arity 0 :constants ("+" "*cyst-counter*" 1 "str" "sx-cyst-") :bytecode (20 1 0 1 2 0 52 0 0 2 21 1 0 5 1 4 0 20 1 0 52 3 0 2 50)} "contains-deref?" {:upvalue-count 0 :arity 1 :constants ("not" "list?" "empty?" "=" "type-of" "first" "symbol" "symbol-name" "deref" "some" "contains-deref?") :bytecode (16 0 52 1 0 1 52 0 0 1 33 4 0 4 32 68 0 16 0 52 2 0 1 33 4 0 4 32 55 0 16 0 52 5 0 1 52 4 0 1 1 6 0 52 3 0 2 6 33 18 0 5 16 0 52 5 0 1 52 7 0 1 1 8 0 52 3 0 2 33 4 0 3 32 9 0 20 10 0 16 0 52 9 0 2 50)} "dom-on" {:upvalue-count 0 :arity 3 :constants ("dom-listen" "lambda?" "=" 0 "len" "lambda-params" {:upvalue-count 1 :arity 1 :constants ("trampoline" "call-lambda" "list" "run-post-render-hooks") :bytecode (18 0 52 2 0 0 52 1 0 2 52 0 0 1 5 20 3 0 49 0 50)} {:upvalue-count 1 :arity 1 :constants ("trampoline" "call-lambda" "list" "run-post-render-hooks") :bytecode (18 0 16 0 52 2 0 1 52 1 0 2 52 0 0 1 5 20 3 0 49 0 50)}) :bytecode (20 0 0 16 0 16 1 16 2 52 1 0 1 33 36 0 1 3 0 16 2 52 5 0 1 52 4 0 1 52 2 0 2 33 8 0 51 6 0 1 2 32 5 0 51 7 0 1 2 32 2 0 16 2 49 3 50)} "render-to-dom" {:upvalue-count 0 :arity 3 :constants ("set-render-active!" "type-of" "nil" "=" "create-fragment" "boolean" "raw-html" "dom-parse-html" "raw-html-content" "string" "create-text-node" "number" "str" "symbol" "render-to-dom" "trampoline" "eval-expr" "keyword" "keyword-name" "dom-node" "spread" "not" "island-scope?" "scope-emit!" "element-attrs" "spread-attrs" "dict" "has-key?" "__host_handle" "list" "empty?" "render-dom-list" "signal?" "reactive-text" "deref") :bytecode (3 52 0 0 1 5 16 0 52 1 0 1 6 1 2 0 52 3 0 2 33 9 0 5 20 4 0 49 0 32 102 1 6 1 5 0 52 3 0 2 33 9 0 5 20 4 0 49 0 32 82 1 6 1 6 0 52 3 0 2 33 15 0 5 20 7 0 16 0 52 8 0 1 49 1 32 56 1 6 1 9 0 52 3 0 2 33 11 0 5 20 10 0 16 0 49 1 32 34 1 6 1 11 0 52 3 0 2 33 15 0 5 20 10 0 16 0 52 12 0 1 49 1 32 8 1 6 1 13 0 52 3 0 2 33 25 0 5 20 14 0 16 0 16 1 52 16 0 2 52 15 0 1 16 1 16 2 49 3 32 228 0 6 1 17 0 52 3 0 2 33 15 0 5 20 10 0 16 0 52 18 0 1 49 1 32 202 0 6 1 19 0 52 3 0 2 33 6 0 5 16 0 32 185 0 6 1 20 0 52 3 0 2 33 36 0 5 20 22 0 48 0 52 21 0 1 33 16 0 1 24 0 16 0 52 25 0 1 52 23 0 2 32 1 0 2 5 16 0 32 138 0 6 1 26 0 52 3 0 2 33 26 0 5 16 0 1 28 0 52 27 0 2 33 5 0 16 0 32 5 0 20 4 0 49 0 32 101 0 6 1 29 0 52 3 0 2 33 32 0 5 16 0 52 30 0 1 33 8 0 20 4 0 49 0 32 11 0 20 31 0 16 0 16 1 16 2 49 3 32 58 0 5 20 32 0 16 0 48 1 33 36 0 20 22 0 48 0 33 10 0 20 33 0 16 0 49 1 32 15 0 20 10 0 16 0 52 34 0 1 52 12 0 1 49 1 32 11 0 20 10 0 16 0 52 12 0 1 49 1 50)} "render-dom-list" {:upvalue-count 0 :arity 3 :constants ("first" "=" "type-of" "symbol" "symbol-name" "rest" "raw!" "render-dom-raw" "<>" "render-dom-fragment" "lake" "render-dom-lake" "marsh" "render-dom-marsh" "starts-with?" "html:" "render-dom-element" "slice" 5 "render-dom-form?" "contains?" "HTML_TAGS" ">" "len" 0 "keyword" "dispatch-render-form" "env-has?" "macro?" "env-get" "render-to-dom" "expand-macro" "~" "island?" "scope-peek" "sx-render-markers" "dom-create-element" "span" "dict" "reduce" {:upvalue-count 3 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "trampoline" "eval-expr" "nth" "dict-set!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 145 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 79 0 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 13 0 2 18 1 52 12 0 2 52 11 0 1 17 4 18 2 16 3 16 4 52 14 0 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 22 0 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "i" "skip" "dom-set-attr" "data-sx-island" "component-name" "not" "empty-dict?" "data-sx-state" "sx-serialize" "render-dom-island" "component?" "render-dom-component" "render-dom-unknown-component" "index-of" "-" "deref" "island-scope?" "trampoline" "eval-expr" "signal?" "reactive-text" "create-text-node" "str" "contains-deref?" "computed" {:upvalue-count 2 :arity 0 :constants ("trampoline" "eval-expr") :bytecode (18 0 18 1 52 1 0 2 52 0 0 1 50)} "lambda?" "list" "create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("render-to-dom" "not" "spread?" "dom-append") :bytecode (20 0 0 16 0 18 0 18 1 48 3 17 1 16 1 52 2 0 1 52 1 0 1 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)}) :bytecode (16 0 52 0 0 1 17 3 16 3 52 2 0 1 1 3 0 52 1 0 2 33 52 3 16 3 52 4 0 1 17 4 16 0 52 5 0 1 17 5 16 4 1 6 0 52 1 0 2 33 12 0 20 7 0 16 5 16 1 49 2 32 9 3 16 4 1 8 0 52 1 0 2 33 14 0 20 9 0 16 5 16 1 16 2 49 3 32 239 2 16 4 1 10 0 52 1 0 2 33 14 0 20 11 0 16 5 16 1 16 2 49 3 32 213 2 16 4 1 12 0 52 1 0 2 33 14 0 20 13 0 16 5 16 1 16 2 49 3 32 187 2 16 4 1 15 0 52 14 0 2 33 23 0 20 16 0 16 4 1 18 0 52 17 0 2 16 5 16 1 16 2 49 4 32 152 2 20 19 0 16 4 48 1 33 91 0 20 21 0 16 4 52 20 0 2 6 33 43 0 5 16 5 52 23 0 1 1 24 0 52 22 0 2 6 33 18 0 5 16 5 52 0 0 1 52 2 0 1 1 25 0 52 1 0 2 6 34 3 0 5 16 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 13 0 20 26 0 16 4 16 0 16 1 16 2 49 4 32 51 2 16 1 16 4 52 27 0 2 6 33 13 0 5 16 1 16 4 52 29 0 2 52 28 0 1 33 28 0 20 30 0 16 1 16 4 52 29 0 2 16 5 16 1 52 31 0 3 16 1 16 2 49 3 32 251 1 20 21 0 16 4 52 20 0 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 223 1 16 4 1 32 0 52 14 0 2 6 33 26 0 5 16 1 16 4 52 27 0 2 6 33 13 0 5 16 1 16 4 52 29 0 2 52 33 0 1 33 145 0 1 35 0 52 34 0 1 33 113 0 16 1 16 4 52 29 0 2 17 6 20 36 0 1 37 0 2 48 2 17 7 52 38 0 0 17 8 51 40 0 1 5 1 1 1 8 1 41 0 1 24 0 1 42 0 4 52 38 0 4 16 5 52 39 0 3 5 20 43 0 16 7 1 44 0 16 6 52 45 0 1 48 3 5 16 8 52 47 0 1 52 46 0 1 33 19 0 20 43 0 16 7 1 48 0 16 8 52 49 0 1 48 3 32 1 0 2 5 16 7 32 19 0 20 50 0 16 1 16 4 52 29 0 2 16 5 16 1 16 2 49 4 32 36 1 16 4 1 32 0 52 14 0 2 33 45 0 16 1 16 4 52 29 0 2 17 6 16 6 52 51 0 1 33 16 0 20 52 0 16 6 16 5 16 1 16 2 49 4 32 7 0 20 53 0 16 4 49 1 32 235 0 16 4 1 55 0 52 54 0 2 1 24 0 52 22 0 2 6 33 36 0 5 16 5 52 23 0 1 1 24 0 52 22 0 2 6 33 18 0 5 16 5 52 0 0 1 52 2 0 1 1 25 0 52 1 0 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 160 0 16 2 33 16 0 20 16 0 16 4 16 5 16 1 16 2 49 4 32 139 0 16 4 1 56 0 52 1 0 2 6 33 6 0 5 20 57 0 48 0 33 56 0 16 5 52 0 0 1 16 1 52 59 0 2 52 58 0 1 17 6 20 60 0 16 6 48 1 33 10 0 20 61 0 16 6 49 1 32 15 0 20 62 0 16 6 52 56 0 1 52 63 0 1 49 1 32 61 0 20 57 0 48 0 6 33 8 0 5 20 64 0 16 0 48 1 33 20 0 20 61 0 20 65 0 51 66 0 1 0 1 1 48 1 49 1 32 21 0 20 30 0 16 0 16 1 52 59 0 2 52 58 0 1 16 1 16 2 49 3 32 76 0 16 3 52 67 0 1 6 34 14 0 5 16 3 52 2 0 1 1 68 0 52 1 0 2 33 24 0 20 30 0 16 0 16 1 52 59 0 2 52 58 0 1 16 1 16 2 49 3 32 25 0 20 69 0 48 0 17 4 51 71 0 1 1 1 2 1 4 16 0 52 70 0 2 5 16 4 50)} "render-dom-element" {:upvalue-count 0 :arity 4 :constants ("=" "svg" "SVG_NS" "math" "MATH_NS" "dom-create-element" "scope-push!" "element-attrs" "reduce" {:upvalue-count 5 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "nth" "starts-with?" "on-" "trampoline" "eval-expr" "callable?" "dom-on" "slice" 3 "bind" "signal?" "bind-input" "ref" "dict-set!" "current" "key" "dom-set-attr" "str" "island-scope?" "reactive-attr" {:upvalue-count 2 :arity 0 :constants ("trampoline" "eval-expr") :bytecode (18 0 18 1 52 1 0 2 52 0 0 1 50)} "nil?" "contains?" "BOOLEAN_ATTRS" "" "not" "VOID_ELEMENTS" "render-to-dom" "spread?" "reactive-spread" {:upvalue-count 3 :arity 0 :constants ("render-to-dom") :bytecode (20 0 0 18 0 18 1 18 2 49 3 50)} "dom-append") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 47 2 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 143 1 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 11 0 2 17 4 16 3 1 13 0 52 12 0 2 33 49 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 20 16 0 16 5 48 1 33 21 0 20 17 0 18 2 16 3 1 19 0 52 18 0 2 16 5 48 3 32 1 0 2 32 23 1 16 3 1 20 0 52 5 0 2 33 40 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 20 21 0 16 5 48 1 33 12 0 20 22 0 18 2 16 5 48 2 32 1 0 2 32 227 0 16 3 1 23 0 52 5 0 2 33 28 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 16 5 1 25 0 18 2 52 24 0 3 32 187 0 16 3 1 26 0 52 5 0 2 33 33 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 20 27 0 18 2 1 26 0 16 5 52 28 0 1 48 3 32 142 0 20 29 0 48 0 33 19 0 20 30 0 18 2 16 3 51 31 0 1 4 0 1 48 3 32 115 0 16 4 18 1 52 15 0 2 52 14 0 1 17 5 16 5 52 32 0 1 6 34 8 0 5 16 5 4 52 5 0 2 33 4 0 2 32 76 0 20 34 0 16 3 52 33 0 2 33 24 0 16 5 33 15 0 20 27 0 18 2 16 3 1 35 0 48 3 32 1 0 2 32 40 0 16 5 3 52 5 0 2 33 15 0 20 27 0 18 2 16 3 1 35 0 48 3 32 15 0 20 27 0 18 2 16 3 16 5 52 28 0 1 48 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 116 0 20 37 0 18 3 52 33 0 2 52 36 0 1 33 76 0 20 38 0 16 1 18 1 18 4 48 3 17 3 16 3 52 39 0 1 6 33 6 0 5 20 29 0 48 0 33 19 0 20 40 0 18 2 51 41 0 1 1 0 1 0 4 48 2 32 22 0 16 3 52 39 0 1 33 4 0 2 32 9 0 20 42 0 18 2 16 3 48 2 32 1 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "dict" "i" 0 "skip" "for-each" {:upvalue-count 1 :arity 1 :constants ("for-each" {:upvalue-count 2 :arity 1 :constants ("dict-get" "=" "class" "dom-get-attr" "dom-set-attr" "not" "" "str" " " "style" ";") :bytecode (18 0 16 0 52 0 0 2 17 1 16 0 1 2 0 52 1 0 2 33 64 0 20 3 0 18 1 1 2 0 48 2 17 2 20 4 0 18 1 1 2 0 16 2 6 33 14 0 5 16 2 1 6 0 52 1 0 2 52 5 0 1 33 14 0 16 2 1 8 0 16 1 52 7 0 3 32 2 0 16 1 49 3 32 91 0 16 0 1 9 0 52 1 0 2 33 64 0 20 3 0 18 1 1 9 0 48 2 17 2 20 4 0 18 1 1 9 0 16 2 6 33 14 0 5 16 2 1 6 0 52 1 0 2 52 5 0 1 33 14 0 16 2 1 10 0 16 1 52 7 0 3 32 2 0 16 1 49 3 32 15 0 20 4 0 18 1 16 0 16 1 52 7 0 1 49 3 50)} "keys") :bytecode (51 1 0 1 0 0 0 16 0 52 2 0 1 52 0 0 2 50)} "scope-emitted" "scope-pop!") :bytecode (16 0 1 1 0 52 0 0 2 33 6 0 20 2 0 32 20 0 16 0 1 3 0 52 0 0 2 33 6 0 20 4 0 32 2 0 16 3 17 4 20 5 0 16 0 16 4 48 2 17 5 1 7 0 2 52 6 0 2 5 51 9 0 1 1 1 2 1 5 1 0 1 4 1 11 0 1 12 0 1 13 0 4 52 10 0 4 16 1 52 8 0 3 5 51 15 0 1 5 1 7 0 52 16 0 1 52 14 0 2 5 1 7 0 52 17 0 1 5 16 5 50)} "render-dom-component" {:upvalue-count 0 :arity 4 :constants ("dict" "list" "reduce" {:upvalue-count 4 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "trampoline" "eval-expr" "nth" "dict-set!" "keyword-name" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 150 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 75 0 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 12 0 2 18 1 52 11 0 2 52 10 0 1 17 3 18 2 16 1 52 14 0 1 16 3 52 13 0 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 3 16 1 52 15 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "i" 0 "skip" "env-merge" "component-closure" "for-each" {:upvalue-count 2 :arity 1 :constants ("env-bind!" "dict-has?" "dict-get") :bytecode (18 0 16 0 18 1 16 0 52 1 0 2 33 11 0 18 1 16 0 52 2 0 2 32 1 0 2 52 0 0 3 50)} "component-params" "component-has-children?" "create-fragment" {:upvalue-count 3 :arity 1 :constants ("render-to-dom" "not" "spread?" "dom-append") :bytecode (20 0 0 16 0 18 0 18 1 48 3 17 1 16 1 52 2 0 1 52 1 0 1 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)} "env-bind!" "children" "render-to-dom" "component-body") :bytecode (52 0 0 0 17 4 52 1 0 0 17 5 51 3 0 1 1 1 2 1 4 1 5 1 4 0 1 5 0 1 6 0 4 52 0 0 4 16 1 52 2 0 3 5 16 0 52 8 0 1 16 2 52 7 0 2 17 6 51 10 0 1 6 1 4 16 0 52 11 0 1 52 9 0 2 5 16 0 52 12 0 1 33 37 0 20 13 0 48 0 17 7 51 14 0 1 2 1 3 1 7 16 5 52 9 0 2 5 16 6 1 16 0 16 7 52 15 0 3 32 1 0 2 5 20 17 0 16 0 52 18 0 1 16 6 16 3 49 3 50)} "render-dom-fragment" {:upvalue-count 0 :arity 3 :constants ("create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("render-to-dom" "not" "spread?" "dom-append") :bytecode (20 0 0 16 0 18 0 18 1 48 3 17 1 16 1 52 2 0 1 52 1 0 1 33 12 0 20 3 0 18 2 16 1 49 2 32 1 0 2 50)}) :bytecode (20 0 0 48 0 17 3 51 2 0 1 1 1 2 1 3 16 0 52 1 0 2 5 16 3 50)} "render-dom-raw" {:upvalue-count 0 :arity 2 :constants ("create-fragment" "for-each" {:upvalue-count 2 :arity 1 :constants ("trampoline" "eval-expr" "=" "type-of" "string" "dom-append" "dom-parse-html" "dom-node" "dom-clone" "not" "nil?" "create-text-node" "str") :bytecode (16 0 18 0 52 1 0 2 52 0 0 1 17 1 16 1 52 3 0 1 1 4 0 52 2 0 2 33 17 0 20 5 0 18 1 20 6 0 16 1 48 1 49 2 32 68 0 16 1 52 3 0 1 1 7 0 52 2 0 2 33 17 0 20 5 0 18 1 20 8 0 16 1 48 1 49 2 32 35 0 16 1 52 10 0 1 52 9 0 1 33 21 0 20 5 0 18 1 20 11 0 16 1 52 12 0 1 48 1 49 2 32 1 0 2 50)}) :bytecode (20 0 0 48 0 17 2 51 2 0 1 1 1 2 16 0 52 1 0 2 5 16 2 50)} "render-dom-unknown-component" {:upvalue-count 0 :arity 1 :constants ("error" "str" "Unknown component: ") :bytecode (1 2 0 16 0 52 1 0 2 52 0 0 1 50)} "RENDER_DOM_FORMS" "list" "if" "when" "cond" "case" "let" "let*" "letrec" "begin" "do" "define" "defcomp" "defisland" "defmacro" "defstyle" "map" "map-indexed" "filter" "for-each" "portal" "error-boundary" "scope" "provide" "cyst" "render-dom-form?" {:upvalue-count 0 :arity 1 :constants ("contains?" "RENDER_DOM_FORMS") :bytecode (20 1 0 16 0 52 0 0 2 50)} "dispatch-render-form" {:upvalue-count 0 :arity 4 :constants ("=" "if" "island-scope?" "create-comment" "r-if" "list" "effect" {:upvalue-count 6 :arity 0 :constants ("trampoline" "eval-expr" "nth" 1 "render-to-dom" 2 ">" "len" 3 "create-fragment" "dom-parent" "for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "dom-is-fragment?" "dom-child-nodes" "list" "dom-insert-after") :bytecode (18 0 1 3 0 52 2 0 2 18 1 52 1 0 2 52 0 0 1 17 0 16 0 33 21 0 20 4 0 18 0 1 5 0 52 2 0 2 18 1 18 2 48 3 32 42 0 18 0 52 7 0 1 1 8 0 52 6 0 2 33 21 0 20 4 0 18 0 1 8 0 52 2 0 2 18 1 18 2 48 3 32 5 0 20 9 0 48 0 17 0 20 10 0 18 3 48 1 33 51 0 51 12 0 18 4 52 11 0 2 5 20 13 0 16 0 48 1 33 10 0 20 14 0 16 0 48 1 32 6 0 16 0 52 15 0 1 19 4 5 20 16 0 18 3 16 0 49 2 32 4 0 16 0 19 5 50)} "spread?" "create-fragment" "dom-append" "dom-is-fragment?" "dom-child-nodes" "trampoline" "eval-expr" "nth" 1 "render-to-dom" 2 ">" "len" 3 "when" "r-when" {:upvalue-count 6 :arity 0 :constants ("dom-parent" "for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "list" "trampoline" "eval-expr" "nth" 1 "create-fragment" {:upvalue-count 4 :arity 1 :constants ("dom-append" "render-to-dom" "nth") :bytecode (20 0 0 18 0 20 1 0 18 1 16 0 52 2 0 2 18 2 18 3 48 3 49 2 50)} "range" 2 "len" "dom-child-nodes" "dom-insert-after") :bytecode (20 0 0 18 0 48 1 33 101 0 51 2 0 18 1 52 1 0 2 5 52 3 0 0 19 1 5 18 2 1 7 0 52 6 0 2 18 3 52 5 0 2 52 4 0 1 33 58 0 20 8 0 48 0 17 0 51 9 0 1 0 0 2 0 3 0 4 1 11 0 18 2 52 12 0 1 52 10 0 2 52 1 0 2 5 20 13 0 16 0 48 1 19 1 5 20 14 0 18 0 16 0 49 2 32 1 0 2 32 76 0 18 2 1 7 0 52 6 0 2 18 3 52 5 0 2 52 4 0 1 33 53 0 20 8 0 48 0 17 0 51 9 0 1 0 0 2 0 3 0 4 1 11 0 18 2 52 12 0 1 52 10 0 2 52 1 0 2 5 20 13 0 16 0 48 1 19 1 5 16 0 19 5 32 1 0 2 50)} "not" "for-each" {:upvalue-count 4 :arity 1 :constants ("dom-append" "render-to-dom" "nth") :bytecode (20 0 0 18 0 20 1 0 18 1 16 0 52 2 0 2 18 2 18 3 48 3 49 2 50)} "range" "cond" "r-cond" {:upvalue-count 6 :arity 0 :constants ("eval-cond" "rest" "dom-parent" "for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "list" "render-to-dom" "dom-is-fragment?" "dom-child-nodes" "dom-insert-after") :bytecode (20 0 0 18 0 52 1 0 1 18 1 48 2 17 0 20 2 0 18 2 48 1 33 80 0 51 4 0 18 3 52 3 0 2 5 52 5 0 0 19 3 5 16 0 33 54 0 20 6 0 16 0 18 1 18 4 48 3 17 1 20 7 0 16 1 48 1 33 10 0 20 8 0 16 1 48 1 32 6 0 16 1 52 5 0 1 19 3 5 20 9 0 18 2 16 1 49 2 32 1 0 2 32 55 0 16 0 33 49 0 20 6 0 16 0 18 1 18 4 48 3 17 1 20 7 0 16 1 48 1 33 10 0 20 8 0 16 1 48 1 32 6 0 16 1 52 5 0 1 19 3 5 16 1 19 5 32 1 0 2 50)} "eval-cond" "rest" "case" "let" "let*" "process-bindings" {:upvalue-count 4 :arity 1 :constants ("render-to-dom" "nth" "not" "spread?" "dom-append") :bytecode (20 0 0 18 0 16 0 52 1 0 2 18 1 18 2 48 3 17 1 16 1 52 3 0 1 52 2 0 1 33 12 0 20 4 0 18 3 16 1 49 2 32 1 0 2 50)} "letrec" "slice" "env-extend" {:upvalue-count 1 :arity 1 :constants ("=" "type-of" "first" "symbol" "symbol-name" "str" "env-bind!") :bytecode (16 0 52 2 0 1 52 1 0 1 1 3 0 52 0 0 2 33 13 0 16 0 52 2 0 1 52 4 0 1 32 10 0 16 0 52 2 0 1 52 5 0 1 17 1 18 0 16 1 2 52 6 0 3 50)} {:upvalue-count 1 :arity 1 :constants ("=" "type-of" "first" "symbol" "symbol-name" "str" "env-set!" "trampoline" "eval-expr" "nth" 1) :bytecode (16 0 52 2 0 1 52 1 0 1 1 3 0 52 0 0 2 33 13 0 16 0 52 2 0 1 52 4 0 1 32 10 0 16 0 52 2 0 1 52 5 0 1 17 1 18 0 16 1 16 0 1 10 0 52 9 0 2 18 0 52 8 0 2 52 7 0 1 52 6 0 3 50)} {:upvalue-count 1 :arity 1 :constants ("trampoline" "eval-expr") :bytecode (16 0 18 0 52 1 0 2 52 0 0 1 50)} "init" "last" "begin" "do" "definition-form?" "map" "type-of" "first" "symbol" "symbol-name" "deref" "signal?" "reactive-list" {:upvalue-count 4 :arity 1 :constants ("lambda?" "render-lambda-dom" "list" "render-to-dom" "apply" "dom-append") :bytecode (18 0 52 0 0 1 33 20 0 20 1 0 18 0 16 0 52 2 0 1 18 1 18 2 48 4 32 21 0 20 3 0 18 0 16 0 52 2 0 1 52 4 0 2 18 1 18 2 48 3 17 1 20 5 0 18 3 16 1 49 2 50)} "map-indexed" "for-each-indexed" {:upvalue-count 4 :arity 2 :constants ("lambda?" "render-lambda-dom" "list" "render-to-dom" "apply" "dom-append") :bytecode (18 0 52 0 0 1 33 22 0 20 1 0 18 0 16 0 16 1 52 2 0 2 18 1 18 2 48 4 32 23 0 20 3 0 18 0 16 0 16 1 52 2 0 2 52 4 0 2 18 1 18 2 48 3 17 2 20 5 0 18 3 16 2 49 2 50)} "filter" "portal" "render-dom-portal" "error-boundary" "render-dom-error-boundary" "scope" ">=" "keyword" "keyword-name" "value" "scope-push!" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "scope-pop!" "provide" "cyst" "key" "str" "next-cyst-id" "get" "*memo-cache*" "host-get" "isConnected" "dom-create-element" "div" "dom-set-attr" "data-sx-cyst" "with-island-scope" {:upvalue-count 1 :arity 1 :constants ("append!") :bytecode (18 0 16 0 52 0 0 2 50)} {:upvalue-count 3 :arity 0 :constants ("create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)}) :bytecode (20 0 0 48 0 17 0 51 2 0 1 0 0 0 0 1 18 2 52 1 0 2 5 16 0 50)} "dom-set-data" "sx-disposers" "dict-set!") :bytecode (16 0 1 1 0 52 0 0 2 33 224 0 20 2 0 48 0 33 124 0 20 3 0 1 4 0 48 1 17 4 52 5 0 0 17 5 2 17 6 20 6 0 51 7 0 1 1 1 2 1 3 1 4 1 5 1 6 48 1 5 16 6 52 8 0 1 33 5 0 16 6 32 67 0 20 9 0 48 0 17 7 20 10 0 16 7 16 4 48 2 5 16 6 33 41 0 20 11 0 16 6 48 1 33 10 0 20 12 0 16 6 48 1 32 6 0 16 6 52 5 0 1 17 5 5 20 10 0 16 7 16 6 48 2 32 1 0 2 5 16 7 32 89 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 4 33 21 0 20 17 0 16 1 1 18 0 52 15 0 2 16 2 16 3 49 3 32 42 0 16 1 52 20 0 1 1 21 0 52 19 0 2 33 21 0 20 17 0 16 1 1 21 0 52 15 0 2 16 2 16 3 49 3 32 5 0 20 9 0 49 0 32 175 7 16 0 1 22 0 52 0 0 2 33 178 0 20 2 0 48 0 33 95 0 20 3 0 1 23 0 48 1 17 4 52 5 0 0 17 5 2 17 6 20 6 0 51 24 0 1 4 1 5 1 1 1 2 1 3 1 6 48 1 5 16 6 52 8 0 1 33 5 0 16 6 32 38 0 20 9 0 48 0 17 7 20 10 0 16 7 16 4 48 2 5 16 6 33 12 0 20 10 0 16 7 16 6 48 2 32 1 0 2 5 16 7 32 72 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 52 25 0 1 33 8 0 20 9 0 49 0 32 38 0 20 9 0 48 0 17 4 51 27 0 1 4 1 1 1 2 1 3 1 18 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 4 32 241 6 16 0 1 29 0 52 0 0 2 33 145 0 20 2 0 48 0 33 95 0 20 3 0 1 30 0 48 1 17 4 52 5 0 0 17 5 2 17 6 20 6 0 51 31 0 1 1 1 2 1 4 1 5 1 3 1 6 48 1 5 16 6 52 8 0 1 33 5 0 16 6 32 38 0 20 9 0 48 0 17 7 20 10 0 16 7 16 4 48 2 5 16 6 33 12 0 20 10 0 16 7 16 6 48 2 32 1 0 2 5 16 7 32 39 0 20 32 0 16 1 52 33 0 1 16 2 48 2 17 4 16 4 33 14 0 20 17 0 16 4 16 2 16 3 49 3 32 5 0 20 9 0 49 0 32 84 6 16 0 1 34 0 52 0 0 2 33 24 0 20 17 0 16 1 16 2 52 14 0 2 52 13 0 1 16 2 16 3 49 3 32 48 6 16 0 1 35 0 52 0 0 2 6 34 10 0 5 16 0 1 36 0 52 0 0 2 33 96 0 20 37 0 16 1 1 16 0 52 15 0 2 16 2 48 2 17 4 16 1 52 20 0 1 1 21 0 52 0 0 2 33 21 0 20 17 0 16 1 1 18 0 52 15 0 2 16 4 16 3 49 3 32 38 0 20 9 0 48 0 17 5 51 38 0 1 1 1 4 1 3 1 5 1 18 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 5 32 182 5 16 0 1 39 0 52 0 0 2 33 108 0 16 1 1 16 0 52 15 0 2 17 4 16 1 1 18 0 52 40 0 2 17 5 16 2 52 41 0 1 17 6 51 42 0 1 6 16 4 52 26 0 2 5 51 43 0 1 6 16 4 52 26 0 2 5 16 5 52 20 0 1 1 16 0 52 19 0 2 33 18 0 51 44 0 1 6 16 5 52 45 0 1 52 26 0 2 32 1 0 2 5 20 17 0 16 5 52 46 0 1 16 6 16 3 49 3 32 62 5 16 0 1 47 0 52 0 0 2 6 34 10 0 5 16 0 1 48 0 52 0 0 2 33 78 0 16 1 52 20 0 1 1 18 0 52 0 0 2 33 21 0 20 17 0 16 1 1 16 0 52 15 0 2 16 2 16 3 49 3 32 38 0 20 9 0 48 0 17 4 51 38 0 1 1 1 2 1 3 1 4 1 16 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 4 32 214 4 20 49 0 16 0 48 1 33 21 0 16 1 16 2 52 14 0 2 52 13 0 1 5 20 9 0 49 0 32 183 4 16 0 1 50 0 52 0 0 2 33 21 1 16 1 1 18 0 52 15 0 2 17 4 20 2 0 48 0 6 33 76 0 5 16 4 52 51 0 1 1 5 0 52 0 0 2 6 33 58 0 5 16 4 52 20 0 1 1 16 0 52 19 0 2 6 33 40 0 5 16 4 52 52 0 1 52 51 0 1 1 53 0 52 0 0 2 6 33 18 0 5 16 4 52 52 0 1 52 54 0 1 1 55 0 52 0 0 2 33 106 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 16 4 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 6 20 56 0 16 6 48 1 33 16 0 20 57 0 16 5 16 6 16 2 16 3 49 4 32 35 0 16 6 52 55 0 1 17 7 20 9 0 48 0 17 8 51 58 0 1 5 1 2 1 3 1 8 16 7 52 26 0 2 5 16 8 32 69 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 6 20 9 0 48 0 17 7 51 58 0 1 5 1 2 1 3 1 7 16 6 52 26 0 2 5 16 7 32 150 3 16 0 1 59 0 52 0 0 2 33 72 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 20 9 0 48 0 17 6 51 61 0 1 4 1 2 1 3 1 6 16 5 52 60 0 2 5 16 6 32 66 3 16 0 1 62 0 52 0 0 2 33 24 0 20 17 0 16 1 16 2 52 14 0 2 52 13 0 1 16 2 16 3 49 3 32 30 3 16 0 1 63 0 52 0 0 2 33 18 0 20 64 0 16 1 52 33 0 1 16 2 16 3 49 3 32 0 3 16 0 1 65 0 52 0 0 2 33 18 0 20 66 0 16 1 52 33 0 1 16 2 16 3 49 3 32 226 2 16 0 1 26 0 52 0 0 2 33 72 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 20 9 0 48 0 17 6 51 58 0 1 4 1 2 1 3 1 6 16 5 52 26 0 2 5 16 6 32 142 2 16 0 1 67 0 52 0 0 2 33 183 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 40 0 2 17 5 2 17 6 2 17 7 20 9 0 48 0 17 8 16 5 52 20 0 1 1 18 0 52 68 0 2 6 33 40 0 5 16 5 52 52 0 1 52 51 0 1 1 69 0 52 0 0 2 6 33 18 0 5 16 5 52 52 0 1 52 70 0 1 1 71 0 52 0 0 2 33 36 0 16 5 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 6 5 16 5 1 18 0 52 40 0 2 17 7 32 4 0 16 5 17 7 5 16 4 16 6 52 72 0 2 5 51 73 0 1 8 1 2 1 3 16 7 52 26 0 2 5 16 4 52 74 0 1 5 16 8 32 203 1 16 0 1 75 0 52 0 0 2 33 99 0 16 1 1 16 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 4 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 17 5 20 9 0 48 0 17 6 16 4 16 5 52 72 0 2 5 51 27 0 1 6 1 1 1 2 1 3 1 21 0 16 1 52 20 0 1 52 28 0 2 52 26 0 2 5 16 4 52 74 0 1 5 16 6 32 92 1 16 0 1 76 0 52 0 0 2 33 59 1 16 1 52 20 0 1 1 18 0 52 19 0 2 6 33 46 0 5 16 1 1 16 0 52 15 0 2 52 51 0 1 1 69 0 52 0 0 2 6 33 21 0 5 16 1 1 16 0 52 15 0 2 52 70 0 1 1 77 0 52 0 0 2 33 26 0 16 1 1 18 0 52 15 0 2 16 2 52 14 0 2 52 13 0 1 52 78 0 1 32 5 0 20 79 0 48 0 17 4 20 81 0 16 4 52 80 0 2 17 5 16 5 6 33 11 0 5 20 82 0 16 5 1 83 0 48 2 33 5 0 16 5 32 177 0 20 84 0 1 85 0 2 48 2 17 6 52 5 0 0 17 7 16 1 52 20 0 1 1 18 0 52 19 0 2 6 33 46 0 5 16 1 1 16 0 52 15 0 2 52 51 0 1 1 69 0 52 0 0 2 6 33 21 0 5 16 1 1 16 0 52 15 0 2 52 70 0 1 1 77 0 52 0 0 2 33 12 0 16 1 1 21 0 52 40 0 2 32 9 0 16 1 1 16 0 52 40 0 2 17 8 20 86 0 16 6 1 87 0 16 4 48 3 5 20 88 0 51 89 0 1 7 51 90 0 1 2 1 3 1 8 48 2 17 9 20 10 0 16 6 16 9 48 2 5 20 91 0 16 6 1 92 0 16 7 48 3 5 20 81 0 16 4 16 6 52 93 0 3 5 16 6 32 21 0 20 17 0 16 1 16 2 52 14 0 2 52 13 0 1 16 2 16 3 49 3 50)} "render-lambda-dom" {:upvalue-count 0 :arity 4 :constants ("env-merge" "lambda-closure" "for-each-indexed" {:upvalue-count 2 :arity 2 :constants ("env-bind!" "nth") :bytecode (18 0 16 1 18 1 16 0 52 1 0 2 52 0 0 3 50)} "lambda-params" "render-to-dom" "lambda-body") :bytecode (16 0 52 1 0 1 16 2 52 0 0 2 17 4 51 3 0 1 4 1 1 16 0 52 4 0 1 52 2 0 2 5 20 5 0 16 0 52 6 0 1 16 4 16 3 49 3 50)} "render-dom-island" {:upvalue-count 0 :arity 4 :constants ("dict" "list" "reduce" {:upvalue-count 4 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "trampoline" "eval-expr" "nth" "dict-set!" "keyword-name" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 150 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 75 0 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 12 0 2 18 1 52 11 0 2 52 10 0 1 17 3 18 2 16 1 52 14 0 1 16 3 52 13 0 3 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 3 16 1 52 15 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "i" 0 "skip" "env-merge" "component-closure" "component-name" "for-each" {:upvalue-count 2 :arity 1 :constants ("env-bind!" "dict-has?" "dict-get") :bytecode (18 0 16 0 18 1 16 0 52 1 0 2 33 11 0 18 1 16 0 52 2 0 2 32 1 0 2 52 0 0 3 50)} "component-params" "component-has-children?" "create-fragment" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "env-bind!" "children" "dom-create-element" "span" "dom-set-attr" "data-sx-island" "not" "empty-dict?" "data-sx-state" "sx-serialize" "mark-processed!" "island-hydrated" "with-island-scope" {:upvalue-count 1 :arity 1 :constants ("append!") :bytecode (18 0 16 0 52 0 0 2 50)} {:upvalue-count 3 :arity 0 :constants ("render-to-dom" "component-body") :bytecode (20 0 0 18 0 52 1 0 1 18 1 18 2 49 3 50)} "dom-append" "dom-set-data" "sx-disposers") :bytecode (52 0 0 0 17 4 52 1 0 0 17 5 51 3 0 1 1 1 2 1 4 1 5 1 4 0 1 5 0 1 6 0 4 52 0 0 4 16 1 52 2 0 3 5 16 0 52 8 0 1 16 2 52 7 0 2 17 6 16 0 52 9 0 1 17 7 51 11 0 1 6 1 4 16 0 52 12 0 1 52 10 0 2 5 16 0 52 13 0 1 33 37 0 20 14 0 48 0 17 8 51 15 0 1 8 1 2 1 3 16 5 52 10 0 2 5 16 6 1 17 0 16 8 52 16 0 3 32 1 0 2 5 20 18 0 1 19 0 2 48 2 17 8 52 1 0 0 17 9 20 20 0 16 8 1 21 0 16 7 48 3 5 16 4 52 23 0 1 52 22 0 1 33 19 0 20 20 0 16 8 1 24 0 16 4 52 25 0 1 48 3 32 1 0 2 5 20 26 0 16 8 1 27 0 48 2 5 20 28 0 51 29 0 1 9 51 30 0 1 0 1 6 1 3 48 2 17 10 20 31 0 16 8 16 10 48 2 5 20 32 0 16 8 1 33 0 16 9 48 3 5 16 8 50)} "render-dom-lake" {:upvalue-count 0 :arity 3 :constants ("div" "list" "reduce" {:upvalue-count 5 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "trampoline" "eval-expr" "nth" "id" "tag" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 183 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 108 0 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 13 0 2 18 1 52 12 0 2 52 11 0 1 17 4 16 3 1 14 0 52 5 0 2 33 7 0 16 4 19 2 32 20 0 16 3 1 15 0 52 5 0 2 33 7 0 16 4 19 3 32 1 0 2 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 4 16 1 52 16 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "dict" "i" 0 "skip" "dom-create-element" "dom-set-attr" "data-sx-lake" "" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)}) :bytecode (2 17 3 1 0 0 17 4 52 1 0 0 17 5 51 3 0 1 0 1 1 1 3 1 4 1 5 1 5 0 1 6 0 1 7 0 4 52 4 0 4 16 0 52 2 0 3 5 20 8 0 16 4 2 48 2 17 6 20 9 0 16 6 1 10 0 16 3 6 34 4 0 5 1 11 0 48 3 5 51 13 0 1 6 1 1 1 2 16 5 52 12 0 2 5 16 6 50)} "render-dom-marsh" {:upvalue-count 0 :arity 3 :constants ("div" "list" "reduce" {:upvalue-count 6 :arity 2 :constants ("get" "skip" "assoc" "i" "inc" "=" "type-of" "keyword" "<" "len" "keyword-name" "trampoline" "eval-expr" "nth" "id" "tag" "transform" "append!") :bytecode (16 0 1 1 0 52 0 0 2 17 2 16 2 33 29 0 16 0 1 1 0 4 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 202 0 16 1 52 6 0 1 1 7 0 52 5 0 2 6 33 24 0 5 16 0 1 3 0 52 0 0 2 52 4 0 1 18 0 52 9 0 1 52 8 0 2 33 127 0 16 1 52 10 0 1 17 3 18 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 13 0 2 18 1 52 12 0 2 52 11 0 1 17 4 16 3 1 14 0 52 5 0 2 33 7 0 16 4 19 2 32 39 0 16 3 1 15 0 52 5 0 2 33 7 0 16 4 19 3 32 20 0 16 3 1 16 0 52 5 0 2 33 7 0 16 4 19 4 32 1 0 2 5 16 0 1 1 0 3 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 5 32 31 0 18 5 16 1 52 17 0 2 5 16 0 1 3 0 16 0 1 3 0 52 0 0 2 52 4 0 1 52 2 0 3 50)} "dict" "i" 0 "skip" "dom-create-element" "dom-set-attr" "data-sx-marsh" "" "dom-set-data" "sx-marsh-transform" "sx-marsh-env" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)}) :bytecode (2 17 3 1 0 0 17 4 2 17 5 52 1 0 0 17 6 51 3 0 1 0 1 1 1 3 1 4 1 5 1 6 1 5 0 1 6 0 1 7 0 4 52 4 0 4 16 0 52 2 0 3 5 20 8 0 16 4 2 48 2 17 7 20 9 0 16 7 1 10 0 16 3 6 34 4 0 5 1 11 0 48 3 5 16 5 33 15 0 20 12 0 16 7 1 13 0 16 5 48 3 32 1 0 2 5 20 12 0 16 7 1 14 0 16 1 48 3 5 51 16 0 1 7 1 1 1 2 16 6 52 15 0 2 5 16 7 50)} "reactive-text" {:upvalue-count 0 :arity 1 :constants ("create-text-node" "str" "deref" "effect" {:upvalue-count 2 :arity 0 :constants ("dom-set-text-content" "str" "deref") :bytecode (20 0 0 18 0 18 1 52 2 0 1 52 1 0 1 49 2 50)}) :bytecode (20 0 0 16 0 52 2 0 1 52 1 0 1 48 1 17 1 20 3 0 51 4 0 1 1 1 0 48 1 5 16 1 50)} "reactive-attr" {:upvalue-count 0 :arity 3 :constants ("dom-get-attr" "data-sx-reactive-attrs" "" "empty?" "str" "," "dom-set-attr" "effect" {:upvalue-count 3 :arity 0 :constants ("signal?" "deref" "nil?" "=" "dom-remove-attr" "dom-set-attr" "" "str") :bytecode (18 0 48 0 17 0 20 0 0 16 0 48 1 33 9 0 16 0 52 1 0 1 32 2 0 16 0 17 1 16 1 52 2 0 1 6 34 8 0 5 16 1 4 52 3 0 2 33 12 0 20 4 0 18 1 18 2 49 2 32 40 0 16 1 3 52 3 0 2 33 15 0 20 5 0 18 1 18 2 1 6 0 49 3 32 15 0 20 5 0 18 1 18 2 16 1 52 7 0 1 49 3 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 6 34 4 0 5 1 2 0 17 3 16 3 52 3 0 1 33 5 0 16 1 32 11 0 16 3 1 5 0 16 1 52 4 0 3 17 4 20 6 0 16 0 1 1 0 16 4 48 3 5 20 7 0 51 8 0 1 2 1 0 1 1 49 1 50)} "reactive-spread" {:upvalue-count 0 :arity 2 :constants ("list" "dom-get-attr" "data-sx-reactive-attrs" "" "dom-set-attr" "empty?" "_spread" "str" ",_spread" "effect" {:upvalue-count 4 :arity 0 :constants ("not" "empty?" "dom-get-attr" "class" "" "filter" {:upvalue-count 0 :arity 1 :constants ("not" "=" "") :bytecode (16 0 1 2 0 52 1 0 2 52 0 0 1 50)} "split" " " {:upvalue-count 1 :arity 1 :constants ("not" "some" {:upvalue-count 1 :arity 1 :constants ("=") :bytecode (16 0 18 0 52 0 0 2 50)}) :bytecode (51 2 0 1 0 18 0 52 1 0 2 52 0 0 1 50)} "dom-remove-attr" "dom-set-attr" "join" "for-each" {:upvalue-count 1 :arity 1 :constants ("dom-remove-attr") :bytecode (20 0 0 18 0 16 0 49 2 50)} "spread?" "spread-attrs" "dict-get" {:upvalue-count 0 :arity 1 :constants ("not" "=" "class") :bytecode (16 0 1 2 0 52 1 0 2 52 0 0 1 50)} "keys" "=" "str" {:upvalue-count 2 :arity 1 :constants ("dom-set-attr" "str" "dict-get") :bytecode (20 0 0 18 0 16 0 18 1 16 0 52 2 0 2 52 1 0 1 49 3 50)} "run-post-render-hooks" "list") :bytecode (18 0 52 1 0 1 52 0 0 1 33 95 0 20 2 0 18 1 1 3 0 48 2 6 34 4 0 5 1 4 0 17 0 51 6 0 16 0 1 8 0 52 7 0 2 52 5 0 2 17 1 51 9 0 0 0 16 1 52 5 0 2 17 2 16 2 52 1 0 1 33 13 0 20 10 0 18 1 1 3 0 48 2 32 19 0 20 11 0 18 1 1 3 0 1 8 0 16 2 52 12 0 2 48 3 32 1 0 2 5 51 14 0 0 1 18 2 52 13 0 2 5 18 3 48 0 17 0 16 0 52 15 0 1 33 179 0 16 0 52 16 0 1 17 1 16 1 1 3 0 52 17 0 2 6 34 4 0 5 1 4 0 17 2 51 6 0 16 2 1 8 0 52 7 0 2 52 5 0 2 17 3 51 18 0 16 1 52 19 0 1 52 5 0 2 17 4 16 3 19 0 5 16 4 19 2 5 16 3 52 1 0 1 52 0 0 1 33 72 0 20 2 0 18 1 1 3 0 48 2 6 34 4 0 5 1 4 0 17 5 20 11 0 18 1 1 3 0 16 5 6 33 14 0 5 16 5 1 4 0 52 20 0 2 52 0 0 1 33 14 0 16 5 1 8 0 16 2 52 21 0 3 32 2 0 16 2 48 3 32 1 0 2 5 51 22 0 0 1 1 1 16 4 52 13 0 2 5 20 23 0 49 0 32 13 0 52 24 0 0 19 0 5 52 24 0 0 19 2 50)}) :bytecode (52 0 0 0 17 2 52 0 0 0 17 3 20 1 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 17 4 20 4 0 16 0 1 2 0 16 4 52 5 0 1 33 6 0 1 6 0 32 9 0 16 4 1 8 0 52 7 0 2 48 3 5 20 9 0 51 10 0 1 2 1 0 1 3 1 1 49 1 50)} "reactive-fragment" {:upvalue-count 0 :arity 4 :constants ("create-comment" "island-fragment" "list" "effect" {:upvalue-count 4 :arity 0 :constants ("for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)} "list" "dom-child-nodes" "dom-insert-after") :bytecode (51 1 0 18 0 52 0 0 2 5 52 2 0 0 19 0 5 18 1 48 0 33 28 0 18 2 48 0 17 0 20 3 0 16 0 48 1 19 0 5 20 4 0 18 3 16 0 49 2 32 1 0 2 50)}) :bytecode (20 0 0 1 1 0 48 1 17 4 52 2 0 0 17 5 20 3 0 51 4 0 1 5 1 0 1 1 1 4 48 1 5 16 4 50)} "render-list-item" {:upvalue-count 0 :arity 4 :constants ("lambda?" "render-lambda-dom" "list" "render-to-dom" "apply") :bytecode (16 0 52 0 0 1 33 20 0 20 1 0 16 0 16 1 52 2 0 1 16 2 16 3 49 4 32 21 0 20 3 0 16 0 16 1 52 2 0 1 52 4 0 2 16 2 16 3 49 3 50)} "extract-key" {:upvalue-count 0 :arity 2 :constants ("dom-get-attr" "key" "dom-remove-attr" "dom-get-data" "str" "__idx_") :bytecode (20 0 0 16 0 1 1 0 48 2 17 2 16 2 33 16 0 20 2 0 16 0 1 1 0 48 2 5 16 2 32 35 0 20 3 0 16 0 1 1 0 48 2 17 3 16 3 33 9 0 16 3 52 4 0 1 32 9 0 1 5 0 16 1 52 4 0 2 50)} "reactive-list" {:upvalue-count 0 :arity 4 :constants ("create-fragment" "create-comment" "island-list" "dict" "list" "dom-append" "effect" {:upvalue-count 8 :arity 0 :constants ("deref" "dom-parent" "dict" "list" "for-each-indexed" {:upvalue-count 7 :arity 2 :constants ("render-list-item" "extract-key" "not" "starts-with?" "__idx_" "dict-has?" "dict-set!" "dict-get" "append!") :bytecode (20 0 0 18 0 16 1 18 1 18 2 48 4 17 2 20 1 0 16 2 16 0 48 2 17 3 18 3 52 2 0 1 6 33 14 0 5 16 3 1 4 0 52 3 0 2 52 2 0 1 33 6 0 3 19 3 32 1 0 2 5 18 4 16 3 52 5 0 2 33 19 0 18 5 16 3 18 4 16 3 52 7 0 2 52 6 0 3 32 10 0 18 5 16 3 16 2 52 6 0 3 5 18 6 16 3 52 8 0 2 50)} "not" "dom-remove-children-after" "create-fragment" "for-each" {:upvalue-count 2 :arity 1 :constants ("dom-append" "dict-get") :bytecode (20 0 0 18 0 18 1 16 0 52 1 0 2 49 2 50)} "dom-insert-after" {:upvalue-count 2 :arity 1 :constants ("not" "dict-has?" "dom-remove" "dict-get") :bytecode (18 0 16 0 52 1 0 2 52 0 0 1 33 16 0 20 2 0 18 1 16 0 52 3 0 2 49 1 32 1 0 2 50)} {:upvalue-count 2 :arity 1 :constants ("dict-get" "dom-next-sibling" "not" "identical?" "dom-insert-after") :bytecode (18 0 16 0 52 0 0 2 17 1 20 1 0 18 1 48 1 17 2 16 1 16 2 52 3 0 2 52 2 0 1 33 12 0 20 4 0 18 1 16 1 48 2 32 1 0 2 5 16 1 19 1 50)} {:upvalue-count 6 :arity 2 :constants ("render-list-item" "extract-key" "dict-set!" "append!" "dom-append") :bytecode (20 0 0 18 0 16 1 18 1 18 2 48 4 17 2 20 1 0 16 2 16 0 48 2 17 3 18 3 16 3 16 2 52 2 0 3 5 18 4 16 3 52 3 0 2 5 20 4 0 18 5 16 2 49 2 50)}) :bytecode (18 0 52 0 0 1 17 0 20 1 0 18 1 48 1 33 133 0 52 2 0 0 17 1 52 3 0 0 17 2 4 17 3 51 5 0 0 2 0 3 0 4 1 3 0 5 1 1 1 2 16 0 52 4 0 2 5 16 3 52 6 0 1 33 41 0 20 7 0 18 1 48 1 5 20 8 0 48 0 17 4 51 10 0 1 4 1 1 16 2 52 9 0 2 5 20 11 0 18 1 16 4 48 2 32 31 0 51 12 0 1 1 0 5 18 6 52 9 0 2 5 18 1 17 4 51 13 0 1 1 1 4 16 2 52 9 0 2 5 16 1 19 5 5 16 2 19 6 32 21 0 51 14 0 0 2 0 3 0 4 0 5 0 6 0 7 16 0 52 4 0 2 50)}) :bytecode (20 0 0 48 0 17 4 20 1 0 1 2 0 48 1 17 5 52 3 0 0 17 6 52 4 0 0 17 7 20 5 0 16 4 16 5 48 2 5 20 6 0 51 7 0 1 1 1 5 1 0 1 2 1 3 1 6 1 7 1 4 48 1 5 16 4 50)} "bind-input" {:upvalue-count 0 :arity 2 :constants ("lower" "dom-get-attr" "type" "" "=" "checkbox" "radio" "dom-set-prop" "checked" "deref" "value" "str" "effect" {:upvalue-count 3 :arity 0 :constants ("dom-set-prop" "checked" "deref" "str" "!=" "dom-get-prop" "value") :bytecode (18 0 33 19 0 20 0 0 18 1 1 1 0 18 2 52 2 0 1 49 3 32 47 0 18 2 52 2 0 1 52 3 0 1 17 0 20 5 0 18 1 1 6 0 48 2 16 0 52 4 0 2 33 15 0 20 0 0 18 1 1 6 0 16 0 49 3 32 1 0 2 50)} "dom-on" "change" "input" {:upvalue-count 3 :arity 1 :constants ("reset!" "dom-get-prop" "checked" "value") :bytecode (18 0 33 20 0 20 0 0 18 1 20 1 0 18 2 1 2 0 48 2 49 2 32 17 0 20 0 0 18 1 20 1 0 18 2 1 3 0 48 2 49 2 50)}) :bytecode (20 1 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 52 0 0 1 17 2 16 2 1 5 0 52 4 0 2 6 34 10 0 5 16 2 1 6 0 52 4 0 2 17 3 16 3 33 19 0 20 7 0 16 0 1 8 0 16 1 52 9 0 1 48 3 32 20 0 20 7 0 16 0 1 10 0 16 1 52 9 0 1 52 11 0 1 48 3 5 20 12 0 51 13 0 1 3 1 0 1 1 48 1 5 20 14 0 16 0 16 3 33 6 0 1 15 0 32 3 0 1 16 0 51 17 0 1 3 1 1 1 0 49 3 50)} "*use-cek-reactive*" "enable-cek-reactive!" {:upvalue-count 0 :arity 0 :constants ("*use-cek-reactive*") :bytecode (3 21 0 0 50)} "cek-reactive-text" {:upvalue-count 0 :arity 2 :constants ("create-text-node" "" {:upvalue-count 1 :arity 1 :constants ("dom-set-text-content" "str") :bytecode (20 0 0 18 0 16 0 52 1 0 1 49 2 50)} "cek-run" "make-cek-state" "list" "make-reactive-reset-frame" "dom-set-text-content" "str") :bytecode (20 0 0 1 1 0 48 1 17 2 51 2 0 1 2 17 3 20 3 0 20 4 0 16 0 16 1 20 6 0 16 1 16 3 3 48 3 52 5 0 1 48 3 48 1 17 4 20 7 0 16 2 16 4 52 8 0 1 48 2 5 16 2 50)} "cek-reactive-attr" {:upvalue-count 0 :arity 4 :constants ({:upvalue-count 2 :arity 1 :constants ("nil?" "=" "dom-remove-attr" "dom-set-attr" "" "str") :bytecode (16 0 52 0 0 1 6 34 8 0 5 16 0 4 52 1 0 2 33 12 0 20 2 0 18 0 18 1 49 2 32 40 0 16 0 3 52 1 0 2 33 15 0 20 3 0 18 0 18 1 1 4 0 49 3 32 15 0 20 3 0 18 0 18 1 16 0 52 5 0 1 49 3 50)} "dom-get-attr" "data-sx-reactive-attrs" "" "empty?" "str" "," "dom-set-attr" "cek-run" "make-cek-state" "list" "make-reactive-reset-frame" "cek-call") :bytecode (51 0 0 1 0 1 1 17 4 20 1 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 17 5 16 5 52 4 0 1 33 5 0 16 1 32 11 0 16 5 1 6 0 16 1 52 5 0 3 17 6 20 7 0 16 0 1 2 0 16 6 48 3 5 20 8 0 20 9 0 16 2 16 3 20 11 0 16 3 16 4 3 48 3 52 10 0 1 48 3 48 1 17 5 16 4 16 5 52 10 0 1 52 12 0 2 50)} "render-dom-portal" {:upvalue-count 0 :arity 3 :constants ("trampoline" "eval-expr" "first" "dom-query" "dom-ensure-element" "not" "create-comment" "str" "portal: " " (not found)" "create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "rest" "dom-child-nodes" "dom-append" "register-in-scope" {:upvalue-count 1 :arity 0 :constants ("for-each" {:upvalue-count 0 :arity 1 :constants ("dom-remove") :bytecode (20 0 0 16 0 49 1 50)}) :bytecode (51 1 0 18 0 52 0 0 2 50)}) :bytecode (16 0 52 2 0 1 16 1 52 1 0 2 52 0 0 1 17 3 20 3 0 16 3 48 1 6 34 8 0 5 20 4 0 16 3 48 1 17 4 16 4 52 5 0 1 33 20 0 20 6 0 1 8 0 16 3 1 9 0 52 7 0 3 49 1 32 75 0 20 6 0 1 8 0 16 3 52 7 0 2 48 1 17 5 20 10 0 48 0 17 6 51 12 0 1 6 1 1 1 2 16 0 52 13 0 1 52 11 0 2 5 20 14 0 16 6 48 1 17 7 20 15 0 16 4 16 6 48 2 5 20 16 0 51 17 0 1 7 48 1 5 16 5 50)} "render-dom-error-boundary" {:upvalue-count 0 :arity 3 :constants (">" "len" 1 "first" "rest" "dom-create-element" "div" "signal" 0 "dom-set-attr" "data-sx-boundary" "true" "effect" {:upvalue-count 6 :arity 0 :constants ("deref" "dom-set-prop" "innerHTML" "" "scope-push!" "sx-island-scope" "try-catch" {:upvalue-count 4 :arity 0 :constants ("create-fragment" "for-each" {:upvalue-count 3 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 18 2 48 3 49 2 50)} "dom-append" "scope-pop!" "sx-island-scope") :bytecode (20 0 0 48 0 17 0 51 2 0 1 0 0 0 0 1 18 2 52 1 0 2 5 20 3 0 18 3 16 0 48 2 5 1 5 0 52 4 0 1 50)} {:upvalue-count 5 :arity 1 :constants ("scope-pop!" "sx-island-scope" "trampoline" "eval-expr" {:upvalue-count 1 :arity 0 :constants ("swap!" {:upvalue-count 0 :arity 1 :constants ("+" 1) :bytecode (16 0 1 1 0 52 0 0 2 50)}) :bytecode (20 0 0 18 0 51 1 0 49 2 50)} "nil?" "dom-create-element" "div" "dom-set-attr" "class" "sx-render-error" "style" "color:red;font-size:0.875rem;padding:0.5rem;border:1px solid red;border-radius:0.25rem;margin:0.5rem 0;" "dom-set-text-content" "str" "Render error: " "lambda?" "render-lambda-dom" "list" "render-to-dom" "apply" "dom-append") :bytecode (1 1 0 52 0 0 1 5 18 0 18 1 52 3 0 2 52 2 0 1 17 1 51 4 0 0 2 17 2 16 1 52 5 0 1 33 61 0 20 6 0 1 7 0 2 48 2 17 3 20 8 0 16 3 1 9 0 1 10 0 48 3 5 20 8 0 16 3 1 11 0 1 12 0 48 3 5 20 13 0 16 3 1 15 0 16 0 52 14 0 2 48 2 5 16 3 32 54 0 16 1 52 16 0 1 33 22 0 20 17 0 16 1 16 0 16 2 52 18 0 2 18 1 18 3 48 4 32 23 0 20 19 0 16 1 16 0 16 2 52 18 0 2 52 20 0 2 18 1 18 3 48 3 17 3 20 21 0 18 4 16 3 49 2 50)}) :bytecode (18 0 52 0 0 1 5 20 1 0 18 1 1 2 0 1 3 0 48 3 5 1 5 0 2 52 4 0 2 5 51 7 0 0 2 0 3 0 4 0 1 51 8 0 0 5 0 2 0 0 0 3 0 1 52 6 0 2 50)}) :bytecode (16 0 52 1 0 1 1 2 0 52 0 0 2 33 9 0 16 0 52 3 0 1 32 1 0 2 17 3 16 0 52 1 0 1 1 2 0 52 0 0 2 33 9 0 16 0 52 4 0 1 32 2 0 16 0 17 4 20 5 0 1 6 0 2 48 2 17 5 20 7 0 1 8 0 48 1 17 6 20 9 0 16 5 1 10 0 1 11 0 48 3 5 20 12 0 51 13 0 1 6 1 5 1 1 1 2 1 4 1 3 48 1 5 16 5 50)} {:library (web adapter-dom) :op "import"}) :bytecode (1 0 0 112 5 1 1 0 112 5 1 3 0 128 2 0 5 1 5 0 128 4 0 5 51 7 0 128 6 0 5 52 9 0 0 128 8 0 5 1 11 0 128 10 0 5 51 13 0 128 12 0 5 51 15 0 128 14 0 5 51 17 0 128 16 0 5 51 19 0 128 18 0 5 51 21 0 128 20 0 5 51 23 0 128 22 0 5 51 25 0 128 24 0 5 51 27 0 128 26 0 5 51 29 0 128 28 0 5 51 31 0 128 30 0 5 1 34 0 1 35 0 1 36 0 1 37 0 1 38 0 1 39 0 1 40 0 1 41 0 1 42 0 1 43 0 1 44 0 1 45 0 1 46 0 1 47 0 1 48 0 1 49 0 1 50 0 1 51 0 1 52 0 1 53 0 1 54 0 1 55 0 1 56 0 52 33 0 23 128 32 0 5 51 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 5 51 72 0 128 71 0 5 51 74 0 128 73 0 5 51 76 0 128 75 0 5 51 78 0 128 77 0 5 51 80 0 128 79 0 5 51 82 0 128 81 0 5 51 84 0 128 83 0 5 3 128 85 0 5 51 87 0 128 86 0 5 51 89 0 128 88 0 5 51 91 0 128 90 0 5 51 93 0 128 92 0 5 51 95 0 128 94 0 5 1 96 0 112 50))) diff --git a/shared/static/wasm/sx/boot.sx b/shared/static/wasm/sx/boot.sx index f5af1ad0..e3f9a716 100644 --- a/shared/static/wasm/sx/boot.sx +++ b/shared/static/wasm/sx/boot.sx @@ -55,8 +55,6 @@ (dom-append-to-head el))))) els)))) -(define *hydrating* false) - (define sx-mount :effects (mutation io) @@ -331,14 +329,9 @@ p (if (dict-has? kwargs p) (dict-get kwargs p) nil))) (component-params comp)) - (do - (hydrate-start! el) - (log-info " hydrate-start done") - (with-island-scope - (fn (disposable) (append! disposers disposable)) - (fn () (render-to-dom (component-body comp) local nil))) - (log-info " render-to-dom done") - (hydrate-stop!) + (let + ((body-dom (cek-try (fn () (with-island-scope (fn (disposable) (append! disposers disposable)) (fn () (render-to-dom (component-body comp) local nil)))) (fn (err) (log-warn (str "hydrate-island FAILED: " comp-name " — " err)) (let ((error-el (dom-create-element "div" nil))) (dom-set-attr error-el "class" "sx-island-error") (dom-set-attr error-el "style" "padding:8px;margin:4px 0;border:1px solid #ef4444;border-radius:4px;background:#fef2f2;color:#b91c1c;font-family:monospace;font-size:12px;white-space:pre-wrap") (dom-set-text-content error-el (str "Island error: " comp-name "\n" err)) error-el))))) + (host-call el "replaceChildren" body-dom) (dom-set-data el "sx-disposers" disposers) (set-timeout (fn () (process-elements el)) 0) (log-info diff --git a/shared/static/wasm/sx/boot.sxbc b/shared/static/wasm/sx/boot.sxbc index b21bce8d..7ed812b8 100644 --- a/shared/static/wasm/sx/boot.sxbc +++ b/shared/static/wasm/sx/boot.sxbc @@ -1,3 +1,3 @@ -(sxbc 1 "bb0017332d28db85" +(sxbc 1 "260cb82964e8fccd" (code - :constants ({:library (sx dom) :op "import"} {:library (sx bytecode) :op "import"} {:library (sx browser) :op "import"} {:library (web boot-helpers) :op "import"} {:library (web adapter-dom) :op "import"} {:library (sx signals) :op "import"} {:library (sx signals-web) :op "import"} {:library (web router) :op "import"} {:library (web page-helpers) :op "import"} {:library (web orchestration) :op "import"} {:library (sx render) :op "import"} "HEAD_HOIST_SELECTOR" "meta, title, link[rel='canonical'], script[type='application/ld+json']" "hoist-head-elements-full" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "HEAD_HOIST_SELECTOR" "for-each" {:upvalue-count 0 :arity 1 :constants ("lower" "dom-tag-name" "=" "title" "set-document-title" "dom-text-content" "dom-remove-child" "dom-parent" "meta" "dom-get-attr" "name" "property" "remove-head-element" "str" "meta[name=\"" "\"]" "meta[property=\"" "dom-append-to-head" "link" "rel" "canonical" "link[rel=\"canonical\"]") :bytecode (20 1 0 16 0 48 1 52 0 0 1 17 1 16 1 1 3 0 52 2 0 2 33 30 0 20 4 0 20 5 0 16 0 48 1 48 1 5 20 6 0 20 7 0 16 0 48 1 16 0 49 2 32 205 0 16 1 1 8 0 52 2 0 2 33 103 0 20 9 0 16 0 1 10 0 48 2 17 2 20 9 0 16 0 1 11 0 48 2 17 3 16 2 33 20 0 20 12 0 1 14 0 16 2 1 15 0 52 13 0 3 48 1 32 1 0 2 5 16 3 33 20 0 20 12 0 1 16 0 16 3 1 15 0 52 13 0 3 48 1 32 1 0 2 5 20 6 0 20 7 0 16 0 48 1 16 0 48 2 5 20 17 0 16 0 49 1 32 90 0 16 1 1 18 0 52 2 0 2 6 33 18 0 5 20 9 0 16 0 1 19 0 48 2 1 20 0 52 2 0 2 33 34 0 20 12 0 1 21 0 48 1 5 20 6 0 20 7 0 16 0 48 1 16 0 48 2 5 20 17 0 16 0 49 1 32 22 0 20 6 0 20 7 0 16 0 48 1 16 0 48 2 5 20 17 0 16 0 49 1 50)}) :bytecode (20 0 0 16 0 20 1 0 48 2 17 1 51 3 0 16 1 52 2 0 2 50)} "*hydrating*" "sx-mount" {:upvalue-count 0 :arity 3 :constants ("resolve-mount-target" "empty?" "dom-child-list" "sx-render-with-env" "dom-set-text-content" "" "dom-append" "hoist-head-elements-full" "process-elements" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks") :bytecode (20 0 0 16 0 48 1 17 3 16 3 33 90 0 20 2 0 16 3 48 1 52 1 0 1 33 42 0 20 3 0 16 1 16 2 48 2 17 4 20 4 0 16 3 1 5 0 48 2 5 20 6 0 16 3 16 4 48 2 5 20 7 0 16 3 48 1 32 1 0 2 5 20 8 0 16 3 48 1 5 20 9 0 16 3 48 1 5 20 10 0 16 3 48 1 5 20 11 0 49 0 32 1 0 2 50)} "resolve-suspense" {:upvalue-count 0 :arity 2 :constants ("process-sx-scripts" "dom-query" "str" "[data-suspense=\"" "\"]" "parse" "get-render-env" "dom-set-text-content" "" "for-each" {:upvalue-count 2 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 2 48 3 49 2 50)} "process-elements" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks" "dom-dispatch" "sx:resolved" "id" "log-warn" "resolveSuspense: no element for id=") :bytecode (20 0 0 2 48 1 5 20 1 0 1 3 0 16 0 1 4 0 52 2 0 3 48 1 17 2 16 2 33 92 0 16 1 52 5 0 1 17 3 20 6 0 2 48 1 17 4 20 7 0 16 2 1 8 0 48 2 5 51 10 0 1 2 1 4 16 3 52 9 0 2 5 20 11 0 16 2 48 1 5 20 12 0 16 2 48 1 5 20 13 0 16 2 48 1 5 20 14 0 48 0 5 20 15 0 16 2 1 16 0 1 17 0 16 0 65 1 0 49 3 32 14 0 20 18 0 1 19 0 16 0 52 2 0 2 49 1 50)} "sx-hydrate-elements" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "[data-sx]" "for-each" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "hydrated" "mark-processed!" "sx-update-element") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 33 22 0 20 3 0 16 0 1 2 0 48 2 5 20 4 0 16 0 2 49 2 32 1 0 2 50)}) :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 1 2 0 48 2 17 1 51 4 0 16 1 52 3 0 2 50)} "sx-update-element" {:upvalue-count 0 :arity 2 :constants ("resolve-mount-target" "dom-get-attr" "data-sx" "parse-env-attr" "merge-envs" "sx-render-with-env" "dom-set-text-content" "" "dom-append" "store-env-attr") :bytecode (20 0 0 16 0 48 1 17 2 16 2 33 96 0 20 1 0 16 2 1 2 0 48 2 17 3 16 3 33 75 0 20 3 0 16 2 48 1 17 4 20 4 0 16 4 16 1 48 2 17 5 20 5 0 16 3 16 5 48 2 17 6 20 6 0 16 2 1 7 0 48 2 5 20 8 0 16 2 16 6 48 2 5 16 1 33 14 0 20 9 0 16 2 16 4 16 1 49 3 32 1 0 2 32 1 0 2 32 1 0 2 50)} "sx-render-component" {:upvalue-count 0 :arity 3 :constants ("starts-with?" "~" "str" "get-render-env" "env-get" "not" "component?" "error" "Unknown component: " "list" "make-symbol" "for-each" {:upvalue-count 2 :arity 1 :constants ("append!" "make-keyword" "to-kebab" "dict-get") :bytecode (18 0 20 2 0 16 0 48 1 52 1 0 1 52 0 0 2 5 18 0 18 1 16 0 52 3 0 2 52 0 0 2 50)} "keys" "render-to-dom") :bytecode (16 0 1 1 0 52 0 0 2 33 5 0 16 0 32 9 0 1 1 0 16 0 52 2 0 2 17 3 20 3 0 16 2 48 1 17 4 16 4 16 3 52 4 0 2 17 5 16 5 52 6 0 1 52 5 0 1 33 16 0 1 8 0 16 3 52 2 0 2 52 7 0 1 32 40 0 16 3 52 10 0 1 52 9 0 1 17 6 51 12 0 1 6 1 1 16 1 52 13 0 1 52 11 0 2 5 20 14 0 16 6 16 4 2 49 3 50)} "process-sx-scripts" {:upvalue-count 0 :arity 1 :constants ("query-sx-scripts" "for-each" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "script" "mark-processed!" "dom-text-content" "dom-has-attr?" "data-components" "process-component-script" "nil?" "empty?" "trim" "data-init" "sx-parse" "for-each" {:upvalue-count 0 :arity 1 :constants ("cek-eval") :bytecode (20 0 0 16 0 49 1 50)} "data-mount" "dom-get-attr" "dom-query" "sx-mount" "sx-load-components") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 33 173 0 20 3 0 16 0 1 2 0 48 2 5 20 4 0 16 0 48 1 17 1 20 5 0 16 0 1 6 0 48 2 33 12 0 20 7 0 16 0 16 1 49 2 32 125 0 16 1 52 8 0 1 6 34 11 0 5 16 1 52 10 0 1 52 9 0 1 33 4 0 2 32 97 0 20 5 0 16 0 1 11 0 48 2 33 21 0 20 12 0 16 1 48 1 17 2 51 14 0 16 2 52 13 0 2 32 63 0 20 5 0 16 0 1 15 0 48 2 33 43 0 20 16 0 16 0 1 15 0 48 2 17 2 20 17 0 16 2 48 1 17 3 16 3 33 13 0 20 18 0 16 3 16 1 2 49 3 32 1 0 2 32 7 0 20 19 0 16 1 49 1 32 1 0 2 50)}) :bytecode (20 0 0 16 0 48 1 17 1 51 2 0 16 1 52 1 0 2 50)} "process-component-script" {:upvalue-count 0 :arity 2 :constants ("dom-get-attr" "data-hash" "nil?" "not" "empty?" "trim" "sx-load-components" "local-storage-get" "sx-components-hash" "=" "local-storage-set" "sx-components-src" "log-info" "components: downloaded (cookie stale)" "str" "components: cached (" ")" "clear-sx-comp-cookie" "browser-reload" "components: downloaded (" "local-storage-remove" "set-sx-comp-cookie") :bytecode (20 0 0 16 0 1 1 0 48 2 17 2 16 2 52 2 0 1 33 38 0 16 1 6 33 15 0 5 16 1 52 5 0 1 52 4 0 1 52 3 0 1 33 10 0 20 6 0 16 1 49 1 32 1 0 2 32 239 0 16 1 6 33 15 0 5 16 1 52 5 0 1 52 4 0 1 52 3 0 1 17 3 20 7 0 1 8 0 48 1 17 4 16 4 16 2 52 9 0 2 33 103 0 16 3 33 41 0 20 10 0 1 8 0 16 2 48 2 5 20 10 0 1 11 0 16 1 48 2 5 20 6 0 16 1 48 1 5 20 12 0 1 13 0 48 1 32 54 0 20 7 0 1 11 0 48 1 17 5 16 5 33 28 0 20 6 0 16 5 48 1 5 20 12 0 1 15 0 16 2 1 16 0 52 14 0 3 48 1 32 11 0 20 17 0 48 0 5 20 18 0 48 0 32 84 0 16 3 33 50 0 20 10 0 1 8 0 16 2 48 2 5 20 10 0 1 11 0 16 1 48 2 5 20 6 0 16 1 48 1 5 20 12 0 1 19 0 16 2 1 16 0 52 14 0 3 48 1 32 29 0 20 20 0 1 8 0 48 1 5 20 20 0 1 11 0 48 1 5 20 17 0 48 0 5 20 18 0 48 0 5 20 21 0 16 2 49 1 50)} "_page-routes" "list" "process-page-scripts" {:upvalue-count 0 :arity 0 :constants ("query-page-scripts" "log-info" "str" "pages: found " "len" " script tags" "for-each" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "pages" "mark-processed!" "dom-text-content" "log-info" "str" "pages: script text length=" "len" 0 "empty?" "trim" "parse" "pages: parsed " " entries" "for-each" {:upvalue-count 0 :arity 1 :constants ("append!" "_page-routes" "merge" "parsed" "parse-route-pattern" "get" "path") :bytecode (20 1 0 16 0 1 3 0 20 4 0 16 0 1 6 0 52 5 0 2 48 1 65 1 0 52 2 0 2 52 0 0 2 50)} "log-warn" "pages: script tag is empty") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 33 127 0 20 3 0 16 0 1 2 0 48 2 5 20 4 0 16 0 48 1 17 1 20 5 0 1 7 0 16 1 33 9 0 16 1 52 8 0 1 32 3 0 1 9 0 52 6 0 2 48 1 5 16 1 6 33 15 0 5 16 1 52 11 0 1 52 10 0 1 52 0 0 1 33 42 0 16 1 52 12 0 1 17 2 20 5 0 1 13 0 16 2 52 8 0 1 1 14 0 52 6 0 3 48 1 5 51 16 0 16 2 52 15 0 2 32 8 0 20 17 0 1 18 0 49 1 32 1 0 2 50)} "pages: " "_page-routes" " routes loaded") :bytecode (20 0 0 48 0 17 0 20 1 0 1 3 0 16 0 52 4 0 1 1 5 0 52 2 0 3 48 1 5 51 7 0 16 0 52 6 0 2 5 20 1 0 1 8 0 20 9 0 52 4 0 1 1 10 0 52 2 0 3 49 1 50)} "sx-hydrate-islands" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "[data-sx-island]" "log-info" "str" "sx-hydrate-islands: " "len" " island(s) in " "subtree" "document" "for-each" {:upvalue-count 0 :arity 1 :constants ("is-processed?" "island-hydrated" "log-info" "str" " skip (already hydrated): " "dom-get-attr" "data-sx-island" " hydrating: " "mark-processed!" "hydrate-island") :bytecode (20 0 0 16 0 1 1 0 48 2 33 25 0 20 2 0 1 4 0 20 5 0 16 0 1 6 0 48 2 52 3 0 2 49 1 32 41 0 20 2 0 1 7 0 20 5 0 16 0 1 6 0 48 2 52 3 0 2 48 1 5 20 8 0 16 0 1 1 0 48 2 5 20 9 0 16 0 49 1 50)}) :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 1 2 0 48 2 17 1 20 3 0 1 5 0 16 1 52 6 0 1 1 7 0 16 0 33 6 0 1 8 0 32 3 0 1 9 0 52 4 0 4 48 1 5 51 11 0 16 1 52 10 0 2 50)} "hydrate-island" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "data-sx-island" "data-sx-state" "{}" "str" "~" "get-render-env" "env-get" "not" "component?" "island?" "log-warn" "hydrate-island: unknown island " "first" "sx-parse" "list" "env-merge" "component-closure" "for-each" {:upvalue-count 2 :arity 1 :constants ("env-bind!" "dict-has?" "dict-get") :bytecode (18 0 16 0 18 1 16 0 52 1 0 2 33 11 0 18 1 16 0 52 2 0 2 32 1 0 2 52 0 0 3 50)} "component-params" "hydrate-start!" "log-info" " hydrate-start done" "with-island-scope" {:upvalue-count 1 :arity 1 :constants ("append!") :bytecode (18 0 16 0 52 0 0 2 50)} {:upvalue-count 2 :arity 0 :constants ("render-to-dom" "component-body") :bytecode (20 0 0 18 0 52 1 0 1 18 1 2 49 3 50)} " render-to-dom done" "hydrate-stop!" "dom-set-data" "sx-disposers" "set-timeout" {:upvalue-count 1 :arity 0 :constants ("process-elements") :bytecode (20 0 0 18 0 49 1 50)} 0 "hydrated island: " " (" "len" " disposers)") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 20 0 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 17 2 1 5 0 16 1 52 4 0 2 17 3 20 6 0 2 48 1 17 4 16 4 16 3 52 7 0 2 17 5 16 5 52 9 0 1 6 34 7 0 5 16 5 52 10 0 1 52 8 0 1 33 17 0 20 11 0 1 12 0 16 3 52 4 0 2 49 1 32 162 0 20 14 0 16 2 48 1 52 13 0 1 6 34 4 0 5 65 0 0 17 6 52 15 0 0 17 7 16 5 52 17 0 1 16 4 52 16 0 2 17 8 51 19 0 1 8 1 6 16 5 52 20 0 1 52 18 0 2 5 20 21 0 16 0 48 1 5 20 22 0 1 23 0 48 1 5 20 24 0 51 25 0 1 7 51 26 0 1 5 1 8 48 2 5 20 22 0 1 27 0 48 1 5 20 28 0 48 0 5 20 29 0 16 0 1 30 0 16 7 48 3 5 20 31 0 51 32 0 1 0 1 33 0 48 2 5 20 22 0 1 34 0 16 3 1 35 0 16 7 52 36 0 1 1 37 0 52 4 0 5 49 1 50)} "dispose-island" {:upvalue-count 0 :arity 1 :constants ("dom-get-data" "sx-disposers" "for-each" {:upvalue-count 0 :arity 1 :constants ("callable?") :bytecode (20 0 0 16 0 48 1 33 7 0 16 0 49 0 32 1 0 2 50)} "dom-set-data" "clear-processed!" "island-hydrated") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 24 0 51 3 0 16 1 52 2 0 2 5 20 4 0 16 0 1 1 0 2 48 3 32 1 0 2 5 20 5 0 16 0 1 6 0 49 2 50)} "dispose-islands-in" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "[data-sx-island]" "not" "empty?" "filter" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "island-hydrated") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 50)} "log-info" "str" "disposing " "len" " island(s)" "for-each" "dispose-island") :bytecode (16 0 33 98 0 20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 11 0 5 16 1 52 3 0 1 52 2 0 1 33 62 0 51 5 0 16 1 52 4 0 2 17 2 16 2 52 3 0 1 52 2 0 1 33 34 0 20 6 0 1 8 0 16 2 52 9 0 1 1 10 0 52 7 0 3 48 1 5 20 12 0 16 2 52 11 0 2 32 1 0 2 32 1 0 2 32 1 0 2 50)} "force-dispose-islands-in" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "[data-sx-island]" "not" "empty?" "log-info" "str" "force-disposing " "len" " island(s)" "for-each" "dispose-island") :bytecode (16 0 33 70 0 20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 11 0 5 16 1 52 3 0 1 52 2 0 1 33 34 0 20 4 0 1 6 0 16 1 52 7 0 1 1 8 0 52 5 0 3 48 1 5 20 10 0 16 1 52 9 0 2 32 1 0 2 32 1 0 2 50)} "*pre-render-hooks*" "*post-render-hooks*" "register-pre-render-hook" {:upvalue-count 0 :arity 1 :constants ("append!" "*pre-render-hooks*") :bytecode (20 1 0 16 0 52 0 0 2 50)} "register-post-render-hook" {:upvalue-count 0 :arity 1 :constants ("append!" "*post-render-hooks*") :bytecode (20 1 0 16 0 52 0 0 2 50)} "run-pre-render-hooks" {:upvalue-count 0 :arity 0 :constants ("for-each" {:upvalue-count 0 :arity 1 :constants ("cek-call") :bytecode (16 0 2 52 0 0 2 50)} "*pre-render-hooks*") :bytecode (51 1 0 20 2 0 52 0 0 2 50)} "run-post-render-hooks" {:upvalue-count 0 :arity 0 :constants ("log-info" "str" "run-post-render-hooks: " "len" "*post-render-hooks*" " hooks" "for-each" {:upvalue-count 0 :arity 1 :constants ("log-info" "str" " hook type: " "type-of" " callable: " "callable?" " lambda: " "lambda?" "cek-call") :bytecode (20 0 0 1 2 0 16 0 52 3 0 1 1 4 0 20 5 0 16 0 48 1 1 6 0 16 0 52 7 0 1 52 1 0 6 48 1 5 16 0 2 52 8 0 2 50)} "flush-collected-styles") :bytecode (20 0 0 1 2 0 20 4 0 52 3 0 1 1 5 0 52 1 0 3 48 1 5 51 7 0 20 4 0 52 6 0 2 5 20 8 0 49 0 50)} "boot-init" {:upvalue-count 0 :arity 0 :constants ("log-info" "str" "sx-browser " "SX_VERSION" "process-page-scripts" "process-sx-scripts" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks" "flush-collected-styles" "set-timeout" {:upvalue-count 0 :arity 0 :constants ("process-elements") :bytecode (20 0 0 2 49 1 50)} 0 "dom-set-attr" "host-get" "dom-document" "documentElement" "data-sx-ready" "true" "dom-dispatch" "sx:ready") :bytecode (20 0 0 1 2 0 20 3 0 52 1 0 2 48 1 5 20 4 0 48 0 5 20 5 0 2 48 1 5 20 6 0 2 48 1 5 20 7 0 2 48 1 5 20 8 0 48 0 5 20 9 0 48 0 5 20 10 0 51 11 0 1 12 0 48 2 5 20 13 0 20 14 0 20 15 0 48 0 1 16 0 48 2 1 17 0 1 18 0 48 3 5 20 19 0 20 15 0 48 0 1 20 0 2 48 3 5 20 0 0 1 20 0 49 1 50)}) :bytecode (1 0 0 112 5 1 1 0 112 5 1 2 0 112 5 1 3 0 112 5 1 4 0 112 5 1 5 0 112 5 1 6 0 112 5 1 7 0 112 5 1 8 0 112 5 1 9 0 112 5 1 10 0 112 5 1 12 0 128 11 0 5 51 14 0 128 13 0 5 4 128 15 0 5 51 17 0 128 16 0 5 51 19 0 128 18 0 5 51 21 0 128 20 0 5 51 23 0 128 22 0 5 51 25 0 128 24 0 5 51 27 0 128 26 0 5 51 29 0 128 28 0 5 52 31 0 0 128 30 0 5 51 33 0 128 32 0 5 51 35 0 128 34 0 5 51 37 0 128 36 0 5 51 39 0 128 38 0 5 51 41 0 128 40 0 5 51 43 0 128 42 0 5 52 31 0 0 128 44 0 5 52 31 0 0 128 45 0 5 51 47 0 128 46 0 5 51 49 0 128 48 0 5 51 51 0 128 50 0 5 51 53 0 128 52 0 5 51 55 0 128 54 0 50))) + :constants ({:library (sx dom) :op "import"} {:library (sx bytecode) :op "import"} {:library (sx browser) :op "import"} {:library (web boot-helpers) :op "import"} {:library (web adapter-dom) :op "import"} {:library (sx signals) :op "import"} {:library (sx signals-web) :op "import"} {:library (web router) :op "import"} {:library (web page-helpers) :op "import"} {:library (web orchestration) :op "import"} {:library (sx render) :op "import"} "HEAD_HOIST_SELECTOR" "meta, title, link[rel='canonical'], script[type='application/ld+json']" "hoist-head-elements-full" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "HEAD_HOIST_SELECTOR" "for-each" {:upvalue-count 0 :arity 1 :constants ("lower" "dom-tag-name" "=" "title" "set-document-title" "dom-text-content" "dom-remove-child" "dom-parent" "meta" "dom-get-attr" "name" "property" "remove-head-element" "str" "meta[name=\"" "\"]" "meta[property=\"" "dom-append-to-head" "link" "rel" "canonical" "link[rel=\"canonical\"]") :bytecode (20 1 0 16 0 48 1 52 0 0 1 17 1 16 1 1 3 0 52 2 0 2 33 30 0 20 4 0 20 5 0 16 0 48 1 48 1 5 20 6 0 20 7 0 16 0 48 1 16 0 49 2 32 205 0 16 1 1 8 0 52 2 0 2 33 103 0 20 9 0 16 0 1 10 0 48 2 17 2 20 9 0 16 0 1 11 0 48 2 17 3 16 2 33 20 0 20 12 0 1 14 0 16 2 1 15 0 52 13 0 3 48 1 32 1 0 2 5 16 3 33 20 0 20 12 0 1 16 0 16 3 1 15 0 52 13 0 3 48 1 32 1 0 2 5 20 6 0 20 7 0 16 0 48 1 16 0 48 2 5 20 17 0 16 0 49 1 32 90 0 16 1 1 18 0 52 2 0 2 6 33 18 0 5 20 9 0 16 0 1 19 0 48 2 1 20 0 52 2 0 2 33 34 0 20 12 0 1 21 0 48 1 5 20 6 0 20 7 0 16 0 48 1 16 0 48 2 5 20 17 0 16 0 49 1 32 22 0 20 6 0 20 7 0 16 0 48 1 16 0 48 2 5 20 17 0 16 0 49 1 50)}) :bytecode (20 0 0 16 0 20 1 0 48 2 17 1 51 3 0 16 1 52 2 0 2 50)} "sx-mount" {:upvalue-count 0 :arity 3 :constants ("resolve-mount-target" "empty?" "dom-child-list" "sx-render-with-env" "dom-set-text-content" "" "dom-append" "hoist-head-elements-full" "process-elements" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks") :bytecode (20 0 0 16 0 48 1 17 3 16 3 33 90 0 20 2 0 16 3 48 1 52 1 0 1 33 42 0 20 3 0 16 1 16 2 48 2 17 4 20 4 0 16 3 1 5 0 48 2 5 20 6 0 16 3 16 4 48 2 5 20 7 0 16 3 48 1 32 1 0 2 5 20 8 0 16 3 48 1 5 20 9 0 16 3 48 1 5 20 10 0 16 3 48 1 5 20 11 0 49 0 32 1 0 2 50)} "resolve-suspense" {:upvalue-count 0 :arity 2 :constants ("process-sx-scripts" "dom-query" "str" "[data-suspense=\"" "\"]" "parse" "get-render-env" "dom-set-text-content" "" "for-each" {:upvalue-count 2 :arity 1 :constants ("dom-append" "render-to-dom") :bytecode (20 0 0 18 0 20 1 0 16 0 18 1 2 48 3 49 2 50)} "process-elements" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks" "dom-dispatch" "sx:resolved" "id" "log-warn" "resolveSuspense: no element for id=") :bytecode (20 0 0 2 48 1 5 20 1 0 1 3 0 16 0 1 4 0 52 2 0 3 48 1 17 2 16 2 33 92 0 16 1 52 5 0 1 17 3 20 6 0 2 48 1 17 4 20 7 0 16 2 1 8 0 48 2 5 51 10 0 1 2 1 4 16 3 52 9 0 2 5 20 11 0 16 2 48 1 5 20 12 0 16 2 48 1 5 20 13 0 16 2 48 1 5 20 14 0 48 0 5 20 15 0 16 2 1 16 0 1 17 0 16 0 65 1 0 49 3 32 14 0 20 18 0 1 19 0 16 0 52 2 0 2 49 1 50)} "sx-hydrate-elements" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "[data-sx]" "for-each" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "hydrated" "mark-processed!" "sx-update-element") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 33 22 0 20 3 0 16 0 1 2 0 48 2 5 20 4 0 16 0 2 49 2 32 1 0 2 50)}) :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 1 2 0 48 2 17 1 51 4 0 16 1 52 3 0 2 50)} "sx-update-element" {:upvalue-count 0 :arity 2 :constants ("resolve-mount-target" "dom-get-attr" "data-sx" "parse-env-attr" "merge-envs" "sx-render-with-env" "dom-set-text-content" "" "dom-append" "store-env-attr") :bytecode (20 0 0 16 0 48 1 17 2 16 2 33 96 0 20 1 0 16 2 1 2 0 48 2 17 3 16 3 33 75 0 20 3 0 16 2 48 1 17 4 20 4 0 16 4 16 1 48 2 17 5 20 5 0 16 3 16 5 48 2 17 6 20 6 0 16 2 1 7 0 48 2 5 20 8 0 16 2 16 6 48 2 5 16 1 33 14 0 20 9 0 16 2 16 4 16 1 49 3 32 1 0 2 32 1 0 2 32 1 0 2 50)} "sx-render-component" {:upvalue-count 0 :arity 3 :constants ("starts-with?" "~" "str" "get-render-env" "env-get" "not" "component?" "error" "Unknown component: " "list" "make-symbol" "for-each" {:upvalue-count 2 :arity 1 :constants ("append!" "make-keyword" "to-kebab" "dict-get") :bytecode (18 0 20 2 0 16 0 48 1 52 1 0 1 52 0 0 2 5 18 0 18 1 16 0 52 3 0 2 52 0 0 2 50)} "keys" "render-to-dom") :bytecode (16 0 1 1 0 52 0 0 2 33 5 0 16 0 32 9 0 1 1 0 16 0 52 2 0 2 17 3 20 3 0 16 2 48 1 17 4 16 4 16 3 52 4 0 2 17 5 16 5 52 6 0 1 52 5 0 1 33 16 0 1 8 0 16 3 52 2 0 2 52 7 0 1 32 40 0 16 3 52 10 0 1 52 9 0 1 17 6 51 12 0 1 6 1 1 16 1 52 13 0 1 52 11 0 2 5 20 14 0 16 6 16 4 2 49 3 50)} "process-sx-scripts" {:upvalue-count 0 :arity 1 :constants ("query-sx-scripts" "for-each" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "script" "mark-processed!" "dom-text-content" "dom-has-attr?" "data-components" "process-component-script" "nil?" "empty?" "trim" "data-init" "sx-parse" "for-each" {:upvalue-count 0 :arity 1 :constants ("cek-eval") :bytecode (20 0 0 16 0 49 1 50)} "data-mount" "dom-get-attr" "dom-query" "sx-mount" "sx-load-components") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 33 173 0 20 3 0 16 0 1 2 0 48 2 5 20 4 0 16 0 48 1 17 1 20 5 0 16 0 1 6 0 48 2 33 12 0 20 7 0 16 0 16 1 49 2 32 125 0 16 1 52 8 0 1 6 34 11 0 5 16 1 52 10 0 1 52 9 0 1 33 4 0 2 32 97 0 20 5 0 16 0 1 11 0 48 2 33 21 0 20 12 0 16 1 48 1 17 2 51 14 0 16 2 52 13 0 2 32 63 0 20 5 0 16 0 1 15 0 48 2 33 43 0 20 16 0 16 0 1 15 0 48 2 17 2 20 17 0 16 2 48 1 17 3 16 3 33 13 0 20 18 0 16 3 16 1 2 49 3 32 1 0 2 32 7 0 20 19 0 16 1 49 1 32 1 0 2 50)}) :bytecode (20 0 0 16 0 48 1 17 1 51 2 0 16 1 52 1 0 2 50)} "process-component-script" {:upvalue-count 0 :arity 2 :constants ("dom-get-attr" "data-hash" "nil?" "not" "empty?" "trim" "sx-load-components" "local-storage-get" "sx-components-hash" "=" "local-storage-set" "sx-components-src" "log-info" "components: downloaded (cookie stale)" "str" "components: cached (" ")" "clear-sx-comp-cookie" "browser-reload" "components: downloaded (" "local-storage-remove" "set-sx-comp-cookie") :bytecode (20 0 0 16 0 1 1 0 48 2 17 2 16 2 52 2 0 1 33 38 0 16 1 6 33 15 0 5 16 1 52 5 0 1 52 4 0 1 52 3 0 1 33 10 0 20 6 0 16 1 49 1 32 1 0 2 32 239 0 16 1 6 33 15 0 5 16 1 52 5 0 1 52 4 0 1 52 3 0 1 17 3 20 7 0 1 8 0 48 1 17 4 16 4 16 2 52 9 0 2 33 103 0 16 3 33 41 0 20 10 0 1 8 0 16 2 48 2 5 20 10 0 1 11 0 16 1 48 2 5 20 6 0 16 1 48 1 5 20 12 0 1 13 0 48 1 32 54 0 20 7 0 1 11 0 48 1 17 5 16 5 33 28 0 20 6 0 16 5 48 1 5 20 12 0 1 15 0 16 2 1 16 0 52 14 0 3 48 1 32 11 0 20 17 0 48 0 5 20 18 0 48 0 32 84 0 16 3 33 50 0 20 10 0 1 8 0 16 2 48 2 5 20 10 0 1 11 0 16 1 48 2 5 20 6 0 16 1 48 1 5 20 12 0 1 19 0 16 2 1 16 0 52 14 0 3 48 1 32 29 0 20 20 0 1 8 0 48 1 5 20 20 0 1 11 0 48 1 5 20 17 0 48 0 5 20 18 0 48 0 5 20 21 0 16 2 49 1 50)} "_page-routes" "list" "process-page-scripts" {:upvalue-count 0 :arity 0 :constants ("query-page-scripts" "log-info" "str" "pages: found " "len" " script tags" "for-each" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "pages" "mark-processed!" "dom-text-content" "log-info" "str" "pages: script text length=" "len" 0 "empty?" "trim" "parse" "pages: parsed " " entries" "for-each" {:upvalue-count 0 :arity 1 :constants ("append!" "_page-routes" "merge" "parsed" "parse-route-pattern" "get" "path") :bytecode (20 1 0 16 0 1 3 0 20 4 0 16 0 1 6 0 52 5 0 2 48 1 65 1 0 52 2 0 2 52 0 0 2 50)} "log-warn" "pages: script tag is empty") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 33 127 0 20 3 0 16 0 1 2 0 48 2 5 20 4 0 16 0 48 1 17 1 20 5 0 1 7 0 16 1 33 9 0 16 1 52 8 0 1 32 3 0 1 9 0 52 6 0 2 48 1 5 16 1 6 33 15 0 5 16 1 52 11 0 1 52 10 0 1 52 0 0 1 33 42 0 16 1 52 12 0 1 17 2 20 5 0 1 13 0 16 2 52 8 0 1 1 14 0 52 6 0 3 48 1 5 51 16 0 16 2 52 15 0 2 32 8 0 20 17 0 1 18 0 49 1 32 1 0 2 50)} "pages: " "_page-routes" " routes loaded") :bytecode (20 0 0 48 0 17 0 20 1 0 1 3 0 16 0 52 4 0 1 1 5 0 52 2 0 3 48 1 5 51 7 0 16 0 52 6 0 2 5 20 1 0 1 8 0 20 9 0 52 4 0 1 1 10 0 52 2 0 3 49 1 50)} "sx-hydrate-islands" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "[data-sx-island]" "log-info" "str" "sx-hydrate-islands: " "len" " island(s) in " "subtree" "document" "for-each" {:upvalue-count 0 :arity 1 :constants ("is-processed?" "island-hydrated" "log-info" "str" " skip (already hydrated): " "dom-get-attr" "data-sx-island" " hydrating: " "mark-processed!" "hydrate-island") :bytecode (20 0 0 16 0 1 1 0 48 2 33 25 0 20 2 0 1 4 0 20 5 0 16 0 1 6 0 48 2 52 3 0 2 49 1 32 41 0 20 2 0 1 7 0 20 5 0 16 0 1 6 0 48 2 52 3 0 2 48 1 5 20 8 0 16 0 1 1 0 48 2 5 20 9 0 16 0 49 1 50)}) :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 1 2 0 48 2 17 1 20 3 0 1 5 0 16 1 52 6 0 1 1 7 0 16 0 33 6 0 1 8 0 32 3 0 1 9 0 52 4 0 4 48 1 5 51 11 0 16 1 52 10 0 2 50)} "hydrate-island" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "data-sx-island" "data-sx-state" "{}" "str" "~" "get-render-env" "env-get" "not" "component?" "island?" "log-warn" "hydrate-island: unknown island " "first" "sx-parse" "list" "env-merge" "component-closure" "for-each" {:upvalue-count 2 :arity 1 :constants ("env-bind!" "dict-has?" "dict-get") :bytecode (18 0 16 0 18 1 16 0 52 1 0 2 33 11 0 18 1 16 0 52 2 0 2 32 1 0 2 52 0 0 3 50)} "component-params" "cek-try" {:upvalue-count 3 :arity 0 :constants ("with-island-scope" {:upvalue-count 1 :arity 1 :constants ("append!") :bytecode (18 0 16 0 52 0 0 2 50)} {:upvalue-count 2 :arity 0 :constants ("render-to-dom" "component-body") :bytecode (20 0 0 18 0 52 1 0 1 18 1 2 49 3 50)}) :bytecode (20 0 0 51 1 0 0 0 51 2 0 0 1 0 2 49 2 50)} {:upvalue-count 1 :arity 1 :constants ("log-warn" "str" "hydrate-island FAILED: " " — " "dom-create-element" "div" "dom-set-attr" "class" "sx-island-error" "style" "padding:8px;margin:4px 0;border:1px solid #ef4444;border-radius:4px;background:#fef2f2;color:#b91c1c;font-family:monospace;font-size:12px;white-space:pre-wrap" "dom-set-text-content" "Island error: " "\n") :bytecode (20 0 0 1 2 0 18 0 1 3 0 16 0 52 1 0 4 48 1 5 20 4 0 1 5 0 2 48 2 17 1 20 6 0 16 1 1 7 0 1 8 0 48 3 5 20 6 0 16 1 1 9 0 1 10 0 48 3 5 20 11 0 16 1 1 12 0 18 0 1 13 0 16 0 52 1 0 4 48 2 5 16 1 50)} "host-call" "replaceChildren" "dom-set-data" "sx-disposers" "set-timeout" {:upvalue-count 1 :arity 0 :constants ("process-elements") :bytecode (20 0 0 18 0 49 1 50)} 0 "log-info" "hydrated island: " " (" "len" " disposers)") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 20 0 0 16 0 1 2 0 48 2 6 34 4 0 5 1 3 0 17 2 1 5 0 16 1 52 4 0 2 17 3 20 6 0 2 48 1 17 4 16 4 16 3 52 7 0 2 17 5 16 5 52 9 0 1 6 34 7 0 5 16 5 52 10 0 1 52 8 0 1 33 17 0 20 11 0 1 12 0 16 3 52 4 0 2 49 1 32 145 0 20 14 0 16 2 48 1 52 13 0 1 6 34 4 0 5 65 0 0 17 6 52 15 0 0 17 7 16 5 52 17 0 1 16 4 52 16 0 2 17 8 51 19 0 1 8 1 6 16 5 52 20 0 1 52 18 0 2 5 51 22 0 1 7 1 5 1 8 51 23 0 1 3 52 21 0 2 17 9 20 24 0 16 0 1 25 0 16 9 48 3 5 20 26 0 16 0 1 27 0 16 7 48 3 5 20 28 0 51 29 0 1 0 1 30 0 48 2 5 20 31 0 1 32 0 16 3 1 33 0 16 7 52 34 0 1 1 35 0 52 4 0 5 49 1 50)} "dispose-island" {:upvalue-count 0 :arity 1 :constants ("dom-get-data" "sx-disposers" "for-each" {:upvalue-count 0 :arity 1 :constants ("callable?") :bytecode (20 0 0 16 0 48 1 33 7 0 16 0 49 0 32 1 0 2 50)} "dom-set-data" "clear-processed!" "island-hydrated") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 24 0 51 3 0 16 1 52 2 0 2 5 20 4 0 16 0 1 1 0 2 48 3 32 1 0 2 5 20 5 0 16 0 1 6 0 49 2 50)} "dispose-islands-in" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "[data-sx-island]" "not" "empty?" "filter" {:upvalue-count 0 :arity 1 :constants ("not" "is-processed?" "island-hydrated") :bytecode (20 1 0 16 0 1 2 0 48 2 52 0 0 1 50)} "log-info" "str" "disposing " "len" " island(s)" "for-each" "dispose-island") :bytecode (16 0 33 98 0 20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 11 0 5 16 1 52 3 0 1 52 2 0 1 33 62 0 51 5 0 16 1 52 4 0 2 17 2 16 2 52 3 0 1 52 2 0 1 33 34 0 20 6 0 1 8 0 16 2 52 9 0 1 1 10 0 52 7 0 3 48 1 5 20 12 0 16 2 52 11 0 2 32 1 0 2 32 1 0 2 32 1 0 2 50)} "force-dispose-islands-in" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "[data-sx-island]" "not" "empty?" "log-info" "str" "force-disposing " "len" " island(s)" "for-each" "dispose-island") :bytecode (16 0 33 70 0 20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 11 0 5 16 1 52 3 0 1 52 2 0 1 33 34 0 20 4 0 1 6 0 16 1 52 7 0 1 1 8 0 52 5 0 3 48 1 5 20 10 0 16 1 52 9 0 2 32 1 0 2 32 1 0 2 50)} "*pre-render-hooks*" "*post-render-hooks*" "register-pre-render-hook" {:upvalue-count 0 :arity 1 :constants ("append!" "*pre-render-hooks*") :bytecode (20 1 0 16 0 52 0 0 2 50)} "register-post-render-hook" {:upvalue-count 0 :arity 1 :constants ("append!" "*post-render-hooks*") :bytecode (20 1 0 16 0 52 0 0 2 50)} "run-pre-render-hooks" {:upvalue-count 0 :arity 0 :constants ("for-each" {:upvalue-count 0 :arity 1 :constants ("cek-call") :bytecode (16 0 2 52 0 0 2 50)} "*pre-render-hooks*") :bytecode (51 1 0 20 2 0 52 0 0 2 50)} "run-post-render-hooks" {:upvalue-count 0 :arity 0 :constants ("log-info" "str" "run-post-render-hooks: " "len" "*post-render-hooks*" " hooks" "for-each" {:upvalue-count 0 :arity 1 :constants ("log-info" "str" " hook type: " "type-of" " callable: " "callable?" " lambda: " "lambda?" "cek-call") :bytecode (20 0 0 1 2 0 16 0 52 3 0 1 1 4 0 20 5 0 16 0 48 1 1 6 0 16 0 52 7 0 1 52 1 0 6 48 1 5 16 0 2 52 8 0 2 50)} "flush-collected-styles") :bytecode (20 0 0 1 2 0 20 4 0 52 3 0 1 1 5 0 52 1 0 3 48 1 5 51 7 0 20 4 0 52 6 0 2 5 20 8 0 49 0 50)} "boot-init" {:upvalue-count 0 :arity 0 :constants ("log-info" "str" "sx-browser " "SX_VERSION" "process-page-scripts" "process-sx-scripts" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks" "flush-collected-styles" "set-timeout" {:upvalue-count 0 :arity 0 :constants ("process-elements") :bytecode (20 0 0 2 49 1 50)} 0 "dom-set-attr" "host-get" "dom-document" "documentElement" "data-sx-ready" "true" "dom-dispatch" "sx:ready") :bytecode (20 0 0 1 2 0 20 3 0 52 1 0 2 48 1 5 20 4 0 48 0 5 20 5 0 2 48 1 5 20 6 0 2 48 1 5 20 7 0 2 48 1 5 20 8 0 48 0 5 20 9 0 48 0 5 20 10 0 51 11 0 1 12 0 48 2 5 20 13 0 20 14 0 20 15 0 48 0 1 16 0 48 2 1 17 0 1 18 0 48 3 5 20 19 0 20 15 0 48 0 1 20 0 2 48 3 5 20 0 0 1 20 0 49 1 50)}) :bytecode (1 0 0 112 5 1 1 0 112 5 1 2 0 112 5 1 3 0 112 5 1 4 0 112 5 1 5 0 112 5 1 6 0 112 5 1 7 0 112 5 1 8 0 112 5 1 9 0 112 5 1 10 0 112 5 1 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 52 30 0 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 52 30 0 0 128 43 0 5 52 30 0 0 128 44 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 50))) diff --git a/web/adapter-dom.sx b/web/adapter-dom.sx index af0b1708..8be3ae23 100644 --- a/web/adapter-dom.sx +++ b/web/adapter-dom.sx @@ -1,453 +1,220 @@ (import (sx dom)) (import (sx render)) -(define-library - (web adapter-dom) - (export - SVG_NS - MATH_NS - island-scope? - contains-deref? - dom-on - render-to-dom - render-dom-list - render-dom-element - render-dom-component - render-dom-fragment - render-dom-raw - render-dom-unknown-component - RENDER_DOM_FORMS - render-dom-form? - dispatch-render-form - render-lambda-dom - render-dom-island - render-dom-lake - render-dom-marsh - reactive-text - reactive-attr - reactive-spread - reactive-fragment - render-list-item - extract-key - reactive-list - bind-input - *use-cek-reactive* - enable-cek-reactive! - cek-reactive-text - cek-reactive-attr - render-dom-portal - render-dom-error-boundary) +(define-library (web adapter-dom) + (export SVG_NS MATH_NS island-scope? contains-deref? dom-on render-to-dom render-dom-list render-dom-element render-dom-component render-dom-fragment render-dom-raw render-dom-unknown-component RENDER_DOM_FORMS render-dom-form? dispatch-render-form render-lambda-dom render-dom-island render-dom-lake render-dom-marsh reactive-text reactive-attr reactive-spread reactive-fragment render-list-item extract-key reactive-list bind-input *use-cek-reactive* enable-cek-reactive! cek-reactive-text cek-reactive-attr render-dom-portal render-dom-error-boundary) (begin - (define SVG_NS "http://www.w3.org/2000/svg") - (define MATH_NS "http://www.w3.org/1998/Math/MathML") - (define - island-scope? - (fn () (not (nil? (scope-peek "sx-island-scope"))))) - (begin - (define *memo-cache* (dict)) - (define *cyst-counter* 0) - (define - next-cyst-id - (fn - () - (set! *cyst-counter* (+ *cyst-counter* 1)) - (str "sx-cyst-" *cyst-counter*)))) - (define - contains-deref? - (fn - (expr) + +(define SVG_NS "http://www.w3.org/2000/svg") + +(define MATH_NS "http://www.w3.org/1998/Math/MathML") + +(define island-scope? (fn () (not (nil? (scope-peek "sx-island-scope"))))) + +(begin + (define *memo-cache* (dict)) + (define *cyst-counter* 0) + (define + next-cyst-id + (fn + () + (set! *cyst-counter* (+ *cyst-counter* 1)) + (str "sx-cyst-" *cyst-counter*)))) + +(define + contains-deref? + (fn + (expr) + (if + (not (list? expr)) + false + (if + (empty? expr) + false (if - (not (list? expr)) - false - (if - (empty? expr) - false + (and + (= (type-of (first expr)) "symbol") + (= (symbol-name (first expr)) "deref")) + true + (some contains-deref? expr)))))) + +(define + dom-on + :effects (io) + (fn + (el name handler) + (dom-listen + el + name + (if + (lambda? handler) + (if + (= 0 (len (lambda-params handler))) + (fn + (_e) + (trampoline (call-lambda handler (list))) + (run-post-render-hooks)) + (fn + (e) + (trampoline (call-lambda handler (list e))) + (run-post-render-hooks))) + handler)))) + +(define + render-to-dom + :effects (render) + (fn + (expr (env :as dict) (ns :as string)) + (set-render-active! true) + (case + (type-of expr) + "nil" + (create-fragment) + "boolean" + (create-fragment) + "raw-html" + (dom-parse-html (raw-html-content expr)) + "string" + (create-text-node expr) + "number" + (create-text-node (str expr)) + "symbol" + (render-to-dom (trampoline (eval-expr expr env)) env ns) + "keyword" + (create-text-node (keyword-name expr)) + "dom-node" + expr + "spread" + (do + (when + (not (island-scope?)) + (scope-emit! "element-attrs" (spread-attrs expr))) + expr) + "dict" + (if (has-key? expr "__host_handle") expr (create-fragment)) + "list" + (if (empty? expr) (create-fragment) (render-dom-list expr env ns)) + :else (if + (signal? expr) + (if + (island-scope?) + (reactive-text expr) + (create-text-node (str (deref expr)))) + (create-text-node (str expr)))))) + +(define + render-dom-list + :effects (render) + (fn + (expr (env :as dict) (ns :as string)) + (let + ((head (first expr))) + (cond + (= (type-of head) "symbol") + (let + ((name (symbol-name head)) (args (rest expr))) + (cond + (= name "raw!") + (render-dom-raw args env) + (= name "<>") + (render-dom-fragment args env ns) + (= name "lake") + (render-dom-lake args env ns) + (= name "marsh") + (render-dom-marsh args env ns) + (starts-with? name "html:") + (render-dom-element (slice name 5) args env ns) + (render-dom-form? name) (if (and - (= (type-of (first expr)) "symbol") - (= (symbol-name (first expr)) "deref")) - true - (some contains-deref? expr)))))) - (define - dom-on - :effects (io) - (fn - (el name handler) - (dom-listen - el - name - (if - (lambda? handler) - (if - (= 0 (len (lambda-params handler))) - (fn - (_e) - (trampoline (call-lambda handler (list))) - (run-post-render-hooks)) - (fn - (e) - (trampoline (call-lambda handler (list e))) - (run-post-render-hooks))) - handler)))) - (define - render-to-dom - :effects (render) - (fn - (expr (env :as dict) (ns :as string)) - (set-render-active! true) - (case - (type-of expr) - "nil" - (create-fragment) - "boolean" - (create-fragment) - "raw-html" - (dom-parse-html (raw-html-content expr)) - "string" - (if - *hydrating* - (or (hydrate-next-text!) (create-text-node expr)) - (create-text-node expr)) - "number" - (if - *hydrating* - (or (hydrate-next-text!) (create-text-node (str expr))) - (create-text-node (str expr))) - "symbol" - (render-to-dom (trampoline (eval-expr expr env)) env ns) - "keyword" - (create-text-node (keyword-name expr)) - "dom-node" - expr - "spread" - (do - (when - (not (island-scope?)) - (scope-emit! "element-attrs" (spread-attrs expr))) - expr) - "dict" - (if (has-key? expr "__host_handle") expr (create-fragment)) - "list" - (if (empty? expr) (create-fragment) (render-dom-list expr env ns)) - :else (if - (signal? expr) - (if - (island-scope?) - (reactive-text expr) - (create-text-node (str (deref expr)))) - (create-text-node (str expr)))))) - (define - render-dom-list - :effects (render) - (fn - (expr (env :as dict) (ns :as string)) - (let - ((head (first expr))) - (cond - (= (type-of head) "symbol") - (let - ((name (symbol-name head)) (args (rest expr))) - (cond - (= name "raw!") - (render-dom-raw args env) - (= name "<>") - (render-dom-fragment args env ns) - (= name "lake") - (render-dom-lake args env ns) - (= name "marsh") - (render-dom-marsh args env ns) - (starts-with? name "html:") - (render-dom-element (slice name 5) args env ns) - (render-dom-form? name) - (if - (and - (contains? HTML_TAGS name) - (or - (and - (> (len args) 0) - (= (type-of (first args)) "keyword")) - ns)) - (render-dom-element name args env ns) - (dispatch-render-form name expr env ns)) - (and (env-has? env name) (macro? (env-get env name))) - (render-to-dom - (expand-macro (env-get env name) args env) - env - ns) (contains? HTML_TAGS name) - (render-dom-element name args env ns) - (and - (starts-with? name "~") - (env-has? env name) - (island? (env-get env name))) - (if - (scope-peek "sx-render-markers") - (let - ((island (env-get env name)) - (marker (dom-create-element "span" nil)) - (kw-state (dict))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip + (or + (and + (> (len args) 0) + (= (type-of (first args)) "keyword")) + ns)) + (render-dom-element name args env ns) + (dispatch-render-form name expr env ns)) + (and (env-has? env name) (macro? (env-get env name))) + (render-to-dom (expand-macro (env-get env name) args env) env ns) + (contains? HTML_TAGS name) + (render-dom-element name args env ns) + (and + (starts-with? name "~") + (env-has? env name) + (island? (env-get env name))) + (if + (scope-peek "sx-render-markers") + (let + ((island (env-get env name)) + (marker (dom-create-element "span" nil)) + (kw-state (dict))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((kname (keyword-name arg)) + (kval + (trampoline + (eval-expr + (nth args (inc (get state "i"))) + env)))) + (dict-set! kw-state kname kval) (assoc state "skip" - false + true "i" - (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((kname (keyword-name arg)) - (kval - (trampoline - (eval-expr - (nth args (inc (get state "i"))) - env)))) - (dict-set! kw-state kname kval) - (assoc - state - "skip" - true - "i" - (inc (get state "i")))) - (assoc state "i" (inc (get state "i"))))))) - (dict "i" 0 "skip" false) - args) - (dom-set-attr - marker - "data-sx-island" - (component-name island)) - (when - (not (empty-dict? kw-state)) - (dom-set-attr - marker - "data-sx-state" - (sx-serialize kw-state))) - marker) - (render-dom-island (env-get env name) args env ns)) - (starts-with? name "~") - (let - ((comp (env-get env name))) - (if - (component? comp) - (render-dom-component comp args env ns) - (render-dom-unknown-component name))) - (and - (> (index-of name "-") 0) - (> (len args) 0) - (= (type-of (first args)) "keyword")) - (render-dom-element name args env ns) - ns - (render-dom-element name args env ns) - (and (= name "deref") (island-scope?)) - (let - ((sig-or-val (trampoline (eval-expr (first args) env)))) - (if - (signal? sig-or-val) - (reactive-text sig-or-val) - (create-text-node (str (deref sig-or-val))))) - (and (island-scope?) (contains-deref? expr)) - (reactive-text - (computed (fn () (trampoline (eval-expr expr env))))) - :else (render-to-dom (trampoline (eval-expr expr env)) env ns))) - (or (lambda? head) (= (type-of head) "list")) - (render-to-dom (trampoline (eval-expr expr env)) env ns) - :else (let - ((frag (create-fragment))) - (for-each - (fn - (x) - (let - ((result (render-to-dom x env ns))) - (when (not (spread? result)) (dom-append frag result)))) - expr) - frag))))) - (define - render-dom-element - :effects (render) - (fn - ((tag :as string) (args :as list) (env :as dict) (ns :as string)) - (let - ((new-ns (if (= tag "svg") SVG_NS (if (= tag "math") MATH_NS ns))) - (el + (inc (get state "i")))) + (assoc state "i" (inc (get state "i"))))))) + (dict "i" 0 "skip" false) + args) + (dom-set-attr marker "data-sx-island" (component-name island)) + (when + (not (empty-dict? kw-state)) + (dom-set-attr + marker + "data-sx-state" + (sx-serialize kw-state))) + marker) + (render-dom-island (env-get env name) args env ns)) + (starts-with? name "~") + (let + ((comp (env-get env name))) (if - *hydrating* - (let - ((existing (hydrate-next-element!))) - (when existing (hydrate-push! existing)) - (or existing (dom-create-element tag new-ns))) - (dom-create-element tag new-ns)))) - (scope-push! "element-attrs" nil) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((attr-name (keyword-name arg)) - (attr-expr (nth args (inc (get state "i"))))) - (cond - (starts-with? attr-name "on-") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (when - (callable? attr-val) - (dom-on el (slice attr-name 3) attr-val))) - (= attr-name "bind") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (when (signal? attr-val) (bind-input el attr-val))) - (= attr-name "ref") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (dict-set! attr-val "current" el)) - (= attr-name "key") - (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (dom-set-attr el "key" (str attr-val))) - (island-scope?) - (reactive-attr - el - attr-name - (fn () (trampoline (eval-expr attr-expr env)))) - :else (let - ((attr-val (trampoline (eval-expr attr-expr env)))) - (cond - (or (nil? attr-val) (= attr-val false)) - nil - (contains? BOOLEAN_ATTRS attr-name) - (when attr-val (dom-set-attr el attr-name "")) - (= attr-val true) - (dom-set-attr el attr-name "") - :else (dom-set-attr el attr-name (str attr-val))))) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (when - (not (contains? VOID_ELEMENTS tag)) - (let - ((child (render-to-dom arg env new-ns))) - (cond - (and (spread? child) (island-scope?)) - (reactive-spread - el - (fn () (render-to-dom arg env new-ns))) - (spread? child) - nil - :else (when (not *hydrating*) (dom-append el child))))) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (for-each - (fn - (spread-dict) - (for-each - (fn - ((key :as string)) - (let - ((val (dict-get spread-dict key))) - (if - (= key "class") - (let - ((existing (dom-get-attr el "class"))) - (dom-set-attr - el - "class" - (if - (and existing (not (= existing ""))) - (str existing " " val) - val))) - (if - (= key "style") - (let - ((existing (dom-get-attr el "style"))) - (dom-set-attr - el - "style" - (if - (and existing (not (= existing ""))) - (str existing ";" val) - val))) - (dom-set-attr el key (str val)))))) - (keys spread-dict))) - (scope-emitted "element-attrs")) - (scope-pop! "element-attrs") - (do (when *hydrating* (hydrate-pop!)) el)))) - (define - render-dom-component - :effects (render) - (fn - ((comp :as component) - (args :as list) - (env :as dict) - (ns :as string)) - (let - ((kwargs (dict)) (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) - (dict-set! kwargs (keyword-name arg) val) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((local (env-merge (component-closure comp) env))) - (for-each - (fn - (p) - (env-bind! - local - p - (if (dict-has? kwargs p) (dict-get kwargs p) nil))) - (component-params comp)) - (when - (component-has-children? comp) - (let - ((child-frag (create-fragment))) - (for-each - (fn - (c) - (let - ((result (render-to-dom c env ns))) - (when - (not (spread? result)) - (dom-append child-frag result)))) - children) - (env-bind! local "children" child-frag))) - (render-to-dom (component-body comp) local ns))))) - (define - render-dom-fragment - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let + (component? comp) + (render-dom-component comp args env ns) + (render-dom-unknown-component name))) + (and + (> (index-of name "-") 0) + (> (len args) 0) + (= (type-of (first args)) "keyword")) + (render-dom-element name args env ns) + ns + (render-dom-element name args env ns) + (and (= name "deref") (island-scope?)) + (let + ((sig-or-val (trampoline (eval-expr (first args) env)))) + (if + (signal? sig-or-val) + (reactive-text sig-or-val) + (create-text-node (str (deref sig-or-val))))) + (and (island-scope?) (contains-deref? expr)) + (reactive-text + (computed (fn () (trampoline (eval-expr expr env))))) + :else (render-to-dom (trampoline (eval-expr expr env)) env ns))) + (or (lambda? head) (= (type-of head) "list")) + (render-to-dom (trampoline (eval-expr expr env)) env ns) + :else (let ((frag (create-fragment))) (for-each (fn @@ -455,320 +222,490 @@ (let ((result (render-to-dom x env ns))) (when (not (spread? result)) (dom-append frag result)))) - args) - frag))) - (define - render-dom-raw - :effects (render) - (fn - ((args :as list) (env :as dict)) - (let - ((frag (create-fragment))) + expr) + frag))))) + +(define + render-dom-element + :effects (render) + (fn + ((tag :as string) (args :as list) (env :as dict) (ns :as string)) + (let + ((new-ns (cond (= tag "svg") SVG_NS (= tag "math") MATH_NS :else ns)) + (el (dom-create-element tag new-ns))) + (scope-push! "element-attrs" nil) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((attr-name (keyword-name arg)) + (attr-expr (nth args (inc (get state "i"))))) + (cond + (starts-with? attr-name "on-") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (when + (callable? attr-val) + (dom-on el (slice attr-name 3) attr-val))) + (= attr-name "bind") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (when (signal? attr-val) (bind-input el attr-val))) + (= attr-name "ref") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (dict-set! attr-val "current" el)) + (= attr-name "key") + (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (dom-set-attr el "key" (str attr-val))) + (island-scope?) + (reactive-attr + el + attr-name + (fn () (trampoline (eval-expr attr-expr env)))) + :else (let + ((attr-val (trampoline (eval-expr attr-expr env)))) + (cond + (or (nil? attr-val) (= attr-val false)) + nil + (contains? BOOLEAN_ATTRS attr-name) + (when attr-val (dom-set-attr el attr-name "")) + (= attr-val true) + (dom-set-attr el attr-name "") + :else (dom-set-attr el attr-name (str attr-val))))) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (when + (not (contains? VOID_ELEMENTS tag)) + (let + ((child (render-to-dom arg env new-ns))) + (cond + (and (spread? child) (island-scope?)) + (reactive-spread + el + (fn () (render-to-dom arg env new-ns))) + (spread? child) + nil + :else (dom-append el child)))) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (for-each + (fn + (spread-dict) (for-each (fn - (arg) + ((key :as string)) (let - ((val (trampoline (eval-expr arg env)))) - (cond - (= (type-of val) "string") - (dom-append frag (dom-parse-html val)) - (= (type-of val) "dom-node") - (dom-append frag (dom-clone val)) - (not (nil? val)) - (dom-append frag (create-text-node (str val)))))) - args) - frag))) - (define - render-dom-unknown-component - :effects (render) - (fn ((name :as string)) (error (str "Unknown component: " name)))) - (define - RENDER_DOM_FORMS - (list - "if" - "when" - "cond" - "case" - "let" - "let*" - "letrec" - "begin" - "do" - "define" - "defcomp" - "defisland" - "defmacro" - "defstyle" - "map" - "map-indexed" - "filter" - "for-each" - "portal" - "error-boundary" - "scope" - "provide" - "cyst")) - (define - render-dom-form? - :effects () - (fn ((name :as string)) (contains? RENDER_DOM_FORMS name))) - (define - dispatch-render-form - :effects (render) - (fn - ((name :as string) expr (env :as dict) (ns :as string)) - (cond - (= name "if") - (if - (island-scope?) - (let - ((marker (create-comment "r-if")) - (current-nodes (list)) - (initial-result nil)) - (effect - (fn - () + ((val (dict-get spread-dict key))) + (if + (= key "class") (let - ((result (let ((cond-val (trampoline (eval-expr (nth expr 1) env)))) (if cond-val (render-to-dom (nth expr 2) env ns) (if (> (len expr) 3) (render-to-dom (nth expr 3) env ns) (create-fragment)))))) - (if - (dom-parent marker) - (do - (for-each (fn (n) (dom-remove n)) current-nodes) + ((existing (dom-get-attr el "class"))) + (dom-set-attr + el + "class" + (if + (and existing (not (= existing ""))) + (str existing " " val) + val))) + (if + (= key "style") + (let + ((existing (dom-get-attr el "style"))) + (dom-set-attr + el + "style" + (if + (and existing (not (= existing ""))) + (str existing ";" val) + val))) + (dom-set-attr el key (str val)))))) + (keys spread-dict))) + (scope-emitted "element-attrs")) + (scope-pop! "element-attrs") + el))) + +(define + render-dom-component + :effects (render) + (fn + ((comp :as component) (args :as list) (env :as dict) (ns :as string)) + (let + ((kwargs (dict)) (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) + (dict-set! kwargs (keyword-name arg) val) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((local (env-merge (component-closure comp) env))) + (for-each + (fn + (p) + (env-bind! + local + p + (if (dict-has? kwargs p) (dict-get kwargs p) nil))) + (component-params comp)) + (when + (component-has-children? comp) + (let + ((child-frag (create-fragment))) + (for-each + (fn + (c) + (let + ((result (render-to-dom c env ns))) + (when + (not (spread? result)) + (dom-append child-frag result)))) + children) + (env-bind! local "children" child-frag))) + (render-to-dom (component-body comp) local ns))))) + +(define + render-dom-fragment + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((frag (create-fragment))) + (for-each + (fn + (x) + (let + ((result (render-to-dom x env ns))) + (when (not (spread? result)) (dom-append frag result)))) + args) + frag))) + +(define + render-dom-raw + :effects (render) + (fn + ((args :as list) (env :as dict)) + (let + ((frag (create-fragment))) + (for-each + (fn + (arg) + (let + ((val (trampoline (eval-expr arg env)))) + (cond + (= (type-of val) "string") + (dom-append frag (dom-parse-html val)) + (= (type-of val) "dom-node") + (dom-append frag (dom-clone val)) + (not (nil? val)) + (dom-append frag (create-text-node (str val)))))) + args) + frag))) + +(define + render-dom-unknown-component + :effects (render) + (fn ((name :as string)) (error (str "Unknown component: " name)))) + +(define + RENDER_DOM_FORMS + (list + "if" + "when" + "cond" + "case" + "let" + "let*" + "letrec" + "begin" + "do" + "define" + "defcomp" + "defisland" + "defmacro" + "defstyle" + "map" + "map-indexed" + "filter" + "for-each" + "portal" + "error-boundary" + "scope" + "provide" + "cyst")) + +(define + render-dom-form? + :effects () + (fn ((name :as string)) (contains? RENDER_DOM_FORMS name))) + +(define + dispatch-render-form + :effects (render) + (fn + ((name :as string) expr (env :as dict) (ns :as string)) + (cond + (= name "if") + (if + (island-scope?) + (let + ((marker (create-comment "r-if")) + (current-nodes (list)) + (initial-result nil)) + (effect + (fn + () + (let + ((result (let ((cond-val (trampoline (eval-expr (nth expr 1) env)))) (if cond-val (render-to-dom (nth expr 2) env ns) (if (> (len expr) 3) (render-to-dom (nth expr 3) env ns) (create-fragment)))))) + (if + (dom-parent marker) + (do + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! + current-nodes + (if + (dom-is-fragment? result) + (dom-child-nodes result) + (list result))) + (dom-insert-after marker result)) + (set! initial-result result))))) + (if + (spread? initial-result) + initial-result + (let + ((frag (create-fragment))) + (dom-append frag marker) + (when + initial-result + (set! + current-nodes + (if + (dom-is-fragment? initial-result) + (dom-child-nodes initial-result) + (list initial-result))) + (dom-append frag initial-result)) + frag))) + (let + ((cond-val (trampoline (eval-expr (nth expr 1) env)))) + (if + cond-val + (render-to-dom (nth expr 2) env ns) + (if + (> (len expr) 3) + (render-to-dom (nth expr 3) env ns) + (create-fragment))))) + (= name "when") + (if + (island-scope?) + (let + ((marker (create-comment "r-when")) + (current-nodes (list)) + (initial-result nil)) + (effect + (fn + () + (if + (dom-parent marker) + (do + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! current-nodes (list)) + (when + (trampoline (eval-expr (nth expr 1) env)) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (dom-append + frag + (render-to-dom (nth expr i) env ns))) + (range 2 (len expr))) + (set! current-nodes (dom-child-nodes frag)) + (dom-insert-after marker frag)))) + (when + (trampoline (eval-expr (nth expr 1) env)) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (dom-append frag (render-to-dom (nth expr i) env ns))) + (range 2 (len expr))) + (set! current-nodes (dom-child-nodes frag)) + (set! initial-result frag)))))) + (if + (spread? initial-result) + initial-result + (let + ((frag (create-fragment))) + (dom-append frag marker) + (when initial-result (dom-append frag initial-result)) + frag))) + (if + (not (trampoline (eval-expr (nth expr 1) env))) + (create-fragment) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (dom-append frag (render-to-dom (nth expr i) env ns))) + (range 2 (len expr))) + frag))) + (= name "cond") + (if + (island-scope?) + (let + ((marker (create-comment "r-cond")) + (current-nodes (list)) + (initial-result nil)) + (effect + (fn + () + (let + ((branch (eval-cond (rest expr) env))) + (if + (dom-parent marker) + (do + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! current-nodes (list)) + (when + branch + (let + ((result (render-to-dom branch env ns))) (set! current-nodes (if (dom-is-fragment? result) (dom-child-nodes result) (list result))) - (dom-insert-after marker result)) - (set! initial-result result))))) - (if - (spread? initial-result) - initial-result - (let - ((frag (create-fragment))) - (dom-append frag marker) + (dom-insert-after marker result)))) (when - initial-result - (set! - current-nodes - (if - (dom-is-fragment? initial-result) - (dom-child-nodes initial-result) - (list initial-result))) - (dom-append frag initial-result)) - frag))) - (let - ((cond-val (trampoline (eval-expr (nth expr 1) env)))) - (if - cond-val - (render-to-dom (nth expr 2) env ns) - (if - (> (len expr) 3) - (render-to-dom (nth expr 3) env ns) - (create-fragment))))) - (= name "when") - (if - (island-scope?) - (let - ((marker (create-comment "r-when")) - (current-nodes (list)) - (initial-result nil)) - (effect - (fn - () - (if - (dom-parent marker) - (do - (for-each (fn (n) (dom-remove n)) current-nodes) - (set! current-nodes (list)) - (when - (trampoline (eval-expr (nth expr 1) env)) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) - (dom-append - frag - (render-to-dom (nth expr i) env ns))) - (range 2 (len expr))) - (set! current-nodes (dom-child-nodes frag)) - (dom-insert-after marker frag)))) - (when - (trampoline (eval-expr (nth expr 1) env)) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) - (dom-append - frag - (render-to-dom (nth expr i) env ns))) - (range 2 (len expr))) - (set! current-nodes (dom-child-nodes frag)) - (set! initial-result frag)))))) - (if - (spread? initial-result) - initial-result - (let - ((frag (create-fragment))) - (dom-append frag marker) - (when initial-result (dom-append frag initial-result)) - frag))) - (if - (not (trampoline (eval-expr (nth expr 1) env))) - (create-fragment) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) - (dom-append frag (render-to-dom (nth expr i) env ns))) - (range 2 (len expr))) - frag))) - (= name "cond") - (if - (island-scope?) - (let - ((marker (create-comment "r-cond")) - (current-nodes (list)) - (initial-result nil)) - (effect - (fn - () - (let - ((branch (eval-cond (rest expr) env))) - (if - (dom-parent marker) - (do - (for-each (fn (n) (dom-remove n)) current-nodes) - (set! current-nodes (list)) - (when - branch - (let - ((result (render-to-dom branch env ns))) - (set! - current-nodes - (if - (dom-is-fragment? result) - (dom-child-nodes result) - (list result))) - (dom-insert-after marker result)))) - (when - branch - (let - ((result (render-to-dom branch env ns))) - (set! - current-nodes - (if - (dom-is-fragment? result) - (dom-child-nodes result) - (list result))) - (set! initial-result result))))))) - (if - (spread? initial-result) - initial-result - (let - ((frag (create-fragment))) - (dom-append frag marker) - (when initial-result (dom-append frag initial-result)) - frag))) - (let - ((branch (eval-cond (rest expr) env))) - (if branch (render-to-dom branch env ns) (create-fragment)))) - (= name "case") - (render-to-dom (trampoline (eval-expr expr env)) env ns) - (or (= name "let") (= name "let*")) - (let - ((local (process-bindings (nth expr 1) env))) - (if - (= (len expr) 3) - (render-to-dom (nth expr 2) local ns) - (let - ((frag (create-fragment))) - (for-each - (fn - (i) + branch (let - ((result (render-to-dom (nth expr i) local ns))) - (when (not (spread? result)) (dom-append frag result)))) - (range 2 (len expr))) - frag))) - (= name "letrec") - (let - ((bindings (nth expr 1)) - (body (slice expr 2)) - (local (env-extend env))) - (for-each - (fn - (pair) - (let - ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) - (env-bind! local pname nil))) - bindings) - (for-each - (fn - (pair) - (let - ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) - (env-set! - local - pname - (trampoline (eval-expr (nth pair 1) local))))) - bindings) - (when - (> (len body) 1) - (for-each - (fn (e) (trampoline (eval-expr e local))) - (init body))) - (render-to-dom (last body) local ns)) - (or (= name "begin") (= name "do")) + ((result (render-to-dom branch env ns))) + (set! + current-nodes + (if + (dom-is-fragment? result) + (dom-child-nodes result) + (list result))) + (set! initial-result result))))))) (if - (= (len expr) 2) - (render-to-dom (nth expr 1) env ns) + (spread? initial-result) + initial-result (let ((frag (create-fragment))) - (for-each - (fn - (i) - (let - ((result (render-to-dom (nth expr i) env ns))) - (when (not (spread? result)) (dom-append frag result)))) - (range 1 (len expr))) - frag)) - (definition-form? name) - (do (trampoline (eval-expr expr env)) (create-fragment)) - (= name "map") + (dom-append frag marker) + (when initial-result (dom-append frag initial-result)) + frag))) + (let + ((branch (eval-cond (rest expr) env))) + (if branch (render-to-dom branch env ns) (create-fragment)))) + (= name "case") + (render-to-dom (trampoline (eval-expr expr env)) env ns) + (or (= name "let") (= name "let*")) + (let + ((local (process-bindings (nth expr 1) env))) + (if + (= (len expr) 3) + (render-to-dom (nth expr 2) local ns) (let - ((coll-expr (nth expr 2))) + ((frag (create-fragment))) + (for-each + (fn + (i) + (let + ((result (render-to-dom (nth expr i) local ns))) + (when (not (spread? result)) (dom-append frag result)))) + (range 2 (len expr))) + frag))) + (= name "letrec") + (let + ((bindings (nth expr 1)) + (body (slice expr 2)) + (local (env-extend env))) + (for-each + (fn + (pair) + (let + ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) + (env-bind! local pname nil))) + bindings) + (for-each + (fn + (pair) + (let + ((pname (if (= (type-of (first pair)) "symbol") (symbol-name (first pair)) (str (first pair))))) + (env-set! + local + pname + (trampoline (eval-expr (nth pair 1) local))))) + bindings) + (when + (> (len body) 1) + (for-each (fn (e) (trampoline (eval-expr e local))) (init body))) + (render-to-dom (last body) local ns)) + (or (= name "begin") (= name "do")) + (if + (= (len expr) 2) + (render-to-dom (nth expr 1) env ns) + (let + ((frag (create-fragment))) + (for-each + (fn + (i) + (let + ((result (render-to-dom (nth expr i) env ns))) + (when (not (spread? result)) (dom-append frag result)))) + (range 1 (len expr))) + frag)) + (definition-form? name) + (do (trampoline (eval-expr expr env)) (create-fragment)) + (= name "map") + (let + ((coll-expr (nth expr 2))) + (if + (and + (island-scope?) + (= (type-of coll-expr) "list") + (> (len coll-expr) 1) + (= (type-of (first coll-expr)) "symbol") + (= (symbol-name (first coll-expr)) "deref")) + (let + ((f (trampoline (eval-expr (nth expr 1) env))) + (sig (trampoline (eval-expr (nth coll-expr 1) env)))) (if - (and - (island-scope?) - (= (type-of coll-expr) "list") - (> (len coll-expr) 1) - (= (type-of (first coll-expr)) "symbol") - (= (symbol-name (first coll-expr)) "deref")) + (signal? sig) + (reactive-list f sig env ns) (let - ((f (trampoline (eval-expr (nth expr 1) env))) - (sig (trampoline (eval-expr (nth coll-expr 1) env)))) - (if - (signal? sig) - (reactive-list f sig env ns) - (let - ((coll (deref sig)) (frag (create-fragment))) - (for-each - (fn - (item) - (let - ((val (if (lambda? f) (render-lambda-dom f (list item) env ns) (render-to-dom (apply f (list item)) env ns)))) - (dom-append frag val))) - coll) - frag))) - (let - ((f (trampoline (eval-expr (nth expr 1) env))) - (coll (trampoline (eval-expr (nth expr 2) env))) - (frag (create-fragment))) + ((coll (deref sig)) (frag (create-fragment))) (for-each (fn (item) @@ -777,26 +714,6 @@ (dom-append frag val))) coll) frag))) - (= name "map-indexed") - (let - ((f (trampoline (eval-expr (nth expr 1) env))) - (coll (trampoline (eval-expr (nth expr 2) env))) - (frag (create-fragment))) - (for-each-indexed - (fn - (i item) - (let - ((val (if (lambda? f) (render-lambda-dom f (list i item) env ns) (render-to-dom (apply f (list i item)) env ns)))) - (dom-append frag val))) - coll) - frag) - (= name "filter") - (render-to-dom (trampoline (eval-expr expr env)) env ns) - (= name "portal") - (render-dom-portal (rest expr) env ns) - (= name "error-boundary") - (render-dom-error-boundary (rest expr) env ns) - (= name "for-each") (let ((f (trampoline (eval-expr (nth expr 1) env))) (coll (trampoline (eval-expr (nth expr 2) env))) @@ -808,593 +725,627 @@ ((val (if (lambda? f) (render-lambda-dom f (list item) env ns) (render-to-dom (apply f (list item)) env ns)))) (dom-append frag val))) coll) - frag) - (= name "scope") - (let - ((scope-name (trampoline (eval-expr (nth expr 1) env))) - (rest-args (slice expr 2)) - (scope-val nil) - (body-exprs nil) - (frag (create-fragment))) - (if - (and - (>= (len rest-args) 2) - (= (type-of (first rest-args)) "keyword") - (= (keyword-name (first rest-args)) "value")) - (do - (set! - scope-val - (trampoline (eval-expr (nth rest-args 1) env))) - (set! body-exprs (slice rest-args 2))) - (set! body-exprs rest-args)) - (scope-push! scope-name scope-val) - (for-each - (fn (e) (dom-append frag (render-to-dom e env ns))) - body-exprs) - (scope-pop! scope-name) - frag) - (= name "provide") - (let - ((prov-name (trampoline (eval-expr (nth expr 1) env))) - (prov-val (trampoline (eval-expr (nth expr 2) env))) - (frag (create-fragment))) - (scope-push! prov-name prov-val) - (for-each - (fn - (i) - (dom-append frag (render-to-dom (nth expr i) env ns))) - (range 3 (len expr))) - (scope-pop! prov-name) - frag) - (= name "cyst") - (let - ((cyst-key (if (and (> (len expr) 2) (= (type-of (nth expr 1)) "keyword") (= (keyword-name (nth expr 1)) "key")) (str (trampoline (eval-expr (nth expr 2) env))) (next-cyst-id))) - (cached (get *memo-cache* cyst-key))) - (if - (and cached (host-get cached "isConnected")) - cached - (let - ((container (dom-create-element "div" nil)) - (disposers (list)) - (body-exprs - (if - (and - (> (len expr) 2) - (= (type-of (nth expr 1)) "keyword") - (= (keyword-name (nth expr 1)) "key")) - (slice expr 3) - (slice expr 1)))) - (dom-set-attr container "data-sx-cyst" cyst-key) - (let - ((body-dom (with-island-scope (fn (d) (append! disposers d)) (fn () (let ((frag (create-fragment))) (for-each (fn (child) (dom-append frag (render-to-dom child env ns))) body-exprs) frag))))) - (dom-append container body-dom) - (dom-set-data container "sx-disposers" disposers) - (dict-set! *memo-cache* cyst-key container) - container)))) - :else (render-to-dom (trampoline (eval-expr expr env)) env ns)))) - (define - render-lambda-dom - :effects (render) - (fn - ((f :as lambda) (args :as list) (env :as dict) (ns :as string)) - (let - ((local (env-merge (lambda-closure f) env))) - (for-each-indexed - (fn (i p) (env-bind! local p (nth args i))) - (lambda-params f)) - (render-to-dom (lambda-body f) local ns)))) - (define - render-dom-island - :effects (render mutation) - (fn - ((island :as island) - (args :as list) - (env :as dict) - (ns :as string)) - (let - ((kwargs (dict)) (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) - (dict-set! kwargs (keyword-name arg) val) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((local (env-merge (component-closure island) env)) - (island-name (component-name island))) - (for-each - (fn - (p) - (env-bind! - local - p - (if (dict-has? kwargs p) (dict-get kwargs p) nil))) - (component-params island)) - (when - (component-has-children? island) - (let - ((child-frag (create-fragment))) - (for-each - (fn (c) (dom-append child-frag (render-to-dom c env ns))) - children) - (env-bind! local "children" child-frag))) - (let - ((container (dom-create-element "span" nil)) - (disposers (list))) - (begin - (dom-set-attr container "data-sx-island" island-name) - (when - (not (empty-dict? kwargs)) - (dom-set-attr - container - "data-sx-state" - (sx-serialize kwargs)))) - (mark-processed! container "island-hydrated") - (let - ((body-dom (with-island-scope (fn (disposable) (append! disposers disposable)) (fn () (render-to-dom (component-body island) local ns))))) - (dom-append container body-dom) - (dom-set-data container "sx-disposers" disposers) - container)))))) - (define - render-dom-lake - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let - ((lake-id nil) (lake-tag "div") (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((kname (keyword-name arg)) - (kval - (trampoline - (eval-expr (nth args (inc (get state "i"))) env)))) - (cond - (= kname "id") - (set! lake-id kval) - (= kname "tag") - (set! lake-tag kval)) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((el (dom-create-element lake-tag nil))) - (dom-set-attr el "data-sx-lake" (or lake-id "")) - (for-each - (fn (c) (dom-append el (render-to-dom c env ns))) - children) - el)))) - (define - render-dom-marsh - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let - ((marsh-id nil) - (marsh-tag "div") - (marsh-transform nil) - (children (list))) - (reduce - (fn - (state arg) - (let - ((skip (get state "skip"))) - (if - skip - (assoc state "skip" false "i" (inc (get state "i"))) - (if - (and - (= (type-of arg) "keyword") - (< (inc (get state "i")) (len args))) - (let - ((kname (keyword-name arg)) - (kval - (trampoline - (eval-expr (nth args (inc (get state "i"))) env)))) - (cond - (= kname "id") - (set! marsh-id kval) - (= kname "tag") - (set! marsh-tag kval) - (= kname "transform") - (set! marsh-transform kval)) - (assoc state "skip" true "i" (inc (get state "i")))) - (do - (append! children arg) - (assoc state "i" (inc (get state "i")))))))) - (dict "i" 0 "skip" false) - args) - (let - ((el (dom-create-element marsh-tag nil))) - (dom-set-attr el "data-sx-marsh" (or marsh-id "")) - (when - marsh-transform - (dom-set-data el "sx-marsh-transform" marsh-transform)) - (dom-set-data el "sx-marsh-env" env) - (for-each - (fn (c) (dom-append el (render-to-dom c env ns))) - children) - el)))) - (define - reactive-text - :effects (render mutation) - (fn - (sig) - (let - ((node (if *hydrating* (or (hydrate-next-text!) (create-text-node (str (deref sig)))) (create-text-node (str (deref sig)))))) - (effect (fn () (dom-set-text-content node (str (deref sig))))) - node))) - (define - reactive-attr - :effects (render mutation) - (fn - (el (attr-name :as string) (compute-fn :as lambda)) - (let - ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) - (updated - (if (empty? existing) attr-name (str existing "," attr-name)))) - (dom-set-attr el "data-sx-reactive-attrs" updated)) - (effect + frag))) + (= name "map-indexed") + (let + ((f (trampoline (eval-expr (nth expr 1) env))) + (coll (trampoline (eval-expr (nth expr 2) env))) + (frag (create-fragment))) + (for-each-indexed (fn - () + (i item) (let - ((raw (compute-fn))) - (let - ((val (if (signal? raw) (deref raw) raw))) - (cond - (or (nil? val) (= val false)) - (dom-remove-attr el attr-name) - (= val true) - (dom-set-attr el attr-name "") - :else (dom-set-attr el attr-name (str val))))))))) - (define - reactive-spread - :effects (render mutation) - (fn - (el (render-fn :as lambda)) - (let - ((prev-classes (list)) (prev-extra-keys (list))) - (let - ((existing (or (dom-get-attr el "data-sx-reactive-attrs") ""))) - (dom-set-attr - el - "data-sx-reactive-attrs" - (if (empty? existing) "_spread" (str existing ",_spread")))) - (effect - (fn - () - (when - (not (empty? prev-classes)) - (let - ((current (or (dom-get-attr el "class") "")) - (tokens - (filter (fn (c) (not (= c ""))) (split current " "))) - (kept - (filter - (fn - (c) - (not (some (fn (pc) (= pc c)) prev-classes))) - tokens))) - (if - (empty? kept) - (dom-remove-attr el "class") - (dom-set-attr el "class" (join " " kept))))) - (for-each (fn (k) (dom-remove-attr el k)) prev-extra-keys) - (let - ((result (render-fn))) - (if - (spread? result) - (let - ((attrs (spread-attrs result)) - (cls-str (or (dict-get attrs "class") "")) - (new-classes - (filter - (fn (c) (not (= c ""))) - (split cls-str " "))) - (extra-keys - (filter (fn (k) (not (= k "class"))) (keys attrs)))) - (set! prev-classes new-classes) - (set! prev-extra-keys extra-keys) - (when - (not (empty? new-classes)) - (let - ((current (or (dom-get-attr el "class") ""))) - (dom-set-attr - el - "class" - (if - (and current (not (= current ""))) - (str current " " cls-str) - cls-str)))) - (for-each - (fn (k) (dom-set-attr el k (str (dict-get attrs k)))) - extra-keys) - (run-post-render-hooks)) - (do - (set! prev-classes (list)) - (set! prev-extra-keys (list)))))))))) - (define - reactive-fragment - :effects (render mutation) - (fn - ((test-fn :as lambda) - (render-fn :as lambda) - (env :as dict) - (ns :as string)) - (let - ((marker (create-comment "island-fragment")) - (current-nodes (list))) - (effect - (fn - () - (for-each (fn (n) (dom-remove n)) current-nodes) - (set! current-nodes (list)) - (when - (test-fn) - (let - ((frag (render-fn))) - (set! current-nodes (dom-child-nodes frag)) - (dom-insert-after marker frag))))) - marker))) - (define - render-list-item - :effects (render) - (fn - ((map-fn :as lambda) item (env :as dict) (ns :as string)) + ((val (if (lambda? f) (render-lambda-dom f (list i item) env ns) (render-to-dom (apply f (list i item)) env ns)))) + (dom-append frag val))) + coll) + frag) + (= name "filter") + (render-to-dom (trampoline (eval-expr expr env)) env ns) + (= name "portal") + (render-dom-portal (rest expr) env ns) + (= name "error-boundary") + (render-dom-error-boundary (rest expr) env ns) + (= name "for-each") + (let + ((f (trampoline (eval-expr (nth expr 1) env))) + (coll (trampoline (eval-expr (nth expr 2) env))) + (frag (create-fragment))) + (for-each + (fn + (item) + (let + ((val (if (lambda? f) (render-lambda-dom f (list item) env ns) (render-to-dom (apply f (list item)) env ns)))) + (dom-append frag val))) + coll) + frag) + (= name "scope") + (let + ((scope-name (trampoline (eval-expr (nth expr 1) env))) + (rest-args (slice expr 2)) + (scope-val nil) + (body-exprs nil) + (frag (create-fragment))) (if - (lambda? map-fn) - (render-lambda-dom map-fn (list item) env ns) - (render-to-dom (apply map-fn (list item)) env ns)))) - (define - extract-key - :effects (render) - (fn - (node (index :as number)) - (let - ((k (dom-get-attr node "key"))) - (if - k - (do (dom-remove-attr node "key") k) - (let - ((dk (dom-get-data node "key"))) - (if dk (str dk) (str "__idx_" index))))))) - (define - reactive-list - :effects (render mutation) - (fn - ((map-fn :as lambda) - (items-sig :as signal) - (env :as dict) - (ns :as string)) - (let - ((container (create-fragment)) - (marker (create-comment "island-list")) - (key-map (dict)) - (key-order (list))) - (dom-append container marker) - (effect - (fn - () - (let - ((items (deref items-sig))) + (and + (>= (len rest-args) 2) + (= (type-of (first rest-args)) "keyword") + (= (keyword-name (first rest-args)) "value")) + (do + (set! scope-val (trampoline (eval-expr (nth rest-args 1) env))) + (set! body-exprs (slice rest-args 2))) + (set! body-exprs rest-args)) + (scope-push! scope-name scope-val) + (for-each + (fn (e) (dom-append frag (render-to-dom e env ns))) + body-exprs) + (scope-pop! scope-name) + frag) + (= name "provide") + (let + ((prov-name (trampoline (eval-expr (nth expr 1) env))) + (prov-val (trampoline (eval-expr (nth expr 2) env))) + (frag (create-fragment))) + (scope-push! prov-name prov-val) + (for-each + (fn (i) (dom-append frag (render-to-dom (nth expr i) env ns))) + (range 3 (len expr))) + (scope-pop! prov-name) + frag) + (= name "cyst") + (let + ((cyst-key (if (and (> (len expr) 2) (= (type-of (nth expr 1)) "keyword") (= (keyword-name (nth expr 1)) "key")) (str (trampoline (eval-expr (nth expr 2) env))) (next-cyst-id))) + (cached (get *memo-cache* cyst-key))) + (if + (and cached (host-get cached "isConnected")) + cached + (let + ((container (dom-create-element "div" nil)) + (disposers (list)) + (body-exprs (if - (dom-parent marker) - (let - ((new-map (dict)) (new-keys (list)) (has-keys false)) - (for-each-indexed - (fn - (idx item) - (let - ((rendered (render-list-item map-fn item env ns)) - (key (extract-key rendered idx))) - (when - (and - (not has-keys) - (not (starts-with? key "__idx_"))) - (set! has-keys true)) - (if - (dict-has? key-map key) - (dict-set! new-map key (dict-get key-map key)) - (dict-set! new-map key rendered)) - (append! new-keys key))) - items) - (if - (not has-keys) - (do - (dom-remove-children-after marker) - (let - ((frag (create-fragment))) - (for-each - (fn (k) (dom-append frag (dict-get new-map k))) - new-keys) - (dom-insert-after marker frag))) - (do - (for-each - (fn - (old-key) - (when - (not (dict-has? new-map old-key)) - (dom-remove (dict-get key-map old-key)))) - key-order) - (let - ((cursor marker)) - (for-each - (fn - (k) - (let - ((node (dict-get new-map k)) - (next (dom-next-sibling cursor))) - (when - (not (identical? node next)) - (dom-insert-after cursor node)) - (set! cursor node))) - new-keys)))) - (set! key-map new-map) - (set! key-order new-keys)) - (for-each-indexed - (fn - (idx item) - (let - ((rendered (render-list-item map-fn item env ns)) - (key (extract-key rendered idx))) - (dict-set! key-map key rendered) - (append! key-order key) - (dom-append container rendered))) - items))))) - container))) - (define - bind-input - :effects (render mutation) - (fn - (el (sig :as signal)) + (and + (> (len expr) 2) + (= (type-of (nth expr 1)) "keyword") + (= (keyword-name (nth expr 1)) "key")) + (slice expr 3) + (slice expr 1)))) + (dom-set-attr container "data-sx-cyst" cyst-key) + (let + ((body-dom (with-island-scope (fn (d) (append! disposers d)) (fn () (let ((frag (create-fragment))) (for-each (fn (child) (dom-append frag (render-to-dom child env ns))) body-exprs) frag))))) + (dom-append container body-dom) + (dom-set-data container "sx-disposers" disposers) + (dict-set! *memo-cache* cyst-key container) + container)))) + :else (render-to-dom (trampoline (eval-expr expr env)) env ns)))) + +(define + render-lambda-dom + :effects (render) + (fn + ((f :as lambda) (args :as list) (env :as dict) (ns :as string)) + (let + ((local (env-merge (lambda-closure f) env))) + (for-each-indexed + (fn (i p) (env-bind! local p (nth args i))) + (lambda-params f)) + (render-to-dom (lambda-body f) local ns)))) + +(define + render-dom-island + :effects (render mutation) + (fn + ((island :as island) (args :as list) (env :as dict) (ns :as string)) + (let + ((kwargs (dict)) (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((val (trampoline (eval-expr (nth args (inc (get state "i"))) env)))) + (dict-set! kwargs (keyword-name arg) val) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((local (env-merge (component-closure island) env)) + (island-name (component-name island))) + (for-each + (fn + (p) + (env-bind! + local + p + (if (dict-has? kwargs p) (dict-get kwargs p) nil))) + (component-params island)) + (when + (component-has-children? island) + (let + ((child-frag (create-fragment))) + (for-each + (fn (c) (dom-append child-frag (render-to-dom c env ns))) + children) + (env-bind! local "children" child-frag))) (let - ((input-type (lower (or (dom-get-attr el "type") ""))) - (is-checkbox - (or (= input-type "checkbox") (= input-type "radio")))) + ((container (dom-create-element "span" nil)) (disposers (list))) + (begin + (dom-set-attr container "data-sx-island" island-name) + (when + (not (empty-dict? kwargs)) + (dom-set-attr container "data-sx-state" (sx-serialize kwargs)))) + (mark-processed! container "island-hydrated") + (let + ((body-dom (with-island-scope (fn (disposable) (append! disposers disposable)) (fn () (render-to-dom (component-body island) local ns))))) + (dom-append container body-dom) + (dom-set-data container "sx-disposers" disposers) + container)))))) + +(define + render-dom-lake + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((lake-id nil) (lake-tag "div") (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((kname (keyword-name arg)) + (kval + (trampoline + (eval-expr (nth args (inc (get state "i"))) env)))) + (cond + (= kname "id") + (set! lake-id kval) + (= kname "tag") + (set! lake-tag kval)) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((el (dom-create-element lake-tag nil))) + (dom-set-attr el "data-sx-lake" (or lake-id "")) + (for-each + (fn (c) (dom-append el (render-to-dom c env ns))) + children) + el)))) + +(define + render-dom-marsh + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((marsh-id nil) + (marsh-tag "div") + (marsh-transform nil) + (children (list))) + (reduce + (fn + (state arg) + (let + ((skip (get state "skip"))) + (if + skip + (assoc state "skip" false "i" (inc (get state "i"))) + (if + (and + (= (type-of arg) "keyword") + (< (inc (get state "i")) (len args))) + (let + ((kname (keyword-name arg)) + (kval + (trampoline + (eval-expr (nth args (inc (get state "i"))) env)))) + (cond + (= kname "id") + (set! marsh-id kval) + (= kname "tag") + (set! marsh-tag kval) + (= kname "transform") + (set! marsh-transform kval)) + (assoc state "skip" true "i" (inc (get state "i")))) + (do + (append! children arg) + (assoc state "i" (inc (get state "i")))))))) + (dict "i" 0 "skip" false) + args) + (let + ((el (dom-create-element marsh-tag nil))) + (dom-set-attr el "data-sx-marsh" (or marsh-id "")) + (when + marsh-transform + (dom-set-data el "sx-marsh-transform" marsh-transform)) + (dom-set-data el "sx-marsh-env" env) + (for-each + (fn (c) (dom-append el (render-to-dom c env ns))) + children) + el)))) + +(define + reactive-text + :effects (render mutation) + (fn + (sig) + (let + ((node (create-text-node (str (deref sig))))) + (effect (fn () (dom-set-text-content node (str (deref sig))))) + node))) + +(define + reactive-attr + :effects (render mutation) + (fn + (el (attr-name :as string) (compute-fn :as lambda)) + (let + ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) + (updated + (if (empty? existing) attr-name (str existing "," attr-name)))) + (dom-set-attr el "data-sx-reactive-attrs" updated)) + (effect + (fn + () + (let + ((raw (compute-fn))) + (let + ((val (if (signal? raw) (deref raw) raw))) + (cond + (or (nil? val) (= val false)) + (dom-remove-attr el attr-name) + (= val true) + (dom-set-attr el attr-name "") + :else (dom-set-attr el attr-name (str val))))))))) + +(define + reactive-spread + :effects (render mutation) + (fn + (el (render-fn :as lambda)) + (let + ((prev-classes (list)) (prev-extra-keys (list))) + (let + ((existing (or (dom-get-attr el "data-sx-reactive-attrs") ""))) + (dom-set-attr + el + "data-sx-reactive-attrs" + (if (empty? existing) "_spread" (str existing ",_spread")))) + (effect + (fn + () + (when + (not (empty? prev-classes)) + (let + ((current (or (dom-get-attr el "class") "")) + (tokens + (filter (fn (c) (not (= c ""))) (split current " "))) + (kept + (filter + (fn (c) (not (some (fn (pc) (= pc c)) prev-classes))) + tokens))) + (if + (empty? kept) + (dom-remove-attr el "class") + (dom-set-attr el "class" (join " " kept))))) + (for-each (fn (k) (dom-remove-attr el k)) prev-extra-keys) + (let + ((result (render-fn))) + (if + (spread? result) + (let + ((attrs (spread-attrs result)) + (cls-str (or (dict-get attrs "class") "")) + (new-classes + (filter (fn (c) (not (= c ""))) (split cls-str " "))) + (extra-keys + (filter (fn (k) (not (= k "class"))) (keys attrs)))) + (set! prev-classes new-classes) + (set! prev-extra-keys extra-keys) + (when + (not (empty? new-classes)) + (let + ((current (or (dom-get-attr el "class") ""))) + (dom-set-attr + el + "class" + (if + (and current (not (= current ""))) + (str current " " cls-str) + cls-str)))) + (for-each + (fn (k) (dom-set-attr el k (str (dict-get attrs k)))) + extra-keys) + (run-post-render-hooks)) + (do (set! prev-classes (list)) (set! prev-extra-keys (list)))))))))) + +(define + reactive-fragment + :effects (render mutation) + (fn + ((test-fn :as lambda) + (render-fn :as lambda) + (env :as dict) + (ns :as string)) + (let + ((marker (create-comment "island-fragment")) (current-nodes (list))) + (effect + (fn + () + (for-each (fn (n) (dom-remove n)) current-nodes) + (set! current-nodes (list)) + (when + (test-fn) + (let + ((frag (render-fn))) + (set! current-nodes (dom-child-nodes frag)) + (dom-insert-after marker frag))))) + marker))) + +(define + render-list-item + :effects (render) + (fn + ((map-fn :as lambda) item (env :as dict) (ns :as string)) + (if + (lambda? map-fn) + (render-lambda-dom map-fn (list item) env ns) + (render-to-dom (apply map-fn (list item)) env ns)))) + +(define + extract-key + :effects (render) + (fn + (node (index :as number)) + (let + ((k (dom-get-attr node "key"))) + (if + k + (do (dom-remove-attr node "key") k) + (let + ((dk (dom-get-data node "key"))) + (if dk (str dk) (str "__idx_" index))))))) + +(define + reactive-list + :effects (render mutation) + (fn + ((map-fn :as lambda) + (items-sig :as signal) + (env :as dict) + (ns :as string)) + (let + ((container (create-fragment)) + (marker (create-comment "island-list")) + (key-map (dict)) + (key-order (list))) + (dom-append container marker) + (effect + (fn + () + (let + ((items (deref items-sig))) + (if + (dom-parent marker) + (let + ((new-map (dict)) (new-keys (list)) (has-keys false)) + (for-each-indexed + (fn + (idx item) + (let + ((rendered (render-list-item map-fn item env ns)) + (key (extract-key rendered idx))) + (when + (and + (not has-keys) + (not (starts-with? key "__idx_"))) + (set! has-keys true)) + (if + (dict-has? key-map key) + (dict-set! new-map key (dict-get key-map key)) + (dict-set! new-map key rendered)) + (append! new-keys key))) + items) + (if + (not has-keys) + (do + (dom-remove-children-after marker) + (let + ((frag (create-fragment))) + (for-each + (fn (k) (dom-append frag (dict-get new-map k))) + new-keys) + (dom-insert-after marker frag))) + (do + (for-each + (fn + (old-key) + (when + (not (dict-has? new-map old-key)) + (dom-remove (dict-get key-map old-key)))) + key-order) + (let + ((cursor marker)) + (for-each + (fn + (k) + (let + ((node (dict-get new-map k)) + (next (dom-next-sibling cursor))) + (when + (not (identical? node next)) + (dom-insert-after cursor node)) + (set! cursor node))) + new-keys)))) + (set! key-map new-map) + (set! key-order new-keys)) + (for-each-indexed + (fn + (idx item) + (let + ((rendered (render-list-item map-fn item env ns)) + (key (extract-key rendered idx))) + (dict-set! key-map key rendered) + (append! key-order key) + (dom-append container rendered))) + items))))) + container))) + +(define + bind-input + :effects (render mutation) + (fn + (el (sig :as signal)) + (let + ((input-type (lower (or (dom-get-attr el "type") ""))) + (is-checkbox (or (= input-type "checkbox") (= input-type "radio")))) + (if + is-checkbox + (dom-set-prop el "checked" (deref sig)) + (dom-set-prop el "value" (str (deref sig)))) + (effect + (fn + () (if is-checkbox (dom-set-prop el "checked" (deref sig)) - (dom-set-prop el "value" (str (deref sig)))) - (effect - (fn - () - (if - is-checkbox - (dom-set-prop el "checked" (deref sig)) - (let - ((v (str (deref sig)))) - (when - (!= (dom-get-prop el "value") v) - (dom-set-prop el "value" v)))))) - (dom-on - el - (if is-checkbox "change" "input") - (fn - (e) - (if - is-checkbox - (reset! sig (dom-get-prop el "checked")) - (reset! sig (dom-get-prop el "value")))))))) - (define *use-cek-reactive* true) - (define enable-cek-reactive! (fn () (set! *use-cek-reactive* true))) - (define - cek-reactive-text - :effects (render mutation) - (fn - (expr env) - (let - ((node (create-text-node "")) - (update-fn (fn (val) (dom-set-text-content node (str val))))) - (let - ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) - (dom-set-text-content node (str initial)) - node)))) - (define - cek-reactive-attr - :effects (render mutation) - (fn - (el attr-name expr env) - (let - ((update-fn (fn (val) (cond (or (nil? val) (= val false)) (dom-remove-attr el attr-name) (= val true) (dom-set-attr el attr-name "") :else (dom-set-attr el attr-name (str val)))))) - (let - ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) - (updated - (if (empty? existing) attr-name (str existing "," attr-name)))) - (dom-set-attr el "data-sx-reactive-attrs" updated)) - (let - ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) - (cek-call update-fn (list initial)))))) - (define - render-dom-portal - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) - (let - ((selector (trampoline (eval-expr (first args) env))) - (target (or (dom-query selector) (dom-ensure-element selector)))) - (if - (not target) - (create-comment (str "portal: " selector " (not found)")) (let - ((marker (create-comment (str "portal: " selector))) - (frag (create-fragment))) - (for-each - (fn (child) (dom-append frag (render-to-dom child env ns))) - (rest args)) - (let - ((portal-nodes (dom-child-nodes frag))) - (dom-append target frag) - (register-in-scope - (fn () (for-each (fn (n) (dom-remove n)) portal-nodes)))) - marker))))) - (define - render-dom-error-boundary - :effects (render) - (fn - ((args :as list) (env :as dict) (ns :as string)) + ((v (str (deref sig)))) + (when + (!= (dom-get-prop el "value") v) + (dom-set-prop el "value" v)))))) + (dom-on + el + (if is-checkbox "change" "input") + (fn + (e) + (if + is-checkbox + (reset! sig (dom-get-prop el "checked")) + (reset! sig (dom-get-prop el "value")))))))) + +(define *use-cek-reactive* true) + +(define enable-cek-reactive! (fn () (set! *use-cek-reactive* true))) + +(define + cek-reactive-text + :effects (render mutation) + (fn + (expr env) + (let + ((node (create-text-node "")) + (update-fn (fn (val) (dom-set-text-content node (str val))))) + (let + ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) + (dom-set-text-content node (str initial)) + node)))) + +(define + cek-reactive-attr + :effects (render mutation) + (fn + (el attr-name expr env) + (let + ((update-fn (fn (val) (cond (or (nil? val) (= val false)) (dom-remove-attr el attr-name) (= val true) (dom-set-attr el attr-name "") :else (dom-set-attr el attr-name (str val)))))) + (let + ((existing (or (dom-get-attr el "data-sx-reactive-attrs") "")) + (updated + (if (empty? existing) attr-name (str existing "," attr-name)))) + (dom-set-attr el "data-sx-reactive-attrs" updated)) + (let + ((initial (cek-run (make-cek-state expr env (list (make-reactive-reset-frame env update-fn true)))))) + (cek-call update-fn (list initial)))))) + +(define + render-dom-portal + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((selector (trampoline (eval-expr (first args) env))) + (target (or (dom-query selector) (dom-ensure-element selector)))) + (if + (not target) + (create-comment (str "portal: " selector " (not found)")) (let - ((fallback-expr (if (> (len args) 1) (first args) nil)) - (body-exprs (if (> (len args) 1) (rest args) args)) - (container (dom-create-element "div" nil)) - (retry-version (signal 0))) - (dom-set-attr container "data-sx-boundary" "true") - (effect + ((marker (create-comment (str "portal: " selector))) + (frag (create-fragment))) + (for-each + (fn (child) (dom-append frag (render-to-dom child env ns))) + (rest args)) + (let + ((portal-nodes (dom-child-nodes frag))) + (dom-append target frag) + (register-in-scope + (fn () (for-each (fn (n) (dom-remove n)) portal-nodes)))) + marker))))) + +(define + render-dom-error-boundary + :effects (render) + (fn + ((args :as list) (env :as dict) (ns :as string)) + (let + ((fallback-expr (if (> (len args) 1) (first args) nil)) + (body-exprs (if (> (len args) 1) (rest args) args)) + (container (dom-create-element "div" nil)) + (retry-version (signal 0))) + (dom-set-attr container "data-sx-boundary" "true") + (effect + (fn + () + (deref retry-version) + (dom-set-prop container "innerHTML" "") + (scope-push! "sx-island-scope" nil) + (try-catch (fn () - (deref retry-version) - (dom-set-prop container "innerHTML" "") - (scope-push! "sx-island-scope" nil) - (try-catch - (fn - () - (let - ((frag (create-fragment))) - (for-each - (fn - (child) - (dom-append frag (render-to-dom child env ns))) - body-exprs) - (dom-append container frag)) - (scope-pop! "sx-island-scope")) - (fn - (err) - (scope-pop! "sx-island-scope") - (let - ((fallback-fn (trampoline (eval-expr fallback-expr env))) - (retry-fn - (fn () (swap! retry-version (fn (n) (+ n 1)))))) - (let - ((fallback-dom (if (nil? fallback-fn) (let ((el (dom-create-element "div" nil))) (dom-set-attr el "class" "sx-render-error") (dom-set-attr el "style" "color:red;font-size:0.875rem;padding:0.5rem;border:1px solid red;border-radius:0.25rem;margin:0.5rem 0;") (dom-set-text-content el (str "Render error: " err)) el) (if (lambda? fallback-fn) (render-lambda-dom fallback-fn (list err retry-fn) env ns) (render-to-dom (apply fallback-fn (list err retry-fn)) env ns))))) - (dom-append container fallback-dom))))))) - container))))) + (let + ((frag (create-fragment))) + (for-each + (fn + (child) + (dom-append frag (render-to-dom child env ns))) + body-exprs) + (dom-append container frag)) + (scope-pop! "sx-island-scope")) + (fn + (err) + (scope-pop! "sx-island-scope") + (let + ((fallback-fn (trampoline (eval-expr fallback-expr env))) + (retry-fn + (fn () (swap! retry-version (fn (n) (+ n 1)))))) + (let + ((fallback-dom (if (nil? fallback-fn) (let ((el (dom-create-element "div" nil))) (dom-set-attr el "class" "sx-render-error") (dom-set-attr el "style" "color:red;font-size:0.875rem;padding:0.5rem;border:1px solid red;border-radius:0.25rem;margin:0.5rem 0;") (dom-set-text-content el (str "Render error: " err)) el) (if (lambda? fallback-fn) (render-lambda-dom fallback-fn (list err retry-fn) env ns) (render-to-dom (apply fallback-fn (list err retry-fn)) env ns))))) + (dom-append container fallback-dom))))))) + container))) + + +)) ;; Re-export to global env (import (web adapter-dom)) diff --git a/web/boot.sx b/web/boot.sx index f5af1ad0..e3f9a716 100644 --- a/web/boot.sx +++ b/web/boot.sx @@ -55,8 +55,6 @@ (dom-append-to-head el))))) els)))) -(define *hydrating* false) - (define sx-mount :effects (mutation io) @@ -331,14 +329,9 @@ p (if (dict-has? kwargs p) (dict-get kwargs p) nil))) (component-params comp)) - (do - (hydrate-start! el) - (log-info " hydrate-start done") - (with-island-scope - (fn (disposable) (append! disposers disposable)) - (fn () (render-to-dom (component-body comp) local nil))) - (log-info " render-to-dom done") - (hydrate-stop!) + (let + ((body-dom (cek-try (fn () (with-island-scope (fn (disposable) (append! disposers disposable)) (fn () (render-to-dom (component-body comp) local nil)))) (fn (err) (log-warn (str "hydrate-island FAILED: " comp-name " — " err)) (let ((error-el (dom-create-element "div" nil))) (dom-set-attr error-el "class" "sx-island-error") (dom-set-attr error-el "style" "padding:8px;margin:4px 0;border:1px solid #ef4444;border-radius:4px;background:#fef2f2;color:#b91c1c;font-family:monospace;font-size:12px;white-space:pre-wrap") (dom-set-text-content error-el (str "Island error: " comp-name "\n" err)) error-el))))) + (host-call el "replaceChildren" body-dom) (dom-set-data el "sx-disposers" disposers) (set-timeout (fn () (process-elements el)) 0) (log-info