Rename all 1,169 components to path-based names with namespace support

Component names now reflect filesystem location using / as path separator
and : as namespace separator for shared components:
  ~sx-header → ~layouts/header
  ~layout-app-body → ~shared:layout/app-body
  ~blog-admin-dashboard → ~admin/dashboard

209 files, 4,941 replacements across all services.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 22:00:12 +00:00
parent de80d921e9
commit b0920a1121
209 changed files with 4620 additions and 4620 deletions

View File

@@ -1,28 +1,28 @@
;; SX docs — documentation page components
(defcomp ~doc-page (&key title &rest children)
(defcomp ~docs/page (&key title &rest children)
(div :class "max-w-4xl mx-auto px-6 py-8"
(div :class "prose prose-stone max-w-none space-y-6" children)))
(defcomp ~doc-section (&key title id &rest children)
(defcomp ~docs/section (&key title id &rest children)
(section :id id :class "space-y-4"
(h2 :class "text-2xl font-semibold text-stone-800" title)
children))
(defcomp ~doc-subsection (&key title &rest children)
(defcomp ~docs/subsection (&key title &rest children)
(div :class "space-y-3"
(h3 :class "text-xl font-semibold text-stone-700" title)
children))
(defcomp ~doc-code (&key code)
(defcomp ~docs/code (&key code)
(div :class "not-prose bg-stone-100 rounded-lg p-5 mx-auto max-w-3xl"
(pre :class "text-sm leading-relaxed whitespace-pre-wrap break-words" (code code))))
(defcomp ~doc-note (&key &rest children)
(defcomp ~docs/note (&key &rest children)
(div :class "border-l-4 border-violet-400 bg-violet-50 p-4 text-stone-700 text-sm"
children))
(defcomp ~doc-table (&key headers rows)
(defcomp ~docs/table (&key headers rows)
(div :class "overflow-x-auto rounded border border-stone-200"
(table :class "w-full text-left text-sm"
(thead
@@ -34,7 +34,7 @@
(map (fn (cell) (td :class "px-3 py-2 text-stone-700" cell)) row)))
rows)))))
(defcomp ~doc-attr-row (&key attr description exists href)
(defcomp ~docs/attr-row (&key attr description exists href)
(tr :class "border-b border-stone-100"
(td :class "px-3 py-2 font-mono text-sm whitespace-nowrap"
(if href
@@ -49,7 +49,7 @@
(span :class "text-emerald-600 text-sm" "yes")
(span :class "text-stone-400 text-sm italic" "not yet")))))
(defcomp ~doc-primitives-table (&key category primitives)
(defcomp ~docs/primitives-table (&key category primitives)
(div :class "space-y-2"
(h4 :class "text-lg font-semibold text-stone-700" category)
(div :class "flex flex-wrap gap-2"
@@ -57,7 +57,7 @@
(span :class "inline-block px-2 py-1 rounded bg-stone-100 font-mono text-sm text-stone-700" p))
primitives))))
(defcomp ~doc-nav (&key items current)
(defcomp ~docs/nav (&key items current)
(nav :class "flex flex-wrap gap-2 mb-8"
(map (fn (item)
(a :href (nth item 1)

View File

@@ -1,6 +1,6 @@
;; SX docs — example and demo components
(defcomp ~example-card (&key title description &rest children)
(defcomp ~examples/card (&key title description &rest children)
(div :class "border border-stone-200 rounded-lg overflow-hidden"
(div :class "bg-stone-100 px-4 py-3 border-b border-stone-200"
(h3 :class "font-semibold text-stone-800" title)
@@ -8,16 +8,16 @@
(p :class "text-sm text-stone-500 mt-1" description)))
(div :class "p-4" children)))
(defcomp ~example-demo (&key &rest children)
(defcomp ~examples/demo (&key &rest children)
(div :class "border border-dashed border-stone-300 rounded p-4 bg-stone-100" children))
(defcomp ~example-source (&key code)
(defcomp ~examples/source (&key code)
(div :class "not-prose bg-stone-100 rounded p-5 mt-3 mx-auto max-w-3xl"
(pre :class "text-sm leading-relaxed whitespace-pre-wrap break-words" (code code))))
;; --- Click to load demo ---
(defcomp ~click-to-load-demo ()
(defcomp ~examples/click-to-load-demo ()
(div :class "space-y-4"
(div :id "click-result" :class "p-4 rounded bg-stone-100 text-stone-500 text-center"
"Click the button to load content.")
@@ -28,7 +28,7 @@
:class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors"
"Load content")))
(defcomp ~click-result (&key time)
(defcomp ~examples/click-result (&key time)
(div :class "space-y-2"
(p :class "text-stone-800 font-medium" "Content loaded!")
(p :class "text-stone-500 text-sm"
@@ -36,7 +36,7 @@
;; --- Form submission demo ---
(defcomp ~form-demo ()
(defcomp ~examples/form-demo ()
(div :class "space-y-4"
(form
:sx-post "/sx/(geography.(hypermedia.(example.(api.form))))"
@@ -53,14 +53,14 @@
(div :id "form-result" :class "p-3 rounded bg-stone-100 text-stone-500 text-sm text-center"
"Submit the form to see the result.")))
(defcomp ~form-result (&key name)
(defcomp ~examples/form-result (&key name)
(div :class "text-stone-800"
(p (str "Hello, " (if (empty? name) "stranger" name) "!"))
(p :class "text-sm text-stone-500 mt-1" "Submitted via sx-post. The form data was sent as a POST request.")))
;; --- Polling demo ---
(defcomp ~polling-demo ()
(defcomp ~examples/polling-demo ()
(div :class "space-y-4"
(div :id "poll-target"
:sx-get "/sx/(geography.(hypermedia.(example.(api.poll))))"
@@ -69,7 +69,7 @@
:class "p-4 rounded border border-stone-200 bg-stone-100 text-center font-mono"
"Loading...")))
(defcomp ~poll-result (&key time count)
(defcomp ~examples/poll-result (&key time count)
(div
(p :class "text-stone-800 font-medium" (str "Server time: " time))
(p :class "text-stone-500 text-sm mt-1" (str "Poll count: " count))
@@ -82,7 +82,7 @@
;; --- Delete row demo ---
(defcomp ~delete-demo (&key items)
(defcomp ~examples/delete-demo (&key items)
(div
(table :class "w-full text-left text-sm"
(thead
@@ -91,10 +91,10 @@
(th :class "px-3 py-2 font-medium text-stone-600 w-20" "")))
(tbody :id "delete-rows"
(map (fn (item)
(~delete-row :id (nth item 0) :name (nth item 1)))
(~examples/delete-row :id (nth item 0) :name (nth item 1)))
items)))))
(defcomp ~delete-row (&key id name)
(defcomp ~examples/delete-row (&key id name)
(tr :id (str "row-" id) :class "border-b border-stone-100 transition-all"
(td :class "px-3 py-2 text-stone-700" name)
(td :class "px-3 py-2"
@@ -108,11 +108,11 @@
;; --- Inline edit demo ---
(defcomp ~inline-edit-demo ()
(defcomp ~examples/inline-edit-demo ()
(div :id "edit-target" :class "space-y-3"
(~inline-view :value "Click edit to change this text")))
(~examples/inline-view :value "Click edit to change this text")))
(defcomp ~inline-view (&key value)
(defcomp ~examples/inline-view (&key value)
(div :class "flex items-center justify-between p-3 rounded border border-stone-200"
(span :class "text-stone-800" value)
(button
@@ -122,7 +122,7 @@
:class "text-sm text-violet-600 hover:text-violet-800"
"edit")))
(defcomp ~inline-edit-form (&key value)
(defcomp ~examples/inline-edit-form (&key value)
(form
:sx-post "/sx/(geography.(hypermedia.(example.(api.edit))))"
:sx-target "#edit-target"
@@ -142,7 +142,7 @@
;; --- OOB swap demo ---
(defcomp ~oob-demo ()
(defcomp ~examples/oob-demo ()
(div :class "space-y-4"
(div :class "grid grid-cols-2 gap-4"
(div :id "oob-box-a" :class "p-4 rounded border border-stone-200 bg-stone-100 text-center"
@@ -160,7 +160,7 @@
;; --- Lazy loading demo ---
(defcomp ~lazy-loading-demo ()
(defcomp ~examples/lazy-loading-demo ()
(div :class "space-y-4"
(p :class "text-sm text-stone-500" "The content below loads automatically when the page renders.")
(div :id "lazy-target"
@@ -172,14 +172,14 @@
(div :class "h-4 bg-stone-200 rounded w-3/4 mx-auto")
(div :class "h-4 bg-stone-200 rounded w-1/2 mx-auto")))))
(defcomp ~lazy-result (&key time)
(defcomp ~examples/lazy-result (&key time)
(div :class "space-y-2"
(p :class "text-stone-800 font-medium" "Content loaded on page render!")
(p :class "text-stone-500 text-sm" (str "Loaded via sx-trigger=\"load\" at " time))))
;; --- Infinite scroll demo ---
(defcomp ~infinite-scroll-demo ()
(defcomp ~examples/infinite-scroll-demo ()
(div :class "h-64 overflow-y-auto border border-stone-200 rounded" :id "scroll-container"
(div :id "scroll-items"
(map-indexed (fn (i item)
@@ -194,7 +194,7 @@
:class "p-3 text-center text-stone-400 text-sm"
"Loading more..."))))
(defcomp ~scroll-items (&key items page)
(defcomp ~examples/scroll-items (&key items page)
(<>
(map (fn (item)
(div :class "px-4 py-3 border-b border-stone-100 text-sm text-stone-700" item))
@@ -210,7 +210,7 @@
;; --- Progress bar demo ---
(defcomp ~progress-bar-demo ()
(defcomp ~examples/progress-bar-demo ()
(div :class "space-y-4"
(div :id "progress-target" :class "space-y-3"
(div :class "w-full bg-stone-200 rounded-full h-4"
@@ -223,7 +223,7 @@
:class "px-4 py-2 bg-violet-600 text-white rounded hover:bg-violet-700 transition-colors text-sm"
"Start job")))
(defcomp ~progress-status (&key percent job-id)
(defcomp ~examples/progress-status (&key percent job-id)
(div :class "space-y-3"
(div :class "w-full bg-stone-200 rounded-full h-4"
(div :class "bg-violet-600 h-4 rounded-full transition-all"
@@ -239,7 +239,7 @@
;; --- Active search demo ---
(defcomp ~active-search-demo ()
(defcomp ~examples/active-search-demo ()
(div :class "space-y-3"
(input :type "text" :name "q"
:sx-get "/sx/(geography.(hypermedia.(example.(api.search))))"
@@ -251,7 +251,7 @@
(div :id "search-results" :class "border border-stone-200 rounded divide-y divide-stone-100"
(p :class "p-3 text-sm text-stone-400" "Type to search..."))))
(defcomp ~search-results (&key items query)
(defcomp ~examples/search-results (&key items query)
(<>
(if (empty? items)
(p :class "p-3 text-sm text-stone-400" (str "No results for \"" query "\""))
@@ -261,7 +261,7 @@
;; --- Inline validation demo ---
(defcomp ~inline-validation-demo ()
(defcomp ~examples/inline-validation-demo ()
(form :class "space-y-4" :sx-post "/sx/(geography.(hypermedia.(example.(api.validate-submit))))" :sx-target "#validation-result" :sx-swap "innerHTML"
(div
(label :class "block text-sm font-medium text-stone-700 mb-1" "Email")
@@ -277,15 +277,15 @@
"Submit")
(div :id "validation-result")))
(defcomp ~validation-ok (&key email)
(defcomp ~examples/validation-ok (&key email)
(p :class "text-sm text-emerald-600" (str email " is available")))
(defcomp ~validation-error (&key message)
(defcomp ~examples/validation-error (&key message)
(p :class "text-sm text-rose-600" message))
;; --- Value select demo ---
(defcomp ~value-select-demo ()
(defcomp ~examples/value-select-demo ()
(div :class "space-y-3"
(div
(label :class "block text-sm font-medium text-stone-700 mb-1" "Category")
@@ -305,13 +305,13 @@
:class "w-full px-3 py-2 border border-stone-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-violet-500"
(option :value "" "Select a category first...")))))
(defcomp ~value-options (&key items)
(defcomp ~examples/value-options (&key items)
(<>
(map (fn (item) (option :value item item)) items)))
;; --- Reset on submit demo ---
(defcomp ~reset-on-submit-demo ()
(defcomp ~examples/reset-on-submit-demo ()
(div :class "space-y-3"
(form :id "reset-form"
:sx-post "/sx/(geography.(hypermedia.(example.(api.reset-submit))))"
@@ -327,13 +327,13 @@
(div :id "reset-result" :class "space-y-2"
(p :class "text-sm text-stone-400" "Messages will appear here."))))
(defcomp ~reset-message (&key message time)
(defcomp ~examples/reset-message (&key message time)
(div :class "px-3 py-2 bg-stone-100 rounded text-sm text-stone-700"
(str "[" time "] " message)))
;; --- Edit row demo ---
(defcomp ~edit-row-demo (&key rows)
(defcomp ~examples/edit-row-demo (&key rows)
(div
(table :class "w-full text-left text-sm"
(thead
@@ -344,10 +344,10 @@
(th :class "px-3 py-2 font-medium text-stone-600 w-24" "")))
(tbody :id "edit-rows"
(map (fn (row)
(~edit-row-view :id (nth row 0) :name (nth row 1) :price (nth row 2) :stock (nth row 3)))
(~examples/edit-row-view :id (nth row 0) :name (nth row 1) :price (nth row 2) :stock (nth row 3)))
rows)))))
(defcomp ~edit-row-view (&key id name price stock)
(defcomp ~examples/edit-row-view (&key id name price stock)
(tr :id (str "erow-" id) :class "border-b border-stone-100"
(td :class "px-3 py-2 text-stone-700" name)
(td :class "px-3 py-2 text-stone-700" (str "$" price))
@@ -360,7 +360,7 @@
:class "text-sm text-violet-600 hover:text-violet-800"
"edit"))))
(defcomp ~edit-row-form (&key id name price stock)
(defcomp ~examples/edit-row-form (&key id name price stock)
(tr :id (str "erow-" id) :class "border-b border-stone-100 bg-violet-50"
(td :class "px-3 py-2"
(input :type "text" :name "name" :value name
@@ -388,7 +388,7 @@
;; --- Bulk update demo ---
(defcomp ~bulk-update-demo (&key users)
(defcomp ~examples/bulk-update-demo (&key users)
(div :class "space-y-3"
(form :id "bulk-form"
(div :class "flex gap-2 mb-3"
@@ -415,10 +415,10 @@
(th :class "px-3 py-2 font-medium text-stone-600" "Status")))
(tbody :id "bulk-table"
(map (fn (u)
(~bulk-row :id (nth u 0) :name (nth u 1) :email (nth u 2) :status (nth u 3)))
(~examples/bulk-row :id (nth u 0) :name (nth u 1) :email (nth u 2) :status (nth u 3)))
users))))))
(defcomp ~bulk-row (&key id name email status)
(defcomp ~examples/bulk-row (&key id name email status)
(tr :class "border-b border-stone-100"
(td :class "px-3 py-2"
(input :type "checkbox" :name "ids" :value id))
@@ -433,7 +433,7 @@
;; --- Swap positions demo ---
(defcomp ~swap-positions-demo ()
(defcomp ~examples/swap-positions-demo ()
(div :class "space-y-3"
(div :class "flex gap-2"
(button
@@ -459,13 +459,13 @@
:class "border border-stone-200 rounded h-48 overflow-y-auto divide-y divide-stone-100"
(p :class "p-3 text-sm text-stone-400" "Log entries will appear here."))))
(defcomp ~swap-entry (&key time mode)
(defcomp ~examples/swap-entry (&key time mode)
(div :class "px-3 py-2 text-sm text-stone-700"
(str "[" time "] " mode)))
;; --- Select filter demo ---
(defcomp ~select-filter-demo ()
(defcomp ~examples/select-filter-demo ()
(div :class "space-y-3"
(div :class "flex gap-2"
(button
@@ -493,17 +493,17 @@
;; --- Tabs demo ---
(defcomp ~tabs-demo ()
(defcomp ~examples/tabs-demo ()
(div :class "space-y-0"
(div :class "flex border-b border-stone-200" :id "tab-buttons"
(~tab-btn :tab "tab1" :label "Overview" :active "true")
(~tab-btn :tab "tab2" :label "Details" :active "false")
(~tab-btn :tab "tab3" :label "History" :active "false"))
(~examples/tab-btn :tab "tab1" :label "Overview" :active "true")
(~examples/tab-btn :tab "tab2" :label "Details" :active "false")
(~examples/tab-btn :tab "tab3" :label "History" :active "false"))
(div :id "tab-content" :class "p-4 border border-t-0 border-stone-200 rounded-b"
(p :class "text-stone-700" "Welcome to the Overview tab. This content is loaded by default.")
(p :class "text-stone-500 text-sm mt-2" "Click the tabs above to navigate. Watch the browser URL update."))))
(defcomp ~tab-btn (&key tab label active)
(defcomp ~examples/tab-btn (&key tab label active)
(button
:sx-get (str "/sx/(geography.(hypermedia.(example.(api.(tabs." tab ")))))")
:sx-target "#tab-content"
@@ -517,7 +517,7 @@
;; --- Animations demo ---
(defcomp ~animations-demo ()
(defcomp ~examples/animations-demo ()
(div :class "space-y-4"
(button
:sx-get "/sx/(geography.(hypermedia.(example.(api.animate))))"
@@ -528,7 +528,7 @@
(div :id "anim-target" :class "p-4 rounded border border-stone-200 bg-stone-100 text-center"
(p :class "text-stone-400" "Content will fade in here."))))
(defcomp ~anim-result (&key color time)
(defcomp ~examples/anim-result (&key color time)
(div :class "sx-fade-in space-y-2"
(div :class (str "p-4 rounded transition-colors duration-700 " color)
(p :class "font-medium" "Faded in!")
@@ -536,7 +536,7 @@
;; --- Dialogs demo ---
(defcomp ~dialogs-demo ()
(defcomp ~examples/dialogs-demo ()
(div
(button
:sx-get "/sx/(geography.(hypermedia.(example.(api.dialog))))"
@@ -546,7 +546,7 @@
"Open Dialog")
(div :id "dialog-container")))
(defcomp ~dialog-modal (&key title message)
(defcomp ~examples/dialog-modal (&key title message)
(div :class "fixed inset-0 z-50 flex items-center justify-center"
(div :class "absolute inset-0 bg-black/50"
:sx-get "/sx/(geography.(hypermedia.(example.(api.dialog-close))))"
@@ -571,7 +571,7 @@
;; --- Keyboard shortcuts demo ---
(defcomp ~keyboard-shortcuts-demo ()
(defcomp ~examples/keyboard-shortcuts-demo ()
(div :class "space-y-4"
(div :class "p-4 rounded border border-stone-200 bg-stone-100"
(p :class "text-sm text-stone-600 font-medium mb-2" "Keyboard shortcuts:")
@@ -600,18 +600,18 @@
:sx-target "#kbd-target"
:sx-swap "innerHTML")))
(defcomp ~kbd-result (&key key action)
(defcomp ~examples/kbd-result (&key key action)
(div :class "space-y-1"
(p :class "text-stone-800 font-medium" action)
(p :class "text-sm text-stone-500" (str "Triggered by pressing '" key "'"))))
;; --- PUT / PATCH demo ---
(defcomp ~put-patch-demo (&key name email role)
(defcomp ~examples/put-patch-demo (&key name email role)
(div :id "pp-target" :class "space-y-4"
(~pp-view :name name :email email :role role)))
(~examples/pp-view :name name :email email :role role)))
(defcomp ~pp-view (&key name email role)
(defcomp ~examples/pp-view (&key name email role)
(div :class "space-y-3"
(div :class "flex justify-between items-start"
(div
@@ -625,7 +625,7 @@
:class "text-sm text-violet-600 hover:text-violet-800"
"Edit All (PUT)"))))
(defcomp ~pp-form-full (&key name email role)
(defcomp ~examples/pp-form-full (&key name email role)
(form
:sx-put "/sx/(geography.(hypermedia.(example.(api.putpatch))))"
:sx-target "#pp-target"
@@ -656,7 +656,7 @@
;; --- JSON encoding demo ---
(defcomp ~json-encoding-demo ()
(defcomp ~examples/json-encoding-demo ()
(div :class "space-y-4"
(form
:sx-post "/sx/(geography.(hypermedia.(example.(api.json-echo))))"
@@ -678,7 +678,7 @@
(div :id "json-result" :class "p-3 rounded bg-stone-100 text-stone-500 text-sm"
"Submit the form to see the server echo the parsed JSON.")))
(defcomp ~json-result (&key body content-type)
(defcomp ~examples/json-result (&key body content-type)
(div :class "space-y-2"
(p :class "text-stone-800 font-medium" "Server received:")
(pre :class "text-sm bg-stone-100 p-3 rounded overflow-x-auto" (code body))
@@ -686,7 +686,7 @@
;; --- Vals & Headers demo ---
(defcomp ~vals-headers-demo ()
(defcomp ~examples/vals-headers-demo ()
(div :class "space-y-6"
(div :class "space-y-2"
(h4 :class "text-sm font-semibold text-stone-700" "sx-vals — send extra values")
@@ -711,7 +711,7 @@
(div :id "headers-result" :class "p-3 rounded bg-stone-100 text-sm text-stone-400"
"Click to see server-received headers."))))
(defcomp ~echo-result (&key label items)
(defcomp ~examples/echo-result (&key label items)
(div :class "space-y-1"
(p :class "text-stone-800 font-medium" (str "Server received " label ":"))
(map (fn (item)
@@ -720,7 +720,7 @@
;; --- Loading states demo ---
(defcomp ~loading-states-demo ()
(defcomp ~examples/loading-states-demo ()
(div :class "space-y-4"
(button
:sx-get "/sx/(geography.(hypermedia.(example.(api.slow))))"
@@ -732,14 +732,14 @@
(div :id "loading-result" :class "p-4 rounded border border-stone-200 bg-stone-100 text-center"
(p :class "text-stone-400 text-sm" "Click the button — it takes 2 seconds."))))
(defcomp ~loading-result (&key time)
(defcomp ~examples/loading-result (&key time)
(div
(p :class "text-stone-800 font-medium" "Loaded!")
(p :class "text-sm text-stone-500" (str "Response arrived at " time))))
;; --- Sync replace demo (request abort) ---
(defcomp ~sync-replace-demo ()
(defcomp ~examples/sync-replace-demo ()
(div :class "space-y-3"
(input :type "text" :name "q"
:sx-get "/sx/(geography.(hypermedia.(example.(api.slow-search))))"
@@ -752,14 +752,14 @@
(div :id "sync-result" :class "p-4 rounded border border-stone-200 bg-stone-100"
(p :class "text-sm text-stone-400" "Type to trigger requests — stale ones get aborted."))))
(defcomp ~sync-result (&key query delay)
(defcomp ~examples/sync-result (&key query delay)
(div
(p :class "text-stone-800 font-medium" (str "Result for: \"" query "\""))
(p :class "text-sm text-stone-500" (str "Server took " delay "ms to respond"))))
;; --- Retry demo ---
(defcomp ~retry-demo ()
(defcomp ~examples/retry-demo ()
(div :class "space-y-4"
(button
:sx-get "/sx/(geography.(hypermedia.(example.(api.flaky))))"
@@ -771,7 +771,7 @@
(div :id "retry-result" :class "p-4 rounded border border-stone-200 bg-stone-100 text-center"
(p :class "text-stone-400 text-sm" "Endpoint fails twice, succeeds on 3rd attempt."))))
(defcomp ~retry-result (&key attempt message)
(defcomp ~examples/retry-result (&key attempt message)
(div :class "space-y-1"
(p :class "text-stone-800 font-medium" message)
(p :class "text-sm text-stone-500" (str "Succeeded on attempt #" attempt))))

View File

@@ -1,7 +1,7 @@
;; SX docs — home page components
(defcomp ~sx-hero (&key &rest children)
(defcomp ~home/hero (&key &rest children)
(div :class "max-w-4xl mx-auto px-6 py-16 text-center"
(h1 :class "text-5xl font-bold text-stone-900 mb-4"
(span :class "text-violet-600 font-mono" "(<sx>)"))
@@ -14,7 +14,7 @@
(div :class "bg-stone-100 rounded-lg p-6 text-left font-mono text-sm mx-auto max-w-2xl"
(pre :class "leading-relaxed whitespace-pre-wrap" children))))
(defcomp ~sx-philosophy ()
(defcomp ~home/philosophy ()
(div :class "max-w-4xl mx-auto px-6 py-12"
(h2 :class "text-3xl font-bold text-stone-900 mb-8" "Design philosophy")
(div :class "grid md:grid-cols-2 gap-8"
@@ -35,7 +35,7 @@
(li "On-demand CSS — only ship what's used")
(li "DOM morphing for smooth history navigation"))))))
(defcomp ~sx-how-it-works ()
(defcomp ~home/how-it-works ()
(div :class "max-w-4xl mx-auto px-6 py-12"
(h2 :class "text-3xl font-bold text-stone-900 mb-8" "How it works")
(div :class "space-y-6"
@@ -55,7 +55,7 @@
(h3 :class "font-semibold text-stone-900" "Client evaluates + renders")
(p :class "text-stone-600" "sx.js parses, evaluates, and renders to DOM. Same evaluator runs server-side (Python) and client-side (JS)."))))))
(defcomp ~sx-credits ()
(defcomp ~home/credits ()
(div :class "max-w-4xl mx-auto px-6 py-12 border-t border-stone-200"
(p :class "text-stone-500 text-sm"
"sx is heavily inspired by "

View File

@@ -11,7 +11,7 @@
:path "/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/" (~sx-home-content)))
:content (~layouts/doc :path "/" (~docs-content/home-content)))
;; ---------------------------------------------------------------------------
;; Language section (parent of Docs, Specs, Bootstrappers, Testing)
@@ -21,7 +21,7 @@
:path "/language/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(language)"))
:content (~layouts/doc :path "/sx/(language)"))
;; ---------------------------------------------------------------------------
;; Docs section (under Language)
@@ -31,24 +31,24 @@
:path "/language/docs/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(language.(doc))" (~docs-introduction-content)))
:content (~layouts/doc :path "/sx/(language.(doc))" (~docs-content/docs-introduction-content)))
(defpage docs-page
:path "/language/docs/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(language.(doc." slug "))")
:content (~layouts/doc :path (str "/sx/(language.(doc." slug "))")
(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)))
"server-rendering" (~docs-server-rendering-content)
:else (~docs-introduction-content))))
"introduction" (~docs-content/docs-introduction-content)
"getting-started" (~docs-content/docs-getting-started-content)
"components" (~docs-content/docs-components-content)
"evaluator" (~docs-content/docs-evaluator-content)
"primitives" (~docs-content/docs-primitives-content
:prims (~docs/primitives-tables :primitives (primitives-data)))
"special-forms" (~docs-content/docs-special-forms-content
:forms (~docs/special-forms-tables :forms (special-forms-data)))
"server-rendering" (~docs-content/docs-server-rendering-content)
:else (~docs-content/docs-introduction-content))))
;; ---------------------------------------------------------------------------
;; Reference section
@@ -58,50 +58,50 @@
:path "/geography/hypermedia/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(hypermedia))"))
:content (~layouts/doc :path "/sx/(geography.(hypermedia))"))
(defpage reference-index
:path "/geography/hypermedia/reference/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(hypermedia.(reference)))" (~reference-index-content)))
:content (~layouts/doc :path "/sx/(geography.(hypermedia.(reference)))" (~examples/reference-index-content)))
(defpage reference-page
:path "/geography/hypermedia/reference/<slug>"
:auth :public
:layout :sx-docs
:data (reference-data slug)
:content (~sx-doc :path (str "/sx/(geography.(hypermedia.(reference." slug ")))")
:content (~layouts/doc :path (str "/sx/(geography.(hypermedia.(reference." slug ")))")
(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
"attributes" (~reference/attrs-content
:req-table (~docs/attr-table-from-data :title "Request Attributes" :attrs req-attrs)
:beh-table (~docs/attr-table-from-data :title "Behavior Attributes" :attrs beh-attrs)
:uniq-table (~docs/attr-table-from-data :title "Unique to sx" :attrs uniq-attrs))
"headers" (~reference/headers-content
:req-table (~docs/headers-table-from-data :title "Request Headers" :headers req-headers)
:resp-table (~docs/headers-table-from-data :title "Response Headers" :headers resp-headers))
"events" (~reference/events-content
:table (~docs/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
"js-api" (~reference/js-api-content
:table (~docs/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)))))
:else (~reference/attrs-content
:req-table (~docs/attr-table-from-data :title "Request Attributes" :attrs req-attrs)
:beh-table (~docs/attr-table-from-data :title "Behavior Attributes" :attrs beh-attrs)
:uniq-table (~docs/attr-table-from-data :title "Unique to sx" :attrs uniq-attrs)))))
(defpage reference-attr-detail
:path "/geography/hypermedia/reference/attributes/<slug>"
:auth :public
:layout :sx-docs
:data (attr-detail-data slug)
:content (~sx-doc :path (str "/sx/(geography.(hypermedia.(reference-detail.attributes." slug ")))")
:content (~layouts/doc :path (str "/sx/(geography.(hypermedia.(reference-detail.attributes." slug ")))")
(if attr-not-found
(~reference-attr-not-found :slug slug)
(~reference-attr-detail-content
(~reference/attr-not-found :slug slug)
(~reference/attr-detail-content
:title attr-title
:description attr-description
:demo attr-demo
@@ -114,10 +114,10 @@
:auth :public
:layout :sx-docs
:data (header-detail-data slug)
:content (~sx-doc :path (str "/sx/(geography.(hypermedia.(reference-detail.headers." slug ")))")
:content (~layouts/doc :path (str "/sx/(geography.(hypermedia.(reference-detail.headers." slug ")))")
(if header-not-found
(~reference-attr-not-found :slug slug)
(~reference-header-detail-content
(~reference/attr-not-found :slug slug)
(~reference/header-detail-content
:title header-title
:direction header-direction
:description header-description
@@ -129,10 +129,10 @@
:auth :public
:layout :sx-docs
:data (event-detail-data slug)
:content (~sx-doc :path (str "/sx/(geography.(hypermedia.(reference-detail.events." slug ")))")
:content (~layouts/doc :path (str "/sx/(geography.(hypermedia.(reference-detail.events." slug ")))")
(if event-not-found
(~reference-attr-not-found :slug slug)
(~reference-event-detail-content
(~reference/attr-not-found :slug slug)
(~reference/event-detail-content
:title event-title
:description event-description
:example-code event-example
@@ -146,7 +146,7 @@
:path "/applications/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(applications)"))
:content (~layouts/doc :path "/sx/(applications)"))
;; ---------------------------------------------------------------------------
;; Protocols section (under Applications)
@@ -156,21 +156,21 @@
:path "/applications/protocols/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(applications.(protocol))" (~protocol-wire-format-content)))
:content (~layouts/doc :path "/sx/(applications.(protocol))" (~protocols/wire-format-content)))
(defpage protocol-page
:path "/applications/protocols/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(applications.(protocol." slug "))")
:content (~layouts/doc :path (str "/sx/(applications.(protocol." slug "))")
(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))))
"wire-format" (~protocols/wire-format-content)
"fragments" (~protocols/fragments-content)
"resolver-io" (~protocols/resolver-io-content)
"internal-services" (~protocols/internal-services-content)
"activitypub" (~protocols/activitypub-content)
"future" (~protocols/future-content)
:else (~protocols/wire-format-content))))
;; ---------------------------------------------------------------------------
;; Examples section
@@ -180,42 +180,42 @@
:path "/geography/hypermedia/examples/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(hypermedia.(example)))"))
:content (~layouts/doc :path "/sx/(geography.(hypermedia.(example)))"))
(defpage examples-page
:path "/geography/hypermedia/examples/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(geography.(hypermedia.(example." slug ")))")
:content (~layouts/doc :path (str "/sx/(geography.(hypermedia.(example." slug ")))")
(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))))
"click-to-load" (~examples-content/example-click-to-load)
"form-submission" (~examples-content/example-form-submission)
"polling" (~examples-content/example-polling)
"delete-row" (~examples-content/example-delete-row)
"inline-edit" (~examples-content/example-inline-edit)
"oob-swaps" (~examples-content/example-oob-swaps)
"lazy-loading" (~examples-content/example-lazy-loading)
"infinite-scroll" (~examples-content/example-infinite-scroll)
"progress-bar" (~examples-content/example-progress-bar)
"active-search" (~examples-content/example-active-search)
"inline-validation" (~examples-content/example-inline-validation)
"value-select" (~examples-content/example-value-select)
"reset-on-submit" (~examples-content/example-reset-on-submit)
"edit-row" (~examples-content/example-edit-row)
"bulk-update" (~examples-content/example-bulk-update)
"swap-positions" (~examples-content/example-swap-positions)
"select-filter" (~examples-content/example-select-filter)
"tabs" (~examples-content/example-tabs)
"animations" (~examples-content/example-animations)
"dialogs" (~examples-content/example-dialogs)
"keyboard-shortcuts" (~examples-content/example-keyboard-shortcuts)
"put-patch" (~examples-content/example-put-patch)
"json-encoding" (~examples-content/example-json-encoding)
"vals-and-headers" (~examples-content/example-vals-and-headers)
"loading-states" (~examples-content/example-loading-states)
"sync-replace" (~examples-content/example-sync-replace)
"retry" (~examples-content/example-retry)
:else (~examples-content/example-click-to-load))))
;; ---------------------------------------------------------------------------
;; Etc section (parent of Essays, Philosophy, Plans)
@@ -225,7 +225,7 @@
:path "/etc/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(etc)"))
:content (~layouts/doc :path "/sx/(etc)"))
;; ---------------------------------------------------------------------------
;; Essays section (under Etc)
@@ -235,33 +235,33 @@
:path "/etc/essays/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(etc.(essay))" (~essays-index-content)))
:content (~layouts/doc :path "/sx/(etc.(essay))" (~essays/index/essays-index-content)))
(defpage essay-page
:path "/etc/essays/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(etc.(essay." slug "))")
:content (~layouts/doc :path (str "/sx/(etc.(essay." slug "))")
(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)
"tail-call-optimization" (~essay-tail-call-optimization)
"continuations" (~essay-continuations)
"reflexive-web" (~essay-reflexive-web)
"server-architecture" (~essay-server-architecture)
"separation-of-concerns" (~essay-separation-of-concerns)
"sx-and-ai" (~essay-sx-and-ai)
"no-alternative" (~essay-no-alternative)
"zero-tooling" (~essay-zero-tooling)
"react-is-hypermedia" (~essay-react-is-hypermedia)
"hegelian-synthesis" (~essay-hegelian-synthesis)
"the-art-chain" (~essay-the-art-chain)
"self-defining-medium" (~essay-self-defining-medium)
:else (~essays-index-content))))
"sx-sucks" (~essays/sx-sucks/essay-sx-sucks)
"why-sexps" (~essays/why-sexps/essay-why-sexps)
"htmx-react-hybrid" (~essays/htmx-react-hybrid/essay-htmx-react-hybrid)
"on-demand-css" (~essays/on-demand-css/essay-on-demand-css)
"client-reactivity" (~essays/client-reactivity/essay-client-reactivity)
"sx-native" (~essays/sx-native/essay-sx-native)
"tail-call-optimization" (~essays/tail-call-optimization/essay-tail-call-optimization)
"continuations" (~essays/continuations/essay-continuations)
"reflexive-web" (~essays/reflexive-web/essay-reflexive-web)
"server-architecture" (~essays/server-architecture/essay-server-architecture)
"separation-of-concerns" (~essays/separation-of-concerns/essay-separation-of-concerns)
"sx-and-ai" (~essays/sx-and-ai/essay-sx-and-ai)
"no-alternative" (~essays/no-alternative/essay-no-alternative)
"zero-tooling" (~essays/zero-tooling/essay-zero-tooling)
"react-is-hypermedia" (~essays/react-is-hypermedia/essay-react-is-hypermedia)
"hegelian-synthesis" (~essays/hegelian-synthesis/essay-hegelian-synthesis)
"the-art-chain" (~essays/the-art-chain/essay-the-art-chain)
"self-defining-medium" (~essays/self-defining-medium/essay-self-defining-medium)
:else (~essays/index/essays-index-content))))
;; ---------------------------------------------------------------------------
;; Philosophy section
@@ -271,20 +271,20 @@
:path "/etc/philosophy/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(etc.(philosophy))" (~philosophy-index-content)))
:content (~layouts/doc :path "/sx/(etc.(philosophy))" (~essays/philosophy-index/content)))
(defpage philosophy-page
:path "/etc/philosophy/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(etc.(philosophy." slug "))")
:content (~layouts/doc :path (str "/sx/(etc.(philosophy." slug "))")
(case slug
"sx-manifesto" (~essay-sx-manifesto)
"godel-escher-bach" (~essay-godel-escher-bach)
"wittgenstein" (~essay-sx-and-wittgenstein)
"dennett" (~essay-sx-and-dennett)
"existentialism" (~essay-s-existentialism)
:else (~philosophy-index-content))))
"godel-escher-bach" (~essays/godel-escher-bach/essay-godel-escher-bach)
"wittgenstein" (~essays/sx-and-wittgenstein/essay-sx-and-wittgenstein)
"dennett" (~essays/sx-and-dennett/essay-sx-and-dennett)
"existentialism" (~essays/s-existentialism/essay-s-existentialism)
:else (~essays/philosophy-index/content))))
;; ---------------------------------------------------------------------------
;; CSSX section
@@ -294,21 +294,21 @@
:path "/applications/cssx/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(applications.(cssx))" (~cssx-overview-content)))
:content (~layouts/doc :path "/sx/(applications.(cssx))" (~cssx/overview-content)))
(defpage cssx-page
:path "/applications/cssx/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(applications.(cssx." slug "))")
:content (~layouts/doc :path (str "/sx/(applications.(cssx." slug "))")
(case slug
"patterns" (~cssx-patterns-content)
"delivery" (~cssx-delivery-content)
"async" (~cssx-async-content)
"live" (~cssx-live-content)
"comparisons" (~cssx-comparison-content)
"philosophy" (~cssx-philosophy-content)
:else (~cssx-overview-content))))
"patterns" (~cssx/patterns-content)
"delivery" (~cssx/delivery-content)
"async" (~cssx/async-content)
"live" (~cssx/live-content)
"comparisons" (~cssx/comparison-content)
"philosophy" (~cssx/philosophy-content)
:else (~cssx/overview-content))))
;; ---------------------------------------------------------------------------
;; Specs section
@@ -318,13 +318,13 @@
:path "/language/specs/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(language.(spec))" (~spec-architecture-content)))
:content (~layouts/doc :path "/sx/(language.(spec))" (~specs/architecture-content)))
(defpage specs-page
:path "/language/specs/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(language.(spec." slug "))")
:content (~layouts/doc :path (str "/sx/(language.(spec." slug "))")
(let ((make-spec-files (fn (items)
(map (fn (item)
(dict :title (get item "title") :desc (get item "desc")
@@ -333,33 +333,33 @@
:source (read-spec-file (get item "filename"))))
items))))
(case slug
"core" (~spec-overview-content
"core" (~specs/overview-content
:spec-title "Core Language"
:spec-files (make-spec-files core-spec-items))
"adapters" (~spec-overview-content
"adapters" (~specs/overview-content
:spec-title "Adapters"
:spec-files (make-spec-files adapter-spec-items))
"browser" (~spec-overview-content
"browser" (~specs/overview-content
:spec-title "Browser Runtime"
:spec-files (make-spec-files browser-spec-items))
"reactive" (~spec-overview-content
"reactive" (~specs/overview-content
:spec-title "Reactive System"
:spec-files (make-spec-files reactive-spec-items))
"host" (~spec-overview-content
"host" (~specs/overview-content
:spec-title "Host Interface"
:spec-files (make-spec-files host-spec-items))
"extensions" (~spec-overview-content
"extensions" (~specs/overview-content
:spec-title "Extensions"
:spec-files (make-spec-files extension-spec-items))
:else (let ((spec (find-spec slug)))
(if spec
(~spec-detail-content
(~specs/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)))))))
(~specs/not-found :slug slug)))))))
;; ---------------------------------------------------------------------------
;; Spec Explorer — structured interactive view of spec files
@@ -369,7 +369,7 @@
:path "/language/specs/explore/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(language.(spec.(explore." slug ")))")
:content (~layouts/doc :path (str "/sx/(language.(spec.(explore." slug ")))")
(let ((spec (find-spec slug)))
(if spec
(let ((data (spec-explorer-data
@@ -377,9 +377,9 @@
(get spec "title")
(get spec "desc"))))
(if data
(~spec-explorer-content :data data)
(~spec-not-found :slug slug)))
(~spec-not-found :slug slug)))))
(~specs-explorer/spec-explorer-content :data data)
(~specs/not-found :slug slug)))
(~specs/not-found :slug slug)))))
;; ---------------------------------------------------------------------------
;; Bootstrappers section
@@ -389,19 +389,19 @@
:path "/language/bootstrappers/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(language.(bootstrapper))" (~bootstrappers-index-content)))
:content (~layouts/doc :path "/sx/(language.(bootstrapper))" (~specs/bootstrappers-index-content)))
(defpage bootstrapper-page
:path "/language/bootstrappers/<slug>"
:auth :public
:layout :sx-docs
:data (bootstrapper-data slug)
:content (~sx-doc :path (str "/sx/(language.(bootstrapper." slug "))")
:content (~layouts/doc :path (str "/sx/(language.(bootstrapper." slug "))")
(if bootstrapper-not-found
(~spec-not-found :slug slug)
(~specs/not-found :slug slug)
(case slug
"self-hosting"
(~bootstrapper-self-hosting-content
(~specs/bootstrapper-self-hosting-content
:py-sx-source py-sx-source
:g0-output g0-output
:g1-output g1-output
@@ -411,18 +411,18 @@
:g0-bytes g0-bytes
:verification-status verification-status)
"self-hosting-js"
(~bootstrapper-self-hosting-js-content
(~specs/bootstrapper-self-hosting-js-content
:js-sx-source js-sx-source
:defines-matched defines-matched
:defines-total defines-total
:js-sx-lines js-sx-lines
:verification-status verification-status)
"python"
(~bootstrapper-py-content
(~specs/bootstrapper-py-content
:bootstrapper-source bootstrapper-source
:bootstrapped-output bootstrapped-output)
:else
(~bootstrapper-js-content
(~specs/bootstrapper-js-content
:bootstrapper-source bootstrapper-source
:bootstrapped-output bootstrapped-output)))))
@@ -434,15 +434,15 @@
:path "/geography/isomorphism/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(isomorphism))" (~plan-isomorphic-content)))
:content (~layouts/doc :path "/sx/(geography.(isomorphism))" (~plans/isomorphic/plan-isomorphic-content)))
(defpage bundle-analyzer
:path "/geography/isomorphism/bundle-analyzer"
:auth :public
:layout :sx-docs
:data (bundle-analyzer-data)
:content (~sx-doc :path "/sx/(geography.(isomorphism.bundle-analyzer))"
(~bundle-analyzer-content
:content (~layouts/doc :path "/sx/(geography.(isomorphism.bundle-analyzer))"
(~analyzer/bundle-analyzer-content
:pages pages :total-components total-components :total-macros total-macros
:pure-count pure-count :io-count io-count)))
@@ -451,8 +451,8 @@
:auth :public
:layout :sx-docs
:data (routing-analyzer-data)
:content (~sx-doc :path "/sx/(geography.(isomorphism.routing-analyzer))"
(~routing-analyzer-content
:content (~layouts/doc :path "/sx/(geography.(isomorphism.routing-analyzer))"
(~routing-analyzer/content
:pages pages :total-pages total-pages :client-count client-count
:server-count server-count :registry-sample registry-sample)))
@@ -461,8 +461,8 @@
:auth :public
:layout :sx-docs
:data (data-test-data)
:content (~sx-doc :path "/sx/(geography.(isomorphism.data-test))"
(~data-test-content
:content (~layouts/doc :path "/sx/(geography.(isomorphism.data-test))"
(~data-test/content
:server-time server-time :items items
:phase phase :transport transport)))
@@ -470,20 +470,20 @@
:path "/geography/isomorphism/async-io"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(isomorphism.async-io))" (~async-io-demo-content)))
:content (~layouts/doc :path "/sx/(geography.(isomorphism.async-io))" (~async-io-demo/content)))
(defpage streaming-demo
:path "/geography/isomorphism/streaming"
:auth :public
:stream true
:layout :sx-docs
:shell (~sx-doc :path "/sx/(geography.(isomorphism.streaming))"
(~streaming-demo-layout
(~suspense :id "stream-fast" :fallback (~stream-skeleton))
(~suspense :id "stream-medium" :fallback (~stream-skeleton))
(~suspense :id "stream-slow" :fallback (~stream-skeleton))))
:shell (~layouts/doc :path "/sx/(geography.(isomorphism.streaming))"
(~streaming-demo/layout
(~shared:pages/suspense :id "stream-fast" :fallback (~streaming-demo/stream-skeleton))
(~shared:pages/suspense :id "stream-medium" :fallback (~streaming-demo/stream-skeleton))
(~shared:pages/suspense :id "stream-slow" :fallback (~streaming-demo/stream-skeleton))))
:data (streaming-demo-data)
:content (~streaming-demo-chunk
:content (~streaming-demo/chunk
:stream-label stream-label
:stream-color stream-color
:stream-message stream-message
@@ -494,39 +494,39 @@
:auth :public
:layout :sx-docs
:data (affinity-demo-data)
:content (~sx-doc :path "/sx/(geography.(isomorphism.affinity))"
(~affinity-demo-content :components components :page-plans page-plans)))
:content (~layouts/doc :path "/sx/(geography.(isomorphism.affinity))"
(~affinity-demo/content :components components :page-plans page-plans)))
(defpage optimistic-demo
:path "/geography/isomorphism/optimistic"
:auth :public
:layout :sx-docs
:data (optimistic-demo-data)
:content (~sx-doc :path "/sx/(geography.(isomorphism.optimistic))"
(~optimistic-demo-content :items items :server-time server-time)))
:content (~layouts/doc :path "/sx/(geography.(isomorphism.optimistic))"
(~optimistic-demo/content :items items :server-time server-time)))
(defpage offline-demo
:path "/geography/isomorphism/offline"
:auth :public
:layout :sx-docs
:data (offline-demo-data)
:content (~sx-doc :path "/sx/(geography.(isomorphism.offline))"
(~offline-demo-content :notes notes :server-time server-time)))
:content (~layouts/doc :path "/sx/(geography.(isomorphism.offline))"
(~offline-demo/content :notes notes :server-time server-time)))
;; Wildcard must come AFTER specific routes (first-match routing)
(defpage isomorphism-page
:path "/geography/isomorphism/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(geography.(isomorphism." slug "))")
:content (~layouts/doc :path (str "/sx/(geography.(isomorphism." slug "))")
(case slug
"bundle-analyzer" (~bundle-analyzer-content
"bundle-analyzer" (~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
"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))))
:else (~plans/isomorphic/plan-isomorphic-content))))
;; ---------------------------------------------------------------------------
;; Plans section
@@ -536,7 +536,7 @@
:path "/etc/plans/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(etc.(plan))" (~plans-index-content)))
:content (~layouts/doc :path "/sx/(etc.(plan))" (~plans/index/plans-index-content)))
(defpage plan-page
:path "/etc/plans/<slug>"
@@ -545,38 +545,38 @@
:data (case slug
"theorem-prover" (prove-data)
:else nil)
:content (~sx-doc :path (str "/sx/(etc.(plan." slug "))")
:content (~layouts/doc :path (str "/sx/(etc.(plan." slug "))")
(case slug
"status" (~plan-status-content)
"reader-macros" (~plan-reader-macros-content)
"reader-macro-demo" (~plan-reader-macro-demo-content)
"theorem-prover" (~plan-theorem-prover-content)
"self-hosting-bootstrapper" (~plan-self-hosting-bootstrapper-content)
"js-bootstrapper" (~plan-js-bootstrapper-content)
"sx-activity" (~plan-sx-activity-content)
"predictive-prefetch" (~plan-predictive-prefetch-content)
"content-addressed-components" (~plan-content-addressed-components-content)
"environment-images" (~plan-environment-images-content)
"runtime-slicing" (~plan-runtime-slicing-content)
"typed-sx" (~plan-typed-sx-content)
"nav-redesign" (~plan-nav-redesign-content)
"fragment-protocol" (~plan-fragment-protocol-content)
"glue-decoupling" (~plan-glue-decoupling-content)
"social-sharing" (~plan-social-sharing-content)
"sx-ci" (~plan-sx-ci-content)
"live-streaming" (~plan-live-streaming-content)
"sx-web-platform" (~plan-sx-web-platform-content)
"sx-forge" (~plan-sx-forge-content)
"sx-swarm" (~plan-sx-swarm-content)
"sx-proxy" (~plan-sx-proxy-content)
"async-eval-convergence" (~plan-async-eval-convergence-content)
"wasm-bytecode-vm" (~plan-wasm-bytecode-vm-content)
"generative-sx" (~plan-generative-sx-content)
"art-dag-sx" (~plan-art-dag-sx-content)
"spec-explorer" (~plan-spec-explorer-content)
"sx-urls" (~plan-sx-urls-content)
"sx-protocol" (~plan-sx-protocol-content)
:else (~plans-index-content))))
"status" (~plans/status/plan-status-content)
"reader-macros" (~plans/reader-macros/plan-reader-macros-content)
"reader-macro-demo" (~plans/reader-macro-demo/plan-reader-macro-demo-content)
"theorem-prover" (~plans/theorem-prover/plan-theorem-prover-content)
"self-hosting-bootstrapper" (~plans/self-hosting-bootstrapper/plan-self-hosting-bootstrapper-content)
"js-bootstrapper" (~plans/js-bootstrapper/plan-js-bootstrapper-content)
"sx-activity" (~plans/sx-activity/plan-sx-activity-content)
"predictive-prefetch" (~plans/predictive-prefetch/plan-predictive-prefetch-content)
"content-addressed-components" (~plans/content-addressed-components/plan-content-addressed-components-content)
"environment-images" (~plans/environment-images/plan-environment-images-content)
"runtime-slicing" (~plans/runtime-slicing/plan-runtime-slicing-content)
"typed-sx" (~plans/typed-sx/plan-typed-sx-content)
"nav-redesign" (~plans/nav-redesign/plan-nav-redesign-content)
"fragment-protocol" (~plans/fragment-protocol/plan-fragment-protocol-content)
"glue-decoupling" (~plans/glue-decoupling/plan-glue-decoupling-content)
"social-sharing" (~plans/social-sharing/plan-social-sharing-content)
"sx-ci" (~plans/sx-ci/plan-sx-ci-content)
"live-streaming" (~plans/live-streaming/plan-live-streaming-content)
"sx-web-platform" (~plans/sx-web-platform/plan-sx-web-platform-content)
"sx-forge" (~plans/sx-forge/plan-sx-forge-content)
"sx-swarm" (~plans/sx-swarm/plan-sx-swarm-content)
"sx-proxy" (~plans/sx-proxy/plan-sx-proxy-content)
"async-eval-convergence" (~plans/async-eval-convergence/plan-async-eval-convergence-content)
"wasm-bytecode-vm" (~plans/wasm-bytecode-vm/plan-wasm-bytecode-vm-content)
"generative-sx" (~plans/generative-sx/plan-generative-sx-content)
"art-dag-sx" (~plans/art-dag-sx/plan-art-dag-sx-content)
"spec-explorer" (~plans/spec-explorer/plan-spec-explorer-content)
"sx-urls" (~plans/sx-urls/plan-sx-urls-content)
"sx-protocol" (~plans/sx-protocol/plan-sx-protocol-content)
:else (~plans/index/plans-index-content))))
;; ---------------------------------------------------------------------------
;; Geography section (parent of Reactive Islands, Hypermedia Lakes, Marshes)
@@ -586,7 +586,7 @@
:path "/geography/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography)"))
:content (~layouts/doc :path "/sx/(geography)"))
;; ---------------------------------------------------------------------------
;; Reactive Islands section (under Geography)
@@ -596,20 +596,20 @@
:path "/geography/reactive/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(reactive))" (~reactive-islands-index-content)))
:content (~layouts/doc :path "/sx/(geography.(reactive))" (~reactive-islands/index/reactive-islands-index-content)))
(defpage reactive-islands-page
:path "/geography/reactive/<slug>"
:auth :public
:layout :sx-docs
:content (~sx-doc :path (str "/sx/(geography.(reactive." slug "))")
:content (~layouts/doc :path (str "/sx/(geography.(reactive." slug "))")
(case slug
"demo" (~reactive-islands-demo-content)
"event-bridge" (~reactive-islands-event-bridge-content)
"named-stores" (~reactive-islands-named-stores-content)
"plan" (~reactive-islands-plan-content)
"phase2" (~reactive-islands-phase2-content)
:else (~reactive-islands-index-content))))
"demo" (~reactive-islands/demo/reactive-islands-demo-content)
"event-bridge" (~reactive-islands/event-bridge/reactive-islands-event-bridge-content)
"named-stores" (~reactive-islands/named-stores/reactive-islands-named-stores-content)
"plan" (~reactive-islands/plan/reactive-islands-plan-content)
"phase2" (~reactive-islands/phase2/reactive-islands-phase2-content)
:else (~reactive-islands/index/reactive-islands-index-content))))
;; ---------------------------------------------------------------------------
;; Marshes section (under Geography)
@@ -619,7 +619,7 @@
:path "/geography/marshes/"
:auth :public
:layout :sx-docs
:content (~sx-doc :path "/sx/(geography.(marshes))" (~reactive-islands-marshes-content)))
:content (~layouts/doc :path "/sx/(geography.(marshes))" (~reactive-islands/marshes/reactive-islands-marshes-content)))
;; ---------------------------------------------------------------------------
;; Bootstrapped page helpers demo
@@ -630,8 +630,8 @@
:auth :public
:layout :sx-docs
:data (page-helpers-demo-data)
:content (~sx-doc :path "/sx/(language.(bootstrapper.page-helpers))"
(~page-helpers-demo-content
:content (~layouts/doc :path "/sx/(language.(bootstrapper.page-helpers))"
(~page-helpers-demo/content
:sf-categories sf-categories :sf-total sf-total :sf-ms sf-ms
:ref-sample ref-sample :ref-ms ref-ms
:attr-result attr-result :attr-ms attr-ms
@@ -652,8 +652,8 @@
:auth :public
:layout :sx-docs
:data (run-modular-tests "all")
:content (~sx-doc :path "/sx/(language.(test))"
(~testing-overview-content
:content (~layouts/doc :path "/sx/(language.(test))"
(~testing/overview-content
:server-results server-results
:framework-source framework-source
:eval-source eval-source
@@ -676,57 +676,57 @@
"engine" (run-modular-tests "engine")
"orchestration" (run-modular-tests "orchestration")
:else (dict))
:content (~sx-doc :path (str "/sx/(language.(test." slug "))")
:content (~layouts/doc :path (str "/sx/(language.(test." slug "))")
(case slug
"eval" (~testing-spec-content
"eval" (~testing/spec-content
:spec-name "eval"
:spec-title "Evaluator Tests"
:spec-desc "81 tests covering the core evaluator and all primitives — literals, arithmetic, comparison, strings, lists, dicts, predicates, special forms, lambdas, higher-order functions, components, macros, threading, and edge cases."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"parser" (~testing-spec-content
"parser" (~testing/spec-content
:spec-name "parser"
:spec-title "Parser Tests"
:spec-desc "39 tests covering tokenization and parsing — integers, floats, strings, escape sequences, booleans, nil, keywords, symbols, lists, dicts, whitespace, comments, quote sugar, serialization, and round-trips."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"router" (~testing-spec-content
"router" (~testing/spec-content
:spec-name "router"
:spec-title "Router Tests"
:spec-desc "18 tests covering client-side route matching — path splitting, pattern parsing, segment matching, parameter extraction, and route table search."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"render" (~testing-spec-content
"render" (~testing/spec-content
:spec-name "render"
:spec-title "Renderer Tests"
:spec-desc "23 tests covering HTML rendering — elements, attributes, void elements, boolean attributes, fragments, escaping, control flow, and component rendering."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"deps" (~testing-spec-content
"deps" (~testing/spec-content
:spec-name "deps"
:spec-title "Dependency Analysis Tests"
:spec-desc "33 tests covering component dependency analysis — scan-refs, scan-components-from-source, transitive-deps, components-needed, scan-io-refs, and component-pure? classification."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"engine" (~testing-spec-content
"engine" (~testing/spec-content
:spec-name "engine"
:spec-title "Engine Tests"
:spec-desc "37 tests covering engine pure functions — parse-time, parse-trigger-spec, default-trigger, parse-swap-spec, parse-retry-spec, next-retry-ms, and filter-params."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"orchestration" (~testing-spec-content
"orchestration" (~testing/spec-content
:spec-name "orchestration"
:spec-title "Orchestration Tests"
:spec-desc "17 tests covering Phase 7c+7d orchestration — page data cache, optimistic cache update/revert/confirm, offline connectivity, offline queue mutation, and offline-aware routing."
:spec-source spec-source
:framework-source framework-source
:server-results server-results)
"runners" (~testing-runners-content)
:else (~testing-overview-content
"runners" (~testing/runners-content)
:else (~testing/overview-content
:server-results server-results))))

View File

@@ -1372,7 +1372,7 @@ def _data_test_data() -> dict:
async def _streaming_demo_data():
"""Multi-stream demo — yields three chunks at staggered intervals.
Each yield is a dict with _stream_id (matching a ~suspense :id in the
Each yield is a dict with _stream_id (matching a ~shared:pages/suspense :id in the
shell) plus bindings for the :content expression. The streaming
infrastructure detects the async generator and resolves each suspense
placeholder as each chunk arrives.
@@ -1418,8 +1418,8 @@ def _affinity_demo_data() -> dict:
# I/O edge: extract component data and page render plans
env = get_component_env()
demo_names = [
"~aff-demo-auto", "~aff-demo-client", "~aff-demo-server",
"~aff-demo-io-auto", "~aff-demo-io-client",
"~affinity-demo/aff-demo-auto", "~affinity-demo/aff-demo-client", "~affinity-demo/aff-demo-server",
"~affinity-demo/aff-demo-io-auto", "~affinity-demo/aff-demo-io-client",
]
components = []
for name in demo_names:

View File

@@ -5,7 +5,7 @@ Handles URLs like /(language.(doc.introduction)) by:
2. Parsing the path as an SX expression
3. Auto-quoting unknown symbols to strings (slugs)
4. Evaluating the expression against page functions
5. Wrapping the result in (~sx-doc :path "..." content)
5. Wrapping the result in (~layouts/doc :path "..." content)
6. Returning full page or OOB response
Special cases:
@@ -217,7 +217,7 @@ async def eval_sx_url(raw_path: str) -> Any:
# Nav hrefs use /sx/ prefix — reconstruct the full path for nav matching
path_str = f"/sx{raw_path}" if raw_path != "/" else "/sx/"
# Check if expression head is a component (~name) — if so, skip
# Check if expression head is a component (~plans/content-addressed-components/name) — if so, skip
# async_eval and pass directly to _eval_slot. Components contain HTML
# tags that only the aser path can handle, not eval_expr.
head = quoted_expr[0] if isinstance(quoted_expr, list) and quoted_expr else None
@@ -227,7 +227,7 @@ async def eval_sx_url(raw_path: str) -> Any:
)
if is_component_call:
# Direct component URL: /(~essay-sx-sucks) or /(~comp :key val)
# Direct component URL: /(~essays/sx-sucks/essay-sx-sucks) or /(~comp :key val)
# Pass straight to _eval_slot — aser handles component expansion.
page_ast = quoted_expr
else:
@@ -237,7 +237,7 @@ async def eval_sx_url(raw_path: str) -> Any:
# [Symbol("~docs-intro-content")] or quasiquoted trees with data).
# This phase resolves routing + fetches data, but does NOT expand
# components or handle HTML tags (eval_expr can't do that).
# Phase 2: Wrap the returned AST in (~sx-doc :path "..." <ast>) and
# Phase 2: Wrap the returned AST in (~layouts/doc :path "..." <ast>) and
# pass to _eval_slot (aser), which expands components and handles
# HTML tags correctly.
import os
@@ -257,7 +257,7 @@ async def eval_sx_url(raw_path: str) -> Any:
page_ast = [] # empty content for sections with no index
wrapped_ast = [
Symbol("~sx-doc"), Keyword("path"), path_str,
Symbol("~layouts/doc"), Keyword("path"), path_str,
page_ast,
]

View File

@@ -7,7 +7,7 @@
;; sx-get
;; ---------------------------------------------------------------------------
(defcomp ~ref-get-demo ()
(defcomp ~reference/ref-get-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.time))))"
@@ -23,7 +23,7 @@
;; sx-post
;; ---------------------------------------------------------------------------
(defcomp ~ref-post-demo ()
(defcomp ~reference/ref-post-demo ()
(div :class "space-y-3"
(form
:sx-post "/sx/(geography.(hypermedia.(reference.(api.greet))))"
@@ -43,7 +43,7 @@
;; sx-put
;; ---------------------------------------------------------------------------
(defcomp ~ref-put-demo ()
(defcomp ~reference/ref-put-demo ()
(div :id "ref-put-view"
(div :class "flex items-center justify-between p-3 bg-stone-100 rounded"
(span :class "text-stone-700 text-sm" "Status: " (strong "draft"))
@@ -59,7 +59,7 @@
;; sx-delete
;; ---------------------------------------------------------------------------
(defcomp ~ref-delete-demo ()
(defcomp ~reference/ref-delete-demo ()
(div :class "space-y-2"
(div :id "ref-del-1" :class "flex items-center justify-between p-2 border border-stone-200 rounded"
(span :class "text-sm text-stone-700" "Item A")
@@ -81,7 +81,7 @@
;; sx-patch
;; ---------------------------------------------------------------------------
(defcomp ~ref-patch-demo ()
(defcomp ~reference/ref-patch-demo ()
(div :id "ref-patch-view" :class "space-y-2"
(div :class "p-3 bg-stone-100 rounded"
(span :class "text-stone-700 text-sm" "Theme: " (strong :id "ref-patch-val" "light")))
@@ -99,7 +99,7 @@
;; sx-trigger
;; ---------------------------------------------------------------------------
(defcomp ~ref-trigger-demo ()
(defcomp ~reference/ref-trigger-demo ()
(div :class "space-y-3"
(input :type "text" :name "q" :placeholder "Type to search..."
:sx-get "/sx/(geography.(hypermedia.(reference.(api.trigger-search))))"
@@ -115,7 +115,7 @@
;; sx-target
;; ---------------------------------------------------------------------------
(defcomp ~ref-target-demo ()
(defcomp ~reference/ref-target-demo ()
(div :class "space-y-3"
(div :class "flex gap-2"
(button :sx-get "/sx/(geography.(hypermedia.(reference.(api.time))))"
@@ -138,7 +138,7 @@
;; sx-swap
;; ---------------------------------------------------------------------------
(defcomp ~ref-swap-demo ()
(defcomp ~reference/ref-swap-demo ()
(div :class "space-y-3"
(div :class "flex gap-2 flex-wrap"
(button :sx-get "/sx/(geography.(hypermedia.(reference.(api.swap-item))))"
@@ -158,7 +158,7 @@
;; sx-swap-oob
;; ---------------------------------------------------------------------------
(defcomp ~ref-oob-demo ()
(defcomp ~reference/ref-oob-demo ()
(div :class "space-y-3"
(button :sx-get "/sx/(geography.(hypermedia.(reference.(api.oob))))"
:sx-target "#ref-oob-main"
@@ -177,7 +177,7 @@
;; sx-select
;; ---------------------------------------------------------------------------
(defcomp ~ref-select-demo ()
(defcomp ~reference/ref-select-demo ()
(div :class "space-y-3"
(button :sx-get "/sx/(geography.(hypermedia.(reference.(api.select-page))))"
:sx-target "#ref-select-result"
@@ -193,7 +193,7 @@
;; sx-confirm
;; ---------------------------------------------------------------------------
(defcomp ~ref-confirm-demo ()
(defcomp ~reference/ref-confirm-demo ()
(div :class "space-y-2"
(div :id "ref-confirm-item"
:class "flex items-center justify-between p-3 border border-stone-200 rounded"
@@ -208,7 +208,7 @@
;; sx-push-url
;; ---------------------------------------------------------------------------
(defcomp ~ref-pushurl-demo ()
(defcomp ~reference/ref-pushurl-demo ()
(div :class "space-y-3"
(div :class "flex gap-2"
(a :href "/sx/(geography.(hypermedia.(reference-detail.attributes.sx-get)))"
@@ -230,7 +230,7 @@
;; sx-sync
;; ---------------------------------------------------------------------------
(defcomp ~ref-sync-demo ()
(defcomp ~reference/ref-sync-demo ()
(div :class "space-y-3"
(input :type "text" :name "q" :placeholder "Type quickly..."
:sx-get "/sx/(geography.(hypermedia.(reference.(api.slow-echo))))"
@@ -249,7 +249,7 @@
;; sx-encoding
;; ---------------------------------------------------------------------------
(defcomp ~ref-encoding-demo ()
(defcomp ~reference/ref-encoding-demo ()
(div :class "space-y-3"
(form :sx-post "/sx/(geography.(hypermedia.(reference.(api.upload-name))))"
:sx-encoding "multipart/form-data"
@@ -269,7 +269,7 @@
;; sx-headers
;; ---------------------------------------------------------------------------
(defcomp ~ref-headers-demo ()
(defcomp ~reference/ref-headers-demo ()
(div :class "space-y-3"
(button :sx-get "/sx/(geography.(hypermedia.(reference.(api.echo-headers))))"
:sx-headers {:X-Custom-Token "abc123" :X-Request-Source "demo"}
@@ -285,7 +285,7 @@
;; sx-include
;; ---------------------------------------------------------------------------
(defcomp ~ref-include-demo ()
(defcomp ~reference/ref-include-demo ()
(div :class "space-y-3"
(div :class "flex gap-2 items-end"
(div
@@ -309,7 +309,7 @@
;; sx-vals
;; ---------------------------------------------------------------------------
(defcomp ~ref-vals-demo ()
(defcomp ~reference/ref-vals-demo ()
(div :class "space-y-3"
(button :sx-post "/sx/(geography.(hypermedia.(reference.(api.echo-vals))))"
:sx-vals "{\"source\": \"demo\", \"page\": \"3\"}"
@@ -325,7 +325,7 @@
;; sx-media
;; ---------------------------------------------------------------------------
(defcomp ~ref-media-demo ()
(defcomp ~reference/ref-media-demo ()
(div :class "space-y-3"
(a :href "/sx/(geography.(hypermedia.(reference-detail.attributes.sx-get)))"
:sx-get "/sx/(geography.(hypermedia.(reference-detail.attributes.sx-get)))"
@@ -341,7 +341,7 @@
;; sx-disable
;; ---------------------------------------------------------------------------
(defcomp ~ref-disable-demo ()
(defcomp ~reference/ref-disable-demo ()
(div :class "space-y-3"
(div :class "grid grid-cols-2 gap-3"
(div :class "p-3 border border-stone-200 rounded"
@@ -362,7 +362,7 @@
;; sx-on:*
;; ---------------------------------------------------------------------------
(defcomp ~ref-on-demo ()
(defcomp ~reference/ref-on-demo ()
(div :class "space-y-3"
(button
:sx-on:click "document.getElementById('ref-on-result').textContent = 'Clicked at ' + new Date().toLocaleTimeString()"
@@ -376,7 +376,7 @@
;; sx-retry
;; ---------------------------------------------------------------------------
(defcomp ~ref-retry-demo ()
(defcomp ~reference/ref-retry-demo ()
(div :class "space-y-3"
(button :sx-get "/sx/(geography.(hypermedia.(reference.(api.flaky))))"
:sx-target "#ref-retry-result"
@@ -392,7 +392,7 @@
;; data-sx
;; ---------------------------------------------------------------------------
(defcomp ~ref-data-sx-demo ()
(defcomp ~reference/ref-data-sx-demo ()
(div :class "space-y-3"
(div :data-sx "(div :class \"p-3 bg-violet-50 rounded\" (h3 :class \"font-semibold text-violet-800\" \"Client-rendered\") (p :class \"text-sm text-stone-600\" \"This was evaluated in the browser — no server request.\"))")
(p :class "text-xs text-stone-400" "The content above is rendered client-side from the data-sx attribute.")))
@@ -401,7 +401,7 @@
;; data-sx-env
;; ---------------------------------------------------------------------------
(defcomp ~ref-data-sx-env-demo ()
(defcomp ~reference/ref-data-sx-env-demo ()
(div :class "space-y-3"
(div :data-sx "(div :class \"p-3 bg-emerald-50 rounded\" (h3 :class \"font-semibold text-emerald-800\" title) (p :class \"text-sm text-stone-600\" message))"
:data-sx-env "{\"title\": \"Dynamic content\", \"message\": \"Variables passed via data-sx-env are available in the expression.\"}")
@@ -411,7 +411,7 @@
;; sx-boost
;; ---------------------------------------------------------------------------
(defcomp ~ref-boost-demo ()
(defcomp ~reference/ref-boost-demo ()
(div :class "space-y-3"
(nav :sx-boost "true" :class "flex gap-3"
(a :href "/sx/(geography.(hypermedia.(reference-detail.attributes.sx-get)))"
@@ -431,7 +431,7 @@
;; sx-preload
;; ---------------------------------------------------------------------------
(defcomp ~ref-preload-demo ()
(defcomp ~reference/ref-preload-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.time))))"
@@ -448,7 +448,7 @@
;; sx-preserve
;; ---------------------------------------------------------------------------
(defcomp ~ref-preserve-demo ()
(defcomp ~reference/ref-preserve-demo ()
(div :class "space-y-3"
(div :class "flex gap-2 items-center"
(button
@@ -469,7 +469,7 @@
;; sx-indicator
;; ---------------------------------------------------------------------------
(defcomp ~ref-indicator-demo ()
(defcomp ~reference/ref-indicator-demo ()
(div :class "space-y-3"
(div :class "flex gap-3 items-center"
(button
@@ -492,7 +492,7 @@
;; sx-validate
;; ---------------------------------------------------------------------------
(defcomp ~ref-validate-demo ()
(defcomp ~reference/ref-validate-demo ()
(div :class "space-y-3"
(form
:sx-post "/sx/(geography.(hypermedia.(reference.(api.greet))))"
@@ -514,7 +514,7 @@
;; sx-ignore
;; ---------------------------------------------------------------------------
(defcomp ~ref-ignore-demo ()
(defcomp ~reference/ref-ignore-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.time))))"
@@ -534,7 +534,7 @@
;; sx-optimistic
;; ---------------------------------------------------------------------------
(defcomp ~ref-optimistic-demo ()
(defcomp ~reference/ref-optimistic-demo ()
(div :class "space-y-2"
(div :id "ref-opt-item-1"
:class "flex items-center justify-between p-2 border border-stone-200 rounded"
@@ -557,7 +557,7 @@
;; sx-replace-url
;; ---------------------------------------------------------------------------
(defcomp ~ref-replace-url-demo ()
(defcomp ~reference/ref-replace-url-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.time))))"
@@ -574,7 +574,7 @@
;; sx-disabled-elt
;; ---------------------------------------------------------------------------
(defcomp ~ref-disabled-elt-demo ()
(defcomp ~reference/ref-disabled-elt-demo ()
(div :class "space-y-3"
(div :class "flex gap-3 items-center"
(button :id "ref-diselt-btn"
@@ -594,7 +594,7 @@
;; sx-prompt
;; ---------------------------------------------------------------------------
(defcomp ~ref-prompt-demo ()
(defcomp ~reference/ref-prompt-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.prompt-echo))))"
@@ -611,7 +611,7 @@
;; sx-params
;; ---------------------------------------------------------------------------
(defcomp ~ref-params-demo ()
(defcomp ~reference/ref-params-demo ()
(div :class "space-y-3"
(form
:sx-post "/sx/(geography.(hypermedia.(reference.(api.echo-vals))))"
@@ -634,7 +634,7 @@
;; sx-sse
;; ---------------------------------------------------------------------------
(defcomp ~ref-sse-demo ()
(defcomp ~reference/ref-sse-demo ()
(div :class "space-y-3"
(div :sx-sse "/sx/(geography.(hypermedia.(reference.(api.sse-time))))"
:sx-sse-swap "time"
@@ -653,7 +653,7 @@
;; SX-Prompt header demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-header-prompt-demo ()
(defcomp ~reference/ref-header-prompt-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.prompt-echo))))"
@@ -670,7 +670,7 @@
;; SX-Trigger response header demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-header-trigger-demo ()
(defcomp ~reference/ref-header-trigger-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.trigger-event))))"
@@ -687,7 +687,7 @@
;; SX-Retarget response header demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-header-retarget-demo ()
(defcomp ~reference/ref-header-retarget-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.retarget))))"
@@ -711,7 +711,7 @@
;; sx:beforeRequest event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-before-request-demo ()
(defcomp ~reference/ref-event-before-request-demo ()
(div :class "space-y-3"
(div :class "flex gap-2 items-center"
(input :id "ref-evt-br-input" :type "text" :placeholder "Type something first..."
@@ -731,7 +731,7 @@
;; sx:afterRequest event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-after-request-demo ()
(defcomp ~reference/ref-event-after-request-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.time))))"
@@ -751,7 +751,7 @@
;; sx:afterSwap event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-after-swap-demo ()
(defcomp ~reference/ref-event-after-swap-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.swap-item))))"
@@ -771,7 +771,7 @@
;; sx:responseError event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-response-error-demo ()
(defcomp ~reference/ref-event-response-error-demo ()
(div :class "space-y-3"
(button
:sx-get "/sx/(geography.(hypermedia.(reference.(api.error-500))))"
@@ -793,7 +793,7 @@
;; ---------------------------------------------------------------------------
;; @css invalid:border-red-400
(defcomp ~ref-event-validation-failed-demo ()
(defcomp ~reference/ref-event-validation-failed-demo ()
(div :class "space-y-3"
(form
:sx-post "/sx/(geography.(hypermedia.(reference.(api.greet))))"
@@ -820,7 +820,7 @@
;; sx:requestError event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-request-error-demo ()
(defcomp ~reference/ref-event-request-error-demo ()
(div :class "space-y-3"
(button
:sx-get "https://this-domain-does-not-exist.invalid/api"
@@ -841,7 +841,7 @@
;; sx:clientRoute event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-client-route-demo ()
(defcomp ~reference/ref-event-client-route-demo ()
(div :class "space-y-3"
(p :class "text-sm text-stone-600"
"Open DevTools console, then navigate to a pure page (no :data expression). "
@@ -864,7 +864,7 @@
;; sx:sseOpen event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-sse-open-demo ()
(defcomp ~reference/ref-event-sse-open-demo ()
(div :class "space-y-3"
(div :sx-sse "/sx/(geography.(hypermedia.(reference.(api.sse-time))))"
:sx-sse-swap "time"
@@ -882,7 +882,7 @@
;; sx:sseMessage event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-sse-message-demo ()
(defcomp ~reference/ref-event-sse-message-demo ()
(div :class "space-y-3"
(div :sx-sse "/sx/(geography.(hypermedia.(reference.(api.sse-time))))"
:sx-sse-swap "time"
@@ -900,7 +900,7 @@
;; sx:sseError event demo
;; ---------------------------------------------------------------------------
(defcomp ~ref-event-sse-error-demo ()
(defcomp ~reference/ref-event-sse-error-demo ()
(div :class "space-y-3"
(div :sx-sse "/sx/(geography.(hypermedia.(reference.(api.sse-time))))"
:sx-sse-swap "time"