@fluixi/reactive 1.0.0-alpha.82 → 1.0.0-alpha.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +4 -0
  2. package/dist/cdn/reactive.cjs +2673 -1
  3. package/dist/cdn/reactive.global.js +2 -1
  4. package/dist/cdn/reactive.mjs +2657 -1
  5. package/dist/cdn/signal.cjs +299 -1
  6. package/dist/cdn/signal.d.ts +1 -1
  7. package/dist/cdn/signal.global.js +2 -1
  8. package/dist/cdn/signal.js +1 -1
  9. package/dist/cdn/signal.mjs +276 -1
  10. package/dist/index.cjs +2673 -1
  11. package/dist/index.mjs +2657 -1
  12. package/dist/lib/index.cjs +2674 -1
  13. package/dist/lib/index.js +1 -1
  14. package/dist/lib/index.mjs +2659 -1
  15. package/dist/lib/observable/index.cjs +386 -1
  16. package/dist/lib/observable/index.mjs +364 -1
  17. package/dist/lib/observable/observable.cjs +384 -1
  18. package/dist/lib/observable/observable.d.ts +0 -137
  19. package/dist/lib/observable/observable.d.ts.map +1 -1
  20. package/dist/lib/observable/observable.js +0 -71
  21. package/dist/lib/observable/observable.mjs +361 -1
  22. package/dist/lib/observable/subscription.cjs +180 -1
  23. package/dist/lib/observable/subscription.d.ts +0 -12
  24. package/dist/lib/observable/subscription.d.ts.map +1 -1
  25. package/dist/lib/observable/subscription.js +0 -12
  26. package/dist/lib/observable/subscription.mjs +157 -1
  27. package/dist/lib/observable/types.cjs +18 -1
  28. package/dist/lib/observable/types.d.ts.map +1 -1
  29. package/dist/lib/predicates.cjs +44 -1
  30. package/dist/lib/predicates.d.ts +2 -2
  31. package/dist/lib/predicates.js +2 -2
  32. package/dist/lib/predicates.mjs +23 -1
  33. package/dist/lib/signal/api.cjs +571 -1
  34. package/dist/lib/signal/api.d.ts +211 -1
  35. package/dist/lib/signal/api.d.ts.map +1 -1
  36. package/dist/lib/signal/api.js +207 -12
  37. package/dist/lib/signal/api.mjs +548 -1
  38. package/dist/lib/signal/cached-resource.cjs +672 -1
  39. package/dist/lib/signal/cached-resource.d.ts +28 -16
  40. package/dist/lib/signal/cached-resource.d.ts.map +1 -1
  41. package/dist/lib/signal/cached-resource.js +35 -29
  42. package/dist/lib/signal/cached-resource.mjs +650 -1
  43. package/dist/lib/signal/graph/children.cjs +325 -1
  44. package/dist/lib/signal/graph/children.js +1 -1
  45. package/dist/lib/signal/graph/children.mjs +302 -1
  46. package/dist/lib/signal/graph/compat.cjs +578 -1
  47. package/dist/lib/signal/graph/compat.d.ts +13 -13
  48. package/dist/lib/signal/graph/compat.d.ts.map +1 -1
  49. package/dist/lib/signal/graph/compat.js +51 -32
  50. package/dist/lib/signal/graph/compat.mjs +556 -1
  51. package/dist/lib/signal/graph/core.cjs +295 -1
  52. package/dist/lib/signal/graph/core.d.ts +28 -24
  53. package/dist/lib/signal/graph/core.d.ts.map +1 -1
  54. package/dist/lib/signal/graph/core.js +45 -31
  55. package/dist/lib/signal/graph/core.mjs +273 -1
  56. package/dist/lib/signal/graph/debounced.cjs +668 -1
  57. package/dist/lib/signal/graph/debounced.d.ts +5 -5
  58. package/dist/lib/signal/graph/debounced.d.ts.map +1 -1
  59. package/dist/lib/signal/graph/debounced.js +5 -5
  60. package/dist/lib/signal/graph/debounced.mjs +645 -1
  61. package/dist/lib/signal/graph/derived.cjs +496 -1
  62. package/dist/lib/signal/graph/derived.d.ts +1 -1
  63. package/dist/lib/signal/graph/derived.js +1 -1
  64. package/dist/lib/signal/graph/derived.mjs +473 -1
  65. package/dist/lib/signal/graph/detect.cjs +66 -1
  66. package/dist/lib/signal/graph/detect.mjs +45 -1
  67. package/dist/lib/signal/graph/error-boundary.cjs +301 -1
  68. package/dist/lib/signal/graph/error-boundary.js +3 -3
  69. package/dist/lib/signal/graph/error-boundary.mjs +278 -1
  70. package/dist/lib/signal/graph/index.cjs +305 -1
  71. package/dist/lib/signal/graph/index.d.ts +7 -6
  72. package/dist/lib/signal/graph/index.d.ts.map +1 -1
  73. package/dist/lib/signal/graph/index.js +7 -6
  74. package/dist/lib/signal/graph/index.mjs +283 -1
  75. package/dist/lib/signal/graph/observe.cjs +163 -0
  76. package/dist/lib/signal/graph/observe.d.ts +141 -0
  77. package/dist/lib/signal/graph/observe.d.ts.map +1 -0
  78. package/dist/lib/signal/graph/observe.js +149 -0
  79. package/dist/lib/signal/graph/observe.mjs +140 -0
  80. package/dist/lib/signal/graph/resource.cjs +620 -1
  81. package/dist/lib/signal/graph/resource.d.ts +1 -1
  82. package/dist/lib/signal/graph/resource.js +7 -8
  83. package/dist/lib/signal/graph/resource.mjs +597 -1
  84. package/dist/lib/signal/graph/runtime.cjs +501 -1
  85. package/dist/lib/signal/graph/runtime.d.ts +9 -9
  86. package/dist/lib/signal/graph/runtime.d.ts.map +1 -1
  87. package/dist/lib/signal/graph/runtime.js +56 -37
  88. package/dist/lib/signal/graph/runtime.mjs +478 -1
  89. package/dist/lib/signal/graph/signal-next.cjs +1208 -1
  90. package/dist/lib/signal/graph/signal-next.d.ts +5 -5
  91. package/dist/lib/signal/graph/signal-next.d.ts.map +1 -1
  92. package/dist/lib/signal/graph/signal-next.js +14 -12
  93. package/dist/lib/signal/graph/signal-next.mjs +1186 -1
  94. package/dist/lib/signal/graph/ssr-hooks.cjs +60 -1
  95. package/dist/lib/signal/graph/ssr-hooks.d.ts +6 -7
  96. package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -1
  97. package/dist/lib/signal/graph/ssr-hooks.js +6 -7
  98. package/dist/lib/signal/graph/ssr-hooks.mjs +39 -1
  99. package/dist/lib/signal/graph/state.cjs +72 -1
  100. package/dist/lib/signal/graph/state.d.ts +43 -10
  101. package/dist/lib/signal/graph/state.d.ts.map +1 -1
  102. package/dist/lib/signal/graph/state.js +83 -21
  103. package/dist/lib/signal/graph/state.mjs +49 -1
  104. package/dist/lib/signal/graph/suspense.cjs +301 -1
  105. package/dist/lib/signal/graph/suspense.js +4 -4
  106. package/dist/lib/signal/graph/suspense.mjs +278 -1
  107. package/dist/lib/signal/index-legacy.cjs +2540 -1
  108. package/dist/lib/signal/index-legacy.d.ts +1 -1
  109. package/dist/lib/signal/index-legacy.js +1 -1
  110. package/dist/lib/signal/index-legacy.mjs +2518 -1
  111. package/dist/lib/signal/index.cjs +1275 -1
  112. package/dist/lib/signal/index.d.ts +5 -2
  113. package/dist/lib/signal/index.d.ts.map +1 -1
  114. package/dist/lib/signal/index.js +8 -3
  115. package/dist/lib/signal/index.mjs +1253 -1
  116. package/dist/lib/signal/list.cjs +549 -1
  117. package/dist/lib/signal/list.d.ts +5 -5
  118. package/dist/lib/signal/list.js +10 -10
  119. package/dist/lib/signal/list.mjs +526 -1
  120. package/dist/lib/signal/resource-api.cjs +626 -1
  121. package/dist/lib/signal/resource-api.d.ts +5 -5
  122. package/dist/lib/signal/resource-api.js +5 -5
  123. package/dist/lib/signal/resource-api.mjs +603 -1
  124. package/dist/lib/signal/signal.cjs +2023 -1
  125. package/dist/lib/signal/signal.d.ts +4 -4
  126. package/dist/lib/signal/signal.d.ts.map +1 -1
  127. package/dist/lib/signal/signal.js +22 -23
  128. package/dist/lib/signal/signal.mjs +2000 -1
  129. package/dist/lib/signal/types.cjs +38 -1
  130. package/dist/lib/signal/types.d.ts.map +1 -1
  131. package/dist/lib/signal/types.js +2 -2
  132. package/dist/lib/signal/types.mjs +17 -1
  133. package/dist/lib/signal/utilities.cjs +1012 -1
  134. package/dist/lib/signal/utilities.d.ts +0 -108
  135. package/dist/lib/signal/utilities.d.ts.map +1 -1
  136. package/dist/lib/signal/utilities.js +0 -158
  137. package/dist/lib/signal/utilities.mjs +990 -1
  138. package/dist/lib/store/api.cjs +612 -1
  139. package/dist/lib/store/api.d.ts +33 -0
  140. package/dist/lib/store/api.d.ts.map +1 -1
  141. package/dist/lib/store/api.js +41 -8
  142. package/dist/lib/store/api.mjs +596 -1
  143. package/dist/lib/store/index.cjs +691 -1
  144. package/dist/lib/store/index.js +1 -1
  145. package/dist/lib/store/index.mjs +676 -1
  146. package/dist/lib/store/setter.types.cjs +18 -1
  147. package/dist/lib/store/setter.types.d.ts +43 -3
  148. package/dist/lib/store/setter.types.d.ts.map +1 -1
  149. package/dist/lib/store/store.cjs +658 -1
  150. package/dist/lib/store/store.d.ts +72 -0
  151. package/dist/lib/store/store.d.ts.map +1 -1
  152. package/dist/lib/store/store.js +294 -11
  153. package/dist/lib/store/store.mjs +644 -1
  154. package/dist/lib/store/types.cjs +18 -1
  155. package/dist/lib/store/types.d.ts +1 -1
  156. package/dist/lib/store/types.d.ts.map +1 -1
  157. package/dist/lib/store/utils.cjs +43 -1
  158. package/dist/lib/store/utils.d.ts +1 -1
  159. package/dist/lib/store/utils.js +1 -1
  160. package/dist/lib/store/utils.mjs +22 -1
  161. package/dist/lib/subject.cjs +450 -1
  162. package/dist/lib/subject.js +3 -91
  163. package/dist/lib/subject.mjs +427 -1
  164. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  165. package/dist/version.generated.cjs +27 -1
  166. package/dist/version.generated.d.ts +1 -1
  167. package/dist/version.generated.js +2 -2
  168. package/dist/version.generated.mjs +7 -1
  169. package/package.json +5 -4
