Fix island dep scanning + spread-through-reactive-if debug

deps.sx: scan island bodies for component deps (was only scanning
"component" and "macro", missing "island" type). This ensures
~cssx/tw and its dependencies are sent to the client for islands.

cssx.sx: move if inside make-spread arg so it's evaluated by
eval-expr (no reactive wrapping) instead of render-to-dom which
applies reactive-if inside island scope, converting the spread
into a fragment and losing the class attrs.

Added island dep tests at 3 levels: test-deps.sx (spec),
test_deps.py (Python), test_parity.py (ref vs fallback).

sx-browser.js: temporary debug logging at spread detection points.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 04:37:45 +00:00
parent 1d1e7f30bb
commit 2c97542ee8
7 changed files with 69 additions and 13 deletions

View File

@@ -73,7 +73,7 @@
(append! seen n)
(let ((val (env-get env n)))
(cond
(= (type-of val) "component")
(or (= (type-of val) "component") (= (type-of val) "island"))
(for-each (fn ((ref :as string)) (transitive-deps-walk ref seen env))
(scan-refs (component-body val)))
(= (type-of val) "macro")
@@ -105,7 +105,7 @@
(for-each
(fn ((name :as string))
(let ((val (env-get env name)))
(when (= (type-of val) "component")
(when (or (= (type-of val) "component") (= (type-of val) "island"))
(component-set-deps! val (transitive-deps name env)))))
(env-components env))))

View File

@@ -2757,7 +2757,7 @@ def transitive_deps_walk(n, seen, env):
if sx_truthy((not sx_truthy(contains_p(seen, n)))):
seen.append(n)
val = env_get(env, n)
if sx_truthy((type_of(val) == 'component')):
if sx_truthy(((type_of(val) == 'component') if sx_truthy((type_of(val) == 'component')) else (type_of(val) == 'island'))):
for ref in scan_refs(component_body(val)):
transitive_deps_walk(ref, seen, env)
return NIL
@@ -2780,7 +2780,7 @@ def transitive_deps(name, env):
def compute_all_deps(env):
for name in env_components(env):
val = env_get(env, name)
if sx_truthy((type_of(val) == 'component')):
if sx_truthy(((type_of(val) == 'component') if sx_truthy((type_of(val) == 'component')) else (type_of(val) == 'island'))):
component_set_deps(val, transitive_deps(name, env))
return NIL

View File

@@ -36,6 +36,13 @@
(defcomp ~dep-island ()
(div "no deps"))
;; Islands with dependencies — defisland bodies must be scanned
(defisland ~dep-island-with-child ()
(div (~dep-leaf) "island content"))
(defisland ~dep-island-with-chain ()
(div (~dep-branch) "deep island"))
;; --------------------------------------------------------------------------
;; 1. scan-refs — finds component references in AST nodes
@@ -145,6 +152,15 @@
(deftest "accepts name without tilde"
(let ((deps (transitive-deps "dep-branch" (test-env))))
(assert-contains "~dep-leaf" deps)))
(deftest "island direct dep scanned"
(let ((deps (transitive-deps "~dep-island-with-child" (test-env))))
(assert-contains "~dep-leaf" deps)))
(deftest "island transitive deps scanned"
(let ((deps (transitive-deps "~dep-island-with-chain" (test-env))))
(assert-contains "~dep-branch" deps)
(assert-contains "~dep-leaf" deps))))
@@ -173,7 +189,13 @@
(deftest "handles multiple top-level components"
(let ((needed (components-needed "(div (~dep-leaf) (~dep-island))" (test-env))))
(assert-contains "~dep-leaf" needed)
(assert-contains "~dep-island" needed))))
(assert-contains "~dep-island" needed)))
(deftest "island deps included in page bundle"
(let ((needed (components-needed "(~dep-island-with-chain)" (test-env))))
(assert-contains "~dep-island-with-chain" needed)
(assert-contains "~dep-branch" needed)
(assert-contains "~dep-leaf" needed))))
;; --------------------------------------------------------------------------