Collapse reactive islands into scopes: replace TrackingContext and *island-scope* with scope-push!/scope-pop!/context
Reactive tracking (deref/computed/effect dep discovery) and island lifecycle now use the general scoped effects system instead of parallel infrastructure. Two scope names: "sx-reactive" for tracking context, "sx-island-scope" for island disposable collection. Eliminates ~98 net lines: _TrackingContext class, 7 tracking context platform functions (Python + JS), *island-scope* global, and corresponding RENAME_MAP entries. All 20 signal tests pass (17 original + 3 new scope integration tests), plus CEK/continuation/type tests clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -171,3 +171,46 @@
|
||||
(list "wrap" children))
|
||||
(assert-equal (list "wrap" (list "a" "b"))
|
||||
(~wrapper "a" "b"))))
|
||||
|
||||
|
||||
;; --------------------------------------------------------------------------
|
||||
;; Scope integration — reactive tracking uses scope-push!/scope-pop!
|
||||
;; --------------------------------------------------------------------------
|
||||
|
||||
(defsuite "scope integration"
|
||||
(deftest "deref outside reactive scope does not subscribe"
|
||||
(let ((s (signal 42)))
|
||||
;; Reading outside any reactive context should not add subscribers
|
||||
(assert-equal 42 (deref s))
|
||||
(assert-equal 0 (len (signal-subscribers s)))))
|
||||
|
||||
(deftest "computed uses scope for tracking"
|
||||
(let ((a (signal 1))
|
||||
(b (signal 2))
|
||||
(sum (computed (fn () (+ (deref a) (deref b))))))
|
||||
;; Each signal should have exactly 1 subscriber (the computed's recompute)
|
||||
(assert-equal 1 (len (signal-subscribers a)))
|
||||
(assert-equal 1 (len (signal-subscribers b)))
|
||||
;; Verify computed value
|
||||
(assert-equal 3 (deref sum))))
|
||||
|
||||
(deftest "nested effects with overlapping deps use scope correctly"
|
||||
(let ((shared (signal 0))
|
||||
(inner-only (signal 0))
|
||||
(outer-count (signal 0))
|
||||
(inner-count (signal 0)))
|
||||
;; Outer effect tracks shared
|
||||
(effect (fn () (do (deref shared) (swap! outer-count inc))))
|
||||
;; Inner effect tracks shared AND inner-only
|
||||
(effect (fn () (do (deref shared) (deref inner-only) (swap! inner-count inc))))
|
||||
;; Both ran once
|
||||
(assert-equal 1 (deref outer-count))
|
||||
(assert-equal 1 (deref inner-count))
|
||||
;; Changing shared triggers both
|
||||
(reset! shared 1)
|
||||
(assert-equal 2 (deref outer-count))
|
||||
(assert-equal 2 (deref inner-count))
|
||||
;; Changing inner-only triggers only inner
|
||||
(reset! inner-only 1)
|
||||
(assert-equal 2 (deref outer-count))
|
||||
(assert-equal 3 (deref inner-count)))))
|
||||
|
||||
Reference in New Issue
Block a user