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

@@ -4,7 +4,7 @@
(~docs/page
:title "Capabilities"
(p
:class "text-stone-500 text-sm italic mb-8"
(~tw :tokens "text-stone-500 text-sm italic mb-8")
"Abstract evaluation contexts — what an expression is allowed to do, without prescribing where it runs.")
(~docs/section
:title "The model"
@@ -32,34 +32,34 @@
:title "Capability primitives"
:id "primitives"
(table
:class "min-w-full text-sm mb-6"
(~tw :tokens "min-w-full text-sm mb-6")
(thead
(tr
(th
:class "text-left pr-4 pb-2 font-semibold text-stone-700"
(~tw :tokens "text-left pr-4 pb-2 font-semibold text-stone-700")
"Primitive")
(th :class "text-left pb-2 font-semibold text-stone-700" "Purpose")))
(th (~tw :tokens "text-left pb-2 font-semibold text-stone-700") "Purpose")))
(tbody
:class "text-stone-600"
(~tw :tokens "text-stone-600")
(tr
(td :class "pr-4 py-1 font-mono text-xs" "with-capabilities")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "with-capabilities")
(td
:class "py-1"
(~tw :tokens "py-1")
"Restrict capabilities for a body. Takes a list of capability names and a thunk."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "has-capability?")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "has-capability?")
(td
:class "py-1"
(~tw :tokens "py-1")
"Check if a capability is available. Returns true in unrestricted contexts."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "require-capability!")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "require-capability!")
(td
:class "py-1"
(~tw :tokens "py-1")
"Assert a capability. Error with a clear message if not available."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "current-capabilities")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "current-capabilities")
(td
:class "py-1"
(~tw :tokens "py-1")
"Return the current capability set, or nil if unrestricted.")))))
(~docs/section
:title "Effect annotations"
@@ -81,41 +81,41 @@
:title "Standard capabilities"
:id "standard"
(table
:class "min-w-full text-sm mb-6"
(~tw :tokens "min-w-full text-sm mb-6")
(thead
(tr
(th
:class "text-left pr-4 pb-2 font-semibold text-stone-700"
(~tw :tokens "text-left pr-4 pb-2 font-semibold text-stone-700")
"Capability")
(th
:class "text-left pb-2 font-semibold text-stone-700"
(~tw :tokens "text-left pb-2 font-semibold text-stone-700")
"What it permits")))
(tbody
:class "text-stone-600"
(~tw :tokens "text-stone-600")
(tr
(td :class "pr-4 py-1 font-mono text-xs" "pure")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "pure")
(td
:class "py-1"
(~tw :tokens "py-1")
"No side effects. Deterministic. Cacheable. Runnable anywhere."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "mutation")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "mutation")
(td
:class "py-1"
(~tw :tokens "py-1")
"Mutable state: set!, append!, dict-set!, signal mutation."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "io")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "io")
(td
:class "py-1"
(~tw :tokens "py-1")
"External I/O: network, filesystem, timers, promises."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "dom")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "dom")
(td
:class "py-1"
(~tw :tokens "py-1")
"Browser DOM operations: create elements, set attributes, event listeners."))
(tr
(td :class "pr-4 py-1 font-mono text-xs" "render")
(td (~tw :tokens "pr-4 py-1 font-mono text-xs") "render")
(td
:class "py-1"
(~tw :tokens "py-1")
"Rendering operations: component expansion, HTML generation, DOM patching.")))))
(~docs/section
:title "Why not phases?"
@@ -145,7 +145,7 @@
"The same expression can evaluate on the server or in the browser. The capability context determines which is possible, but the "
(em "code")
" is identical.")
(h4 :class "font-semibold mt-6 mb-2" "Server-side fetch")
(h4 (~tw :tokens "font-semibold mt-6 mb-2") "Server-side fetch")
(p
"A component that fetches data during SSR. The server has "
(code "io")
@@ -160,7 +160,7 @@
" annotation documents the requirement — if you try to call this in a "
(code "pure")
" context, it fails with a clear error.")
(h4 :class "font-semibold mt-6 mb-2" "Client-side fetch")
(h4 (~tw :tokens "font-semibold mt-6 mb-2") "Client-side fetch")
(p
"An island that fetches after hydration. The browser has "
(code "io")
@@ -171,7 +171,7 @@
"lisp"))
(p
"Same data, same UI, different evaluation context. The server version is faster (no roundtrip from browser). The client version is interactive (can refetch, react to user actions). The capability model lets the same language express both without separate 'server code' and 'client code' concepts.")
(h4 :class "font-semibold mt-6 mb-2" "The same component, both ways")
(h4 (~tw :tokens "font-semibold mt-6 mb-2") "The same component, both ways")
(p
"With isomorphic evaluation, a single component can be SSR'd on first load (server provides "
(code "io")

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
(defcomp ~geography/eval-rules-content ()
(~docs/page :title "Evaluation Rules"
(p :class "text-stone-500 text-sm italic mb-8"
(p (~tw :tokens "text-stone-500 text-sm italic mb-8")
"Machine-readable SX semantics — a non-circular reference for how the language evaluates expressions.")
(~docs/section :title "Why rules as data" :id "why"
@@ -9,22 +9,22 @@
(~docs/code :src (str ";; Ask the MCP server to explain a form\nsx_explain name=\"let\"\n\nlet\n Category: special-form\n Pattern: (let ((name val) ...) body ...)\n Effects: (none)\n\nCreate new scope. Evaluate each val sequentially,\nbind name. Last body form is in tail position.\n\nExamples:\n (let ((x 1) (y 2)) (+ x y)) → 3")))
(~docs/section :title "Rule categories" :id "categories"
(table :class "min-w-full text-sm mb-6"
(table (~tw :tokens "min-w-full text-sm mb-6")
(thead
(tr
(th :class "text-left pr-4 pb-2 font-semibold text-stone-700" "Category")
(th :class "text-left pr-4 pb-2 font-semibold text-stone-700" "Count")
(th :class "text-left pb-2 font-semibold text-stone-700" "What it covers")))
(tbody :class "text-stone-600"
(tr (td :class "pr-4 py-1 font-mono text-xs" "literal") (td :class "pr-4 py-1" "6") (td :class "py-1" "Numbers, strings, booleans, nil, keywords, dicts"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "lookup") (td :class "pr-4 py-1" "1") (td :class "py-1" "Symbol resolution: env → primitives → error"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "special-form") (td :class "pr-4 py-1" "13") (td :class "py-1" "if, when, cond, case, let, letrec, lambda, define, set!, begin, quote, quasiquote, ->"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "definition") (td :class "pr-4 py-1" "3") (td :class "py-1" "defcomp, defisland, defmacro"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "higher-order") (td :class "pr-4 py-1" "6") (td :class "py-1" "map, filter, reduce, some, every?, for-each"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "scope") (td :class "pr-4 py-1" "5") (td :class "py-1" "scope, provide, context, emit!, emitted"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "continuation") (td :class "pr-4 py-1" "2") (td :class "py-1" "reset, shift (delimited continuations)"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "reactive") (td :class "pr-4 py-1" "1") (td :class "py-1" "deref (signal reading)"))
(tr (td :class "pr-4 py-1 font-mono text-xs" "call") (td :class "pr-4 py-1" "1") (td :class "py-1" "General function call dispatch")))))
(th (~tw :tokens "text-left pr-4 pb-2 font-semibold text-stone-700") "Category")
(th (~tw :tokens "text-left pr-4 pb-2 font-semibold text-stone-700") "Count")
(th (~tw :tokens "text-left pb-2 font-semibold text-stone-700") "What it covers")))
(tbody (~tw :tokens "text-stone-600")
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "literal") (td (~tw :tokens "pr-4 py-1") "6") (td (~tw :tokens "py-1") "Numbers, strings, booleans, nil, keywords, dicts"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "lookup") (td (~tw :tokens "pr-4 py-1") "1") (td (~tw :tokens "py-1") "Symbol resolution: env → primitives → error"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "special-form") (td (~tw :tokens "pr-4 py-1") "13") (td (~tw :tokens "py-1") "if, when, cond, case, let, letrec, lambda, define, set!, begin, quote, quasiquote, ->"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "definition") (td (~tw :tokens "pr-4 py-1") "3") (td (~tw :tokens "py-1") "defcomp, defisland, defmacro"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "higher-order") (td (~tw :tokens "pr-4 py-1") "6") (td (~tw :tokens "py-1") "map, filter, reduce, some, every?, for-each"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "scope") (td (~tw :tokens "pr-4 py-1") "5") (td (~tw :tokens "py-1") "scope, provide, context, emit!, emitted"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "continuation") (td (~tw :tokens "pr-4 py-1") "2") (td (~tw :tokens "py-1") "reset, shift (delimited continuations)"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "reactive") (td (~tw :tokens "pr-4 py-1") "1") (td (~tw :tokens "py-1") "deref (signal reading)"))
(tr (td (~tw :tokens "pr-4 py-1 font-mono text-xs") "call") (td (~tw :tokens "pr-4 py-1") "1") (td (~tw :tokens "py-1") "General function call dispatch")))))
(~docs/section :title "The sx_explain tool" :id "tool"
(p "Query rules by name or category:")

View File

@@ -2,63 +2,63 @@
;; Describes the rendering pipeline: OCaml evaluator → wire formats → client
(defcomp ~geography/index-content () :affinity :server
(div :class "max-w-4xl mx-auto px-6 pb-8 pt-4"
(h2 :class "text-3xl font-bold text-stone-800 mb-4" "Geography")
(p :class "text-lg text-stone-600 mb-8"
(div (~tw :tokens "max-w-4xl mx-auto px-6 pb-8 pt-4")
(h2 (~tw :tokens "text-3xl font-bold text-stone-800 mb-4") "Geography")
(p (~tw :tokens "text-lg text-stone-600 mb-8")
"Where code runs and how it gets there. Geography maps the rendering pipeline from server-side evaluation through wire formats to client-side hydration.")
;; Architecture diagram
(div :class "bg-stone-50 border border-stone-200 rounded-lg p-6 mb-8"
(h3 :class "text-xl font-semibold text-stone-700 mb-4" "Rendering Pipeline")
(div :class "space-y-4"
(div (~tw :tokens "bg-stone-50 border border-stone-200 rounded-lg p-6 mb-8")
(h3 (~tw :tokens "text-xl font-semibold text-stone-700 mb-4") "Rendering Pipeline")
(div (~tw :tokens "space-y-4")
;; Server
(div :class "flex items-start gap-4"
(div :class "w-28 shrink-0 font-mono text-sm font-semibold text-sky-700 bg-sky-50 rounded px-2 py-1 text-center" "OCaml kernel")
(div (~tw :tokens "flex items-start gap-4")
(div (~tw :tokens "w-28 shrink-0 font-mono text-sm font-semibold text-sky-700 bg-sky-50 rounded px-2 py-1 text-center") "OCaml kernel")
(div
(p :class "text-stone-700"
(p (~tw :tokens "text-stone-700")
"The evaluator is a CEK machine written in SX and bootstrapped to OCaml. It evaluates page definitions, expands components, resolves IO (helpers, queries), and serializes the result as SX wire format.")
(p :class "text-sm text-stone-500 mt-1"
(p (~tw :tokens "text-sm text-stone-500 mt-1")
"spec/evaluator.sx → hosts/ocaml/ → aser-slot with batch IO")))
;; Wire format
(div :class "flex items-start gap-4"
(div :class "w-28 shrink-0 font-mono text-sm font-semibold text-amber-700 bg-amber-50 rounded px-2 py-1 text-center" "Wire format")
(div (~tw :tokens "flex items-start gap-4")
(div (~tw :tokens "w-28 shrink-0 font-mono text-sm font-semibold text-amber-700 bg-amber-50 rounded px-2 py-1 text-center") "Wire format")
(div
(p :class "text-stone-700"
(p (~tw :tokens "text-stone-700")
"The aser (async-serialize) mode produces SX text — HTML tags and component calls serialized as s-expressions. Components with server affinity are expanded; client components stay as calls. The wire format is placed in a "
(code :class "text-sm" "<script type=\"text/sx\">")
(code (~tw :tokens "text-sm") "<script type=\"text/sx\">")
" tag inside the HTML shell.")
(p :class "text-sm text-stone-500 mt-1"
(p (~tw :tokens "text-sm text-stone-500 mt-1")
"web/adapter-sx.sx → SxExpr values pass through serialize unquoted")))
;; Client
(div :class "flex items-start gap-4"
(div :class "w-28 shrink-0 font-mono text-sm font-semibold text-emerald-700 bg-emerald-50 rounded px-2 py-1 text-center" "sx-browser.js")
(div (~tw :tokens "flex items-start gap-4")
(div (~tw :tokens "w-28 shrink-0 font-mono text-sm font-semibold text-emerald-700 bg-emerald-50 rounded px-2 py-1 text-center") "sx-browser.js")
(div
(p :class "text-stone-700"
(p (~tw :tokens "text-stone-700")
"The client engine parses the SX wire format, evaluates component definitions, renders the DOM, and hydrates reactive islands. It includes the same CEK evaluator (transpiled from the spec), the parser, all web adapters, and the orchestration layer for fetch/swap/polling.")
(p :class "text-sm text-stone-500 mt-1"
(p (~tw :tokens "text-sm text-stone-500 mt-1")
"spec/ + web/ → hosts/javascript/cli.py → sx-browser.js (~400KB)")))))
;; What lives where
(h3 :class "text-xl font-semibold text-stone-700 mb-4 mt-8" "What lives where")
(h3 (~tw :tokens "text-xl font-semibold text-stone-700 mb-4 mt-8") "What lives where")
(div :class "grid md:grid-cols-2 gap-4 mb-8"
(div (~tw :tokens "grid md:grid-cols-2 gap-4 mb-8")
;; Spec
(div :class "border border-stone-200 rounded-lg p-4"
(h4 :class "font-semibold text-stone-700 mb-2" "Spec (shared)")
(p :class "text-sm text-stone-600 mb-2" "The canonical SX language, bootstrapped identically to OCaml, JavaScript, and Python:")
(ul :class "text-sm text-stone-600 space-y-1 list-disc ml-4"
(div (~tw :tokens "border border-stone-200 rounded-lg p-4")
(h4 (~tw :tokens "font-semibold text-stone-700 mb-2") "Spec (shared)")
(p (~tw :tokens "text-sm text-stone-600 mb-2") "The canonical SX language, bootstrapped identically to OCaml, JavaScript, and Python:")
(ul (~tw :tokens "text-sm text-stone-600 space-y-1 list-disc ml-4")
(li "CEK evaluator — frames, step function, call dispatch")
(li "Parser — tokenizer, s-expression reader, serializer")
(li "Primitives — ~80 built-in pure functions")
(li "Render modes — HTML, SX wire, DOM")))
;; Web adapters
(div :class "border border-stone-200 rounded-lg p-4"
(h4 :class "font-semibold text-stone-700 mb-2" "Web Adapters")
(p :class "text-sm text-stone-600 mb-2" "SX-defined modules that run on both server and client:")
(ul :class "text-sm text-stone-600 space-y-1 list-disc ml-4"
(div (~tw :tokens "border border-stone-200 rounded-lg p-4")
(h4 (~tw :tokens "font-semibold text-stone-700 mb-2") "Web Adapters")
(p (~tw :tokens "text-sm text-stone-600 mb-2") "SX-defined modules that run on both server and client:")
(ul (~tw :tokens "text-sm text-stone-600 space-y-1 list-disc ml-4")
(li "adapter-sx.sx — aser wire format (server component expansion)")
(li "adapter-html.sx — server HTML rendering")
(li "adapter-dom.sx — client DOM rendering")
@@ -66,20 +66,20 @@
(li "engine.sx — trigger parsing, request building")))
;; OCaml kernel
(div :class "border border-stone-200 rounded-lg p-4"
(h4 :class "font-semibold text-stone-700 mb-2" "OCaml Kernel (server)")
(p :class "text-sm text-stone-600 mb-2" "Persistent process connected via a binary pipe protocol:")
(ul :class "text-sm text-stone-600 space-y-1 list-disc ml-4"
(div (~tw :tokens "border border-stone-200 rounded-lg p-4")
(h4 (~tw :tokens "font-semibold text-stone-700 mb-2") "OCaml Kernel (server)")
(p (~tw :tokens "text-sm text-stone-600 mb-2") "Persistent process connected via a binary pipe protocol:")
(ul (~tw :tokens "text-sm text-stone-600 space-y-1 list-disc ml-4")
(li "CEK evaluator + VM bytecode compiler")
(li "Batch IO bridge — defers helper/query calls to Python")
(li "Length-prefixed blob protocol — no string escaping")
(li "Component hot-reload on .sx file changes")))
;; sx-browser.js
(div :class "border border-stone-200 rounded-lg p-4"
(h4 :class "font-semibold text-stone-700 mb-2" "sx-browser.js (client)")
(p :class "text-sm text-stone-600 mb-2" "Single JS bundle transpiled from spec + web adapters:")
(ul :class "text-sm text-stone-600 space-y-1 list-disc ml-4"
(div (~tw :tokens "border border-stone-200 rounded-lg p-4")
(h4 (~tw :tokens "font-semibold text-stone-700 mb-2") "sx-browser.js (client)")
(p (~tw :tokens "text-sm text-stone-600 mb-2") "Single JS bundle transpiled from spec + web adapters:")
(ul (~tw :tokens "text-sm text-stone-600 space-y-1 list-disc ml-4")
(li "Parses SX wire format from script tags")
(li "Renders component trees to DOM")
(li "Hydrates reactive islands (signals, effects)")
@@ -87,62 +87,62 @@
(li "HTMX-like fetch/swap orchestration"))))
;; Rendering modes
(h3 :class "text-xl font-semibold text-stone-700 mb-4 mt-8" "Rendering Modes")
(h3 (~tw :tokens "text-xl font-semibold text-stone-700 mb-4 mt-8") "Rendering Modes")
(div :class "overflow-x-auto mb-8"
(table :class "w-full text-sm"
(div (~tw :tokens "overflow-x-auto mb-8")
(table (~tw :tokens "w-full text-sm")
(thead
(tr :class "border-b border-stone-200"
(th :class "px-3 py-2 text-left font-medium text-stone-600" "Mode")
(th :class "px-3 py-2 text-left font-medium text-stone-600" "Runs on")
(th :class "px-3 py-2 text-left font-medium text-stone-600" "Components")
(th :class "px-3 py-2 text-left font-medium text-stone-600" "Output")))
(tr (~tw :tokens "border-b border-stone-200")
(th (~tw :tokens "px-3 py-2 text-left font-medium text-stone-600") "Mode")
(th (~tw :tokens "px-3 py-2 text-left font-medium text-stone-600") "Runs on")
(th (~tw :tokens "px-3 py-2 text-left font-medium text-stone-600") "Components")
(th (~tw :tokens "px-3 py-2 text-left font-medium text-stone-600") "Output")))
(tbody
(tr :class "border-b border-stone-100"
(td :class "px-3 py-2 font-mono" "render-to-html")
(td :class "px-3 py-2" "Server (OCaml)")
(td :class "px-3 py-2" "Expanded recursively")
(td :class "px-3 py-2" "HTML string"))
(tr :class "border-b border-stone-100"
(td :class "px-3 py-2 font-mono" "aser / aser-slot")
(td :class "px-3 py-2" "Server (OCaml)")
(td :class "px-3 py-2" "Server-affinity expanded; client preserved")
(td :class "px-3 py-2" "SX wire format"))
(tr :class "border-b border-stone-100"
(td :class "px-3 py-2 font-mono" "render-to-dom")
(td :class "px-3 py-2" "Client (sx-browser.js)")
(td :class "px-3 py-2" "Expanded recursively")
(td :class "px-3 py-2" "DOM nodes"))
(tr :class "border-b border-stone-100"
(td :class "px-3 py-2 font-mono" "client routing")
(td :class "px-3 py-2" "Client (sx-browser.js)")
(td :class "px-3 py-2" "defpage content evaluated locally")
(td :class "px-3 py-2" "DOM swap")))))
(tr (~tw :tokens "border-b border-stone-100")
(td (~tw :tokens "px-3 py-2 font-mono") "render-to-html")
(td (~tw :tokens "px-3 py-2") "Server (OCaml)")
(td (~tw :tokens "px-3 py-2") "Expanded recursively")
(td (~tw :tokens "px-3 py-2") "HTML string"))
(tr (~tw :tokens "border-b border-stone-100")
(td (~tw :tokens "px-3 py-2 font-mono") "aser / aser-slot")
(td (~tw :tokens "px-3 py-2") "Server (OCaml)")
(td (~tw :tokens "px-3 py-2") "Server-affinity expanded; client preserved")
(td (~tw :tokens "px-3 py-2") "SX wire format"))
(tr (~tw :tokens "border-b border-stone-100")
(td (~tw :tokens "px-3 py-2 font-mono") "render-to-dom")
(td (~tw :tokens "px-3 py-2") "Client (sx-browser.js)")
(td (~tw :tokens "px-3 py-2") "Expanded recursively")
(td (~tw :tokens "px-3 py-2") "DOM nodes"))
(tr (~tw :tokens "border-b border-stone-100")
(td (~tw :tokens "px-3 py-2 font-mono") "client routing")
(td (~tw :tokens "px-3 py-2") "Client (sx-browser.js)")
(td (~tw :tokens "px-3 py-2") "defpage content evaluated locally")
(td (~tw :tokens "px-3 py-2") "DOM swap")))))
;; Topics
(h3 :class "text-xl font-semibold text-stone-700 mb-4 mt-8" "Topics")
(h3 (~tw :tokens "text-xl font-semibold text-stone-700 mb-4 mt-8") "Topics")
(div :class "grid md:grid-cols-2 gap-4"
(a :href "/sx/(geography.(hypermedia))" :class "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors"
(h4 :class "font-semibold text-stone-700" "Hypermedia Lakes")
(p :class "text-sm text-stone-500" "Server-driven UI with sx-get/post/put/delete — fetch, swap, and the request lifecycle."))
(div (~tw :tokens "grid md:grid-cols-2 gap-4")
(a :href "/sx/(geography.(hypermedia))" (~tw :tokens "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors")
(h4 (~tw :tokens "font-semibold text-stone-700") "Hypermedia Lakes")
(p (~tw :tokens "text-sm text-stone-500") "Server-driven UI with sx-get/post/put/delete — fetch, swap, and the request lifecycle."))
(a :href "/sx/(geography.(reactive))" :class "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors"
(h4 :class "font-semibold text-stone-700" "Reactive Islands")
(p :class "text-sm text-stone-500" "Client-side signals and effects hydrated from server-rendered HTML. defisland, deref, lakes."))
(a :href "/sx/(geography.(reactive))" (~tw :tokens "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors")
(h4 (~tw :tokens "font-semibold text-stone-700") "Reactive Islands")
(p (~tw :tokens "text-sm text-stone-500") "Client-side signals and effects hydrated from server-rendered HTML. defisland, deref, lakes."))
(a :href "/sx/(geography.(marshes))" :class "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors"
(h4 :class "font-semibold text-stone-700" "Marshes")
(p :class "text-sm text-stone-500" "Where reactivity and hypermedia interpenetrate — server writes to signals, reactive views reshape server content."))
(a :href "/sx/(geography.(marshes))" (~tw :tokens "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors")
(h4 (~tw :tokens "font-semibold text-stone-700") "Marshes")
(p (~tw :tokens "text-sm text-stone-500") "Where reactivity and hypermedia interpenetrate — server writes to signals, reactive views reshape server content."))
(a :href "/sx/(geography.(scopes))" :class "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors"
(h4 :class "font-semibold text-stone-700" "Scopes")
(p :class "text-sm text-stone-500" "Render-time dynamic scope — the primitive beneath provide, collect!, spreads, and islands."))
(a :href "/sx/(geography.(scopes))" (~tw :tokens "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors")
(h4 (~tw :tokens "font-semibold text-stone-700") "Scopes")
(p (~tw :tokens "text-sm text-stone-500") "Render-time dynamic scope — the primitive beneath provide, collect!, spreads, and islands."))
(a :href "/sx/(geography.(cek))" :class "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors"
(h4 :class "font-semibold text-stone-700" "CEK Machine")
(p :class "text-sm text-stone-500" "The evaluator internals — frames, continuations, tail-call optimization, and the VM bytecode compiler."))
(a :href "/sx/(geography.(cek))" (~tw :tokens "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors")
(h4 (~tw :tokens "font-semibold text-stone-700") "CEK Machine")
(p (~tw :tokens "text-sm text-stone-500") "The evaluator internals — frames, continuations, tail-call optimization, and the VM bytecode compiler."))
(a :href "/sx/(geography.(isomorphism))" :class "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors"
(h4 :class "font-semibold text-stone-700" "Isomorphism")
(p :class "text-sm text-stone-500" "One spec, multiple hosts — how the same SX code runs on OCaml, JavaScript, and Python.")))))
(a :href "/sx/(geography.(isomorphism))" (~tw :tokens "block border border-stone-200 rounded-lg p-4 hover:border-sky-300 hover:bg-sky-50 transition-colors")
(h4 (~tw :tokens "font-semibold text-stone-700") "Isomorphism")
(p (~tw :tokens "text-sm text-stone-500") "One spec, multiple hosts — how the same SX code runs on OCaml, JavaScript, and Python.")))))

View File

@@ -1,6 +1,6 @@
(defcomp ~geography/modules-content ()
(~docs/page :title "Modules"
(p :class "text-stone-500 text-sm italic mb-8"
(p (~tw :tokens "text-stone-500 text-sm italic mb-8")
"Declaring what a file needs — for documentation, static analysis, and tooling.")
(~docs/section :title "The use form" :id "use-form"
@@ -9,22 +9,22 @@
(p (code "use") " is purely declarative — it doesn't load anything. The glob loader still loads all " (code ".sx") " files. The declaration documents intent and enables static checking."))
(~docs/section :title "What use enables" :id "what-it-enables"
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Dependency visibility")
(h4 (~tw :tokens "font-semibold text-stone-700 mt-6 mb-2") "Dependency visibility")
(p "The " (code "sx_deps") " tool reports both referenced symbols and declared modules. If a file references " (code "resource") " but doesn't " (code "(use web-signals)") ", the tool flags the gap.")
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Build pipeline validation")
(h4 (~tw :tokens "font-semibold text-stone-700 mt-6 mb-2") "Build pipeline validation")
(p "The " (code "sx_build_manifest") " tool shows which modules are in the current build. Cross-referencing with " (code "use") " declarations catches missing build modules — exactly the bug that caused the " (code "resource") " island hydration failure.")
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Documentation")
(h4 (~tw :tokens "font-semibold text-stone-700 mt-6 mb-2") "Documentation")
(p "For humans and LLMs reading a file: " (code "use") " declarations immediately show what the file depends on, without grep."))
(~docs/section :title "Semantics" :id "semantics"
(p (code "(use name)") " is a no-op at evaluation time. It does not:")
(ul :class "space-y-1 text-stone-600 ml-4"
(ul (~tw :tokens "space-y-1 text-stone-600 ml-4")
(li "Load any files")
(li "Modify the environment")
(li "Affect evaluation order")
(li "Create any runtime cost"))
(p "It " (em "does") ":")
(ul :class "space-y-1 text-stone-600 ml-4"
(ul (~tw :tokens "space-y-1 text-stone-600 ml-4")
(li "Appear in the parsed tree for static analysis")
(li "Get reported by " (code "sx_deps"))
(li "Enable future tooling (unused-import warnings, auto-import suggestions)")))))