sx-tools: WASM kernel updates, TW/CSSX rework, content refresh, new debugging tools

Build tooling: updated OCaml bootstrapper, compile-modules, bundle.sh, sx-build-all.
WASM browser: rebuilt sx_browser.bc.js/wasm, sx-platform-2.js, .sxbc bytecode files.
CSSX/Tailwind: reworked cssx.sx templates and tw-layout, added tw-type support.
Content: refreshed essays, plans, geography, reactive islands, docs, demos, handlers.
New tools: bisect_sxbc.sh, test-spa.js, render-trace.sx, morph playwright spec.
Tests: added test-match.sx, test-examples.sx, updated test-tw.sx and web tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-02 11:31:57 +00:00
parent 9ed1100ef6
commit d40a9c6796
178 changed files with 13591 additions and 9110 deletions

View File

@@ -178,13 +178,13 @@
(let
((now (helper "now" "%H:%M:%S")))
(<>
(p :class "text-emerald-600 font-medium" "Box A updated!")
(p :class "text-sm text-stone-500" (str "at " now))
(p (~tw :tokens "text-emerald-600 font-medium") "Box A updated!")
(p (~tw :tokens "text-sm text-stone-500") (str "at " now))
(div
:id "oob-box-b"
:sx-swap-oob "innerHTML"
(p :class "text-violet-600 font-medium" "Box B updated via OOB!")
(p :class "text-sm text-stone-500" (str "at " now)))
(p (~tw :tokens "text-violet-600 font-medium") "Box B updated via OOB!")
(p (~tw :tokens "text-sm text-stone-500") (str "at " now)))
(~docs/oob-code
:target-id "oob-wire"
:text (str
@@ -222,7 +222,7 @@
(fn
(i)
(div
:class "px-4 py-3 border-b border-stone-100 text-sm text-stone-700"
(~tw :tokens "px-4 py-3 border-b border-stone-100 text-sm text-stone-700")
(str "Item " i " — loaded from page " page)))
(range start (+ start 5)))
(if
@@ -235,10 +235,10 @@
:sx-trigger "intersect once"
:sx-target "#scroll-items"
:sx-swap "beforeend"
:class "p-3 text-center text-stone-400 text-sm"
(~tw :tokens "p-3 text-center text-stone-400 text-sm")
"Loading more...")
(div
:class "p-3 text-center text-stone-500 text-sm font-medium"
(~tw :tokens "p-3 text-center text-stone-500 text-sm font-medium")
"All items loaded."))
(~docs/oob-code
:target-id "scroll-wire"
@@ -373,9 +373,9 @@
((email (helper "request-form" "email" "")))
(if
(or (= email "") (not (contains? email "@")))
(p :class "text-sm text-rose-600 mt-2" "Please enter a valid email.")
(p (~tw :tokens "text-sm text-rose-600 mt-2") "Please enter a valid email.")
(p
:class "text-sm text-emerald-600 mt-2"
(~tw :tokens "text-sm text-emerald-600 mt-2")
(str "Form submitted with: " email)))))
(defhandler
@@ -536,12 +536,12 @@
(helper "state-set!" "ex-swap-n" n)
(<>
(div
:class "px-3 py-2 text-sm text-stone-700"
(~tw :tokens "px-3 py-2 text-sm text-stone-700")
(str "[" now "] " mode " (#" n ")"))
(span
:id "swap-counter"
:sx-swap-oob "innerHTML"
:class "self-center text-sm text-stone-500"
(~tw :tokens "self-center text-sm text-stone-500")
(str "Count: " n))
(~docs/oob-code
:target-id "swap-wire"
@@ -558,28 +558,28 @@
(<>
(div
:id "dash-header"
:class "p-3 bg-violet-50 rounded mb-3"
(h4 :class "font-semibold text-violet-800" "Dashboard Header")
(p :class "text-sm text-violet-600" (str "Generated at " now)))
(~tw :tokens "p-3 bg-violet-50 rounded mb-3")
(h4 (~tw :tokens "font-semibold text-violet-800") "Dashboard Header")
(p (~tw :tokens "text-sm text-violet-600") (str "Generated at " now)))
(div
:id "dash-stats"
:class "grid grid-cols-3 gap-3 mb-3"
(~tw :tokens "grid grid-cols-3 gap-3 mb-3")
(div
:class "p-3 bg-emerald-50 rounded text-center"
(p :class "text-2xl font-bold text-emerald-700" "142")
(p :class "text-xs text-emerald-600" "Users"))
(~tw :tokens "p-3 bg-emerald-50 rounded text-center")
(p (~tw :tokens "text-2xl font-bold text-emerald-700") "142")
(p (~tw :tokens "text-xs text-emerald-600") "Users"))
(div
:class "p-3 bg-blue-50 rounded text-center"
(p :class "text-2xl font-bold text-blue-700" "89")
(p :class "text-xs text-blue-600" "Orders"))
(~tw :tokens "p-3 bg-blue-50 rounded text-center")
(p (~tw :tokens "text-2xl font-bold text-blue-700") "89")
(p (~tw :tokens "text-xs text-blue-600") "Orders"))
(div
:class "p-3 bg-amber-50 rounded text-center"
(p :class "text-2xl font-bold text-amber-700" "$4.2k")
(p :class "text-xs text-amber-600" "Revenue")))
(~tw :tokens "p-3 bg-amber-50 rounded text-center")
(p (~tw :tokens "text-2xl font-bold text-amber-700") "$4.2k")
(p (~tw :tokens "text-xs text-amber-600") "Revenue")))
(div
:id "dash-footer"
:class "p-3 bg-stone-50 rounded"
(p :class "text-sm text-stone-500" (str "Last updated: " now)))
(~tw :tokens "p-3 bg-stone-50 rounded")
(p (~tw :tokens "text-sm text-stone-500") (str "Last updated: " now)))
(~docs/oob-code
:target-id "filter-wire"
:text (str
@@ -598,7 +598,7 @@
(div
:id "tab-buttons"
:sx-swap-oob "innerHTML"
:class "flex border-b border-stone-200"
(~tw :tokens "flex border-b border-stone-200")
(~examples/tab-btn
:tab "tab1"
:label "Overview"

View File

@@ -45,11 +45,11 @@
(filter (fn (item) (string-contains? (lower item) (lower query)))
items))))
(let ((shown (slice matches 0 3)))
(div :class "space-y-1"
(div (~tw :tokens "space-y-1")
(p :class (str "text-xs font-semibold uppercase " color) label)
(ul :class "list-disc pl-4"
(map (fn (m) (li :class "text-sm text-stone-600" m)) shown))
(p :class "text-xs text-stone-400"
(ul (~tw :tokens "list-disc pl-4")
(map (fn (m) (li (~tw :tokens "text-sm text-stone-600") m)) shown))
(p (~tw :tokens "text-xs text-stone-400")
(str (length matches) " result(s)"))))))
@@ -66,10 +66,10 @@
(now (helper "now" "%H:%M:%S")))
(let ((price (nth flash-sale-prices idx)))
(<>
(div :class "space-y-2"
(p :class "text-sm text-emerald-600 font-medium"
(div (~tw :tokens "space-y-2")
(p (~tw :tokens "text-sm text-emerald-600 font-medium")
(str "⚡ Flash sale! Price: $" price))
(p :class "text-xs text-stone-400" (str "at " now)))
(p (~tw :tokens "text-xs text-stone-400") (str "at " now)))
(script :type "text/sx" :data-init ""
(str "(reset! (use-store \"demo-price\") " price ")"))))))
@@ -86,9 +86,9 @@
(let ((idx (random-int 0 (- (length settle-items) 1)))
(now (helper "now" "%H:%M:%S")))
(let ((item (nth settle-items idx)))
(div :class "space-y-1"
(p :class "text-sm font-medium text-stone-700" (str "Fetched: " item))
(p :class "text-xs text-stone-400" (str "at " now))))))
(div (~tw :tokens "space-y-1")
(p (~tw :tokens "text-sm font-medium text-stone-700") (str "Fetched: " item))
(p (~tw :tokens "text-xs text-stone-400") (str "at " now))))))
;; --------------------------------------------------------------------------
@@ -160,7 +160,7 @@
"" rotated)
")")))
(<>
(p :class "text-sm text-emerald-600 font-medium"
(p (~tw :tokens "text-sm text-emerald-600 font-medium")
(str "Catalog loaded: " (length rotated) " items (shuffled at " now ")"))
(script :type "text/sx" :data-init ""
(str "(reset! (use-store \"catalog-items\") " items-sx ")")))))))

