@fluixi/reactive 1.0.0-alpha.83 → 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 (167) hide show
  1. package/dist/cdn/reactive.cjs +2673 -1
  2. package/dist/cdn/reactive.global.js +2 -1
  3. package/dist/cdn/reactive.mjs +2657 -1
  4. package/dist/cdn/signal.cjs +299 -1
  5. package/dist/cdn/signal.d.ts +1 -1
  6. package/dist/cdn/signal.global.js +2 -1
  7. package/dist/cdn/signal.js +1 -1
  8. package/dist/cdn/signal.mjs +276 -1
  9. package/dist/index.cjs +2673 -1
  10. package/dist/index.mjs +2657 -1
  11. package/dist/lib/index.cjs +2674 -1
  12. package/dist/lib/index.js +1 -1
  13. package/dist/lib/index.mjs +2659 -1
  14. package/dist/lib/observable/index.cjs +386 -1
  15. package/dist/lib/observable/index.mjs +364 -1
  16. package/dist/lib/observable/observable.cjs +384 -1
  17. package/dist/lib/observable/observable.d.ts +0 -137
  18. package/dist/lib/observable/observable.d.ts.map +1 -1
  19. package/dist/lib/observable/observable.js +0 -71
  20. package/dist/lib/observable/observable.mjs +361 -1
  21. package/dist/lib/observable/subscription.cjs +180 -1
  22. package/dist/lib/observable/subscription.d.ts +0 -12
  23. package/dist/lib/observable/subscription.d.ts.map +1 -1
  24. package/dist/lib/observable/subscription.js +0 -12
  25. package/dist/lib/observable/subscription.mjs +157 -1
  26. package/dist/lib/observable/types.cjs +18 -1
  27. package/dist/lib/observable/types.d.ts.map +1 -1
  28. package/dist/lib/predicates.cjs +44 -1
  29. package/dist/lib/predicates.d.ts +2 -2
  30. package/dist/lib/predicates.js +2 -2
  31. package/dist/lib/predicates.mjs +23 -1
  32. package/dist/lib/signal/api.cjs +571 -1
  33. package/dist/lib/signal/api.d.ts +211 -1
  34. package/dist/lib/signal/api.d.ts.map +1 -1
  35. package/dist/lib/signal/api.js +207 -12
  36. package/dist/lib/signal/api.mjs +548 -1
  37. package/dist/lib/signal/cached-resource.cjs +672 -1
  38. package/dist/lib/signal/cached-resource.d.ts +28 -16
  39. package/dist/lib/signal/cached-resource.d.ts.map +1 -1
  40. package/dist/lib/signal/cached-resource.js +35 -29
  41. package/dist/lib/signal/cached-resource.mjs +650 -1
  42. package/dist/lib/signal/graph/children.cjs +325 -1
  43. package/dist/lib/signal/graph/children.js +1 -1
  44. package/dist/lib/signal/graph/children.mjs +302 -1
  45. package/dist/lib/signal/graph/compat.cjs +578 -1
  46. package/dist/lib/signal/graph/compat.d.ts +13 -13
  47. package/dist/lib/signal/graph/compat.d.ts.map +1 -1
  48. package/dist/lib/signal/graph/compat.js +33 -31
  49. package/dist/lib/signal/graph/compat.mjs +556 -1
  50. package/dist/lib/signal/graph/core.cjs +295 -1
  51. package/dist/lib/signal/graph/core.d.ts +28 -24
  52. package/dist/lib/signal/graph/core.d.ts.map +1 -1
  53. package/dist/lib/signal/graph/core.js +38 -31
  54. package/dist/lib/signal/graph/core.mjs +273 -1
  55. package/dist/lib/signal/graph/debounced.cjs +668 -1
  56. package/dist/lib/signal/graph/debounced.d.ts +5 -5
  57. package/dist/lib/signal/graph/debounced.d.ts.map +1 -1
  58. package/dist/lib/signal/graph/debounced.js +5 -5
  59. package/dist/lib/signal/graph/debounced.mjs +645 -1
  60. package/dist/lib/signal/graph/derived.cjs +496 -1
  61. package/dist/lib/signal/graph/derived.d.ts +1 -1
  62. package/dist/lib/signal/graph/derived.js +1 -1
  63. package/dist/lib/signal/graph/derived.mjs +473 -1
  64. package/dist/lib/signal/graph/detect.cjs +66 -1
  65. package/dist/lib/signal/graph/detect.mjs +45 -1
  66. package/dist/lib/signal/graph/error-boundary.cjs +301 -1
  67. package/dist/lib/signal/graph/error-boundary.js +3 -3
  68. package/dist/lib/signal/graph/error-boundary.mjs +278 -1
  69. package/dist/lib/signal/graph/index.cjs +305 -1
  70. package/dist/lib/signal/graph/index.d.ts +7 -6
  71. package/dist/lib/signal/graph/index.d.ts.map +1 -1
  72. package/dist/lib/signal/graph/index.js +7 -6
  73. package/dist/lib/signal/graph/index.mjs +283 -1
  74. package/dist/lib/signal/graph/observe.cjs +163 -1
  75. package/dist/lib/signal/graph/observe.d.ts +8 -8
  76. package/dist/lib/signal/graph/observe.js +5 -5
  77. package/dist/lib/signal/graph/observe.mjs +140 -1
  78. package/dist/lib/signal/graph/resource.cjs +620 -1
  79. package/dist/lib/signal/graph/resource.d.ts +1 -1
  80. package/dist/lib/signal/graph/resource.js +7 -8
  81. package/dist/lib/signal/graph/resource.mjs +597 -1
  82. package/dist/lib/signal/graph/runtime.cjs +501 -1
  83. package/dist/lib/signal/graph/runtime.d.ts +7 -7
  84. package/dist/lib/signal/graph/runtime.d.ts.map +1 -1
  85. package/dist/lib/signal/graph/runtime.js +34 -30
  86. package/dist/lib/signal/graph/runtime.mjs +478 -1
  87. package/dist/lib/signal/graph/signal-next.cjs +1208 -1
  88. package/dist/lib/signal/graph/signal-next.d.ts +5 -5
  89. package/dist/lib/signal/graph/signal-next.d.ts.map +1 -1
  90. package/dist/lib/signal/graph/signal-next.js +14 -12
  91. package/dist/lib/signal/graph/signal-next.mjs +1186 -1
  92. package/dist/lib/signal/graph/ssr-hooks.cjs +60 -1
  93. package/dist/lib/signal/graph/ssr-hooks.d.ts +6 -7
  94. package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -1
  95. package/dist/lib/signal/graph/ssr-hooks.js +6 -7
  96. package/dist/lib/signal/graph/ssr-hooks.mjs +39 -1
  97. package/dist/lib/signal/graph/state.cjs +72 -1
  98. package/dist/lib/signal/graph/state.d.ts +41 -10
  99. package/dist/lib/signal/graph/state.d.ts.map +1 -1
  100. package/dist/lib/signal/graph/state.js +83 -22
  101. package/dist/lib/signal/graph/state.mjs +49 -1
  102. package/dist/lib/signal/graph/suspense.cjs +301 -1
  103. package/dist/lib/signal/graph/suspense.js +4 -4
  104. package/dist/lib/signal/graph/suspense.mjs +278 -1
  105. package/dist/lib/signal/index-legacy.cjs +2540 -1
  106. package/dist/lib/signal/index-legacy.d.ts +1 -1
  107. package/dist/lib/signal/index-legacy.js +1 -1
  108. package/dist/lib/signal/index-legacy.mjs +2518 -1
  109. package/dist/lib/signal/index.cjs +1275 -1
  110. package/dist/lib/signal/index.d.ts +3 -2
  111. package/dist/lib/signal/index.d.ts.map +1 -1
  112. package/dist/lib/signal/index.js +7 -4
  113. package/dist/lib/signal/index.mjs +1253 -1
  114. package/dist/lib/signal/list.cjs +549 -1
  115. package/dist/lib/signal/list.d.ts +5 -5
  116. package/dist/lib/signal/list.js +5 -5
  117. package/dist/lib/signal/list.mjs +526 -1
  118. package/dist/lib/signal/resource-api.cjs +626 -1
  119. package/dist/lib/signal/resource-api.d.ts +5 -5
  120. package/dist/lib/signal/resource-api.js +5 -5
  121. package/dist/lib/signal/resource-api.mjs +603 -1
  122. package/dist/lib/signal/signal.cjs +2023 -1
  123. package/dist/lib/signal/signal.d.ts +4 -4
  124. package/dist/lib/signal/signal.d.ts.map +1 -1
  125. package/dist/lib/signal/signal.js +22 -23
  126. package/dist/lib/signal/signal.mjs +2000 -1
  127. package/dist/lib/signal/types.cjs +38 -1
  128. package/dist/lib/signal/types.d.ts.map +1 -1
  129. package/dist/lib/signal/types.js +2 -2
  130. package/dist/lib/signal/types.mjs +17 -1
  131. package/dist/lib/signal/utilities.cjs +1012 -1
  132. package/dist/lib/signal/utilities.d.ts +0 -108
  133. package/dist/lib/signal/utilities.d.ts.map +1 -1
  134. package/dist/lib/signal/utilities.js +0 -158
  135. package/dist/lib/signal/utilities.mjs +990 -1
  136. package/dist/lib/store/api.cjs +612 -1
  137. package/dist/lib/store/api.d.ts +33 -0
  138. package/dist/lib/store/api.d.ts.map +1 -1
  139. package/dist/lib/store/api.js +41 -8
  140. package/dist/lib/store/api.mjs +596 -1
  141. package/dist/lib/store/index.cjs +691 -1
  142. package/dist/lib/store/index.js +1 -1
  143. package/dist/lib/store/index.mjs +676 -1
  144. package/dist/lib/store/setter.types.cjs +18 -1
  145. package/dist/lib/store/setter.types.d.ts +43 -3
  146. package/dist/lib/store/setter.types.d.ts.map +1 -1
  147. package/dist/lib/store/store.cjs +658 -1
  148. package/dist/lib/store/store.d.ts +72 -0
  149. package/dist/lib/store/store.d.ts.map +1 -1
  150. package/dist/lib/store/store.js +148 -5
  151. package/dist/lib/store/store.mjs +644 -1
  152. package/dist/lib/store/types.cjs +18 -1
  153. package/dist/lib/store/types.d.ts +1 -1
  154. package/dist/lib/store/types.d.ts.map +1 -1
  155. package/dist/lib/store/utils.cjs +43 -1
  156. package/dist/lib/store/utils.d.ts +1 -1
  157. package/dist/lib/store/utils.js +1 -1
  158. package/dist/lib/store/utils.mjs +22 -1
  159. package/dist/lib/subject.cjs +450 -1
  160. package/dist/lib/subject.js +3 -91
  161. package/dist/lib/subject.mjs +427 -1
  162. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  163. package/dist/version.generated.cjs +27 -1
  164. package/dist/version.generated.d.ts +1 -1
  165. package/dist/version.generated.js +2 -2
  166. package/dist/version.generated.mjs +7 -1
  167. package/package.json +5 -4