@@ -1 +1,295 @@
1
- "use strict";var l=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var S=(s,e)=>{for(var t in e)l(s,t,{get:e[t],enumerable:!0})},m=(s,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of T(e))!k.call(s,i)&&i!==t&&l(s,i,{get:()=>e[i],enumerable:!(o=b(e,i))||o.enumerable});return s};var g=s=>m(l({},"__esModule",{value:!0}),s);var D={};S(D,{Computed:()=>f,State:()=>d,Watcher:()=>p,currentComputed:()=>N,hasSinks:()=>E,untrack:()=>C});module.exports=g(D);var q="__fluixi_signal_next_state__",x=s=>{typeof queueMicrotask=="function"?queueMicrotask(s):Promise.resolve().then(s)},r=globalThis[q]??={consumer:null,untracked:!1,owner:null,queue:[],scheduled:!1,flushing:!1,batchDepth:0,hostSchedule:x,onSuspend:null,onError:null};var _=0,w=1,a=2,h=class{constructor(){this.observers=null;this.watchers=null;this.version=0}updateIfNecessary(){}track(){if(r.untracked)return;let e=r.consumer;e&&((this.observers??=new Set).add(e),(e.sources??=new Set).add(this))}},d=class extends h{constructor(e,t){super(),this._value=e,this._equals=t?.equals===!1?()=>!1:t?.equals??Object.is}get(){return this.track(),this._value}set(e){if(!this._equals(this._value,e)){if(this._value=e,this.version++,this.observers)for(let t of[...this.observers])t.markDirty(a);v(this)}}peek(){return this._value}},f=class extends h{constructor(t,o){super();this._threw=!1;this._initialized=!1;this.state=a;this.sources=null;this._fn=t,this._equals=o?.equals===!1?()=>!1:o?.equals??Object.is}get(){if(r.consumer===this)throw new Error("Signal.Computed cannot read itself");if(this.track(),this.updateIfNecessary(),this._threw)throw this._error;return this._value}updateIfNecessary(){if(this.state===w&&this.sources){for(let t of this.sources)if(t.updateIfNecessary(),this.state===a)break}(this.state===a||!this._initialized)&&this.recompute(),this.state=_}recompute(){if(this.sources){for(let n of this.sources)n.observers?.delete(this);this.sources.clear()}let t=r.consumer,o=r.untracked;r.consumer=this,r.untracked=!1;let i,u=!1,c;try{i=this._fn()}catch(n){u=!0,c=n,i=this._value}finally{r.consumer=t,r.untracked=o}let y=!this._initialized||this._threw!==u||(u?c!==this._error:!this._equals(this._value,i));if(this._initialized=!0,this._threw=u,this._error=c,this._value=i,y){if(this.version++,this.observers)for(let n of[...this.observers])n.markDirty(a);v(this)}}markDirty(t){if(this.state>=t)return;let o=this.state===_;if(this.state=t,o){if(this.observers)for(let i of[...this.observers])i.markDirty(w);v(this)}}peek(){if(this.updateIfNecessary(),this._threw)throw this._error;return this._value}};function v(s){if(s.watchers)for(let e of[...s.watchers])e._notify(s)}var p=class{constructor(e){this._watched=new Set;this._pending=new Set;this._notifyFn=e}watch(...e){for(let t of e)this._watched.add(t),(t.watchers??=new Set).add(this)}unwatch(...e){for(let t of e)this._watched.delete(t),t.watchers?.delete(this),this._pending.delete(t)}getPending(){let e=[...this._pending];return this._pending.clear(),e}_notify(e){if(!this._watched.has(e)||this._pending.has(e))return;let t=this._pending.size===0;this._pending.add(e),t&&this._notifyFn()}};function C(s){if(r.untracked)return s();r.untracked=!0;try{return s()}finally{r.untracked=!1}}function N(){return r.consumer}function E(s){return!!(s.observers&&s.observers.size)||!!(s.watchers&&s.watchers.size)}
1
+ /*! @fluixi/reactive v1.0.0-alpha.84 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/lib/signal/graph/core.ts
22
+ var core_exports = {};
23
+ __export(core_exports, {
24
+ Computed: () => Computed,
25
+ State: () => State,
26
+ Watcher: () => Watcher,
27
+ currentComputed: () => currentComputed,
28
+ hasSinks: () => hasSinks,
29
+ untrack: () => untrack
30
+ });
31
+ module.exports = __toCommonJS(core_exports);
32
+
33
+ // src/version.generated.ts
34
+ var VERSION = "1.0.0-alpha.84";
35
+
36
+ // src/lib/signal/graph/state.ts
37
+ var MAJOR = VERSION.split(".")[0];
38
+ var KEY = `__fluixi_signal_state_v${MAJOR}__`;
39
+ var VERSIONS_KEY = `__fluixi_signal_builds_v${MAJOR}__`;
40
+ var defaultSchedule = (run) => {
41
+ if (typeof queueMicrotask === "function") queueMicrotask(run);
42
+ else void Promise.resolve().then(run);
43
+ };
44
+ function defaults() {
45
+ return {
46
+ consumer: null,
47
+ untracked: false,
48
+ owner: null,
49
+ queue: [],
50
+ scheduled: false,
51
+ flushing: false,
52
+ batchDepth: 0,
53
+ hostSchedule: defaultSchedule,
54
+ onSuspend: null,
55
+ onError: null,
56
+ observer: null
57
+ };
58
+ }
59
+ var realm = globalThis;
60
+ function backfillState(existing) {
61
+ const fresh = defaults();
62
+ const target = existing;
63
+ for (const field of Object.keys(fresh)) {
64
+ if (!(field in existing)) target[field] = fresh[field];
65
+ }
66
+ return existing;
67
+ }
68
+ function claim() {
69
+ const existing = realm[KEY];
70
+ return existing ? backfillState(existing) : realm[KEY] = defaults();
71
+ }
72
+ var G = claim();
73
+ (realm[VERSIONS_KEY] ??= []).push(VERSION);
74
+
75
+ // src/lib/signal/graph/observe.ts
76
+ function observeReactiveNodes(next) {
77
+ G.observer = next;
78
+ return () => {
79
+ if (G.observer === next) G.observer = null;
80
+ };
81
+ }
82
+ var running = [];
83
+ function enterReactiveRun(node) {
84
+ if (!G.observer) return false;
85
+ running.push(node);
86
+ return true;
87
+ }
88
+ function exitReactiveRun() {
89
+ running.pop();
90
+ }
91
+ function reportReactiveRun(node) {
92
+ G.observer?.ran?.(node);
93
+ }
94
+ function reportReactiveWrite(node, by) {
95
+ G.observer?.wrote?.(node, by);
96
+ }
97
+ var HOOK = "__FLUIXI_DEVTOOLS_HOOK__";
98
+ var hook = globalThis[HOOK];
99
+ if (typeof hook?.inject === "function") {
100
+ try {
101
+ hook.inject({ observeReactiveNodes, version: VERSION });
102
+ } catch {
103
+ }
104
+ }
105
+
106
+ // src/lib/signal/graph/core.ts
107
+ var CLEAN = 0;
108
+ var CHECK = 1;
109
+ var DIRTY = 2;
110
+ var Source = class {
111
+ constructor() {
112
+ /** Computeds, and watched leaves, that read this node. */
113
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
+ this.observers = null;
115
+ /** Watchers eagerly observing this node, which is how `runtime.ts` schedules effects. */
116
+ this.watchers = null;
117
+ /** Bumped whenever this node's value actually changes (equality-gated). */
118
+ this.version = 0;
119
+ }
120
+ /** Settle this node so a reader sees a current value/version. Overridden by Computed. */
121
+ updateIfNecessary() {
122
+ }
123
+ /** Link the current consumer (if any) as an observer of this node. */
124
+ track() {
125
+ if (G.untracked) return;
126
+ const consumer = G.consumer;
127
+ if (!consumer) return;
128
+ (this.observers ??= /* @__PURE__ */ new Set()).add(consumer);
129
+ (consumer.sources ??= /* @__PURE__ */ new Set()).add(this);
130
+ }
131
+ };
132
+ var State = class extends Source {
133
+ constructor(value, options) {
134
+ super();
135
+ this._value = value;
136
+ this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
137
+ }
138
+ get() {
139
+ this.track();
140
+ return this._value;
141
+ }
142
+ set(next) {
143
+ if (this._equals(this._value, next)) return;
144
+ this._value = next;
145
+ this.version++;
146
+ reportReactiveWrite(this, G.consumer);
147
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
148
+ notifyWatchers(this);
149
+ }
150
+ /** Read without subscribing (peek). */
151
+ peek() {
152
+ return this._value;
153
+ }
154
+ };
155
+ var Computed = class extends Source {
156
+ constructor(fn, options) {
157
+ super();
158
+ this._threw = false;
159
+ this._initialized = false;
160
+ this.state = DIRTY;
161
+ /** Nodes this computation read on its last run. Rebuilt on every run. */
162
+ this.sources = null;
163
+ this._fn = fn;
164
+ this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
165
+ }
166
+ get() {
167
+ if (G.consumer === this) {
168
+ throw new Error("Signal.Computed cannot read itself");
169
+ }
170
+ this.track();
171
+ this.updateIfNecessary();
172
+ if (this._threw) throw this._error;
173
+ return this._value;
174
+ }
175
+ /** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
176
+ updateIfNecessary() {
177
+ if (this.state === CHECK) {
178
+ if (this.sources) {
179
+ for (const s of this.sources) {
180
+ s.updateIfNecessary();
181
+ if (this.state === DIRTY) break;
182
+ }
183
+ }
184
+ }
185
+ if (this.state === DIRTY || !this._initialized) this.recompute();
186
+ this.state = CLEAN;
187
+ }
188
+ recompute() {
189
+ if (this.sources) {
190
+ for (const s of this.sources) s.observers?.delete(this);
191
+ this.sources.clear();
192
+ }
193
+ const prevConsumer = G.consumer;
194
+ const prevUntracked = G.untracked;
195
+ const watched = enterReactiveRun(this);
196
+ G.consumer = this;
197
+ G.untracked = false;
198
+ let next;
199
+ let threw = false;
200
+ let err;
201
+ try {
202
+ next = this._fn();
203
+ } catch (e) {
204
+ threw = true;
205
+ err = e;
206
+ next = this._value;
207
+ } finally {
208
+ G.consumer = prevConsumer;
209
+ G.untracked = prevUntracked;
210
+ if (watched) exitReactiveRun();
211
+ }
212
+ const changed = !this._initialized || this._threw !== threw || (threw ? err !== this._error : !this._equals(this._value, next));
213
+ this._initialized = true;
214
+ this._threw = threw;
215
+ this._error = err;
216
+ this._value = next;
217
+ reportReactiveRun(this);
218
+ if (changed) {
219
+ this.version++;
220
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
221
+ notifyWatchers(this);
222
+ }
223
+ }
224
+ /**
225
+ * Push a maybe-dirty mark. A direct observer of a changed node gets DIRTY; its
226
+ * own observers get CHECK (recurse), stopping where already marked, so the
227
+ * push is O(newly-dirtied) and never recomputes.
228
+ */
229
+ markDirty(level) {
230
+ if (this.state >= level) return;
231
+ const wasClean = this.state === CLEAN;
232
+ this.state = level;
233
+ if (wasClean) {
234
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(CHECK);
235
+ notifyWatchers(this);
236
+ }
237
+ }
238
+ peek() {
239
+ this.updateIfNecessary();
240
+ if (this._threw) throw this._error;
241
+ return this._value;
242
+ }
243
+ };
244
+ function notifyWatchers(node) {
245
+ if (!node.watchers) return;
246
+ for (const w of [...node.watchers]) w._notify(node);
247
+ }
248
+ var Watcher = class {
249
+ constructor(notify) {
250
+ this._watched = /* @__PURE__ */ new Set();
251
+ this._pending = /* @__PURE__ */ new Set();
252
+ this._notifyFn = notify;
253
+ }
254
+ watch(...nodes) {
255
+ for (const n of nodes) {
256
+ this._watched.add(n);
257
+ (n.watchers ??= /* @__PURE__ */ new Set()).add(this);
258
+ }
259
+ }
260
+ unwatch(...nodes) {
261
+ for (const n of nodes) {
262
+ this._watched.delete(n);
263
+ n.watchers?.delete(this);
264
+ this._pending.delete(n);
265
+ }
266
+ }
267
+ /** Watched nodes that may have changed since the last getPending(). */
268
+ getPending() {
269
+ const out = [...this._pending];
270
+ this._pending.clear();
271
+ return out;
272
+ }
273
+ /** @internal, a watched node became non-clean. Edge-triggered: notify once. */
274
+ _notify(node) {
275
+ if (!this._watched.has(node) || this._pending.has(node)) return;
276
+ const wasEmpty = this._pending.size === 0;
277
+ this._pending.add(node);
278
+ if (wasEmpty) this._notifyFn();
279
+ }
280
+ };
281
+ function untrack(fn) {
282
+ if (G.untracked) return fn();
283
+ G.untracked = true;
284
+ try {
285
+ return fn();
286
+ } finally {
287
+ G.untracked = false;
288
+ }
289
+ }
290
+ function currentComputed() {
291
+ return G.consumer;
292
+ }
293
+ function hasSinks(node) {
294
+ return !!(node.observers && node.observers.size) || !!(node.watchers && node.watchers.size);
295
+ }
@@ -1,19 +1,23 @@
1
1
  /**
2
- * L0 — the TC39-shaped reactive graph core.
2
+ * The TC39-shaped reactive graph core.
3
3
  *
4
- * Class-based primitives (`State`, `Computed`, `Watcher`) that own ONLY the
5
- * dependency graph: values, versions, source/observer edges, the lazy push-pull
6
- * state machine, and glitch-free pull evaluation. They know nothing about
7
- * ownership, scheduling, effects, suspense, or resources those live in the L1
8
- * runtime that sits on top (see ../signal.ts). This is a re-shaping of the exact
9
- * algorithm the existing graph already runs (CLEAN/CHECK/DIRTY + version + the
10
- * `Listener`/observers edges), so behaviour is preserved; it's just relocated
11
- * onto classes whose shape matches the TC39 Signals proposal.
4
+ * `State`, `Computed` and `Watcher` own the dependency graph and nothing else:
5
+ * values, versions, source and observer edges, the lazy state machine, and
6
+ * glitch-free pull evaluation. Ownership, scheduling, effects, suspense and
7
+ * resources all live in `runtime.ts`, with the `create*` surface over them in
8
+ * `compat.ts`.
12
9
  *
13
- * The model is the "push the dirt, pull the value" scheme (Reactively / SolidJS /
14
- * the TC39 polyfill): a write PUSHES a maybe-dirty mark down to observers without
15
- * recomputing; a read PULLS, settling upstream lazily and recomputing only what
16
- * actually changed (equality-gated). Reads outside a tracking scope don't subscribe.
10
+ * `../signal.ts` also implements a graph and is not the one that runs. It is
11
+ * archive, reachable only through the `@fluixi/reactive/signal-legacy` entry, and
12
+ * editing it changes nothing here. Its `Computation` and `signalObservers` are the
13
+ * earlier spelling of what `Computed` and `Source.observers` do below, which is
14
+ * the only reason to open it.
15
+ *
16
+ * The scheme is push the dirt, pull the value, as in Reactively, SolidJS and the
17
+ * TC39 polyfill. A write pushes a maybe-dirty mark down to observers without
18
+ * recomputing anything. A read pulls: upstream settles lazily and only what
19
+ * actually changed recomputes, gated on equality. A read outside a tracking scope
20
+ * subscribes to nothing.
17
21
  */