View File

@@ -12,7 +12,7 @@
(&key)
(let ((now (helper "now" "%H:%M:%S")))
(<>
(span :class "text-stone-800 text-sm" "Server time: " (strong now))
(span (~tw :tokens "text-stone-800 text-sm") "Server time: " (strong now))
(~docs/oob-code :target-id "ref-wire-sx-get"
:text (str "(span :class \"text-stone-800 text-sm\" \"Server time: \" (strong \"" now "\"))")))))
@@ -26,7 +26,7 @@
(&key)
(let ((name (helper "request-form" "name" "stranger")))
(<>
(span :class "text-stone-800 text-sm" "Hello, " (strong name) "!")
(span (~tw :tokens "text-stone-800 text-sm") "Hello, " (strong name) "!")
(~docs/oob-code :target-id "ref-wire-sx-post"
:text (str "(span :class \"text-stone-800 text-sm\" \"Hello, \" (strong \"" name "\") \"!\")")))))
@@ -40,7 +40,7 @@
(&key)
(let ((status (helper "request-form" "status" "unknown")))
(<>
(span :class "text-stone-700 text-sm" "Status: " (strong status) " — updated via PUT")
(span (~tw :tokens "text-stone-700 text-sm") "Status: " (strong status) " — updated via PUT")
(~docs/oob-code :target-id "ref-wire-sx-put"
:text (str "(span :class \"text-stone-700 text-sm\" \"Status: \" (strong \"" status "\") \" — updated via PUT\")")))))
@@ -82,8 +82,8 @@
(str "(span :class \"text-stone-800 text-sm\" \"Results for: \" (strong \"" q "\"))"))))
(<>
(if (= q "")
(span :class "text-stone-400 text-sm" "Start typing to trigger a search.")
(span :class "text-stone-800 text-sm" "Results for: " (strong q)))
(span (~tw :tokens "text-stone-400 text-sm") "Start typing to trigger a search.")
(span (~tw :tokens "text-stone-800 text-sm") "Results for: " (strong q)))
(~docs/oob-code :target-id "ref-wire-sx-trigger" :text sx-text)))))
;; --- sx-swap demo ---
@@ -95,7 +95,7 @@
(&key)
(let ((now (helper "now" "%H:%M:%S")))
(<>
(div :class "text-sm text-violet-700" (str "New item (" now ")"))
(div (~tw :tokens "text-sm text-violet-700") (str "New item (" now ")"))
(~docs/oob-code :target-id "ref-wire-sx-swap"
:text (str "(div :class \"text-sm text-violet-700\" \"New item (" now ")\")")))))
@@ -108,9 +108,9 @@
(&key)
(let ((now (helper "now" "%H:%M:%S")))
(<>
(span :class "text-emerald-700 text-sm" "Main updated at " now)
(span (~tw :tokens "text-emerald-700 text-sm") "Main updated at " now)
(div :id "ref-oob-side" :sx-swap-oob "innerHTML"
(span :class "text-violet-700 text-sm" "OOB updated at " now))
(span (~tw :tokens "text-violet-700 text-sm") "OOB updated at " now))
(~docs/oob-code :target-id "ref-wire-sx-swap-oob"
:text (str "(<> (span ... \"" now "\") (div :id \"ref-oob-side\" :sx-swap-oob \"innerHTML\" ...))")))))
@@ -125,7 +125,7 @@
(<>
(div :id "the-header" (h3 "Page header — not selected"))
(div :id "the-content"
(span :class "text-emerald-700 text-sm"
(span (~tw :tokens "text-emerald-700 text-sm")
"This fragment was selected from a larger response. Time: " now))
(div :id "the-footer" (p "Page footer — not selected"))
(~docs/oob-code :target-id "ref-wire-sx-select"
@@ -141,7 +141,7 @@
(let ((q (helper "request-arg" "q" "")))
(sleep 800)
(<>
(span :class "text-stone-800 text-sm" "Echo: " (strong q))
(span (~tw :tokens "text-stone-800 text-sm") "Echo: " (strong q))
(~docs/oob-code :target-id "ref-wire-sx-sync"
:text (str "(span :class \"text-stone-800 text-sm\" \"Echo: \" (strong \"" q "\"))")))))
@@ -154,7 +154,7 @@
(&key)
(let ((name (helper "request-header" "SX-Prompt" "anonymous")))
(<>
(span :class "text-stone-800 text-sm" "Hello, " (strong name) "!")
(span (~tw :tokens "text-stone-800 text-sm") "Hello, " (strong name) "!")
(~docs/oob-code :target-id "ref-wire-sx-prompt"
:text (str "(span :class \"text-stone-800 text-sm\" \"Hello, \" (strong \"" name "\") \"!\")")))))
@@ -184,7 +184,7 @@
(let ((display (if (nil? name) "(no file)" name)))
(let ((sx-text (str "(span :class \"text-stone-800 text-sm\" \"Received: \" (strong \"" display "\"))")))
(<>
(span :class "text-stone-800 text-sm" "Received: " (strong display))
(span (~tw :tokens "text-stone-800 text-sm") "Received: " (strong display))
(~docs/oob-code :target-id "ref-wire-sx-encoding" :text sx-text))))))
;; --- sx-headers demo: echo custom headers ---
@@ -206,8 +206,8 @@
")"))))
(<>
(if (empty? custom)
(span :class "text-stone-400 text-sm" "No custom headers received.")
(ul :class "text-sm text-stone-700 space-y-1"
(span (~tw :tokens "text-stone-400 text-sm") "No custom headers received.")
(ul (~tw :tokens "text-sm text-stone-700 space-y-1")
(map (fn (pair) (li (strong (first pair)) ": " (nth pair 1))) custom)))
(~docs/oob-code :target-id "ref-wire-sx-headers" :text sx-text))))))
@@ -227,8 +227,8 @@
")"))))
(<>
(if (empty? vals)
(span :class "text-stone-400 text-sm" "No values received.")
(ul :class "text-sm text-stone-700 space-y-1"
(span (~tw :tokens "text-stone-400 text-sm") "No values received.")
(ul (~tw :tokens "text-sm text-stone-700 space-y-1")
(map (fn (pair) (li (strong (first pair)) ": " (nth pair 1))) vals)))
(~docs/oob-code :target-id "ref-wire-sx-include" :text sx-text)))))
@@ -249,8 +249,8 @@
")"))))
(<>
(if (empty? vals)
(span :class "text-stone-400 text-sm" "No values received.")
(ul :class "text-sm text-stone-700 space-y-1"
(span (~tw :tokens "text-stone-400 text-sm") "No values received.")
(ul (~tw :tokens "text-sm text-stone-700 space-y-1")
(map (fn (pair) (li (strong (first pair)) ": " (nth pair 1))) vals)))
(~docs/oob-code :target-id "ref-wire-sx-vals" :text sx-text)))))
@@ -270,7 +270,7 @@
"")
(let ((sx-text (str "(span :class \"text-emerald-700 text-sm\" \"Success on attempt \" \"" n "\" \"!\")")))
(<>
(span :class "text-emerald-700 text-sm" "Success on attempt " (str n) "!")
(span (~tw :tokens "text-emerald-700 text-sm") "Success on attempt " (str n) "!")
(~docs/oob-code :target-id "ref-wire-sx-retry" :text sx-text)))))))
;; --- sx-trigger-event demo: response header triggers ---
@@ -283,7 +283,7 @@
(let ((now (helper "now" "%H:%M:%S")))
(set-response-header "SX-Trigger" "showNotice")
(<>
(span :class "text-stone-800 text-sm" "Loaded at " (strong now) " — check the border!"))))
(span (~tw :tokens "text-stone-800 text-sm") "Loaded at " (strong now) " — check the border!"))))
;; --- sx-retarget demo: response header retargets ---
@@ -295,4 +295,4 @@
(let ((now (helper "now" "%H:%M:%S")))
(set-response-header "SX-Retarget" "#ref-hdr-retarget-alt")
(<>
(span :class "text-violet-700 text-sm" "Retargeted at " (strong now)))))
(span (~tw :tokens "text-violet-700 text-sm") "Retargeted at " (strong now)))))

View File

@@ -10,7 +10,7 @@
(if
(or (= filename "") (= def-name ""))
(div
:class "text-sm text-stone-400 p-2"
(~tw :tokens "text-sm text-stone-400 p-2")
"Missing file or name parameter")
(let
((d (spec-explore-define filename def-name)))
@@ -18,5 +18,5 @@
d
(~specs-explorer/spec-explorer-define-detail :d d :filename filename)
(div
:class "text-sm text-stone-400 p-2"
(~tw :tokens "text-sm text-stone-400 p-2")
(str "Definition '" def-name "' not found in " filename)))))))