@@ -1 +1,305 @@
1
- "use strict";var p=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var I=(e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})},z=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of D(t))!E.call(e,s)&&s!==n&&p(e,s,{get:()=>t[s],enumerable:!(o=q(t,s))||o.enumerable});return e};var K=e=>z(p({},"__esModule",{value:!0}),e);var L={};I(L,{Computed:()=>a,Signal:()=>F,State:()=>i,Watcher:()=>u});module.exports=K(L);var G="__fluixi_signal_next_state__",H=e=>{typeof queueMicrotask=="function"?queueMicrotask(e):Promise.resolve().then(e)},r=globalThis[G]??={consumer:null,untracked:!1,owner:null,queue:[],scheduled:!1,flushing:!1,batchDepth:0,hostSchedule:H,onSuspend:null,onError:null,observer:null};var w="1.0.0-alpha.83";function j(e){return r.observer=e,()=>{r.observer===e&&(r.observer=null)}}var _=[];function m(e){return r.observer?(_.push(e),!0):!1}function g(){_.pop()}function R(e){r.observer?.ran?.(e)}function y(e,t){r.observer?.wrote?.(e,t)}var W="__FLUIXI_DEVTOOLS_HOOK__",k=globalThis[W];if(typeof k?.inject=="function")try{k.inject({observeReactiveNodes:j,version:w})}catch{}var x=0,S=1,v=2,h=class{constructor(){this.observers=null;this.watchers=null;this.version=0}updateIfNecessary(){}track(){if(r.untracked)return;let t=r.consumer;t&&((this.observers??=new Set).add(t),(t.sources??=new Set).add(this))}},i=class extends h{constructor(t,n){super(),this._value=t,this._equals=n?.equals===!1?()=>!1:n?.equals??Object.is}get(){return this.track(),this._value}set(t){if(!this._equals(this._value,t)){if(this._value=t,this.version++,y(this,r.consumer),this.observers)for(let n of[...this.observers])n.markDirty(v);b(this)}}peek(){return this._value}},a=class extends h{constructor(n,o){super();this._threw=!1;this._initialized=!1;this.state=v;this.sources=null;this._fn=n,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===S&&this.sources){for(let n of this.sources)if(n.updateIfNecessary(),this.state===v)break}(this.state===v||!this._initialized)&&this.recompute(),this.state=x}recompute(){if(this.sources){for(let c of this.sources)c.observers?.delete(this);this.sources.clear()}let n=r.consumer,o=r.untracked,s=m(this);r.consumer=this,r.untracked=!1;let d,l=!1,f;try{d=this._fn()}catch(c){l=!0,f=c,d=this._value}finally{r.consumer=n,r.untracked=o,s&&g()}let C=!this._initialized||this._threw!==l||(l?f!==this._error:!this._equals(this._value,d));if(this._initialized=!0,this._threw=l,this._error=f,this._value=d,R(this),C){if(this.version++,this.observers)for(let c of[...this.observers])c.markDirty(v);b(this)}}markDirty(n){if(this.state>=n)return;let o=this.state===x;if(this.state=n,o){if(this.observers)for(let s of[...this.observers])s.markDirty(S);b(this)}}peek(){if(this.updateIfNecessary(),this._threw)throw this._error;return this._value}};function b(e){if(e.watchers)for(let t of[...e.watchers])t._notify(e)}var u=class{constructor(t){this._watched=new Set;this._pending=new Set;this._notifyFn=t}watch(...t){for(let n of t)this._watched.add(n),(n.watchers??=new Set).add(this)}unwatch(...t){for(let n of t)this._watched.delete(n),n.watchers?.delete(this),this._pending.delete(n)}getPending(){let t=[...this._pending];return this._pending.clear(),t}_notify(t){if(!this._watched.has(t)||this._pending.has(t))return;let n=this._pending.size===0;this._pending.add(t),n&&this._notifyFn()}};function T(e){if(r.untracked)return e();r.untracked=!0;try{return e()}finally{r.untracked=!1}}function O(){return r.consumer}function N(e){return!!(e.observers&&e.observers.size)||!!(e.watchers&&e.watchers.size)}var F={State:i,Computed:a,subtle:{Watcher:u,untrack:T,currentComputed:O,hasSinks:N}};
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/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ Computed: () => Computed,
25
+ Signal: () => Signal,
26
+ State: () => State,
27
+ Watcher: () => Watcher
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/version.generated.ts
32
+ var VERSION = "1.0.0-alpha.84";
33
+
34
+ // src/lib/signal/graph/state.ts
35
+ var MAJOR = VERSION.split(".")[0];
36
+ var KEY = `__fluixi_signal_state_v${MAJOR}__`;
37
+ var VERSIONS_KEY = `__fluixi_signal_builds_v${MAJOR}__`;
38
+ var defaultSchedule = (run) => {
39
+ if (typeof queueMicrotask === "function") queueMicrotask(run);
40
+ else void Promise.resolve().then(run);
41
+ };
42
+ function defaults() {
43
+ return {
44
+ consumer: null,
45
+ untracked: false,
46
+ owner: null,
47
+ queue: [],
48
+ scheduled: false,
49
+ flushing: false,
50
+ batchDepth: 0,
51
+ hostSchedule: defaultSchedule,
52
+ onSuspend: null,
53
+ onError: null,
54
+ observer: null
55
+ };
56
+ }
57
+ var realm = globalThis;
58
+ function backfillState(existing) {
59
+ const fresh = defaults();
60
+ const target = existing;
61
+ for (const field of Object.keys(fresh)) {
62
+ if (!(field in existing)) target[field] = fresh[field];
63
+ }
64
+ return existing;
65
+ }
66
+ function claim() {
67
+ const existing = realm[KEY];
68
+ return existing ? backfillState(existing) : realm[KEY] = defaults();
69
+ }
70
+ var G = claim();
71
+ (realm[VERSIONS_KEY] ??= []).push(VERSION);
72
+
73
+ // src/lib/signal/graph/observe.ts
74
+ function observeReactiveNodes(next) {
75
+ G.observer = next;
76
+ return () => {
77
+ if (G.observer === next) G.observer = null;
78
+ };
79
+ }
80
+ var running = [];
81
+ function enterReactiveRun(node) {
82
+ if (!G.observer) return false;
83
+ running.push(node);
84
+ return true;
85
+ }
86
+ function exitReactiveRun() {
87
+ running.pop();
88
+ }
89
+ function reportReactiveRun(node) {
90
+ G.observer?.ran?.(node);
91
+ }
92
+ function reportReactiveWrite(node, by) {
93
+ G.observer?.wrote?.(node, by);
94
+ }
95
+ var HOOK = "__FLUIXI_DEVTOOLS_HOOK__";
96
+ var hook = globalThis[HOOK];
97
+ if (typeof hook?.inject === "function") {
98
+ try {
99
+ hook.inject({ observeReactiveNodes, version: VERSION });
100
+ } catch {
101
+ }
102
+ }
103
+
104
+ // src/lib/signal/graph/core.ts
105
+ var CLEAN = 0;
106
+ var CHECK = 1;
107
+ var DIRTY = 2;
108
+ var Source = class {
109
+ constructor() {
110
+ /** Computeds, and watched leaves, that read this node. */
111
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
+ this.observers = null;
113
+ /** Watchers eagerly observing this node, which is how `runtime.ts` schedules effects. */
114
+ this.watchers = null;
115
+ /** Bumped whenever this node's value actually changes (equality-gated). */
116
+ this.version = 0;
117
+ }
118
+ /** Settle this node so a reader sees a current value/version. Overridden by Computed. */
119
+ updateIfNecessary() {
120
+ }
121
+ /** Link the current consumer (if any) as an observer of this node. */
122
+ track() {
123
+ if (G.untracked) return;
124
+ const consumer = G.consumer;
125
+ if (!consumer) return;
126
+ (this.observers ??= /* @__PURE__ */ new Set()).add(consumer);
127
+ (consumer.sources ??= /* @__PURE__ */ new Set()).add(this);
128
+ }
129
+ };
130
+ var State = class extends Source {
131
+ constructor(value, options) {
132
+ super();
133
+ this._value = value;
134
+ this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
135
+ }
136
+ get() {
137
+ this.track();
138
+ return this._value;
139
+ }
140
+ set(next) {
141
+ if (this._equals(this._value, next)) return;
142
+ this._value = next;
143
+ this.version++;
144
+ reportReactiveWrite(this, G.consumer);
145
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
146
+ notifyWatchers(this);
147
+ }
148
+ /** Read without subscribing (peek). */
149
+ peek() {
150
+ return this._value;
151
+ }
152
+ };
153
+ var Computed = class extends Source {
154
+ constructor(fn, options) {
155
+ super();
156
+ this._threw = false;
157
+ this._initialized = false;
158
+ this.state = DIRTY;
159
+ /** Nodes this computation read on its last run. Rebuilt on every run. */
160
+ this.sources = null;
161
+ this._fn = fn;
162
+ this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
163
+ }
164
+ get() {
165
+ if (G.consumer === this) {
166
+ throw new Error("Signal.Computed cannot read itself");
167
+ }
168
+ this.track();
169
+ this.updateIfNecessary();
170
+ if (this._threw) throw this._error;
171
+ return this._value;
172
+ }
173
+ /** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
174
+ updateIfNecessary() {
175
+ if (this.state === CHECK) {
176
+ if (this.sources) {
177
+ for (const s of this.sources) {
178
+ s.updateIfNecessary();
179
+ if (this.state === DIRTY) break;
180
+ }
181
+ }
182
+ }
183
+ if (this.state === DIRTY || !this._initialized) this.recompute();
184
+ this.state = CLEAN;
185
+ }
186
+ recompute() {
187
+ if (this.sources) {
188
+ for (const s of this.sources) s.observers?.delete(this);
189
+ this.sources.clear();
190
+ }
191
+ const prevConsumer = G.consumer;
192
+ const prevUntracked = G.untracked;
193
+ const watched = enterReactiveRun(this);
194
+ G.consumer = this;
195
+ G.untracked = false;
196
+ let next;
197
+ let threw = false;
198
+ let err;
199
+ try {
200
+ next = this._fn();
201
+ } catch (e) {
202
+ threw = true;
203
+ err = e;
204
+ next = this._value;
205
+ } finally {
206
+ G.consumer = prevConsumer;
207
+ G.untracked = prevUntracked;
208
+ if (watched) exitReactiveRun();
209
+ }
210
+ const changed = !this._initialized || this._threw !== threw || (threw ? err !== this._error : !this._equals(this._value, next));
211
+ this._initialized = true;
212
+ this._threw = threw;
213
+ this._error = err;
214
+ this._value = next;
215
+ reportReactiveRun(this);
216
+ if (changed) {
217
+ this.version++;
218
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
219
+ notifyWatchers(this);
220
+ }
221
+ }
222
+ /**
223
+ * Push a maybe-dirty mark. A direct observer of a changed node gets DIRTY; its
224
+ * own observers get CHECK (recurse), stopping where already marked, so the
225
+ * push is O(newly-dirtied) and never recomputes.
226
+ */
227
+ markDirty(level) {
228
+ if (this.state >= level) return;
229
+ const wasClean = this.state === CLEAN;
230
+ this.state = level;
231
+ if (wasClean) {
232
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(CHECK);
233
+ notifyWatchers(this);
234
+ }
235
+ }
236
+ peek() {
237
+ this.updateIfNecessary();
238
+ if (this._threw) throw this._error;
239
+ return this._value;
240
+ }
241
+ };
242
+ function notifyWatchers(node) {
243
+ if (!node.watchers) return;
244
+ for (const w of [...node.watchers]) w._notify(node);
245
+ }
246
+ var Watcher = class {
247
+ constructor(notify) {
248
+ this._watched = /* @__PURE__ */ new Set();
249
+ this._pending = /* @__PURE__ */ new Set();
250
+ this._notifyFn = notify;
251
+ }
252
+ watch(...nodes) {
253
+ for (const n of nodes) {
254
+ this._watched.add(n);
255
+ (n.watchers ??= /* @__PURE__ */ new Set()).add(this);
256
+ }
257
+ }
258
+ unwatch(...nodes) {
259
+ for (const n of nodes) {
260
+ this._watched.delete(n);
261
+ n.watchers?.delete(this);
262
+ this._pending.delete(n);
263
+ }
264
+ }
265
+ /** Watched nodes that may have changed since the last getPending(). */
266
+ getPending() {
267
+ const out = [...this._pending];
268
+ this._pending.clear();
269
+ return out;
270
+ }
271
+ /** @internal, a watched node became non-clean. Edge-triggered: notify once. */
272
+ _notify(node) {
273
+ if (!this._watched.has(node) || this._pending.has(node)) return;
274
+ const wasEmpty = this._pending.size === 0;
275
+ this._pending.add(node);
276
+ if (wasEmpty) this._notifyFn();
277
+ }
278
+ };
279
+ function untrack(fn) {
280
+ if (G.untracked) return fn();
281
+ G.untracked = true;
282
+ try {
283
+ return fn();
284
+ } finally {
285
+ G.untracked = false;
286
+ }
287
+ }
288
+ function currentComputed() {
289
+ return G.consumer;
290
+ }
291
+ function hasSinks(node) {
292
+ return !!(node.observers && node.observers.size) || !!(node.watchers && node.watchers.size);
293
+ }
294
+
295
+ // src/lib/signal/graph/index.ts
296
+ var Signal = {
297
+ State,
298
+ Computed,
299
+ subtle: {
300
+ Watcher,
301
+ untrack,
302
+ currentComputed,
303
+ hasSinks
304
+ }
305
+ };
@@ -1,10 +1,11 @@
1
1
  /**
2
- * The TC39-shaped public surface for the L0 graph core: `Signal.State`,
3
- * `Signal.Computed`, and the `Signal.subtle` namespace (Watcher / untrack /
4
- * currentComputed / hasSinks). This mirrors the TC39 Signals proposal so the L1
5
- * runtime (and, eventually, app code) can target the same shape that a native
6
- * `globalThis.Signal` would expose at which point L0 becomes a thin
7
- * `globalThis.Signal ?? polyfill` swap.
2
+ * The TC39-shaped surface over the graph core: `Signal.State`, `Signal.Computed`,
3
+ * and the `Signal.subtle` namespace of Watcher, untrack, currentComputed and
4
+ * hasSinks.
5
+ *
6
+ * It mirrors the proposal so that the runtime layer, and eventually app code, target
7
+ * the shape a native `globalThis.Signal` would expose. When that ships, `core.ts`
8
+ * becomes a `globalThis.Signal ?? polyfill` swap and nothing above it moves.
8
9
  */