18
22
  declare const CLEAN = 0;
19
23
  declare const CHECK = 1;
@@ -21,9 +25,9 @@ declare const DIRTY = 2;
21
25
  type NodeState = typeof CLEAN | typeof CHECK | typeof DIRTY;
22
26
  /** A thing that can be depended upon: holds observers + a monotonic version. */
23
27
  declare abstract class Source {
24
- /** Computeds (and watched leaves) that read this node. (was the signalObservers entry) */
28
+ /** Computeds, and watched leaves, that read this node. */
25
29
  observers: Set<Computed<any>> | null;
26
- /** Watchers eagerly observing this node, for effect scheduling (L1). */
30
+ /** Watchers eagerly observing this node, which is how `runtime.ts` schedules effects. */
27
31
  watchers: Set<Watcher> | null;
28
32
  /** Bumped whenever this node's value actually changes (equality-gated). */
29
33
  version: number;
@@ -49,7 +53,7 @@ export declare class Computed<T> extends Source {
49
53
  private _threw;
50
54
  private _initialized;
51
55
  state: NodeState;
52
- /** Nodes this computation read on its last run. (was Computation.sources) */
56
+ /** Nodes this computation read on its last run. Rebuilt on every run. */
53
57
  sources: Set<Source> | null;
54
58
  private readonly _fn;
55
59
  private readonly _equals;
@@ -57,21 +61,21 @@ export declare class Computed<T> extends Source {
57
61
  equals?: ((a: T, b: T) => boolean) | false;
58
62
  });
59
63
  get(): T;
60
- /** Settle: if CHECK, verify sources; if DIRTY (or never run), recompute. */
64
+ /** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
61
65
  updateIfNecessary(): void;
62
66
  private recompute;
63
67
  /**
64
68
  * Push a maybe-dirty mark. A direct observer of a changed node gets DIRTY; its
65
- * own observers get CHECK (recurse) stopping where already marked, so the
69
+ * own observers get CHECK (recurse), stopping where already marked, so the
66
70
  * push is O(newly-dirtied) and never recomputes.
67
71
  */
68
72
  markDirty(level: NodeState): void;
69
73
  peek(): T;
70
74
  }
