Step 17: streaming render — hyperscript enhancements, WASM builds, live server tests

Streaming chunked transfer with shell-first suspense and resolve scripts.
Hyperscript parser/compiler/runtime expanded for conformance. WASM static
assets added to OCaml host. Playwright streaming and page-level test suites.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 08:41:38 +00:00
parent 7aefe4da8f
commit 6e27442d57
29 changed files with 65959 additions and 628 deletions

View File

@@ -1,7 +1,4 @@
{
"status": "failed",
"failedTests": [
"0ca76506ebddb95b746c-2b2f50f2cbbb858d1272",
"0ca76506ebddb95b746c-8f9d78e488ffc61daf33"
]
"status": "passed",
"failedTests": []
}

View File

@@ -1,33 +0,0 @@
# Page snapshot
```yaml
- main [ref=e4]:
- generic [ref=e6]:
- complementary
- generic [ref=e7]:
- generic [ref=e8]:
- generic [ref=e11]:
- link "(<sx>)" [ref=e12] [cursor=pointer]:
- /url: /sx/
- generic [ref=e14]: (<sx>)
- paragraph [ref=e15]: The framework-free reactive hypermedium
- paragraph [ref=e17]: © Giles Bradshaw 2026· /sx/
- generic [ref=e19]:
- link "Geography" [ref=e20] [cursor=pointer]:
- /url: /sx/(geography)
- link "Language" [ref=e21] [cursor=pointer]:
- /url: /sx/(language)
- link "Applications" [ref=e22] [cursor=pointer]:
- /url: /sx/(applications)
- link "Tools" [ref=e23] [cursor=pointer]:
- /url: /sx/(tools)
- link "Etc" [ref=e24] [cursor=pointer]:
- /url: /sx/(etc)
- generic [ref=e29]:
- generic [ref=e30]: (div (~tw :tokens "text-center") (h1 (~tw :tokens "text-3xl font-bold mb-2") (span (~tw :tokens "text-rose-500") "the ") (span (~tw :tokens "text-amber-500") "joy ") (span (~tw :tokens "text-emerald-500") "of ") (span (~tw :tokens "text-violet-600 text-4xl") "sx")))
- generic [ref=e31]:
- button "◀" [ref=e32] [cursor=pointer]
- generic [ref=e33]: 16 / 16
- button "▶" [ref=e34] [cursor=pointer]
- heading "the joy of sx" [level=1] [ref=e37]
```

View File