9
10
  import { State, Computed, Watcher, untrack, currentComputed, hasSinks } from './core.js';
10
11
  export declare const Signal: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzF,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAEX,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzF,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAEX,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
@@ -1,10 +1,11 @@
1
1
  /**
2
- * The TC39-shaped public surface for the L0 graph core: `Signal.State`,
3
- * `Signal.Computed`, and the `Signal.subtle` namespace (Watcher / untrack /
4
- * currentComputed / hasSinks). This mirrors the TC39 Signals proposal so the L1
5
- * runtime (and, eventually, app code) can target the same shape that a native
6
- * `globalThis.Signal` would expose at which point L0 becomes a thin
7
- * `globalThis.Signal ?? polyfill` swap.
2
+ * The TC39-shaped surface over the graph core: `Signal.State`, `Signal.Computed`,
3
+ * and the `Signal.subtle` namespace of Watcher, untrack, currentComputed and
4
+ * hasSinks.
5
+ *
6
+ * It mirrors the proposal so that the runtime layer, and eventually app code, target
7
+ * the shape a native `globalThis.Signal` would expose. When that ships, `core.ts`
8
+ * becomes a `globalThis.Signal ?? polyfill` swap and nothing above it moves.
8
9
  */
9
10
  import { State, Computed, Watcher, untrack, currentComputed, hasSinks } from './core.js';
