Update sx-docs: add deps spec to viewer, mark Phase 1 complete
Add deps.sx to the spec navigator in sx-docs (nav-data, specs page). Update isomorphic architecture plan to show Phase 1 as complete with link to the canonical spec at /specs/deps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -621,51 +621,66 @@
|
||||
|
||||
(~doc-section :title "Phase 1: Component Distribution & Dependency Analysis" :id "phase-1"
|
||||
|
||||
(div :class "rounded border border-violet-200 bg-violet-50 p-4 mb-4"
|
||||
(p :class "text-violet-900 font-medium" "What it enables")
|
||||
(p :class "text-violet-800" "Per-page component bundles instead of sending every definition to every page. Smaller payloads, faster boot, better cache hit rates."))
|
||||
(div :class "rounded border border-green-300 bg-green-50 p-4 mb-4"
|
||||
(div :class "flex items-center gap-2 mb-2"
|
||||
(span :class "inline-block px-2 py-0.5 rounded text-xs font-bold bg-green-600 text-white uppercase" "Complete")
|
||||
(a :href "/specs/deps" :class "text-green-700 underline text-sm font-medium" "View canonical spec: deps.sx"))
|
||||
(p :class "text-green-900 font-medium" "What it enables")
|
||||
(p :class "text-green-800" "Per-page component bundles instead of sending every definition to every page. Smaller payloads, faster boot, better cache hit rates."))
|
||||
|
||||
(~doc-subsection :title "The Problem"
|
||||
(p "client_components_tag() in jinja_bridge.py serializes ALL entries in _COMPONENT_ENV. The sx_page() template sends everything or nothing based on a single global hash. No mechanism determines which components a page actually needs."))
|
||||
|
||||
(~doc-subsection :title "Approach"
|
||||
(~doc-subsection :title "Implementation"
|
||||
|
||||
(p "Phase 1 follows the spec-first architecture: the dependency analysis algorithm is defined in "
|
||||
(a :href "/specs/deps" :class "text-violet-700 underline" "deps.sx")
|
||||
" and bootstrapped to both Python (sx_ref.py) and JavaScript (sx-ref.js). A thin dispatcher in deps.py routes to the bootstrapped implementation when SX_USE_REF=1.")
|
||||
|
||||
(div :class "space-y-4"
|
||||
(div
|
||||
(h4 :class "font-semibold text-stone-700" "1. Transitive closure analyzer")
|
||||
(p "New module shared/sx/deps.py:")
|
||||
(h4 :class "font-semibold text-stone-700" "1. Transitive closure analyzer (deps.sx)")
|
||||
(p "The spec defines 9 functions for dependency analysis. The core algorithm:")
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1"
|
||||
(li "Walk Component.body AST, collect all Symbol refs starting with ~")
|
||||
(li "Recursively follow into their bodies")
|
||||
(li "Handle control forms (if/when/cond/case) — include ALL branches")
|
||||
(li "Handle macros — expand during walk using limited eval"))
|
||||
(~doc-code :code (highlight "def transitive_deps(name: str, env: dict) -> set[str]:\n \"\"\"Compute transitive component dependencies.\"\"\"\n seen = set()\n def walk(n):\n if n in seen: return\n seen.add(n)\n comp = env.get(n)\n if comp:\n for dep in _scan_ast(comp.body):\n walk(dep)\n walk(name)\n return seen - {name}" "python")))
|
||||
(li "scan-refs: walk a component body AST, collect all Symbol refs starting with ~")
|
||||
(li "transitive-deps: recursively follow component references through the env")
|
||||
(li "compute-all-deps: batch-compute and cache deps for all components in env")
|
||||
(li "Handle circular references safely via seen-set"))
|
||||
(~doc-code :code (highlight "(define (transitive-deps name env)\n (let ((key (if (starts-with? name \"~\") name\n (concat \"~\" name)))\n (seen (set-create)))\n (transitive-deps-walk key env seen)\n (set-remove seen key)))" "lisp")))
|
||||
|
||||
(div
|
||||
(h4 :class "font-semibold text-stone-700" "2. Runtime component scanning")
|
||||
(p "After _aser serializes page content, scan the SX string for (~name patterns (parallel to existing scan_classes_from_sx for CSS). Then compute transitive closure to get sub-components."))
|
||||
(p "scan-components-from-source uses regex to find (~name patterns in serialized SX. components-needed combines scanning with transitive closure to get the full set of components a page requires."))
|
||||
|
||||
(div
|
||||
(h4 :class "font-semibold text-stone-700" "3. Per-page component block")
|
||||
(p "In sx_page() — replace all-or-nothing with page-specific bundle. Hash changes per page, localStorage cache keyed by route pattern."))
|
||||
(h4 :class "font-semibold text-stone-700" "3. Per-page CSS classes")
|
||||
(p "page-css-classes collects Tailwind classes from all components in a page bundle, enabling per-page CSS extraction."))
|
||||
|
||||
(div
|
||||
(h4 :class "font-semibold text-stone-700" "4. SX partial responses")
|
||||
(p "components_for_request() already diffs against SX-Components header. Enhance with transitive closure so only truly needed missing components are sent."))))
|
||||
(h4 :class "font-semibold text-stone-700" "4. Platform interface")
|
||||
(p "The spec declares 6 platform functions that each host implements natively:")
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1 font-mono text-sm"
|
||||
(li "component-deps / component-set-deps!")
|
||||
(li "component-css-classes")
|
||||
(li "env-components")
|
||||
(li "regex-find-all / scan-css-classes")))))
|
||||
|
||||
(~doc-subsection :title "Files"
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1 font-mono text-sm"
|
||||
(li "New: shared/sx/deps.py — dependency analysis")
|
||||
(li "shared/sx/jinja_bridge.py — per-page bundle generation")
|
||||
(li "shared/sx/helpers.py — modify sx_page() and sx_response()")
|
||||
(li "shared/sx/types.py — add deps: set[str] to Component")
|
||||
(li "shared/sx/ref/boot.sx — per-page component caching")))
|
||||
(li "shared/sx/ref/deps.sx — canonical spec (9 functions)")
|
||||
(li "shared/sx/deps.py — dispatcher (SX_USE_REF → bootstrapped, else fallback)")
|
||||
(li "shared/sx/ref/bootstrap_py.py — spec module + platform deps")
|
||||
(li "shared/sx/ref/bootstrap_js.py — spec module + platform deps")
|
||||
(li "shared/sx/ref/sx_ref.py — regenerated with deps module")
|
||||
(li "shared/static/scripts/sx-ref.js — regenerated with deps module")
|
||||
(li "shared/sx/tests/test_deps.py — 15 tests")))
|
||||
|
||||
(~doc-subsection :title "Verification"
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1"
|
||||
(li "Page using 5/50 components → data-components block contains only those 5 + transitive deps")
|
||||
(li "No \"Unknown component\" errors after bundle reduction")
|
||||
(li "Payload size reduction measurable"))))
|
||||
(li "15 dedicated deps tests pass (scan, transitive, circular, compute-all, components-needed)")
|
||||
(li "541 total Python tests pass with zero regressions")
|
||||
(li "JS deps functions verified in Node.js (scanRefs, transitiveDeps, computeAllDeps, componentsNeeded)")
|
||||
(li "Both bootstrapped and fallback code paths produce identical results"))))
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Phase 2
|
||||
|
||||
Reference in New Issue
Block a user