Files
rose-ash/sx/sxc/pages/docs.sx
giles 6f403c0c2d Add server-side test runner to /specs/testing page
Python evaluator runs test.sx at page load, results shown alongside
the browser runner. Both hosts prove the same 81 tests from the same
spec file — server on render, client on click.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:10:24 +00:00

512 lines
18 KiB
Plaintext

;; SX docs app — declarative page definitions
;; All content dispatched via case + direct component references.
;; Navigation built from SX data (nav-data.sx), no Python intermediaries.
;; ---------------------------------------------------------------------------
;; Home page
;; ---------------------------------------------------------------------------
(defpage home
:path "/"
:auth :public
:layout :sx
:content (~sx-home-content))
;; ---------------------------------------------------------------------------
;; Docs section
;; ---------------------------------------------------------------------------
(defpage docs-index
:path "/docs/"
:auth :public
:layout (:sx-section
:section "Docs"
:sub-label "Docs"
:sub-href "/docs/introduction"
:sub-nav (~section-nav :items docs-nav-items :current "Introduction")
:selected "Introduction")
:content (~docs-introduction-content))
(defpage docs-page
:path "/docs/<slug>"
:auth :public
:layout (:sx-section
:section "Docs"
:sub-label "Docs"
:sub-href "/docs/introduction"
:sub-nav (~section-nav :items docs-nav-items
:current (find-current docs-nav-items slug))
:selected (or (find-current docs-nav-items slug) ""))
:content (case slug
"introduction" (~docs-introduction-content)
"getting-started" (~docs-getting-started-content)
"components" (~docs-components-content)
"evaluator" (~docs-evaluator-content)
"primitives" (~docs-primitives-content
:prims (~doc-primitives-tables :primitives (primitives-data)))
"special-forms" (~docs-special-forms-content
:forms (~doc-special-forms-tables :forms (special-forms-data)))
"css" (~docs-css-content)
"server-rendering" (~docs-server-rendering-content)
:else (~docs-introduction-content)))
;; ---------------------------------------------------------------------------
;; Reference section
;; ---------------------------------------------------------------------------
(defpage reference-index
:path "/reference/"
:auth :public
:layout (:sx-section
:section "Reference"
:sub-label "Reference"
:sub-href "/reference/"
:sub-nav (~section-nav :items reference-nav-items :current "")
:selected "")
:content (~reference-index-content))
(defpage reference-page
:path "/reference/<slug>"
:auth :public
:layout (:sx-section
:section "Reference"
:sub-label "Reference"
:sub-href "/reference/"
:sub-nav (~section-nav :items reference-nav-items
:current (find-current reference-nav-items slug))
:selected (or (find-current reference-nav-items slug) ""))
:data (reference-data slug)
:content (case slug
"attributes" (~reference-attrs-content
:req-table (~doc-attr-table-from-data :title "Request Attributes" :attrs req-attrs)
:beh-table (~doc-attr-table-from-data :title "Behavior Attributes" :attrs beh-attrs)
:uniq-table (~doc-attr-table-from-data :title "Unique to sx" :attrs uniq-attrs))
"headers" (~reference-headers-content
:req-table (~doc-headers-table-from-data :title "Request Headers" :headers req-headers)
:resp-table (~doc-headers-table-from-data :title "Response Headers" :headers resp-headers))
"events" (~reference-events-content
:table (~doc-two-col-table-from-data
:intro "sx fires custom DOM events at various points in the request lifecycle."
:col1 "Event" :col2 "Description" :items events-list))
"js-api" (~reference-js-api-content
:table (~doc-two-col-table-from-data
:intro "The client-side sx.js library exposes a public API for programmatic use."
:col1 "Method" :col2 "Description" :items js-api-list))
:else (~reference-attrs-content
:req-table (~doc-attr-table-from-data :title "Request Attributes" :attrs req-attrs)
:beh-table (~doc-attr-table-from-data :title "Behavior Attributes" :attrs beh-attrs)
:uniq-table (~doc-attr-table-from-data :title "Unique to sx" :attrs uniq-attrs))))
(defpage reference-attr-detail
:path "/reference/attributes/<slug>"
:auth :public
:layout (:sx-section
:section "Reference"
:sub-label "Reference"
:sub-href "/reference/"
:sub-nav (~section-nav :items reference-nav-items :current "Attributes")
:selected "Attributes")
:data (attr-detail-data slug)
:content (if attr-not-found
(~reference-attr-not-found :slug slug)
(~reference-attr-detail-content
:title attr-title
:description attr-description
:demo attr-demo
:example-code attr-example
:handler-code attr-handler
:wire-placeholder-id attr-wire-id)))
(defpage reference-header-detail
:path "/reference/headers/<slug>"
:auth :public
:layout (:sx-section
:section "Reference"
:sub-label "Reference"
:sub-href "/reference/"
:sub-nav (~section-nav :items reference-nav-items :current "Headers")
:selected "Headers")
:data (header-detail-data slug)
:content (if header-not-found
(~reference-attr-not-found :slug slug)
(~reference-header-detail-content
:title header-title
:direction header-direction
:description header-description
:example-code header-example
:demo header-demo)))
(defpage reference-event-detail
:path "/reference/events/<slug>"
:auth :public
:layout (:sx-section
:section "Reference"
:sub-label "Reference"
:sub-href "/reference/"
:sub-nav (~section-nav :items reference-nav-items :current "Events")
:selected "Events")
:data (event-detail-data slug)
:content (if event-not-found
(~reference-attr-not-found :slug slug)
(~reference-event-detail-content
:title event-title
:description event-description
:example-code event-example
:demo event-demo)))
;; ---------------------------------------------------------------------------
;; Protocols section
;; ---------------------------------------------------------------------------
(defpage protocols-index
:path "/protocols/"
:auth :public
:layout (:sx-section
:section "Protocols"
:sub-label "Protocols"
:sub-href "/protocols/wire-format"
:sub-nav (~section-nav :items protocols-nav-items :current "Wire Format")
:selected "Wire Format")
:content (~protocol-wire-format-content))
(defpage protocol-page
:path "/protocols/<slug>"
:auth :public
:layout (:sx-section
:section "Protocols"
:sub-label "Protocols"
:sub-href "/protocols/wire-format"
:sub-nav (~section-nav :items protocols-nav-items
:current (find-current protocols-nav-items slug))
:selected (or (find-current protocols-nav-items slug) ""))
:content (case slug
"wire-format" (~protocol-wire-format-content)
"fragments" (~protocol-fragments-content)
"resolver-io" (~protocol-resolver-io-content)
"internal-services" (~protocol-internal-services-content)
"activitypub" (~protocol-activitypub-content)
"future" (~protocol-future-content)
:else (~protocol-wire-format-content)))
;; ---------------------------------------------------------------------------
;; Examples section
;; ---------------------------------------------------------------------------
(defpage examples-index
:path "/examples/"
:auth :public
:layout (:sx-section
:section "Examples"
:sub-label "Examples"
:sub-href "/examples/click-to-load"
:sub-nav (~section-nav :items examples-nav-items :current "Click to Load")
:selected "Click to Load")
:content (~example-click-to-load))
(defpage examples-page
:path "/examples/<slug>"
:auth :public
:layout (:sx-section
:section "Examples"
:sub-label "Examples"
:sub-href "/examples/click-to-load"
:sub-nav (~section-nav :items examples-nav-items
:current (find-current examples-nav-items slug))
:selected (or (find-current examples-nav-items slug) ""))
:content (case slug
"click-to-load" (~example-click-to-load)
"form-submission" (~example-form-submission)
"polling" (~example-polling)
"delete-row" (~example-delete-row)
"inline-edit" (~example-inline-edit)
"oob-swaps" (~example-oob-swaps)
"lazy-loading" (~example-lazy-loading)
"infinite-scroll" (~example-infinite-scroll)
"progress-bar" (~example-progress-bar)
"active-search" (~example-active-search)
"inline-validation" (~example-inline-validation)
"value-select" (~example-value-select)
"reset-on-submit" (~example-reset-on-submit)
"edit-row" (~example-edit-row)
"bulk-update" (~example-bulk-update)
"swap-positions" (~example-swap-positions)
"select-filter" (~example-select-filter)
"tabs" (~example-tabs)
"animations" (~example-animations)
"dialogs" (~example-dialogs)
"keyboard-shortcuts" (~example-keyboard-shortcuts)
"put-patch" (~example-put-patch)
"json-encoding" (~example-json-encoding)
"vals-and-headers" (~example-vals-and-headers)
"loading-states" (~example-loading-states)
"sync-replace" (~example-sync-replace)
"retry" (~example-retry)
:else (~example-click-to-load)))
;; ---------------------------------------------------------------------------
;; Essays section
;; ---------------------------------------------------------------------------
(defpage essays-index
:path "/essays/"
:auth :public
:layout (:sx-section
:section "Essays"
:sub-label "Essays"
:sub-href "/essays/"
:sub-nav (~section-nav :items essays-nav-items :current "")
:selected "")
:content (~essays-index-content))
(defpage essay-page
:path "/essays/<slug>"
:auth :public
:layout (:sx-section
:section "Essays"
:sub-label "Essays"
:sub-href "/essays/"
:sub-nav (~section-nav :items essays-nav-items
:current (find-current essays-nav-items slug))
:selected (or (find-current essays-nav-items slug) ""))
:content (case slug
"sx-sucks" (~essay-sx-sucks)
"why-sexps" (~essay-why-sexps)
"htmx-react-hybrid" (~essay-htmx-react-hybrid)
"on-demand-css" (~essay-on-demand-css)
"client-reactivity" (~essay-client-reactivity)
"sx-native" (~essay-sx-native)
"sx-manifesto" (~essay-sx-manifesto)
"tail-call-optimization" (~essay-tail-call-optimization)
"continuations" (~essay-continuations)
"godel-escher-bach" (~essay-godel-escher-bach)
"reflexive-web" (~essay-reflexive-web)
"server-architecture" (~essay-server-architecture)
:else (~essays-index-content)))
;; ---------------------------------------------------------------------------
;; Specs section
;; ---------------------------------------------------------------------------
(defpage specs-index
:path "/specs/"
:auth :public
:layout (:sx-section
:section "Specs"
:sub-label "Specs"
:sub-href "/specs/"
:sub-nav (~section-nav :items specs-nav-items :current "Architecture")
:selected "Architecture")
:content (~spec-architecture-content))
(defpage specs-page
:path "/specs/<slug>"
:auth :public
:layout (:sx-section
:section "Specs"
:sub-label "Specs"
:sub-href "/specs/"
:sub-nav (~section-nav :items specs-nav-items
:current (find-current specs-nav-items slug))
:selected (or (find-current specs-nav-items slug) ""))
:content (case slug
"core" (~spec-overview-content
:spec-title "Core Language"
:spec-files (map (fn (item)
(dict :title (get item "title") :desc (get item "desc")
:prose (get item "prose")
:filename (get item "filename") :href (str "/specs/" (get item "slug"))
:source (read-spec-file (get item "filename"))))
core-spec-items))
"adapters" (~spec-overview-content
:spec-title "Adapters & Engine"
:spec-files (map (fn (item)
(dict :title (get item "title") :desc (get item "desc")
:prose (get item "prose")
:filename (get item "filename") :href (str "/specs/" (get item "slug"))
:source (read-spec-file (get item "filename"))))
adapter-spec-items))
"browser" (~spec-overview-content
:spec-title "Browser"
:spec-files (map (fn (item)
(dict :title (get item "title") :desc (get item "desc")
:prose (get item "prose")
:filename (get item "filename") :href (str "/specs/" (get item "slug"))
:source (read-spec-file (get item "filename"))))
browser-spec-items))
"extensions" (~spec-overview-content
:spec-title "Extensions"
:spec-files (map (fn (item)
(dict :title (get item "title") :desc (get item "desc")
:prose (get item "prose")
:filename (get item "filename") :href (str "/specs/" (get item "slug"))
:source (read-spec-file (get item "filename"))))
extension-spec-items))
"testing" (~spec-testing-content
:spec-source (read-spec-file "test.sx")
:server-results (run-spec-tests))
:else (let ((spec (find-spec slug)))
(if spec
(~spec-detail-content
:spec-title (get spec "title")
:spec-desc (get spec "desc")
:spec-filename (get spec "filename")
:spec-source (read-spec-file (get spec "filename"))
:spec-prose (get spec "prose"))
(~spec-not-found :slug slug)))))
;; ---------------------------------------------------------------------------
;; Bootstrappers section
;; ---------------------------------------------------------------------------
(defpage bootstrappers-index
:path "/bootstrappers/"
:auth :public
:layout (:sx-section
:section "Bootstrappers"
:sub-label "Bootstrappers"
:sub-href "/bootstrappers/"
:sub-nav (~section-nav :items bootstrappers-nav-items :current "Overview")
:selected "Overview")
:content (~bootstrappers-index-content))
(defpage bootstrapper-page
:path "/bootstrappers/<slug>"
:auth :public
:layout (:sx-section
:section "Bootstrappers"
:sub-label "Bootstrappers"
:sub-href "/bootstrappers/"
:sub-nav (~section-nav :items bootstrappers-nav-items
:current (find-current bootstrappers-nav-items slug))
:selected (or (find-current bootstrappers-nav-items slug) ""))
:data (bootstrapper-data slug)
:content (if bootstrapper-not-found
(~spec-not-found :slug slug)
(if (= slug "python")
(~bootstrapper-py-content
:bootstrapper-source bootstrapper-source
:bootstrapped-output bootstrapped-output)
(~bootstrapper-js-content
:bootstrapper-source bootstrapper-source
:bootstrapped-output bootstrapped-output))))
;; ---------------------------------------------------------------------------
;; Isomorphism section
;; ---------------------------------------------------------------------------
(defpage isomorphism-index
:path "/isomorphism/"
:auth :public
:layout (:sx-section
:section "Isomorphism"
:sub-label "Isomorphism"
:sub-href "/isomorphism/"
:sub-nav (~section-nav :items isomorphism-nav-items :current "Roadmap")
:selected "Roadmap")
:content (~plan-isomorphic-content))
(defpage bundle-analyzer
:path "/isomorphism/bundle-analyzer"
:auth :public
:layout (:sx-section
:section "Isomorphism"
:sub-label "Isomorphism"
:sub-href "/isomorphism/"
:sub-nav (~section-nav :items isomorphism-nav-items :current "Bundle Analyzer")
:selected "Bundle Analyzer")
:data (bundle-analyzer-data)
:content (~bundle-analyzer-content
:pages pages :total-components total-components :total-macros total-macros
:pure-count pure-count :io-count io-count))
(defpage routing-analyzer
:path "/isomorphism/routing-analyzer"
:auth :public
:layout (:sx-section
:section "Isomorphism"
:sub-label "Isomorphism"
:sub-href "/isomorphism/"
:sub-nav (~section-nav :items isomorphism-nav-items :current "Routing Analyzer")
:selected "Routing Analyzer")
:data (routing-analyzer-data)
:content (~routing-analyzer-content
:pages pages :total-pages total-pages :client-count client-count
:server-count server-count :registry-sample registry-sample))
(defpage data-test
:path "/isomorphism/data-test"
:auth :public
:layout (:sx-section
:section "Isomorphism"
:sub-label "Isomorphism"
:sub-href "/isomorphism/"
:sub-nav (~section-nav :items isomorphism-nav-items :current "Data Test")
:selected "Data Test")
:data (data-test-data)
:content (~data-test-content
:server-time server-time :items items
:phase phase :transport transport))
(defpage async-io-demo
:path "/isomorphism/async-io"
:auth :public
:layout (:sx-section
:section "Isomorphism"
:sub-label "Isomorphism"
:sub-href "/isomorphism/"
:sub-nav (~section-nav :items isomorphism-nav-items :current "Async IO")
:selected "Async IO")
:content (~async-io-demo-content))
;; Wildcard must come AFTER specific routes (first-match routing)
(defpage isomorphism-page
:path "/isomorphism/<slug>"
:auth :public
:layout (:sx-section
:section "Isomorphism"
:sub-label "Isomorphism"
:sub-href "/isomorphism/"
:sub-nav (~section-nav :items isomorphism-nav-items
:current (find-current isomorphism-nav-items slug))
:selected (or (find-current isomorphism-nav-items slug) ""))
:content (case slug
"bundle-analyzer" (~bundle-analyzer-content
:pages pages :total-components total-components :total-macros total-macros
:pure-count pure-count :io-count io-count)
"routing-analyzer" (~routing-analyzer-content
:pages pages :total-pages total-pages :client-count client-count
:server-count server-count :registry-sample registry-sample)
:else (~plan-isomorphic-content)))
;; ---------------------------------------------------------------------------
;; Plans section
;; ---------------------------------------------------------------------------
(defpage plans-index
:path "/plans/"
:auth :public
:layout (:sx-section
:section "Plans"
:sub-label "Plans"
:sub-href "/plans/"
:sub-nav (~section-nav :items plans-nav-items :current "")
:selected "")
:content (~plans-index-content))
(defpage plan-page
:path "/plans/<slug>"
:auth :public
:layout (:sx-section
:section "Plans"
:sub-label "Plans"
:sub-href "/plans/"
:sub-nav (~section-nav :items plans-nav-items
:current (find-current plans-nav-items slug))
:selected (or (find-current plans-nav-items slug) ""))
:content (case slug
"reader-macros" (~plan-reader-macros-content)
"sx-activity" (~plan-sx-activity-content)
"predictive-prefetch" (~plan-predictive-prefetch-content)
"content-addressed-components" (~plan-content-addressed-components-content)
:else (~plans-index-content)))