Files
rose-ash/sx/sx/hyperscript-spec.sx
giles 7492ceac4e Restore hyperscript work on stable site base (908f4f80)
Reset to last known-good state (908f4f80) where links, stepper, and
islands all work, then recovered all hyperscript implementation,
conformance tests, behavioral tests, Playwright specs, site sandbox,
IO-aware server loading, and upstream test suite from f271c88a.

Excludes runtime changes (VM resolve hook, VmSuspended browser handler,
sx_ref.ml guard recovery) that need careful re-integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 19:29:56 +00:00

763 lines
29 KiB
Plaintext

;; _hyperscript Language Specification
;; SX Implementation — Formal Reference
(defcomp
~hyperscript/spec-content
()
(~docs/page
:title "_hyperscript Language Specification"
(p
(~tw :tokens "text-lg text-gray-600 mb-8")
"This specification defines the _hyperscript language as implemented by the SX "
"compiler pipeline. _hyperscript source is compiled ahead-of-time to SX expressions "
"targeting the DOM platform primitives — there is no interpreter.")
(~docs/section
:title "1. Overview"
:id "overview"
(p "The _hyperscript compilation pipeline has three stages:")
(ol
(~tw :tokens "list-decimal list-inside space-y-1 text-gray-700 mb-4")
(li
(strong "Tokenize")
" — source string to token list ("
(code "hs-tokenize")
")")
(li
(strong "Parse")
" — token list to AST ("
(code "hs-parse")
", "
(code "hs-compile")
")")
(li
(strong "Compile")
" — AST to SX expressions ("
(code "hs-to-sx")
", "
(code "hs-to-sx-from-source")
")"))
(p
"The compiled SX targets runtime shims in "
(code "lib/hyperscript/runtime.sx")
" which delegate to "
(code "web/lib/dom.sx")
" platform primitives.")
(~docs/subsection
:title "1.1 Attribute Binding"
:id "attribute-binding"
(p
"Hyperscript is bound to DOM elements via the "
(code "_")
" attribute. At boot time, "
(code "hs-boot!")
" scans the document, "
"compiles each attribute value to an SX closure, and invokes it "
"with the element as "
(code "me")
". Dynamic content is activated via "
(code "hs-boot-subtree!")
".")))
(~docs/section
:title "2. Lexical Grammar"
:id "lexical-grammar"
(p
"The tokenizer produces a list of token dicts, each with "
(code ":type")
", "
(code ":value")
", and "
(code ":pos")
" keys.")
(~docs/subsection
:title "2.1 Token Types"
:id "token-types"
(table
(~tw :tokens "w-full text-sm border-collapse mb-6")
(thead
(~tw :tokens "bg-gray-50")
(tr
(th (~tw :tokens "text-left p-2 border-b font-semibold") "Type")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Pattern")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Examples")))
(tbody
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "keyword")
(td (~tw :tokens "p-2") "Reserved word from keyword set")
(td (~tw :tokens "p-2 font-mono") "on, set, add, if, for, def"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "ident")
(td (~tw :tokens "p-2") "Identifier (not a keyword)")
(td (~tw :tokens "p-2 font-mono") "count, x, myVar"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "number")
(td
(~tw :tokens "p-2")
"Integer or decimal, optional ms/s suffix")
(td (~tw :tokens "p-2 font-mono") "42, 3.14, 200ms, 2s"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "string")
(td
(~tw :tokens "p-2")
"Single or double quoted, backslash escapes")
(td (~tw :tokens "p-2 font-mono") "hello, world"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "template")
(td (~tw :tokens "p-2") "Backtick-delimited with interpolation")
(td (~tw :tokens "p-2 font-mono") "count is ..."))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "class")
(td
(~tw :tokens "p-2")
(code ".")
" followed by CSS class name")
(td (~tw :tokens "p-2 font-mono") ".active, .text-red-500"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "id")
(td (~tw :tokens "p-2") (code "#") " followed by identifier")
(td (~tw :tokens "p-2 font-mono") "#main, #output"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "attr")
(td (~tw :tokens "p-2") (code "@") " followed by identifier")
(td (~tw :tokens "p-2 font-mono") "@href, @disabled"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "style")
(td (~tw :tokens "p-2") (code "*") " followed by identifier")
(td (~tw :tokens "p-2 font-mono") "*opacity, *display"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "selector")
(td (~tw :tokens "p-2") "CSS selector in angle brackets")
(td (~tw :tokens "p-2 font-mono") "<button/>, <.item/>"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "local")
(td (~tw :tokens "p-2") (code ":") " followed by identifier")
(td (~tw :tokens "p-2 font-mono") ":count, :name"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "component")
(td (~tw :tokens "p-2") (code "~") " followed by identifier")
(td (~tw :tokens "p-2 font-mono") "~card, ~badge"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "op")
(td (~tw :tokens "p-2") "Operator")
(td (~tw :tokens "p-2 font-mono") "+, -, *, =, ==, !="))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "dot")
(td (~tw :tokens "p-2") "Property access operator")
(td (~tw :tokens "p-2 font-mono") "."))
(tr
(td (~tw :tokens "p-2 font-mono") "eof")
(td (~tw :tokens "p-2") "End of input")
(td (~tw :tokens "p-2") "—")))))
(~docs/subsection
:title "2.2 Comments"
:id "comments"
(p
"Line comments start with "
(code "//")
" and extend to end of line."))
(~docs/subsection
:title "2.3 Keywords (107 reserved words)"
:id "keywords"
(p
"on end set to put into before after add remove toggle "
"if else otherwise then from in of for until wait send "
"trigger call get take log hide show repeat while times "
"forever break continue return throw catch finally def "
"tell make fetch as with every or and not is no the my "
"me it its result true false null when between at by "
"queue elsewhere event target detail sender index "
"increment decrement append settle transition over "
"closest next previous first last random empty exists "
"matches contains do unless you your new init start go "
"js less than greater class anything install measure "
"behavior called render eval"))
(~docs/subsection
:title "2.4 Possessive Operator"
:id "possessive"
(p
"The token "
(code "'s")
" is the possessive operator — equivalent to "
"property access. Only tokenized when followed by whitespace or end-of-input; "
"otherwise "
(code "'")
" begins a string literal.")))
(~docs/section
:title "3. Syntactic Grammar"
:id "syntactic-grammar"
(p
"A program is a sequence of "
(em "features")
" — top-level declarations "
"that define element behavior.")
(~docs/subsection
:title "3.1 Features"
:id "features"
(table
(~tw :tokens "w-full text-sm border-collapse mb-6")
(thead
(~tw :tokens "bg-gray-50")
(tr
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Feature")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Syntax")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Description")))
(tbody
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "on")
(td (~tw :tokens "p-2 text-xs") "on event cmds end")
(td (~tw :tokens "p-2") "Event handler"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "on from")
(td (~tw :tokens "p-2 text-xs") "on event from target cmds end")
(td (~tw :tokens "p-2") "Listen on a different element"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "every")
(td (~tw :tokens "p-2 text-xs") "on every event cmds end")
(td
(~tw :tokens "p-2")
"No queuing — each fires independently"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "def")
(td (~tw :tokens "p-2 text-xs") "def name(params) cmds end")
(td (~tw :tokens "p-2") "Function definition"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "behavior")
(td (~tw :tokens "p-2 text-xs") "behavior Name features end")
(td (~tw :tokens "p-2") "Reusable behavior"))
(tr
(td (~tw :tokens "p-2 font-mono") "init")
(td (~tw :tokens "p-2 text-xs") "init cmds end")
(td (~tw :tokens "p-2") "Run at element boot")))))
(~docs/subsection
:title "3.2 Commands"
:id "commands"
(p
"Commands are imperative statements separated by "
(code "then")
" or newlines.")
(~docs/subsection
:title "Class Manipulation"
:id "cmd-class"
(p (code "add .cls to target") " — append class")
(p (code "remove .cls from target") " — remove class")
(p (code "toggle .cls on target") " — flip one class")
(p
(code "toggle between .a and .b on target")
" — alternate two classes")
(p (code "take .cls") " — add to target, remove from siblings"))
(~docs/subsection
:title "Assignment"
:id "cmd-assignment"
(p (code "set x to 42") " — assign to variable")
(p (code "set my innerHTML to value") " — assign to property")
(p
(code "put value into target")
" — insert content (also before/after)"))
(~docs/subsection
:title "Control Flow"
:id "cmd-control-flow"
(p (code "if condition ... else ... end") " — conditional")
(p (code "for item in collection ... end") " — iteration")
(p (code "repeat N times ... end") " — counted loop")
(p (code "repeat forever ... end") " — infinite loop"))
(~docs/subsection
:title "Events"
:id "cmd-events"
(p
(code "send eventName to target")
" — dispatch with optional detail")
(p (code "trigger eventName") " — dispatch on me")
(p (code "wait 200ms") " — pause execution")
(p (code "wait for transitionend") " — suspend until DOM event"))
(~docs/subsection
:title "DOM"
:id "cmd-dom"
(p (code "hide me") " — set display: none")
(p (code "show me") " — restore display")
(p (code "log value") " — console.log")
(p (code "go to url path") " — navigate"))
(~docs/subsection
:title "Other Commands"
:id "cmd-other"
(p (code "increment :count") " / " (code "decrement :count by 5"))
(p (code "tell target ... end") " — rebind me for block")
(p (code "append value to :list") " — add to collection")
(p (code "fetch url as json") " — HTTP request (json/text/html)")
(p (code "call myFunc(args)") " — function call")
(p (code "make a Set") " — create object")
(p (code "measure me") " — bounding rect")
(p
(code "transition *opacity to 0 over 300ms")
" — CSS animation")
(p (code "install Behavior") " — attach reusable behavior")
(p (code "return value") " — exit def")
(p (code "throw message") " — raise error")))
(~docs/subsection
:title "3.3 Expressions"
:id "expressions"
(~docs/subsection
:title "Literals"
:id "expr-literals"
(p (code "42") ", " (code "3.14") " — numbers")
(p (code "200ms") ", " (code "2s") " — durations")
(p "Single/double quoted strings, backtick template strings")
(p (code "true") ", " (code "false") ", " (code "null"))
(p (code "[1, 2, 3]") " — array literals"))
(~docs/subsection
:title "References"
:id "expr-references"
(table
(~tw :tokens "w-full text-sm border-collapse mb-4")
(thead
(~tw :tokens "bg-gray-50")
(tr
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Syntax")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Meaning")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Compiles to")))
(tbody
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "me")
(td (~tw :tokens "p-2") "Current element")
(td (~tw :tokens "p-2 font-mono") "me"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "my prop")
(td (~tw :tokens "p-2") "Property of me")
(td (~tw :tokens "p-2 font-mono") "(. me prop)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "it / result")
(td (~tw :tokens "p-2") "Last implicit result")
(td (~tw :tokens "p-2 font-mono") "it"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") ":name")
(td (~tw :tokens "p-2") "Element-scoped local")
(td (~tw :tokens "p-2 font-mono") ":name"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "@attr")
(td (~tw :tokens "p-2") "DOM attribute")
(td (~tw :tokens "p-2 font-mono") "(dom-get-attr me attr)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "*style")
(td (~tw :tokens "p-2") "CSS style property")
(td (~tw :tokens "p-2 font-mono") "(dom-get-style me style)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "#id")
(td (~tw :tokens "p-2") "Element by ID")
(td (~tw :tokens "p-2 font-mono") "(dom-query #id)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "<sel/>")
(td (~tw :tokens "p-2") "CSS selector query")
(td (~tw :tokens "p-2 font-mono") "(dom-query sel)"))
(tr
(td (~tw :tokens "p-2 font-mono") "~name")
(td (~tw :tokens "p-2") "SX component reference")
(td (~tw :tokens "p-2 font-mono") "~name")))))
(~docs/subsection
:title "Operators"
:id "expr-operators"
(p
"Arithmetic: "
(code "+")
" "
(code "-")
" "
(code "*")
" "
(code "/")
" "
(code "%"))
(p
"Comparison: "
(code "==")
" "
(code "!=")
" "
(code "<")
" "
(code ">")
" "
(code "<=")
" "
(code ">=")
" and English: "
(code "is")
", "
(code "is not")
", "
(code "is less than")
", "
(code "is greater than"))
(p
"Logical: "
(code "and")
", "
(code "or")
", "
(code "not")
", "
(code "no")
" (alias for not)")
(p
"Access: "
(code ".")
" (dot), "
(code "'s")
" (possessive), "
(code "the X of Y")))
(~docs/subsection
:title "DOM Traversal"
:id "expr-traversal"
(p (code "closest <div/>") " — walk up ancestors")
(p (code "next <button/>") " — next sibling matching")
(p (code "previous <input/>") " — previous sibling")
(p (code "first in <li/>") " — first child matching")
(p (code "last in <li/>") " — last child matching"))
(~docs/subsection
:title "Predicates"
:id "expr-predicates"
(p
(code "x exists")
", "
(code "x is empty")
", "
(code "x matches .active")
", "
(code "x contains text")))
(~docs/subsection
:title "Type Conversion"
:id "expr-conversion"
(p
(code "x as Int")
", "
(code "x as Float")
", "
(code "x as String")
", "
(code "x as Array")))))
(~docs/section
:title "4. SX Extensions"
:id "sx-extensions"
(p "Three features bridge hyperscript and the SX component system.")
(~docs/subsection
:title "4.1 render — Component Rendering"
:id "sx-render"
(p
(code "render ~card :title 'Hello'")
" — invoke SX component. "
"Compiles to "
(code "(render-to-html ~card :title ...)")
". "
"With a target: "
(code "render ~item into me")
" inserts via "
(code "hs-put!")
"."))
(~docs/subsection
:title "4.2 eval — SX Expression Escape"
:id "sx-eval"
(p
(code "set x to eval (+ 1 2)")
" — inline SX. The s-expression is "
"parsed at compile time and spliced into the AST. Variable references "
"inside "
(code "eval")
" resolve against the hyperscript scope."))
(~docs/subsection
:title "4.3 Component References"
:id "sx-comp-ref"
(p
(code "~name")
" produces a component reference. Multi-segment names "
"like "
(code "~nav/sidebar")
" are supported.")))
(~docs/section
:title "5. Compilation Targets"
:id "compilation-targets"
(p "Each construct compiles to a specific SX expression.")
(table
(~tw :tokens "w-full text-sm border-collapse mb-6")
(thead
(~tw :tokens "bg-gray-50")
(tr
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Hyperscript")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"SX Target")))
(tbody
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "on event ... end")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-on me event (fn (event) ...))"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "on every event")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-on-every me event (fn ...))"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "init ... end")
(td (~tw :tokens "p-2 font-mono text-xs") "(hs-init (fn () ...))"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "add .cls to t")
(td (~tw :tokens "p-2 font-mono text-xs") "(dom-add-class t cls)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "remove .cls from t")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(dom-remove-class t cls)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "toggle .cls")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-toggle-class! me cls)"))
(tr
(~tw :tokens "border-b")
(td
(~tw :tokens "p-2 font-mono text-xs")
"toggle between .a and .b")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-toggle-between! me a b)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "take .cls")
(td (~tw :tokens "p-2 font-mono text-xs") "(hs-take! me cls)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "set x to v")
(td (~tw :tokens "p-2 font-mono text-xs") "(set! x v)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "put v into t")
(td (~tw :tokens "p-2 font-mono text-xs") "(hs-put! v into t)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "if c then a else b")
(td (~tw :tokens "p-2 font-mono text-xs") "(if c a b)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "for x in coll ... end")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(for-each (fn (x) ...) coll)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "repeat N times")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-repeat-times N (fn () ...))"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "wait 200ms")
(td (~tw :tokens "p-2 font-mono text-xs") "(hs-wait 200)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "wait for event")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-wait-for me event)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "send event to t")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(dom-dispatch t event {})"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "hide / show")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(dom-set-style me display ...)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "tell t ... end")
(td (~tw :tokens "p-2 font-mono text-xs") "(let ((me t)) ...)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "def name(p) ... end")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(define name (fn (p) ...))"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "return v / throw v")
(td (~tw :tokens "p-2 font-mono text-xs") "v / (raise v)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "render ~comp :k v")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(render-to-html ~comp :k v)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono text-xs") "fetch url as json")
(td (~tw :tokens "p-2 font-mono text-xs") "(hs-fetch url json)"))
(tr
(~tw :tokens "border-b")
(td
(~tw :tokens "p-2 font-mono text-xs")
"transition *p to v over d")
(td
(~tw :tokens "p-2 font-mono text-xs")
"(hs-transition me p v d)"))
(tr
(td (~tw :tokens "p-2 font-mono text-xs") "install Behavior")
(td (~tw :tokens "p-2 font-mono text-xs") "(hs-install Behavior)")))))
(~docs/section
:title "6. Async Model"
:id "async-model"
(p
"Commands execute sequentially but can suspend transparently via "
(code "perform")
" (IO suspension). The CEK machine suspends and "
"resumes when IO completes.")
(ul
(~tw :tokens "list-disc list-inside space-y-1 text-gray-700 mb-4")
(li (code "wait Nms") " — duration suspension")
(li (code "wait for event") " — DOM event suspension")
(li (code "settle") " — CSS transition completion")
(li (code "fetch") " — HTTP request")
(li (code "measure") " — layout measurement"))
(p "No callback syntax, no async/await. Suspension is automatic."))
(~docs/section
:title "7. Scoping"
:id "scoping"
(p "Three variable scopes:")
(ul
(~tw :tokens "list-disc list-inside space-y-1 text-gray-700 mb-4")
(li
(strong "Element-local")
" — "
(code ":name")
" variables persist across event firings, private to element.")
(li
(strong "Event-local")
" — bare identifiers are local to "
"the current handler invocation.")
(li
(strong "Global")
" — "
(code "def")
" definitions are added "
"to the element's closure environment."))
(p
"Implicit variables: "
(code "me")
" (current element), "
(code "it")
"/"
(code "result")
" (last implicit result), "
(code "event")
" (triggering DOM event in on handlers)."))
(~docs/section
:title "8. Integration with SX"
:id "integration"
(~docs/subsection
:title "8.1 Boot Sequence"
:id "boot-sequence"
(ol
(~tw :tokens "list-decimal list-inside space-y-1 text-gray-700 mb-4")
(li (code "hs-boot!") " scans DOM for _ attributes")
(li (code "hs-activate!") " reads each attribute value")
(li
(code "hs-handler")
" compiles via "
(code "hs-to-sx-from-source"))
(li "Wrapped in (fn (me) ...) and evaluated")
(li "Closure called with element as me")))
(~docs/subsection
:title "8.2 Dynamic Content"
:id "dynamic-content"
(p
"After swaps/insertion, "
(code "hs-boot-subtree!")
" activates hyperscript in new content. Elements are marked "
"to prevent double-activation."))
(~docs/subsection
:title "8.3 Source Files"
:id "source-files"
(table
(~tw :tokens "w-full text-sm border-collapse mb-6")
(thead
(~tw :tokens "bg-gray-50")
(tr
(th (~tw :tokens "text-left p-2 border-b font-semibold") "File")
(th
(~tw :tokens "text-left p-2 border-b font-semibold")
"Purpose")))
(tbody
(tr
(~tw :tokens "border-b")
(td
(~tw :tokens "p-2 font-mono")
"lib/hyperscript/tokenizer.sx")
(td (~tw :tokens "p-2") "Source to tokens (22 token types)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "lib/hyperscript/parser.sx")
(td (~tw :tokens "p-2") "Tokens to AST (42 parse functions)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "lib/hyperscript/compiler.sx")
(td (~tw :tokens "p-2") "AST to SX expressions (14 emitters)"))
(tr
(~tw :tokens "border-b")
(td (~tw :tokens "p-2 font-mono") "lib/hyperscript/runtime.sx")
(td (~tw :tokens "p-2") "Runtime shims (25 functions)"))
(tr
(td
(~tw :tokens "p-2 font-mono")
"lib/hyperscript/integration.sx")
(td (~tw :tokens "p-2") "DOM wiring: boot, activate, handler"))))))))