Rewrite Phase 1 plan: express in SX terms, not Python
Remove Python-specific references (deps.py, sx_ref.py, bootstrap_py.py, test_deps.py). Phase 1 is about deps.sx the spec module — hosts are interchangeable. Show SX code examples, describe platform interface abstractly, link to live bundle analyzer for proof. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -630,58 +630,54 @@
|
||||
(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."))
|
||||
(p "The page boot payload serializes every component definition in the environment. A page that uses 5 components still receives all 50+. No mechanism determines which components a page actually needs — the boundary between \"loaded\" and \"used\" is invisible."))
|
||||
|
||||
(~doc-subsection :title "Implementation"
|
||||
|
||||
(p "Phase 1 follows the spec-first architecture: the dependency analysis algorithm is defined in "
|
||||
(p "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.")
|
||||
" — a spec module bootstrapped to every host. Each host loads it via " (code "--spec-modules deps") " and provides 6 platform functions. The spec is the single source of truth; hosts are interchangeable.")
|
||||
|
||||
(div :class "space-y-4"
|
||||
(div
|
||||
(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 "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")))
|
||||
(h4 :class "font-semibold text-stone-700" "1. Transitive closure (deps.sx)")
|
||||
(p "9 functions that walk the component graph. The core:")
|
||||
(~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"))
|
||||
(p (code "scan-refs") " walks a component body AST collecting " (code "~") " symbols. "
|
||||
(code "transitive-deps") " follows references recursively through the env. "
|
||||
(code "compute-all-deps") " batch-computes and caches deps for every component. "
|
||||
"Circular references terminate safely via a seen-set."))
|
||||
|
||||
(div
|
||||
(h4 :class "font-semibold text-stone-700" "2. Runtime component scanning")
|
||||
(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."))
|
||||
(h4 :class "font-semibold text-stone-700" "2. Page scanning")
|
||||
(~doc-code :code (highlight "(define (components-needed page-source env)\n (let ((direct (scan-components-from-source page-source))\n (all-needed (set-create)))\n (for-each (fn (name) ...\n (set-add! all-needed name)\n (set-union! all-needed (component-deps comp)))\n direct)\n all-needed))" "lisp"))
|
||||
(p (code "scan-components-from-source") " finds " (code "(~name") " patterns in serialized SX via regex. " (code "components-needed") " combines scanning with the cached transitive closure to produce the minimal component set for a page."))
|
||||
|
||||
(div
|
||||
(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."))
|
||||
(h4 :class "font-semibold text-stone-700" "3. Per-page CSS scoping")
|
||||
(p (code "page-css-classes") " unions the CSS classes from only the components in the page bundle. Pages that don't use a component never pay for its styles."))
|
||||
|
||||
(div
|
||||
(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")))))
|
||||
(p "The spec declares 6 functions each host implements natively — the only host-specific code:")
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1"
|
||||
(li (code "component-deps") " / " (code "component-set-deps!") " — read/write the cached deps set on a component object")
|
||||
(li (code "component-css-classes") " — read pre-scanned CSS class names from a component")
|
||||
(li (code "env-components") " — enumerate all component entries in an environment")
|
||||
(li (code "regex-find-all") " / " (code "scan-css-classes") " — host-native regex and CSS scanning")))))
|
||||
|
||||
(~doc-subsection :title "Files"
|
||||
(~doc-subsection :title "Spec module"
|
||||
(p "deps.sx is loaded as a " (strong "spec module") " — an optional extension to the core spec. The bootstrapper flag " (code "--spec-modules deps") " includes it in the generated output alongside the core evaluator, parser, and renderer. The same mechanism can carry future modules (e.g., io-detection for Phase 2) without changing the bootstrapper architecture.")
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1 font-mono text-sm"
|
||||
(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")))
|
||||
(li "shared/sx/ref/deps.sx — canonical spec (9 functions, 6 platform declarations)")
|
||||
(li "Bootstrapped to all host targets via --spec-modules deps")))
|
||||
|
||||
(~doc-subsection :title "Verification"
|
||||
(ul :class "list-disc pl-5 text-stone-700 space-y-1"
|
||||
(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"))))
|
||||
(li "15 dedicated tests: scan, transitive closure, circular deps, compute-all, components-needed")
|
||||
(li "Bootstrapped output verified on both host targets")
|
||||
(li "Full test suite passes with zero regressions")
|
||||
(li (a :href "/plans/bundle-analyzer" :class "text-violet-700 underline" "Live bundle analyzer") " shows real per-page savings on this app"))))
|
||||
|
||||
;; -----------------------------------------------------------------------
|
||||
;; Phase 2
|
||||
|
||||
Reference in New Issue
Block a user