Commit Graph

9 Commits

Author SHA1 Message Date
7efd1b401b Add suspense, resource, and transitions — Phase 2 complete
- suspense render-dom form: shows fallback while resource loads, swaps
  to body content when resource signal resolves
- resource async signal: wraps promise into signal with loading/data/error
  dict, auto-transitions on resolve/reject via promise-then
- transition: defers signal writes to requestIdleCallback, sets pending
  signal for UI feedback during expensive operations
- Added schedule-idle, promise-then platform functions
- All Phase 2 features now marked Done in status tables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:40:13 +00:00
a496ee6ae6 Remove reactive class/style (CSSX covers it), add error boundaries + resource
Reactive class/style (:class-map, :style-map) removed — CSSX components
already handle dynamic class/style via defcomp with full SX logic.

Added:
- error-boundary render-dom form: try/catch around children, renders
  fallback fn with (err retry) on failure, disposes partial effects
- resource async signal: wraps promise into signal with loading/data/error
  states, transitions automatically on resolve/reject
- try-catch, error-message, promise-then platform functions
- Updated Phase 2 status tables and demo page numbering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:35:19 +00:00
6bda2bafa2 Add Phase 2 P1 features: reactive class/style, refs, portals
- :class-map dict toggles classes reactively via classList.add/remove
- :style-map dict sets inline styles reactively via el.style[prop]
- ref/ref-get/ref-set! mutable boxes (non-reactive, like useRef)
- :ref attribute sets ref.current to DOM element after rendering
- portal render-dom form renders children into remote target element
- Portal content auto-removed on island disposal via register-in-scope
- Added #portal-root div to page shell template
- Added stop-propagation and dom-focus platform functions
- Demo islands for all three features on the demo page
- Updated status tables: all P0/P1 features marked Done

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:27:55 +00:00
8683cf24c3 Island disposal, reactive lists, input binding, and Phase 2 plan
- Effect and computed auto-register disposers with island scope via
  register-in-scope; dispose-islands-in called before every swap point
  (orchestration.sx) to clean up intervals/subscriptions on navigation.
- Map + deref inside islands auto-upgrades to reactive-list for signal-
  bound list rendering. Demo island with add/remove items.
- New :bind attribute for two-way signal-input binding (text, checkbox,
  radio, textarea, select). bind-input in adapter-dom.sx handles both
  signal→element (effect) and element→signal (event listener).
- Phase 2 plan page at /reactive-islands/phase2 covering input binding,
  keyed reconciliation, reactive class/style, refs, portals, error
  boundaries, suspense, and transitions.
- Updated status tables in overview and plan pages.
- Fixed stopwatch reset (fn body needs do wrapper for multiple exprs).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:10:52 +00:00
189a0258d9 Fix reactive islands client-side navigation and hydration
Three bugs prevented islands from working during SX wire navigation:

1. components_for_request() only bundled Component and Macro defs, not
   Island defs — client never received defisland definitions during
   navigation (components_for_page for initial HTML shell was correct).

2. hydrate-island used morph-children which can't transfer addEventListener
   event handlers from freshly rendered DOM to existing nodes. Changed to
   clear+append so reactive DOM with live signal subscriptions is inserted
   directly.

3. asyncRenderToDom (client-side async page eval) checked _component but
   not _island on ~-prefixed names — islands fell through to generic eval
   which failed. Now delegates to renderDomIsland.

4. setInterval_/setTimeout_ passed SX Lambda objects directly to native
   timers. JS coerced them to "[object Object]" and tried to eval as code,
   causing "missing ] after element list". Added _wrapSxFn to convert SX
   lambdas to JS functions before passing to timers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:18:45 +00:00
c55f0956bc Bootstrap stores + event bridge, add island hydration to boot.sx
- signals.sx: fix has? → has-key?, add def-store/use-store/clear-stores
  (L3 named stores), emit-event/on-event/bridge-event (event bridge)
- boot.sx: add sx-hydrate-islands, hydrate-island, dispose-island
  for client-side island hydration from SSR output
- bootstrap_js.py: add RENAMES, platform fns (domListen, eventDetail,
  domGetData, jsonParse), public API exports for all new functions
- bootstrap_py.py: add RENAMES, server-side no-op stubs for DOM events
- Regenerate sx-ref.js (with boot adapter) and sx_ref.py
- Update reactive-islands status: hydration, stores, bridge all spec'd

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:13:18 +00:00
5b70cd5cfc Spec event bridge and named stores, move plan to reactive islands section
- signals.sx: add def-store/use-store/clear-stores (L3 named stores)
  and emit-event/on-event/bridge-event (lake→island DOM events)
- reactive-islands.sx: add event bridge, named stores, and plan pages
- Remove ~plan-reactive-islands-content from plans.sx
- Update nav-data.sx and docs.sx routing accordingly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:59:58 +00:00
26320abd64 Add signal test suite (17/17) and Island type to evaluator
test-signals.sx: 17 tests covering signal basics (create, deref, reset!,
swap!), computed (derive, update, chain), effects (run, re-run, dispose,
cleanup), batch (deferred deduped notifications), and defisland (create,
call, children).

types.py: Island dataclass mirroring Component but for reactive boundaries.
evaluator.py: sf_defisland special form, Island in call dispatch.
run.py: Signal platform primitives (make-signal, tracking context, etc)
  and native effect/computed/batch implementations that bridge Lambda
  calls across the Python↔SX boundary.
signals.sx: Updated batch to deduplicate subscribers across signals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 09:44:18 +00:00
a97f4c0e39 Add reactive islands spec: signals.sx + defisland across all adapters
New spec file signals.sx defines the signal runtime: signal, computed,
effect, deref, reset!, swap!, batch, dispose, and island scope tracking.

eval.sx: defisland special form + island? type predicate in eval-call.
boundary.sx: signal primitive declarations (Tier 3).
render.sx: defisland in definition-form?.
adapter-dom.sx: render-dom-island with reactive context, reactive-text,
  reactive-attr, reactive-fragment, reactive-list helpers.
adapter-html.sx: render-html-island for SSR with data-sx-island/state.
adapter-sx.sx: island? handling in wire format serialization.
special-forms.sx: defisland declaration with docs and example.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 09:34:47 +00:00