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>
This commit is contained in:
2026-03-08 16:35:19 +00:00
parent 6bda2bafa2
commit a496ee6ae6
6 changed files with 228 additions and 149 deletions

View File

@@ -408,3 +408,33 @@
(reset! target-signal new-val))))))
;; Return cleanup — removes listener on dispose/re-run
remove)))))
;; ==========================================================================
;; 15. Resource — async signal with loading/resolved/error states
;; ==========================================================================
;;
;; A resource wraps an async operation (fetch, computation) and exposes
;; its state as a signal. The signal transitions through:
;; {:loading true :data nil :error nil} — initial/loading
;; {:loading false :data result :error nil} — success
;; {:loading false :data nil :error err} — failure
;;
;; Usage:
;; (let ((user (resource (fn () (fetch-json "/api/user")))))
;; (cond
;; (get (deref user) "loading") (div "Loading...")
;; (get (deref user) "error") (div "Error: " (get (deref user) "error"))
;; :else (div (get (deref user) "data"))))
;;
;; Platform interface required:
;; (promise-then promise on-resolve on-reject) → void
(define resource
(fn (fetch-fn)
(let ((state (signal (dict "loading" true "data" nil "error" nil))))
;; Kick off the async operation
(promise-then (invoke fetch-fn)
(fn (data) (reset! state (dict "loading" false "data" data "error" nil)))
(fn (err) (reset! state (dict "loading" false "data" nil "error" err))))
state)))