10
11
  export const Signal = {
@@ -1 +1,283 @@
1
- var C="__fluixi_signal_next_state__",q=e=>{typeof queueMicrotask=="function"?queueMicrotask(e):Promise.resolve().then(e)},r=globalThis[C]??={consumer:null,untracked:!1,owner:null,queue:[],scheduled:!1,flushing:!1,batchDepth:0,hostSchedule:q,onSuspend:null,onError:null,observer:null};var b="1.0.0-alpha.83";function D(e){return r.observer=e,()=>{r.observer===e&&(r.observer=null)}}var k=[];function _(e){return r.observer?(k.push(e),!0):!1}function m(){k.pop()}function g(e){r.observer?.ran?.(e)}function R(e,t){r.observer?.wrote?.(e,t)}var E="__FLUIXI_DEVTOOLS_HOOK__",w=globalThis[E];if(typeof w?.inject=="function")try{w.inject({observeReactiveNodes:D,version:b})}catch{}var y=0,x=1,i=2,l=class{constructor(){this.observers=null;this.watchers=null;this.version=0}updateIfNecessary(){}track(){if(r.untracked)return;let t=r.consumer;t&&((this.observers??=new Set).add(t),(t.sources??=new Set).add(this))}},a=class extends l{constructor(t,n){super(),this._value=t,this._equals=n?.equals===!1?()=>!1:n?.equals??Object.is}get(){return this.track(),this._value}set(t){if(!this._equals(this._value,t)){if(this._value=t,this.version++,R(this,r.consumer),this.observers)for(let n of[...this.observers])n.markDirty(i);p(this)}}peek(){return this._value}},u=class extends l{constructor(n,o){super();this._threw=!1;this._initialized=!1;this.state=i;this.sources=null;this._fn=n,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===x&&this.sources){for(let n of this.sources)if(n.updateIfNecessary(),this.state===i)break}(this.state===i||!this._initialized)&&this.recompute(),this.state=y}recompute(){if(this.sources){for(let s of this.sources)s.observers?.delete(this);this.sources.clear()}let n=r.consumer,o=r.untracked,h=_(this);r.consumer=this,r.untracked=!1;let v,d=!1,f;try{v=this._fn()}catch(s){d=!0,f=s,v=this._value}finally{r.consumer=n,r.untracked=o,h&&m()}let N=!this._initialized||this._threw!==d||(d?f!==this._error:!this._equals(this._value,v));if(this._initialized=!0,this._threw=d,this._error=f,this._value=v,g(this),N){if(this.version++,this.observers)for(let s of[...this.observers])s.markDirty(i);p(this)}}markDirty(n){if(this.state>=n)return;let o=this.state===y;if(this.state=n,o){if(this.observers)for(let h of[...this.observers])h.markDirty(x);p(this)}}peek(){if(this.updateIfNecessary(),this._threw)throw this._error;return this._value}};function p(e){if(e.watchers)for(let t of[...e.watchers])t._notify(e)}var c=class{constructor(t){this._watched=new Set;this._pending=new Set;this._notifyFn=t}watch(...t){for(let n of t)this._watched.add(n),(n.watchers??=new Set).add(this)}unwatch(...t){for(let n of t)this._watched.delete(n),n.watchers?.delete(this),this._pending.delete(n)}getPending(){let t=[...this._pending];return this._pending.clear(),t}_notify(t){if(!this._watched.has(t)||this._pending.has(t))return;let n=this._pending.size===0;this._pending.add(t),n&&this._notifyFn()}};function S(e){if(r.untracked)return e();r.untracked=!0;try{return e()}finally{r.untracked=!1}}function T(){return r.consumer}function O(e){return!!(e.observers&&e.observers.size)||!!(e.watchers&&e.watchers.size)}var P={State:a,Computed:u,subtle:{Watcher:c,untrack:S,currentComputed:T,hasSinks:O}};export{u as Computed,P as Signal,a as State,c as Watcher};
1
+ /*! @fluixi/reactive v1.0.0-alpha.84 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+
3
+ // src/version.generated.ts
4
+ var VERSION = "1.0.0-alpha.84";
5
+
6
+ // src/lib/signal/graph/state.ts
7
+ var MAJOR = VERSION.split(".")[0];
8
+ var KEY = `__fluixi_signal_state_v${MAJOR}__`;
9
+ var VERSIONS_KEY = `__fluixi_signal_builds_v${MAJOR}__`;
10
+ var defaultSchedule = (run) => {
11
+ if (typeof queueMicrotask === "function") queueMicrotask(run);
12
+ else void Promise.resolve().then(run);
13
+ };
14
+ function defaults() {
15
+ return {
16
+ consumer: null,
17
+ untracked: false,
18
+ owner: null,
19
+ queue: [],
20
+ scheduled: false,
21
+ flushing: false,
22
+ batchDepth: 0,
23
+ hostSchedule: defaultSchedule,
24
+ onSuspend: null,
25
+ onError: null,
26
+ observer: null
27
+ };
28
+ }
29
+ var realm = globalThis;
30
+ function backfillState(existing) {
31
+ const fresh = defaults();
32
+ const target = existing;
33
+ for (const field of Object.keys(fresh)) {
34
+ if (!(field in existing)) target[field] = fresh[field];
35
+ }
36
+ return existing;
37
+ }
38
+ function claim() {
39
+ const existing = realm[KEY];
40
+ return existing ? backfillState(existing) : realm[KEY] = defaults();
41
+ }
42
+ var G = claim();
43
+ (realm[VERSIONS_KEY] ??= []).push(VERSION);
44
+
45
+ // src/lib/signal/graph/observe.ts
46
+ function observeReactiveNodes(next) {
47
+ G.observer = next;
48
+ return () => {
49
+ if (G.observer === next) G.observer = null;
50
+ };
51
+ }
52
+ var running = [];
53
+ function enterReactiveRun(node) {
54
+ if (!G.observer) return false;
55
+ running.push(node);
56
+ return true;
57
+ }
58
+ function exitReactiveRun() {
59
+ running.pop();
60
+ }
61
+ function reportReactiveRun(node) {
62
+ G.observer?.ran?.(node);
63
+ }
64
+ function reportReactiveWrite(node, by) {
65
+ G.observer?.wrote?.(node, by);
66
+ }
67
+ var HOOK = "__FLUIXI_DEVTOOLS_HOOK__";
68
+ var hook = globalThis[HOOK];
69
+ if (typeof hook?.inject === "function") {
70
+ try {
71
+ hook.inject({ observeReactiveNodes, version: VERSION });
72
+ } catch {
73
+ }
74
+ }
75
+
76
+ // src/lib/signal/graph/core.ts
77
+ var CLEAN = 0;
78
+ var CHECK = 1;
79
+ var DIRTY = 2;
80
+ var Source = class {
81
+ constructor() {
82
+ /** Computeds, and watched leaves, that read this node. */
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ this.observers = null;
85
+ /** Watchers eagerly observing this node, which is how `runtime.ts` schedules effects. */
86
+ this.watchers = null;
87
+ /** Bumped whenever this node's value actually changes (equality-gated). */
88
+ this.version = 0;
89
+ }
90
+ /** Settle this node so a reader sees a current value/version. Overridden by Computed. */
91
+ updateIfNecessary() {
92
+ }
93
+ /** Link the current consumer (if any) as an observer of this node. */
94
+ track() {
95
+ if (G.untracked) return;
96
+ const consumer = G.consumer;
97
+ if (!consumer) return;
98
+ (this.observers ??= /* @__PURE__ */ new Set()).add(consumer);
99
+ (consumer.sources ??= /* @__PURE__ */ new Set()).add(this);
100
+ }
101
+ };
102
+ var State = class extends Source {
103
+ constructor(value, options) {
104
+ super();
105
+ this._value = value;
106
+ this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
107
+ }
108
+ get() {
109
+ this.track();
110
+ return this._value;
111
+ }
112
+ set(next) {
113
+ if (this._equals(this._value, next)) return;
114
+ this._value = next;
115
+ this.version++;
116
+ reportReactiveWrite(this, G.consumer);
117
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
118
+ notifyWatchers(this);
119
+ }
120
+ /** Read without subscribing (peek). */
121
+ peek() {
122
+ return this._value;
123
+ }
124
+ };
125
+ var Computed = class extends Source {
126
+ constructor(fn, options) {
127
+ super();
128
+ this._threw = false;
129
+ this._initialized = false;
130
+ this.state = DIRTY;
131
+ /** Nodes this computation read on its last run. Rebuilt on every run. */
132
+ this.sources = null;
133
+ this._fn = fn;
134
+ this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
135
+ }
136
+ get() {
137
+ if (G.consumer === this) {
138
+ throw new Error("Signal.Computed cannot read itself");
139
+ }
140
+ this.track();
141
+ this.updateIfNecessary();
142
+ if (this._threw) throw this._error;
143
+ return this._value;
144
+ }
145
+ /** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
146
+ updateIfNecessary() {
147
+ if (this.state === CHECK) {
148
+ if (this.sources) {
149
+ for (const s of this.sources) {
150
+ s.updateIfNecessary();
151
+ if (this.state === DIRTY) break;
152
+ }
153
+ }
154
+ }
155
+ if (this.state === DIRTY || !this._initialized) this.recompute();
156
+ this.state = CLEAN;
157
+ }
158
+ recompute() {
159
+ if (this.sources) {
160
+ for (const s of this.sources) s.observers?.delete(this);
161
+ this.sources.clear();
162
+ }
163
+ const prevConsumer = G.consumer;
164
+ const prevUntracked = G.untracked;
165
+ const watched = enterReactiveRun(this);
166
+ G.consumer = this;
167
+ G.untracked = false;
168
+ let next;
169
+ let threw = false;
170
+ let err;
171
+ try {
172
+ next = this._fn();
173
+ } catch (e) {
174
+ threw = true;
175
+ err = e;
176
+ next = this._value;
177
+ } finally {
178
+ G.consumer = prevConsumer;
179
+ G.untracked = prevUntracked;
180
+ if (watched) exitReactiveRun();
181
+ }
182
+ const changed = !this._initialized || this._threw !== threw || (threw ? err !== this._error : !this._equals(this._value, next));
183
+ this._initialized = true;
184
+ this._threw = threw;
185
+ this._error = err;
186
+ this._value = next;
187
+ reportReactiveRun(this);
188
+ if (changed) {
189
+ this.version++;
190
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
191
+ notifyWatchers(this);
192
+ }
193
+ }
194
+ /**
195
+ * Push a maybe-dirty mark. A direct observer of a changed node gets DIRTY; its
196
+ * own observers get CHECK (recurse), stopping where already marked, so the
197
+ * push is O(newly-dirtied) and never recomputes.
198
+ */
199
+ markDirty(level) {
200
+ if (this.state >= level) return;
201
+ const wasClean = this.state === CLEAN;
202
+ this.state = level;
203
+ if (wasClean) {
204
+ if (this.observers) for (const o of [...this.observers]) o.markDirty(CHECK);
205
+ notifyWatchers(this);
206
+ }
207
+ }
208
+ peek() {
209
+ this.updateIfNecessary();
210
+ if (this._threw) throw this._error;
211
+ return this._value;
212
+ }
213
+ };
214
+ function notifyWatchers(node) {
215
+ if (!node.watchers) return;
216
+ for (const w of [...node.watchers]) w._notify(node);
217
+ }
218
+ var Watcher = class {
219
+ constructor(notify) {
220
+ this._watched = /* @__PURE__ */ new Set();
221
+ this._pending = /* @__PURE__ */ new Set();
222
+ this._notifyFn = notify;
223
+ }
224
+ watch(...nodes) {
225
+ for (const n of nodes) {
226
+ this._watched.add(n);
227
+ (n.watchers ??= /* @__PURE__ */ new Set()).add(this);
228
+ }
229
+ }
230
+ unwatch(...nodes) {
231
+ for (const n of nodes) {
232
+ this._watched.delete(n);
233
+ n.watchers?.delete(this);
234
+ this._pending.delete(n);
235
+ }
236
+ }
237
+ /** Watched nodes that may have changed since the last getPending(). */
238
+ getPending() {
239
+ const out = [...this._pending];
240
+ this._pending.clear();
241
+ return out;
242
+ }
243
+ /** @internal, a watched node became non-clean. Edge-triggered: notify once. */
244
+ _notify(node) {
245
+ if (!this._watched.has(node) || this._pending.has(node)) return;
246
+ const wasEmpty = this._pending.size === 0;
247
+ this._pending.add(node);
248
+ if (wasEmpty) this._notifyFn();
249
+ }
250
+ };
251
+ function untrack(fn) {
252
+ if (G.untracked) return fn();
253
+ G.untracked = true;
254
+ try {
255
+ return fn();
256
+ } finally {
257
+ G.untracked = false;
258
+ }
259
+ }
260
+ function currentComputed() {
261
+ return G.consumer;
262
+ }
263
+ function hasSinks(node) {
264
+ return !!(node.observers && node.observers.size) || !!(node.watchers && node.watchers.size);
265
+ }
266
+
267
+ // src/lib/signal/graph/index.ts
268
+ var Signal = {
269
+ State,
270
+ Computed,
271
+ subtle: {
272
+ Watcher,
273
+ untrack,
274
+ currentComputed,
275
+ hasSinks
276
+ }
277
+ };
278
+ export {
279
+ Computed,
280
+ Signal,
281
+ State,
282
+ Watcher
283
+ };