Two bugs fixed:
1. Links: bytecode compiler doesn't handle &rest params — treats them as
positional, so (first rest) gets a raw string instead of a list.
Replaced &rest with explicit optional params in all bytecode-compiled
web SX files (dom-query, dom-add-listener, browser-push-state, etc.).
The VM already pads missing args with Nil.
2. Reactive counter: signal-remove-sub! used (filter ...) which returns
immutable List, but signal-add-sub! uses (append!) which only mutates
ListRef. Subscribers silently vanished after first effect re-run.
Fixed by adding remove! primitive that mutates ListRef in-place.
Also:
- Added evalVM API to WASM kernel (compile + run through bytecode VM)
- Added scope tracing (scope-push!/pop!/peek/context instrumentation)
- Added Playwright reactive mode for debugging island signal/DOM state
- Replaced cek-call with direct calls in core-signals.sx effect/computed
- Recompiled all 23 bytecode modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixed three fundamental issues:
1. cek-try arg passing: handler was called with raw string instead of
(List [String msg]), causing "lambda expects 1 args, got N" errors
2. Silent island hydration failures: hydrate-island now wraps body
render in cek-try, displaying red error box with stack trace instead
of empty div. No more silent failures.
3. swap! thunk leak: apply result wasn't trampolined, storing thunks
as signal values instead of evaluated results
Also fixed: assert= uses = instead of equal? for value comparison,
assert-signal-value uses deref instead of signal-value, HTML entity
decoding in script tag test source via host-call replaceAll.
Temperature converter demo page now shows live test results:
✓ initial celsius is 20
✓ computed fahrenheit = celsius * 1.8 + 32
✓ +5 increments celsius
✓ fahrenheit updates on celsius change
✓ multiple clicks accumulate
1116/1116 OCaml tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
web/harness-reactive.sx — signal testing (no DOM dependency):
assert-signal-value, assert-signal-has-subscribers,
assert-signal-subscriber-count, assert-computed-dep-count,
assert-computed-depends-on, simulate-signal-set!/swap!,
make-test-signal (signal + history tracking), assert-batch-coalesces
web/harness-web.sx — web platform testing (mock DOM, no browser):
mock-element, mock-set-text!, mock-append-child!, mock-set-attr!,
mock-add-listener!, simulate-click, simulate-input, simulate-event,
assert-text, assert-attr, assert-class, assert-no-class,
assert-child-count, assert-event-fired, assert-no-event,
event-fire-count, make-web-harness
Both extend spec/harness.sx. The reactive harness uses spec/signals.sx
directly — works on any host. The web harness provides lightweight DOM
stubs that record operations for assertion, no real browser needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>