Add failing test: reactive-spread from module-loaded define
reactive-spread (module-loaded via K.load) doesn't apply CSSX classes to DOM elements. Returns null instead of "sx-text-center". This is the root cause of hydration stripping all styling — every rendering function is define-bound from module load. 12 pass, 1 fail — the reactive-spread test is the blocker. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -192,7 +192,7 @@ async function main() {
|
||||
// This is the root cause of the hydration rendering bug.
|
||||
// A function defined with `define` that takes a host object (DOM element)
|
||||
// and uses `effect` to modify it — the effect body doesn't see the element.
|
||||
assert('define+effect+host-obj',
|
||||
assert('define+effect+host-obj (same eval)',
|
||||
K.eval('(do (define test-set-attr (fn (el name val) (effect (fn () (dom-set-attr el name val))))) (let ((el (dom-create-element "div" nil))) (test-set-attr el "class" "from-define") (dom-get-attr el "class")))'),
|
||||
'from-define');
|
||||
|
||||
@@ -201,6 +201,27 @@ async function main() {
|
||||
K.eval('(let ((test-set-attr (fn (el name val) (effect (fn () (dom-set-attr el name val)))))) (let ((el (dom-create-element "div" nil))) (test-set-attr el "class" "from-let") (dom-get-attr el "class")))'),
|
||||
'from-let');
|
||||
|
||||
// CRITICAL: define in separate eval (matches real module-load pattern).
|
||||
// This is how reactive-spread/reactive-attr work: defined at module load,
|
||||
// called later during hydration. The effect closure must capture host objects.
|
||||
K.eval('(define test-set-attr-sep (fn (el name val) (effect (fn () (dom-set-attr el name val)))))');
|
||||
assert('define+effect+host-obj (separate eval)',
|
||||
K.eval('(let ((el (dom-create-element "div" nil))) (test-set-attr-sep el "class" "from-sep-define") (dom-get-attr el "class"))'),
|
||||
'from-sep-define');
|
||||
|
||||
// Module-loaded define (via K.load, same as real module loading).
|
||||
// reactive-spread is loaded this way — test that effect fires.
|
||||
K.load('(define test-set-attr-mod (fn (el name val) (effect (fn () (dom-set-attr el name val)))))');
|
||||
assert('define+effect+host-obj (module-loaded)',
|
||||
K.eval('(let ((el (dom-create-element "div" nil))) (test-set-attr-mod el "class" "from-mod") (dom-get-attr el "class"))'),
|
||||
'from-mod');
|
||||
|
||||
// The actual reactive-spread pattern: module-loaded function creates effect
|
||||
// that calls cek-call on a render-fn returning a spread, then applies attrs.
|
||||
assert('reactive-spread from module',
|
||||
K.eval('(let ((el (dom-create-element "div" nil)) (d (list))) (with-island-scope (fn (x) (append! d x)) (fn () (reactive-spread el (fn () (~cssx/tw :tokens "text-center"))))) (host-get el "className"))'),
|
||||
'sx-text-center');
|
||||
|
||||
// Reactive: signal update propagation
|
||||
// Note: render-to-dom needs the UNEVALUATED expression (as in real browser boot
|
||||
// where expressions come from parsing). Use quote to prevent eager eval of (deref s).
|
||||
|
||||
Reference in New Issue
Block a user