Frame-based dynamic scope: 870/870 — all tests passing
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 13m34s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 13m34s
provide/context and scope/emit!/emitted now use CEK continuation frames instead of an imperative global stack. Scope state is part of the continuation — captured by shift, restored by k invocation. New frame types: - ProvideFrame: holds name + value, consumed when body completes - ScopeAccFrame: holds name + mutable emitted list New CEK special forms: - context: walks kont for nearest ProvideFrame, returns value - emit!: walks kont for nearest ScopeAccFrame, appends to emitted - emitted: walks kont for nearest ScopeAccFrame, returns list Kont walkers: kont-find-provide, kont-find-scope-acc This fixes the last 2 test failures: - provide survives resume: scope captured by shift, restored by k - scope and emit across shift: accumulator preserved in continuation JS Full: 870/870 (100%) JS Standard: 747/747 (100%) Python: 679/679 (100%) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -491,6 +491,78 @@
|
||||
(td :class "px-3 py-2 text-stone-600" "Full compiled pipeline. JIT compilation, cached WASM functions, near-native rendering speed."))))))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; WASM responses — htmx with compiled components
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
(~docs/section :title "WASM Responses" :id "wasm-responses"
|
||||
|
||||
(p "The server doesn't have to send HTML fragments for HTMX-style swaps. "
|
||||
"It can send compiled WASM functions that produce DOM directly, "
|
||||
"or \u2014 when the client already has the components cached \u2014 "
|
||||
"just the data as gzipped bytecode.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Three response tiers")
|
||||
|
||||
(div :class "overflow-x-auto rounded border border-stone-200 mb-4"
|
||||
(table :class "w-full text-left text-sm"
|
||||
(thead (tr :class "border-b border-stone-200 bg-stone-100"
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Client cache state")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Server sends")
|
||||
(th :class "px-3 py-2 font-medium text-stone-600" "Client does")))
|
||||
(tbody
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Nothing cached")
|
||||
(td :class "px-3 py-2 text-stone-700" "HTML (fallback)")
|
||||
(td :class "px-3 py-2 text-stone-600" "Parse HTML, morph DOM"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Compiler cached")
|
||||
(td :class "px-3 py-2 text-stone-700" "SX source")
|
||||
(td :class "px-3 py-2 text-stone-600" "Compile, execute, morph DOM"))
|
||||
(tr :class "border-b border-stone-100"
|
||||
(td :class "px-3 py-2 text-stone-700" "Components cached")
|
||||
(td :class "px-3 py-2 text-stone-700" "Bytecode (data only)")
|
||||
(td :class "px-3 py-2 text-stone-600" "Call cached WASM function with args"))
|
||||
(tr
|
||||
(td :class "px-3 py-2 text-stone-700" "Components cached + gzip")
|
||||
(td :class "px-3 py-2 text-stone-700" "Gzipped bytecode")
|
||||
(td :class "px-3 py-2 text-stone-600" "Decompress, call cached function")))))
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Why bytecode is tiny")
|
||||
(p "The bytecode doesn't repeat what the client already knows. "
|
||||
"Component CID references are 4-byte pointers to already-cached compiled functions. "
|
||||
"Tag names, class strings, attribute keys \u2014 all baked into the compiled component. "
|
||||
"The only payload is the data that differs between instances.")
|
||||
|
||||
(~docs/code :code (highlight ";; HTML response: ~450 bytes\n<div class=\"card\"><h2>Hello</h2><p class=\"text-stone-600\">World</p></div>\n\n;; SX source response: ~60 bytes\n(~card :title \"Hello\" :body \"World\")\n\n;; Bytecode response: ~18 bytes\n[CALL_CID bafyrei..card] [STR \"Hello\"] [STR \"World\"]\n\n;; Gzipped bytecode: ~12 bytes" "text"))
|
||||
|
||||
(p "For a list of 50 cards:")
|
||||
|
||||
(~docs/code :code (highlight "HTML: 50\u00d7 <div class=\"card\"><h2>...</h2>...</div> ~22 KB\nSX source: 50\u00d7 (~card :title \"...\" :body \"...\") ~3 KB\nBytecode: [CALL_CID] + 50\u00d7 [STR, STR] ~800 bytes\nGzipped bytecode: ~400 bytes" "text"))
|
||||
|
||||
(p "The markup structure is in the compiled component. "
|
||||
"The class strings are in the compiled component. "
|
||||
"The only thing on the wire is the data that differs between instances. "
|
||||
"Gzip crushes the repetitive framing to almost nothing.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "Content negotiation")
|
||||
(p "The client advertises what it has via request headers:")
|
||||
|
||||
(~docs/code :code (highlight ";; Client tells server what's cached\nAccept: application/sx-bytecode, text/sx, text/html\nX-Sx-Cached-Components: bafyrei..card, bafyrei..header, bafyrei..nav\n\n;; Server picks the smallest response:\n;; - Client has ~card cached? Send bytecode (data only)\n;; - Client has compiler but not ~card? Send SX source\n;; - Client has nothing? Send HTML" "text"))
|
||||
|
||||
(p "The server and client negotiate the optimal response format automatically. "
|
||||
"First visit is HTML (full progressive enhancement). "
|
||||
"Subsequent navigations are gzipped bytecode \u2014 "
|
||||
"just the data, a few hundred bytes, instant render via cached compiled components.")
|
||||
|
||||
(h4 :class "font-semibold mt-4 mb-2" "The server becomes a data API")
|
||||
(p "At the bytecode tier, the server is no longer rendering views. "
|
||||
"It's serving data \u2014 structured arguments for compiled client-side functions. "
|
||||
"The rendering logic is cached on the client as compiled WASM. "
|
||||
"This inverts the traditional server-rendered model without sacrificing "
|
||||
"progressive enhancement \u2014 the HTML fallback is always available."))
|
||||
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; How this changes existing plans
|
||||
;; -----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user