@@ -1,158 +0,0 @@
# Page snapshot
```yaml
- main [ref=e4]:
- generic [ref=e6]:
- complementary
- generic [ref=e7]:
- generic [ref=e8]:
- generic [ref=e11]:
- link "(<sx>)" [ref=e12] [cursor=pointer]:
- /url: /sx/
- generic [ref=e14]: (<sx>)
- paragraph [ref=e15]: The framework-free reactive hypermedium
- paragraph [ref=e17]: © Giles Bradshaw 2026· /sx/(geography)
- generic [ref=e18]:
- link "← Etc" [ref=e19] [cursor=pointer]:
- /url: /sx/(etc)
- link "Geography" [ref=e20] [cursor=pointer]:
- /url: /sx/(geography)
- link "Language →" [ref=e21] [cursor=pointer]:
- /url: /sx/(language)
- generic [ref=e23]:
- link "Reactive Islands" [ref=e24] [cursor=pointer]:
- /url: /sx/(geography.(reactive))
- link "Hypermedia Lakes" [ref=e25] [cursor=pointer]:
- /url: /sx/(geography.(hypermedia))
- link "Scopes" [ref=e26] [cursor=pointer]:
- /url: /sx/(geography.(scopes))
- link "Provide / Emit!" [ref=e27] [cursor=pointer]:
- /url: /sx/(geography.(provide))
- link "Spreads" [ref=e28] [cursor=pointer]:
- /url: /sx/(geography.(spreads))
- link "Marshes" [ref=e29] [cursor=pointer]:
- /url: /sx/(geography.(marshes))
- link "Isomorphism" [ref=e30] [cursor=pointer]:
- /url: /sx/(geography.(isomorphism))
- link "CEK Machine" [ref=e31] [cursor=pointer]:
- /url: /sx/(geography.(cek))
- link "Capabilities" [ref=e32] [cursor=pointer]:
- /url: /sx/(geography.(capabilities))
- link "Reactive Runtime" [ref=e33] [cursor=pointer]:
- /url: /sx/(geography.(reactive-runtime))
- generic [ref=e36]:
- heading "Geography" [level=2] [ref=e37]
- paragraph [ref=e38]: Where code runs and how it gets there. Geography maps the rendering pipeline from server-side evaluation through wire formats to client-side hydration.
- generic [ref=e39]:
- heading "Rendering Pipeline" [level=3] [ref=e40]
- generic [ref=e41]:
- generic [ref=e42]:
- generic [ref=e43]: OCaml kernel
- generic [ref=e44]:
- paragraph [ref=e45]: 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.
- paragraph [ref=e46]: spec/evaluator.sx → hosts/ocaml/ → aser-slot with batch IO
- generic [ref=e47]:
- generic [ref=e48]: Wire format
- generic [ref=e49]:
- paragraph [ref=e50]:
- text: 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 [ref=e51]: <script type="text/sx">
- text: tag inside the HTML shell.
- paragraph [ref=e52]: web/adapter-sx.sx → SxExpr values pass through serialize unquoted
- generic [ref=e53]:
- generic [ref=e54]: sx-browser.js
- generic [ref=e55]:
- paragraph [ref=e56]: 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.
- paragraph [ref=e57]: spec/ + web/ → hosts/javascript/cli.py → sx-browser.js (~400KB)
- heading "What lives where" [level=3] [ref=e58]
- generic [ref=e59]:
- generic [ref=e60]:
- heading "Spec (shared)" [level=4] [ref=e61]
- paragraph [ref=e62]: "The canonical SX language, bootstrapped identically to OCaml, JavaScript, and Python:"
- list [ref=e63]:
- listitem [ref=e64]: CEK evaluator — frames, step function, call dispatch
- listitem [ref=e65]: Parser — tokenizer, s-expression reader, serializer
- listitem [ref=e66]: Primitives — ~80 built-in pure functions
- listitem [ref=e67]: Render modes — HTML, SX wire, DOM
- generic [ref=e68]:
- heading "Web Adapters" [level=4] [ref=e69]
- paragraph [ref=e70]: "SX-defined modules that run on both server and client:"
- list [ref=e71]:
- listitem [ref=e72]: adapter-sx.sx — aser wire format (server component expansion)
- listitem [ref=e73]: adapter-html.sx — server HTML rendering
- listitem [ref=e74]: adapter-dom.sx — client DOM rendering
- listitem [ref=e75]: orchestration.sx — fetch, swap, polling, navigation
- listitem [ref=e76]: engine.sx — trigger parsing, request building
- generic [ref=e77]:
- heading "OCaml Kernel (server)" [level=4] [ref=e78]
- paragraph [ref=e79]: "Persistent process connected via a binary pipe protocol:"
- list [ref=e80]:
- listitem [ref=e81]: CEK evaluator + VM bytecode compiler
- listitem [ref=e82]: Batch IO bridge — defers helper/query calls to Python
- listitem [ref=e83]: Length-prefixed blob protocol — no string escaping
- listitem [ref=e84]: Component hot-reload on .sx file changes
- generic [ref=e85]:
- heading "sx-browser.js (client)" [level=4] [ref=e86]
- paragraph [ref=e87]: "Single JS bundle transpiled from spec + web adapters:"
- list [ref=e88]:
- listitem [ref=e89]: Parses SX wire format from script tags
- listitem [ref=e90]: Renders component trees to DOM
- listitem [ref=e91]: Hydrates reactive islands (signals, effects)
- listitem [ref=e92]: Client-side routing with defpage
- listitem [ref=e93]: HTMX-like fetch/swap orchestration
- heading "Rendering Modes" [level=3] [ref=e94]
- table [ref=e96]:
- rowgroup [ref=e97]:
- row "Mode Runs on Components Output" [ref=e98]:
- columnheader "Mode" [ref=e99]
- columnheader "Runs on" [ref=e100]
- columnheader "Components" [ref=e101]
- columnheader "Output" [ref=e102]
- rowgroup [ref=e103]:
- row "render-to-html Server (OCaml) Expanded recursively HTML string" [ref=e104]:
- cell "render-to-html" [ref=e105]
- cell "Server (OCaml)" [ref=e106]
- cell "Expanded recursively" [ref=e107]
- cell "HTML string" [ref=e108]
- row "aser / aser-slot Server (OCaml) Server-affinity expanded; client preserved SX wire format" [ref=e109]:
- cell "aser / aser-slot" [ref=e110]
- cell "Server (OCaml)" [ref=e111]
- cell "Server-affinity expanded; client preserved" [ref=e112]
- cell "SX wire format" [ref=e113]
- row "render-to-dom Client (sx-browser.js) Expanded recursively DOM nodes" [ref=e114]:
- cell "render-to-dom" [ref=e115]
- cell "Client (sx-browser.js)" [ref=e116]
- cell "Expanded recursively" [ref=e117]
- cell "DOM nodes" [ref=e118]
- row "client routing Client (sx-browser.js) defpage content evaluated locally DOM swap" [ref=e119]:
- cell "client routing" [ref=e120]
- cell "Client (sx-browser.js)" [ref=e121]
- cell "defpage content evaluated locally" [ref=e122]
- cell "DOM swap" [ref=e123]
- heading "Topics" [level=3] [ref=e124]
- generic [ref=e125]:
- link "Hypermedia Lakes Server-driven UI with sx-get/post/put/delete — fetch, swap, and the request lifecycle." [ref=e126] [cursor=pointer]:
- /url: /sx/(geography.(hypermedia))
- heading "Hypermedia Lakes" [level=4] [ref=e127]
- paragraph [ref=e128]: Server-driven UI with sx-get/post/put/delete — fetch, swap, and the request lifecycle.
- link "Reactive Islands Client-side signals and effects hydrated from server-rendered HTML. defisland, deref, lakes." [ref=e129] [cursor=pointer]:
- /url: /sx/(geography.(reactive))
- heading "Reactive Islands" [level=4] [ref=e130]
- paragraph [ref=e131]: Client-side signals and effects hydrated from server-rendered HTML. defisland, deref, lakes.
- link "Marshes Where reactivity and hypermedia interpenetrate — server writes to signals, reactive views reshape server content." [ref=e132] [cursor=pointer]:
- /url: /sx/(geography.(marshes))
- heading "Marshes" [level=4] [ref=e133]
- paragraph [ref=e134]: Where reactivity and hypermedia interpenetrate — server writes to signals, reactive views reshape server content.
- link "Scopes Render-time dynamic scope — the primitive beneath provide, collect!, spreads, and islands." [ref=e135] [cursor=pointer]:
- /url: /sx/(geography.(scopes))
- heading "Scopes" [level=4] [ref=e136]
- paragraph [ref=e137]: Render-time dynamic scope — the primitive beneath provide, collect!, spreads, and islands.
- link "CEK Machine The evaluator internals — frames, continuations, tail-call optimization, and the VM bytecode compiler." [ref=e138] [cursor=pointer]:
- /url: /sx/(geography.(cek))
- heading "CEK Machine" [level=4] [ref=e139]
- paragraph [ref=e140]: The evaluator internals — frames, continuations, tail-call optimization, and the VM bytecode compiler.
- link "Isomorphism One spec, multiple hosts — how the same SX code runs on OCaml, JavaScript, and Python." [ref=e141] [cursor=pointer]:
- /url: /sx/(geography.(isomorphism))
- heading "Isomorphism" [level=4] [ref=e142]
- paragraph [ref=e143]: One spec, multiple hosts — how the same SX code runs on OCaml, JavaScript, and Python.
```