71
75
  /**
72
- * Signal.subtle.Watcher the only eager observation primitive. Its callback fires
73
- * when a watched signal MAY have changed; the callback MUST NOT read or write
74
- * signals. Effects (L1) are built on this + a scheduler.
76
+ * Signal.subtle.Watcher, the only eager observation primitive. Its callback fires
77
+ * when a watched signal MAY have changed; the callback must not read or write
78
+ * signals. Effects are built on this and a scheduler, in `runtime.ts`.
75
79
  */
76
80
  export declare class Watcher {
77
81
  private readonly _notifyFn;
@@ -82,12 +86,12 @@ export declare class Watcher {
82
86
  unwatch(...nodes: Source[]): void;
83
87
  /** Watched nodes that may have changed since the last getPending(). */
84
88
  getPending(): Source[];
85
- /** @internal a watched node became non-clean. Edge-triggered: notify once. */
89
+ /** @internal, a watched node became non-clean. Edge-triggered: notify once. */
86
90
  _notify(node: Source): void;
87
91
  }
88
- /** Signal.subtle.untrack run `fn` without subscribing the current consumer. */
92
+ /** Signal.subtle.untrack: run `fn` without subscribing the current consumer. */
89
93
  export declare function untrack<T>(fn: () => T): T;
90
- /** Signal.subtle.currentComputed the computed currently evaluating, or null. */
94
+ /** Signal.subtle.currentComputed, the computed currently evaluating, or null. */
91
95
  export declare function currentComputed(): Computed<unknown> | null;
92
96
  /** Whether a node currently has observers/watchers (Signal.subtle.hasSinks). */
93
97
  export declare function hasSinks(node: Source): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/core.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,31 @@
1
1
  /**
2
- * L0 — the TC39-shaped reactive graph core.
2
+ * The TC39-shaped reactive graph core.
3
3
  *
4
- * Class-based primitives (`State`, `Computed`, `Watcher`) that own ONLY the
5
- * dependency graph: values, versions, source/observer edges, the lazy push-pull
6
- * state machine, and glitch-free pull evaluation. They know nothing about
7
- * ownership, scheduling, effects, suspense, or resources those live in the L1
8
- * runtime that sits on top (see ../signal.ts). This is a re-shaping of the exact
9
- * algorithm the existing graph already runs (CLEAN/CHECK/DIRTY + version + the
10
- * `Listener`/observers edges), so behaviour is preserved; it's just relocated
11
- * onto classes whose shape matches the TC39 Signals proposal.
4
+ * `State`, `Computed` and `Watcher` own the dependency graph and nothing else:
5
+ * values, versions, source and observer edges, the lazy state machine, and
6
+ * glitch-free pull evaluation. Ownership, scheduling, effects, suspense and
7
+ * resources all live in `runtime.ts`, with the `create*` surface over them in
8
+ * `compat.ts`.
12
9
  *
13
- * The model is the "push the dirt, pull the value" scheme (Reactively / SolidJS /
14
- * the TC39 polyfill): a write PUSHES a maybe-dirty mark down to observers without
15
- * recomputing; a read PULLS, settling upstream lazily and recomputing only what
16
- * actually changed (equality-gated). Reads outside a tracking scope don't subscribe.
10
+ * `../signal.ts` also implements a graph and is not the one that runs. It is
11
+ * archive, reachable only through the `@fluixi/reactive/signal-legacy` entry, and
12
+ * editing it changes nothing here. Its `Computation` and `signalObservers` are the
13
+ * earlier spelling of what `Computed` and `Source.observers` do below, which is
14
+ * the only reason to open it.
15
+ *
16
+ * The scheme is push the dirt, pull the value, as in Reactively, SolidJS and the
17
+ * TC39 polyfill. A write pushes a maybe-dirty mark down to observers without
18
+ * recomputing anything. A read pulls: upstream settles lazily and only what
19
+ * actually changed recomputes, gated on equality. A read outside a tracking scope
20
+ * subscribes to nothing.
17
21
  */
18
22
  import { G } from './state.js';
19
- // Node states. CHECK = "a source may have changed — verify on read" (your STALE);
20
- // DIRTY = "definitely recompute"; CLEAN = "cached value is current".
23
+ import { enterReactiveRun, exitReactiveRun, reportReactiveRun, reportReactiveWrite } from './observe.js';
24
+ // CLEAN, the cached value is current. CHECK, a source may have changed, so verify on
25
+ // read. DIRTY, recompute without checking.
26
+ // CHECK is what keeps a diamond from recomputing twice: a write marks direct observers
27
+ // DIRTY and everything downstream of them CHECK, so a transitive reader asks its
28
+ // sources whether their versions moved before it runs its own function.
21
29
  const CLEAN = 0;
22
30
  const CHECK = 1;
23
31
  const DIRTY = 2;
@@ -25,10 +33,10 @@ const DIRTY = 2;
25
33
  // so duplicate module copies share one graph. `consumer`/`untracked` proxy them.
26
34
  /** A thing that can be depended upon: holds observers + a monotonic version. */
27
35
  class Source {
28
- /** Computeds (and watched leaves) that read this node. (was the signalObservers entry) */
36
+ /** Computeds, and watched leaves, that read this node. */
29
37
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
38
  observers = null;
31
- /** Watchers eagerly observing this node, for effect scheduling (L1). */
39
+ /** Watchers eagerly observing this node, which is how `runtime.ts` schedules effects. */
32
40
  watchers = null;
33
41
  /** Bumped whenever this node's value actually changes (equality-gated). */
34
42
  version = 0;
@@ -62,10 +70,12 @@ export class State extends Source {
62
70
  return;
63
71
  this._value = next;
64
72
  this.version++;
65
- // Push: direct observers are DIRTY, their transitive observers are CHECK.
66
- // Snapshot first — a synchronous scheduler can re-run an effect mid-propagation,
67
- // which re-subscribes (mutates `observers`); iterating the live Set would then
68
- // re-visit the re-added node forever. (Matches the legacy Array.from(observers).)
73
+ // Who wrote it: once a write has propagated, nothing else records what caused it.
74
+ reportReactiveWrite(this, G.consumer);
75
+ // Push: direct observers go DIRTY, their transitive observers CHECK.
76
+ // Snapshot first. The scheduler is synchronous, so an effect can re-run part way
77
+ // through this loop, and re-running re-subscribes it, which mutates `observers`.
78
+ // Iterating the live Set would then reach the re-added node again, and again.
69
79
  if (this.observers)
70
80
  for (const o of [...this.observers])
71
81
  o.markDirty(DIRTY);
@@ -82,7 +92,7 @@ export class Computed extends Source {
82
92
  _threw = false;
83
93
  _initialized = false;
84
94
  state = DIRTY;
85
- /** Nodes this computation read on its last run. (was Computation.sources) */
95
+ /** Nodes this computation read on its last run. Rebuilt on every run. */
86
96
  sources = null;
87
97
  _fn;
88
98
  _equals;
@@ -102,7 +112,7 @@ export class Computed extends Source {
102
112
  throw this._error;
103
113
  return this._value;
104
114
  }
105
- /** Settle: if CHECK, verify sources; if DIRTY (or never run), recompute. */
115
+ /** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
106
116
  updateIfNecessary() {
107
117
  if (this.state === CHECK) {
108
118
  // Pull each source; if one recomputes to a new value it will have flipped
@@ -128,6 +138,7 @@ export class Computed extends Source {
128
138
  }
129
139
  const prevConsumer = G.consumer;
130
140
  const prevUntracked = G.untracked;
141
+ const watched = enterReactiveRun(this);
131
142
  G.consumer = this;
132
143
  G.untracked = false;
133
144
  let next;
@@ -144,6 +155,8 @@ export class Computed extends Source {
144
155
  finally {
145
156
  G.consumer = prevConsumer;
146
157
  G.untracked = prevUntracked;
158
+ if (watched)
159
+ exitReactiveRun();
147
160
  }
148
161
  const changed = !this._initialized ||
149
162
  this._threw !== threw ||
@@ -152,9 +165,10 @@ export class Computed extends Source {
152
165
  this._threw = threw;
153
166
  this._error = err;
154
167
  this._value = next;
168
+ reportReactiveRun(this);
155
169
  if (changed) {
156
170
  this.version++;
157
- // Our value moved observers that were merely CHECK must now recompute.
171
+ // Our value moved -> observers that were merely CHECK must now recompute.
158
172
  if (this.observers)
159
173
  for (const o of [...this.observers])
160
174
  o.markDirty(DIRTY);
@@ -163,7 +177,7 @@ export class Computed extends Source {
163
177
  }
164
178
  /**
165
179
  * Push a maybe-dirty mark. A direct observer of a changed node gets DIRTY; its
166
- * own observers get CHECK (recurse) stopping where already marked, so the
180
+ * own observers get CHECK (recurse), stopping where already marked, so the
167
181
  * push is O(newly-dirtied) and never recomputes.
168
182
  */
169
183
  markDirty(level) {
@@ -192,9 +206,9 @@ function notifyWatchers(node) {
192
206
  w._notify(node);
193
207
  }
194
208
  /**
195
- * Signal.subtle.Watcher the only eager observation primitive. Its callback fires
196
- * when a watched signal MAY have changed; the callback MUST NOT read or write
197
- * signals. Effects (L1) are built on this + a scheduler.
209
+ * Signal.subtle.Watcher, the only eager observation primitive. Its callback fires
210
+ * when a watched signal MAY have changed; the callback must not read or write
211
+ * signals. Effects are built on this and a scheduler, in `runtime.ts`.
198
212
  */
199
213
  export class Watcher {
200
214
  _notifyFn;
@@ -222,7 +236,7 @@ export class Watcher {
222
236
  this._pending.clear();
223
237
  return out;
224
238
  }
225
- /** @internal a watched node became non-clean. Edge-triggered: notify once. */
239
+ /** @internal, a watched node became non-clean. Edge-triggered: notify once. */
226
240
  _notify(node) {
227
241
  if (!this._watched.has(node) || this._pending.has(node))
228
242
  return;
@@ -232,7 +246,7 @@ export class Watcher {
232
246
  this._notifyFn();
233
247
  }
234
248
  }
235
- /** Signal.subtle.untrack run `fn` without subscribing the current consumer. */
249
+ /** Signal.subtle.untrack: run `fn` without subscribing the current consumer. */
236
250
  export function untrack(fn) {
237
251
  if (G.untracked)
238
252
  return fn();
@@ -244,7 +258,7 @@ export function untrack(fn) {
244
258
  G.untracked = false;
245
259
  }
246
260
  }
247
- /** Signal.subtle.currentComputed the computed currently evaluating, or null. */
261
+ /** Signal.subtle.currentComputed, the computed currently evaluating, or null. */
248
262
  export function currentComputed() {
249
263
  return G.consumer;
250
264
  }