@nisli/core 0.55.0 → 0.57.0
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.
- package/README.md +58 -1
- package/dist/bundler/component.js +409 -0
- package/dist/bundler/component.js.map +7 -0
- package/dist/bundler/context.js +27 -0
- package/dist/bundler/context.js.map +7 -0
- package/dist/bundler/diagnostics.js +55 -0
- package/dist/bundler/diagnostics.js.map +7 -0
- package/dist/bundler/disposable.js +9 -0
- package/dist/bundler/disposable.js.map +7 -0
- package/dist/bundler/element-context.js +47 -0
- package/dist/bundler/element-context.js.map +7 -0
- package/dist/bundler/emitter.js +70 -0
- package/dist/bundler/emitter.js.map +7 -0
- package/dist/bundler/hmr/registry.js +72 -0
- package/dist/bundler/hmr/registry.js.map +7 -0
- package/dist/bundler/hmr/transform.js +30 -0
- package/dist/bundler/hmr/transform.js.map +7 -0
- package/dist/bundler/index.js +103 -0
- package/dist/bundler/index.js.map +7 -0
- package/dist/bundler/injector.js +75 -0
- package/dist/bundler/injector.js.map +7 -0
- package/dist/bundler/lifecycle.js +56 -0
- package/dist/bundler/lifecycle.js.map +7 -0
- package/dist/bundler/projection.js +92 -0
- package/dist/bundler/projection.js.map +7 -0
- package/dist/bundler/query.js +302 -0
- package/dist/bundler/query.js.map +7 -0
- package/dist/bundler/ref.js +16 -0
- package/dist/bundler/ref.js.map +7 -0
- package/dist/bundler/resource.js +99 -0
- package/dist/bundler/resource.js.map +7 -0
- package/dist/bundler/settle.js +43 -0
- package/dist/bundler/settle.js.map +7 -0
- package/dist/bundler/signal.js +403 -0
- package/dist/bundler/signal.js.map +7 -0
- package/dist/bundler/template-audit.js +162 -0
- package/dist/bundler/template-audit.js.map +7 -0
- package/dist/bundler/template.js +847 -0
- package/dist/bundler/template.js.map +7 -0
- package/dist/bundler/view-transition.js +20 -0
- package/dist/bundler/view-transition.js.map +7 -0
- package/dist/bundler/vite-hmr/plugin.js +32 -0
- package/dist/bundler/vite-hmr/plugin.js.map +7 -0
- package/dist/bundler/vite-hmr/runtime.js +8 -0
- package/dist/bundler/vite-hmr/runtime.js.map +7 -0
- package/dist/index.js +2607 -44
- package/dist/index.js.map +7 -1
- package/dist/index.production.js +2 -0
- package/dist/index.production.js.map +6 -0
- package/dist/{diagnostics.d.ts → types/diagnostics.d.ts} +8 -15
- package/dist/{index.d.ts → types/index.d.ts} +1 -0
- package/dist/{template-audit.d.ts → types/template-audit.d.ts} +4 -5
- package/dist/{template.d.ts → types/template.d.ts} +3 -15
- package/package.json +12 -9
- package/dist/component.js +0 -633
- package/dist/component.js.map +0 -1
- package/dist/context.js +0 -55
- package/dist/context.js.map +0 -1
- package/dist/diagnostics.js +0 -118
- package/dist/diagnostics.js.map +0 -1
- package/dist/disposable.js +0 -8
- package/dist/disposable.js.map +0 -1
- package/dist/element-context.js +0 -108
- package/dist/element-context.js.map +0 -1
- package/dist/emitter.js +0 -91
- package/dist/emitter.js.map +0 -1
- package/dist/hmr/registry.js +0 -136
- package/dist/hmr/registry.js.map +0 -1
- package/dist/hmr/transform.js +0 -52
- package/dist/hmr/transform.js.map +0 -1
- package/dist/injector.js +0 -118
- package/dist/injector.js.map +0 -1
- package/dist/lifecycle.js +0 -117
- package/dist/lifecycle.js.map +0 -1
- package/dist/projection.js +0 -179
- package/dist/projection.js.map +0 -1
- package/dist/query.js +0 -429
- package/dist/query.js.map +0 -1
- package/dist/ref.js +0 -43
- package/dist/ref.js.map +0 -1
- package/dist/resource.js +0 -129
- package/dist/resource.js.map +0 -1
- package/dist/settle.js +0 -106
- package/dist/settle.js.map +0 -1
- package/dist/signal.js +0 -645
- package/dist/signal.js.map +0 -1
- package/dist/template-audit.js +0 -246
- package/dist/template-audit.js.map +0 -1
- package/dist/template.js +0 -1218
- package/dist/template.js.map +0 -1
- package/dist/view-transition.js +0 -98
- package/dist/view-transition.js.map +0 -1
- package/dist/vite-hmr/plugin.js +0 -62
- package/dist/vite-hmr/plugin.js.map +0 -1
- package/dist/vite-hmr/runtime.js +0 -17
- package/dist/vite-hmr/runtime.js.map +0 -1
- /package/dist/{component.d.ts → types/component.d.ts} +0 -0
- /package/dist/{context.d.ts → types/context.d.ts} +0 -0
- /package/dist/{disposable.d.ts → types/disposable.d.ts} +0 -0
- /package/dist/{element-context.d.ts → types/element-context.d.ts} +0 -0
- /package/dist/{emitter.d.ts → types/emitter.d.ts} +0 -0
- /package/dist/{hmr → types/hmr}/registry.d.ts +0 -0
- /package/dist/{hmr → types/hmr}/transform.d.ts +0 -0
- /package/dist/{injector.d.ts → types/injector.d.ts} +0 -0
- /package/dist/{lifecycle.d.ts → types/lifecycle.d.ts} +0 -0
- /package/dist/{projection.d.ts → types/projection.d.ts} +0 -0
- /package/dist/{query.d.ts → types/query.d.ts} +0 -0
- /package/dist/{ref.d.ts → types/ref.d.ts} +0 -0
- /package/dist/{resource.d.ts → types/resource.d.ts} +0 -0
- /package/dist/{settle.d.ts → types/settle.d.ts} +0 -0
- /package/dist/{signal.d.ts → types/signal.d.ts} +0 -0
- /package/dist/{view-transition.d.ts → types/view-transition.d.ts} +0 -0
- /package/dist/{vite-hmr → types/vite-hmr}/plugin.d.ts +0 -0
- /package/dist/{vite-hmr → types/vite-hmr}/runtime.d.ts +0 -0
package/dist/signal.js
DELETED
|
@@ -1,645 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* signal.ts — Reactive primitives: signal(), computed(), effect()
|
|
3
|
-
*
|
|
4
|
-
* Push-pull hybrid model:
|
|
5
|
-
* - Writes push dirty flags up the dependency graph in two flavors: a signal
|
|
6
|
-
* write pushes Dirty (the value definitely changed), a computed propagates
|
|
7
|
-
* MaybeDirty (recompute to find out). Flags never downgrade.
|
|
8
|
-
* - Reads pull fresh values lazily (computed only recalculates when read)
|
|
9
|
-
* - Multiple synchronous writes coalesce into one microtask flush
|
|
10
|
-
*
|
|
11
|
-
* Scheduler invariants (ADR 0030.2 T5):
|
|
12
|
-
* - An effect re-runs iff a value it read changed. Before a MaybeDirty
|
|
13
|
-
* effect runs, its computed sources are polled (recomputed via the
|
|
14
|
-
* node→impl back-pointer); if no source's change-epoch advanced past the
|
|
15
|
-
* effect's last completed run, the run is skipped. A computed's
|
|
16
|
-
* change-epoch also bumps on every error-state TRANSITION (enter and
|
|
17
|
-
* exit), so effects never skip across error entry or equal-value recovery
|
|
18
|
-
* (issue 0003 containment happens at the effect's own read).
|
|
19
|
-
* - Pending effects flush in creation order (monotonic index), so identical
|
|
20
|
-
* writes produce identical run order. Documented cost: a later-created
|
|
21
|
-
* writer effect costs one deterministic extra run vs. topological order.
|
|
22
|
-
* - The loop guard is clock-free: an effect that re-schedules ITSELF on
|
|
23
|
-
* MAX_EFFECT_RERUNS consecutive runs is diagnosed (N301) and disposed.
|
|
24
|
-
*
|
|
25
|
-
* Dependency tracking is automatic: reading a signal inside a computed
|
|
26
|
-
* or effect registers it as a dependency. Dependencies are re-tracked
|
|
27
|
-
* on every execution (dynamic/conditional tracking).
|
|
28
|
-
*/
|
|
29
|
-
// ── Late-bound context hook for auto-disposal ──────────────────────
|
|
30
|
-
// Avoids circular dependency: context.ts imports nothing from signal.ts,
|
|
31
|
-
// but signal.ts needs to check for component context to auto-dispose effects.
|
|
32
|
-
// component.ts wires this up at import time via `setContextHook()`.
|
|
33
|
-
let contextHook = null;
|
|
34
|
-
/**
|
|
35
|
-
* Register the context hook. Called by component.ts at module init.
|
|
36
|
-
* The hook returns an `addDisposer` function if inside setup context, null otherwise.
|
|
37
|
-
*/
|
|
38
|
-
export function setContextHook(hook) {
|
|
39
|
-
contextHook = hook;
|
|
40
|
-
}
|
|
41
|
-
// ── Brand symbol for signal detection in templates ──────────────────
|
|
42
|
-
export const SIGNAL_BRAND = Symbol.for('backlog.signal');
|
|
43
|
-
// ── Internal tracking state ─────────────────────────────────────────
|
|
44
|
-
/**
|
|
45
|
-
* The currently executing reactive context (computed or effect).
|
|
46
|
-
* When non-null, any signal read during execution is recorded as a dependency.
|
|
47
|
-
*/
|
|
48
|
-
let activeObserver = null;
|
|
49
|
-
/**
|
|
50
|
-
* The effect whose fn frame is currently executing. Unlike activeObserver
|
|
51
|
-
* (which switches to a computed during its recompute, and to null under
|
|
52
|
-
* untrack()), this stays pinned to the running effect — it exists solely to
|
|
53
|
-
* attribute writes to the effect that performed them (N302).
|
|
54
|
-
*/
|
|
55
|
-
let runningEffect = null;
|
|
56
|
-
/**
|
|
57
|
-
* Global epoch counter. Incremented on every observable change: a signal
|
|
58
|
-
* write, a computed recomputing to a different value, and a computed's
|
|
59
|
-
* error-state transitions (enter and exit). A node's `lastChanged` epoch is
|
|
60
|
-
* compared against an observer's last-validated/last-run epoch to decide
|
|
61
|
-
* staleness.
|
|
62
|
-
*/
|
|
63
|
-
let globalEpoch = 0;
|
|
64
|
-
/** Monotonic effect creation index — pending effects flush in this order. */
|
|
65
|
-
let nextEffectOrder = 0;
|
|
66
|
-
// ── Dev diagnostics ─────────────────────────────────────────────────
|
|
67
|
-
// Reporting goes through the diagnostics leaf (its dev gate governs);
|
|
68
|
-
// guard BEHAVIOR (loop disposal, rejection containment) is never gated —
|
|
69
|
-
// only the reporting. Assigned codes: N301 effect loop, N302
|
|
70
|
-
// write-in-own-effect, N303 flush/tick cap, N310 effect(async).
|
|
71
|
-
import { diag as emitDiag, isDev } from './diagnostics.js';
|
|
72
|
-
import { disposable } from './disposable.js';
|
|
73
|
-
function diag(code, message, detail) {
|
|
74
|
-
if (!isDev())
|
|
75
|
-
return;
|
|
76
|
-
emitDiag(code, message, detail);
|
|
77
|
-
}
|
|
78
|
-
// ── Effect scheduling ────────────────────────────────────────────────
|
|
79
|
-
const pendingEffects = new Set();
|
|
80
|
-
let flushScheduled = false;
|
|
81
|
-
function scheduleFlush() {
|
|
82
|
-
if (!flushScheduled) {
|
|
83
|
-
flushScheduled = true;
|
|
84
|
-
queueMicrotask(flushPendingEffects);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
function flushPendingEffects() {
|
|
88
|
-
flushScheduled = false;
|
|
89
|
-
// Copy to avoid mutation during iteration; sort by creation index so
|
|
90
|
-
// identical writes produce identical run order forever (ADR 0030.2 T5).
|
|
91
|
-
const effects = [...pendingEffects].sort((a, b) => a.order - b.order);
|
|
92
|
-
pendingEffects.clear();
|
|
93
|
-
for (const effect of effects) {
|
|
94
|
-
if (!effect.disposed) {
|
|
95
|
-
runEffect(effect);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// ── Dependency graph node types ─────────────────────────────────────
|
|
100
|
-
var NodeState;
|
|
101
|
-
(function (NodeState) {
|
|
102
|
-
NodeState[NodeState["Clean"] = 0] = "Clean";
|
|
103
|
-
NodeState[NodeState["MaybeDirty"] = 1] = "MaybeDirty";
|
|
104
|
-
NodeState[NodeState["Dirty"] = 2] = "Dirty";
|
|
105
|
-
})(NodeState || (NodeState = {}));
|
|
106
|
-
const NO_COMPUTED_ERROR = Symbol('no-computed-error');
|
|
107
|
-
class SignalImpl {
|
|
108
|
-
[SIGNAL_BRAND] = true;
|
|
109
|
-
/** @internal */
|
|
110
|
-
_node;
|
|
111
|
-
constructor(initialValue) {
|
|
112
|
-
this._node = {
|
|
113
|
-
value: initialValue,
|
|
114
|
-
lastChanged: globalEpoch,
|
|
115
|
-
observers: new Set(),
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
get value() {
|
|
119
|
-
// Track dependency if inside a reactive context
|
|
120
|
-
if (activeObserver) {
|
|
121
|
-
activeObserver.sources.add(this._node);
|
|
122
|
-
this._node.observers.add(activeObserver);
|
|
123
|
-
}
|
|
124
|
-
return this._node.value;
|
|
125
|
-
}
|
|
126
|
-
set value(newValue) {
|
|
127
|
-
if (Object.is(this._node.value, newValue))
|
|
128
|
-
return;
|
|
129
|
-
// N302: write-in-own-sources — the running effect wrote a signal it also
|
|
130
|
-
// reads this run, so this write re-triggers it. Attribution-only (never
|
|
131
|
-
// disposes; the loop guard owns disposal). Placed AFTER the Object.is
|
|
132
|
-
// cutoff so certified converging writers — registry reflect effects,
|
|
133
|
-
// each() item-signal reuse — never warn on equal-value writes.
|
|
134
|
-
if (runningEffect !== null &&
|
|
135
|
-
runningEffect.sources.has(this._node)) {
|
|
136
|
-
diag('N302', 'Effect wrote to a signal it also reads — the write re-schedules the ' +
|
|
137
|
-
'effect. If this does not converge to an equal value it is an ' +
|
|
138
|
-
'infinite loop. Derive the value with computed() instead.', runningEffect.createdAt ? { effect: runningEffect.createdAt } : undefined);
|
|
139
|
-
}
|
|
140
|
-
this._node.value = newValue;
|
|
141
|
-
this._node.lastChanged = ++globalEpoch;
|
|
142
|
-
notifyObservers(this._node.observers, NodeState.Dirty);
|
|
143
|
-
}
|
|
144
|
-
peek() {
|
|
145
|
-
return this._node.value;
|
|
146
|
-
}
|
|
147
|
-
subscribe(fn) {
|
|
148
|
-
return effect(() => {
|
|
149
|
-
const value = this.value;
|
|
150
|
-
// A subscription depends on THIS signal only. Reads performed by the
|
|
151
|
-
// consumer callback are observational work, not reactive dependencies
|
|
152
|
-
// of the subscription itself (issue 0004).
|
|
153
|
-
untrack(() => fn(value));
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function notifyObservers(observers, flavor) {
|
|
158
|
-
for (const observer of observers) {
|
|
159
|
-
observer.notify(flavor);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
class ComputedImpl {
|
|
163
|
-
[SIGNAL_BRAND] = true;
|
|
164
|
-
/** @internal */
|
|
165
|
-
_node;
|
|
166
|
-
compute;
|
|
167
|
-
state = NodeState.Dirty; // Start dirty so first read computes
|
|
168
|
-
sources = new Set();
|
|
169
|
-
computing = false;
|
|
170
|
-
error = NO_COMPUTED_ERROR;
|
|
171
|
-
/**
|
|
172
|
-
* globalEpoch snapshot at the end of the last update()/validation pass.
|
|
173
|
-
* A MaybeDirty computed recomputes only if some source's lastChanged
|
|
174
|
-
* advanced past this — otherwise it revalidates to Clean for free.
|
|
175
|
-
*/
|
|
176
|
-
lastValidated = 0;
|
|
177
|
-
constructor(fn) {
|
|
178
|
-
this.compute = fn;
|
|
179
|
-
this._node = {
|
|
180
|
-
value: undefined,
|
|
181
|
-
lastChanged: 0,
|
|
182
|
-
observers: new Set(),
|
|
183
|
-
pull: () => { this.peek(); },
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
get value() {
|
|
187
|
-
if (this.computing) {
|
|
188
|
-
throw new Error('Circular dependency detected in computed()');
|
|
189
|
-
}
|
|
190
|
-
// Track dependency if inside a reactive context
|
|
191
|
-
if (activeObserver) {
|
|
192
|
-
activeObserver.sources.add(this._node);
|
|
193
|
-
this._node.observers.add(activeObserver);
|
|
194
|
-
}
|
|
195
|
-
// Pull: recalculate if (maybe) dirty
|
|
196
|
-
if (this.state !== NodeState.Clean) {
|
|
197
|
-
this.update();
|
|
198
|
-
}
|
|
199
|
-
if (this.error !== NO_COMPUTED_ERROR) {
|
|
200
|
-
throw this.error;
|
|
201
|
-
}
|
|
202
|
-
return this._node.value;
|
|
203
|
-
}
|
|
204
|
-
peek() {
|
|
205
|
-
if (this.computing) {
|
|
206
|
-
throw new Error('Circular dependency detected in computed()');
|
|
207
|
-
}
|
|
208
|
-
// Same pull as `get value`, minus dependency registration.
|
|
209
|
-
if (this.state !== NodeState.Clean) {
|
|
210
|
-
this.update();
|
|
211
|
-
}
|
|
212
|
-
if (this.error !== NO_COMPUTED_ERROR) {
|
|
213
|
-
throw this.error;
|
|
214
|
-
}
|
|
215
|
-
return this._node.value;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* MaybeDirty validation: pull each source (computeds recompute lazily) and
|
|
219
|
-
* report whether any source's change-epoch advanced past our last
|
|
220
|
-
* validation. A pulled source may throw — its error-state transition
|
|
221
|
-
* already bumped its change-epoch, so the epoch comparison decides.
|
|
222
|
-
*/
|
|
223
|
-
sourcesChanged() {
|
|
224
|
-
for (const source of this.sources) {
|
|
225
|
-
if ('pull' in source) {
|
|
226
|
-
try {
|
|
227
|
-
source.pull();
|
|
228
|
-
}
|
|
229
|
-
catch (_) { /* transition bumped lastChanged */ }
|
|
230
|
-
}
|
|
231
|
-
if (source.lastChanged > this.lastValidated)
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
update() {
|
|
237
|
-
// MaybeDirty means "an upstream computed MAY have changed". Validate
|
|
238
|
-
// first: if no polled source advanced, revalidate to Clean without
|
|
239
|
-
// recomputing (the half of push-pull that was previously unimplemented).
|
|
240
|
-
if (this.state === NodeState.MaybeDirty && !this.sourcesChanged()) {
|
|
241
|
-
this.state = NodeState.Clean;
|
|
242
|
-
this.lastValidated = globalEpoch;
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
// Unsubscribe from previous sources (for dynamic dependency tracking)
|
|
246
|
-
for (const source of this.sources) {
|
|
247
|
-
source.observers.delete(this);
|
|
248
|
-
}
|
|
249
|
-
this.sources.clear();
|
|
250
|
-
// Run compute with tracking
|
|
251
|
-
const prevObserver = activeObserver;
|
|
252
|
-
activeObserver = this;
|
|
253
|
-
this.computing = true;
|
|
254
|
-
const wasError = this.error !== NO_COMPUTED_ERROR;
|
|
255
|
-
try {
|
|
256
|
-
const newValue = this.compute();
|
|
257
|
-
this.error = NO_COMPUTED_ERROR;
|
|
258
|
-
if (!Object.is(this._node.value, newValue)) {
|
|
259
|
-
this._node.value = newValue;
|
|
260
|
-
this._node.lastChanged = ++globalEpoch;
|
|
261
|
-
// NOTE: no notifyObservers() here. This update() is a *lazy* recompute
|
|
262
|
-
// triggered by a read; every downstream observer was already marked
|
|
263
|
-
// dirty / scheduled eagerly when the source signal changed (notify()
|
|
264
|
-
// propagates through the computed chain). Re-notifying here would
|
|
265
|
-
// re-schedule the very effect performing this read — a spurious
|
|
266
|
-
// double-run that only surfaced once flush() began draining cascades.
|
|
267
|
-
}
|
|
268
|
-
else if (wasError) {
|
|
269
|
-
// Error-state TRANSITION (exit) recovering to an EQUAL value: the
|
|
270
|
-
// epoch must still advance, or downstream effects would skip the
|
|
271
|
-
// recovery in their pre-run poll (ADR 0030.2 §8 T5 error rule).
|
|
272
|
-
this._node.lastChanged = ++globalEpoch;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
catch (error) {
|
|
276
|
-
this.error = error;
|
|
277
|
-
if (!wasError) {
|
|
278
|
-
// Error-state TRANSITION (enter) counts as a change: polls must see
|
|
279
|
-
// the epoch advance so the effect re-runs and its own read rethrows
|
|
280
|
-
// into the effect's containment (issue 0003 semantics).
|
|
281
|
-
this._node.lastChanged = ++globalEpoch;
|
|
282
|
-
}
|
|
283
|
-
throw error;
|
|
284
|
-
}
|
|
285
|
-
finally {
|
|
286
|
-
this.computing = false;
|
|
287
|
-
activeObserver = prevObserver;
|
|
288
|
-
// A failed computed remains in an error state, but it must look clean to
|
|
289
|
-
// notify(): the next dependency write then marks it dirty and propagates
|
|
290
|
-
// to downstream observers so the computation can recover (issue 0003).
|
|
291
|
-
this.state = NodeState.Clean;
|
|
292
|
-
this.lastValidated = globalEpoch;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
/** @internal — called by the ReactiveNode interface when a source changes */
|
|
296
|
-
notify(flavor) {
|
|
297
|
-
// Never downgrade: a Dirty mark (definite signal change) survives a
|
|
298
|
-
// later MaybeDirty from a parallel computed path.
|
|
299
|
-
if (flavor > this.state) {
|
|
300
|
-
const wasClean = this.state === NodeState.Clean;
|
|
301
|
-
this.state = flavor;
|
|
302
|
-
// Propagate once per dirty episode. Downstream observers always get
|
|
303
|
-
// MaybeDirty — through a computed, "changed" is only knowable after a
|
|
304
|
-
// recompute, which stays lazy (pull-based).
|
|
305
|
-
if (wasClean) {
|
|
306
|
-
notifyObservers(this._node.observers, NodeState.MaybeDirty);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
subscribe(fn) {
|
|
311
|
-
return effect(() => {
|
|
312
|
-
const value = this.value;
|
|
313
|
-
untrack(() => fn(value));
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
// ReactiveNode interface — used by dependency tracking
|
|
317
|
-
get sources_() {
|
|
318
|
-
return this.sources;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// Make ComputedImpl satisfy ReactiveNode for the dependency tracker
|
|
322
|
-
Object.defineProperty(ComputedImpl.prototype, 'sources', {
|
|
323
|
-
enumerable: false,
|
|
324
|
-
});
|
|
325
|
-
// ── Effect (side-effect, auto-tracks, auto-disposes) ────────────────
|
|
326
|
-
/**
|
|
327
|
-
* Maximum CONSECUTIVE self-re-schedules before we assume an infinite loop.
|
|
328
|
-
* An effect that writes to a signal it reads re-schedules itself on every
|
|
329
|
-
* run; when that happens MAX_EFFECT_RERUNS times in a row (the counter
|
|
330
|
-
* resets whenever a run does NOT re-schedule the effect), the effect is
|
|
331
|
-
* diagnosed (N301) and disposed. Clock-free — deterministic under CI and
|
|
332
|
-
* fake timers, and convergent clamps pass because their second run writes
|
|
333
|
-
* an equal value (Object.is cutoff → no re-schedule → counter reset).
|
|
334
|
-
* See ADR 0008 Gap 2 / ADR 0009 / ADR 0030.2 T5.
|
|
335
|
-
*/
|
|
336
|
-
const MAX_EFFECT_RERUNS = 100;
|
|
337
|
-
function createEffectNode(fn) {
|
|
338
|
-
return {
|
|
339
|
-
state: NodeState.Dirty,
|
|
340
|
-
fn,
|
|
341
|
-
cleanup: null,
|
|
342
|
-
disposed: false,
|
|
343
|
-
sources: new Set(),
|
|
344
|
-
disposers: [],
|
|
345
|
-
order: nextEffectOrder++,
|
|
346
|
-
lastRunEpoch: 0,
|
|
347
|
-
selfReschedules: 0,
|
|
348
|
-
notify(flavor) {
|
|
349
|
-
if (this.disposed)
|
|
350
|
-
return;
|
|
351
|
-
// Never downgrade Dirty (definite signal change) to MaybeDirty.
|
|
352
|
-
if (flavor > this.state)
|
|
353
|
-
this.state = flavor;
|
|
354
|
-
pendingEffects.add(this);
|
|
355
|
-
scheduleFlush();
|
|
356
|
-
},
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Pre-run poll (ADR 0030.2 T5): the effect was notified MaybeDirty, meaning
|
|
361
|
-
* only computed sources MAY have changed. Pull each computed source (via the
|
|
362
|
-
* node back-pointer) so its change-epoch is fresh, then compare every
|
|
363
|
-
* source's epoch against the effect's last completed run. A pull may throw:
|
|
364
|
-
* the computed's error-state transition already bumped its epoch, so the
|
|
365
|
-
* comparison decides — a NEW error re-runs the effect (whose own read
|
|
366
|
-
* rethrows into its containment, issue 0003), while an error the effect
|
|
367
|
-
* already observed does not.
|
|
368
|
-
*/
|
|
369
|
-
function effectSourcesChanged(node) {
|
|
370
|
-
for (const source of node.sources) {
|
|
371
|
-
if ('pull' in source) {
|
|
372
|
-
try {
|
|
373
|
-
source.pull();
|
|
374
|
-
}
|
|
375
|
-
catch (_) { /* transition bumped lastChanged */ }
|
|
376
|
-
}
|
|
377
|
-
if (source.lastChanged > node.lastRunEpoch)
|
|
378
|
-
return true;
|
|
379
|
-
}
|
|
380
|
-
return false;
|
|
381
|
-
}
|
|
382
|
-
function isThenable(value) {
|
|
383
|
-
return (value !== null &&
|
|
384
|
-
typeof value === 'object' &&
|
|
385
|
-
typeof value.then === 'function');
|
|
386
|
-
}
|
|
387
|
-
function runEffect(node) {
|
|
388
|
-
if (node.disposed)
|
|
389
|
-
return;
|
|
390
|
-
// MaybeDirty: poll sources — skip the run when no value the effect read
|
|
391
|
-
// actually changed (equal recomputes through a computed chain stop here).
|
|
392
|
-
if (node.state === NodeState.MaybeDirty && !effectSourcesChanged(node)) {
|
|
393
|
-
node.state = NodeState.Clean;
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
// Run cleanup from previous execution
|
|
397
|
-
if (node.cleanup) {
|
|
398
|
-
try {
|
|
399
|
-
node.cleanup();
|
|
400
|
-
}
|
|
401
|
-
catch (_) { /* cleanup errors are swallowed */ }
|
|
402
|
-
node.cleanup = null;
|
|
403
|
-
}
|
|
404
|
-
// Unsubscribe from previous sources
|
|
405
|
-
for (const source of node.sources) {
|
|
406
|
-
source.observers.delete(node);
|
|
407
|
-
}
|
|
408
|
-
node.sources.clear();
|
|
409
|
-
// Reset state BEFORE running: a notify fired by the effect's own writes
|
|
410
|
-
// must survive into the next flush pass, not be clobbered afterwards.
|
|
411
|
-
node.state = NodeState.Clean;
|
|
412
|
-
// Run effect with tracking
|
|
413
|
-
const prevObserver = activeObserver;
|
|
414
|
-
const prevRunning = runningEffect;
|
|
415
|
-
activeObserver = node;
|
|
416
|
-
runningEffect = node;
|
|
417
|
-
try {
|
|
418
|
-
const result = node.fn();
|
|
419
|
-
if (typeof result === 'function') {
|
|
420
|
-
node.cleanup = result;
|
|
421
|
-
}
|
|
422
|
-
else if (isThenable(result)) {
|
|
423
|
-
// effect(async …) — rejected at the type level, guarded at runtime for
|
|
424
|
-
// JS callers (ADR 0030.2 §3). The Promise is NOT a cleanup; route its
|
|
425
|
-
// rejection into the effect error path so nothing goes unhandled.
|
|
426
|
-
if (!node.asyncWarned) {
|
|
427
|
-
node.asyncWarned = true;
|
|
428
|
-
diag('N310', 'effect() callback returned a Promise — effects must be synchronous. ' +
|
|
429
|
-
'Async state belongs in resource(). The returned Promise is not a ' +
|
|
430
|
-
'cleanup function; its rejection is contained by the effect error path.', node.createdAt ? { effect: node.createdAt } : undefined);
|
|
431
|
-
}
|
|
432
|
-
result.then(undefined, (err) => {
|
|
433
|
-
console.error('Effect error:', err);
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
catch (err) {
|
|
438
|
-
// Effect errors: log but don't crash the system.
|
|
439
|
-
// The effect is NOT disposed — it may succeed on next signal change.
|
|
440
|
-
console.error('Effect error:', err);
|
|
441
|
-
}
|
|
442
|
-
finally {
|
|
443
|
-
activeObserver = prevObserver;
|
|
444
|
-
runningEffect = prevRunning;
|
|
445
|
-
// Everything observable up to now — including epochs bumped by this
|
|
446
|
-
// run's own lazy computed pulls — counts as SEEN by this run.
|
|
447
|
-
node.lastRunEpoch = globalEpoch;
|
|
448
|
-
}
|
|
449
|
-
// Clock-free loop guard: this run re-scheduled the effect iff the effect
|
|
450
|
-
// is back in the pending set (only its own writes can do that mid-run).
|
|
451
|
-
if (pendingEffects.has(node)) {
|
|
452
|
-
if (++node.selfReschedules > MAX_EFFECT_RERUNS) {
|
|
453
|
-
diag('N301', `Effect exceeded maximum re-run limit (${MAX_EFFECT_RERUNS}). ` +
|
|
454
|
-
`This usually means the effect writes to a signal it reads. ` +
|
|
455
|
-
`The effect has been disposed to prevent a UI freeze.`, node.createdAt ? { effect: node.createdAt } : undefined);
|
|
456
|
-
// Dispose as today: unsubscribe everywhere and drop from the queue.
|
|
457
|
-
node.disposed = true;
|
|
458
|
-
for (const source of node.sources) {
|
|
459
|
-
source.observers.delete(node);
|
|
460
|
-
}
|
|
461
|
-
node.sources.clear();
|
|
462
|
-
pendingEffects.delete(node);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
else {
|
|
466
|
-
node.selfReschedules = 0;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
// ── Public API ──────────────────────────────────────────────────────
|
|
470
|
-
/**
|
|
471
|
-
* Create a writable reactive signal.
|
|
472
|
-
*
|
|
473
|
-
* ```ts
|
|
474
|
-
* const count = signal(0);
|
|
475
|
-
* count.value; // read (auto-tracks in reactive contexts)
|
|
476
|
-
* count.value = 5; // write (notifies dependents)
|
|
477
|
-
* count.peek(); // read WITHOUT tracking
|
|
478
|
-
* ```
|
|
479
|
-
*/
|
|
480
|
-
export function signal(initialValue) {
|
|
481
|
-
return new SignalImpl(initialValue);
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Create a derived, lazy, cached computed signal.
|
|
485
|
-
* Re-evaluates only when dependencies change AND the value is read.
|
|
486
|
-
*
|
|
487
|
-
* ```ts
|
|
488
|
-
* const doubled = computed(() => count.value * 2);
|
|
489
|
-
* doubled.value; // lazy evaluation
|
|
490
|
-
* ```
|
|
491
|
-
*/
|
|
492
|
-
export function computed(fn) {
|
|
493
|
-
return new ComputedImpl(fn);
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* Create a side-effect that re-runs when its dependencies change.
|
|
497
|
-
* Returns a dispose function to stop the effect.
|
|
498
|
-
*
|
|
499
|
-
* The effect function may return a cleanup callback that runs
|
|
500
|
-
* before each re-execution and on disposal. It must be SYNCHRONOUS —
|
|
501
|
-
* async functions are rejected at the type level and diagnosed at
|
|
502
|
-
* runtime (N310); async state belongs in resource().
|
|
503
|
-
*
|
|
504
|
-
* ```ts
|
|
505
|
-
* const dispose = effect(() => {
|
|
506
|
-
* console.log('count is', count.value);
|
|
507
|
-
* return () => { // cleanup
|
|
508
|
-
* console.log('cleaning up');
|
|
509
|
-
* };
|
|
510
|
-
* });
|
|
511
|
-
* dispose(); // stop the effect
|
|
512
|
-
* ```
|
|
513
|
-
*/
|
|
514
|
-
export function effect(fn, ..._rejectAsync) {
|
|
515
|
-
const node = createEffectNode(fn);
|
|
516
|
-
if (isDev()) {
|
|
517
|
-
// Dev-captured effect identity: N301/N302 diagnostics name this site.
|
|
518
|
-
node.createdAt = new Error('effect() created here').stack;
|
|
519
|
-
}
|
|
520
|
-
// Run immediately to establish initial dependencies
|
|
521
|
-
runEffect(node);
|
|
522
|
-
const dispose = () => {
|
|
523
|
-
node.disposed = true;
|
|
524
|
-
// Run final cleanup
|
|
525
|
-
if (node.cleanup) {
|
|
526
|
-
try {
|
|
527
|
-
node.cleanup();
|
|
528
|
-
}
|
|
529
|
-
catch (_) { /* swallow */ }
|
|
530
|
-
node.cleanup = null;
|
|
531
|
-
}
|
|
532
|
-
// Unsubscribe from all sources
|
|
533
|
-
for (const source of node.sources) {
|
|
534
|
-
source.observers.delete(node);
|
|
535
|
-
}
|
|
536
|
-
node.sources.clear();
|
|
537
|
-
pendingEffects.delete(node);
|
|
538
|
-
};
|
|
539
|
-
// Auto-dispose when inside component setup context
|
|
540
|
-
if (contextHook) {
|
|
541
|
-
const addDisposer = contextHook();
|
|
542
|
-
if (addDisposer) {
|
|
543
|
-
addDisposer(dispose);
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
return disposable(dispose, dispose);
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Check if a value is a signal (writable or computed).
|
|
550
|
-
* Used by the template engine to detect signals in expression slots.
|
|
551
|
-
*/
|
|
552
|
-
export function isSignal(value) {
|
|
553
|
-
return (value !== null &&
|
|
554
|
-
typeof value === 'object' &&
|
|
555
|
-
SIGNAL_BRAND in value);
|
|
556
|
-
}
|
|
557
|
-
// ── Observer isolation ───────────────────────────────────────────────
|
|
558
|
-
/**
|
|
559
|
-
* Run a function with activeObserver set to null, preventing any
|
|
560
|
-
* signal reads inside `fn` from being tracked by an outer effect,
|
|
561
|
-
* and return the function's result.
|
|
562
|
-
*
|
|
563
|
-
* Used by component.ts to isolate connectedCallback: child component
|
|
564
|
-
* setup signal reads must not leak into a parent effect's dependency
|
|
565
|
-
* set. See ADR 0008 Gap 1.
|
|
566
|
-
*/
|
|
567
|
-
export function untrack(fn) {
|
|
568
|
-
const prev = activeObserver;
|
|
569
|
-
activeObserver = null;
|
|
570
|
-
try {
|
|
571
|
-
return fn();
|
|
572
|
-
}
|
|
573
|
-
finally {
|
|
574
|
-
activeObserver = prev;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
// ── Synchronous flush ───────────────────────────────────────────────
|
|
578
|
-
/**
|
|
579
|
-
* Synchronously execute all pending effects.
|
|
580
|
-
*
|
|
581
|
-
* In normal usage, effects run automatically on the next microtask.
|
|
582
|
-
* Use flush() only when you need effects to have executed before
|
|
583
|
-
* the next line — e.g., imperative DOM measurement after state change.
|
|
584
|
-
*
|
|
585
|
-
* flush() is idempotent: calling it with no pending effects is a no-op.
|
|
586
|
-
*/
|
|
587
|
-
export function flush() {
|
|
588
|
-
// Drain cascades: an effect may write a signal that schedules more effects
|
|
589
|
-
// (e.g. A computes → B renders). Loop until the queue is empty so a single
|
|
590
|
-
// flush() settles the whole synchronous cascade — no double-flush idiom.
|
|
591
|
-
// Bounded to mirror the effect-loop guard; a runaway is a bug, not silence.
|
|
592
|
-
let guard = 0;
|
|
593
|
-
while (pendingEffects.size > 0) {
|
|
594
|
-
flushPendingEffects();
|
|
595
|
-
if (++guard > 100000) {
|
|
596
|
-
diag('N303', 'flush() cascade cap reached (100000 passes) — effects keep ' +
|
|
597
|
-
'scheduling more effects (a cross-effect write cycle?). Breaking out ' +
|
|
598
|
-
'to avoid a freeze; pending work remains unflushed.');
|
|
599
|
-
break;
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
/** Backward compat alias for tests. */
|
|
604
|
-
export { flush as flushEffects };
|
|
605
|
-
/**
|
|
606
|
-
* Settle the synchronous effect cascade AND all MICROTASK-scheduled work
|
|
607
|
-
* pending at await time (content-projection sweeps, query/command initial
|
|
608
|
-
* passes — at any queueMicrotask depth), plus the effects that work
|
|
609
|
-
* schedules. Replaces the hand-rolled `flush(); await Promise.resolve();
|
|
610
|
-
* flush()` and double-`flushEffects()` idioms.
|
|
611
|
-
*
|
|
612
|
-
* Bounded contract — deliberately NOT awaited: timers and other future
|
|
613
|
-
* TASKS scheduled by that microtask work (e.g. a microtask calling
|
|
614
|
-
* setTimeout) may fire after tick() resolves; awaiting arbitrary future
|
|
615
|
-
* tasks is unbounded. Self-perpetuating schedulers are cut off at the
|
|
616
|
-
* iteration cap (loudly — N303).
|
|
617
|
-
*
|
|
618
|
-
* ```ts
|
|
619
|
-
* host.setProp('x', 1);
|
|
620
|
-
* await tick();
|
|
621
|
-
* expect(el.textContent).toBe('1');
|
|
622
|
-
* ```
|
|
623
|
-
*/
|
|
624
|
-
export async function tick() {
|
|
625
|
-
flush(); // drain the synchronous effect cascade first
|
|
626
|
-
// Each iteration crosses a MACROTASK boundary (setTimeout 0). Doing so runs
|
|
627
|
-
// the ENTIRE microtask queue to completion first — including microtasks a
|
|
628
|
-
// microtask schedules, at any depth — so a 3-deep `queueMicrotask` chain is
|
|
629
|
-
// fully drained before the timer fires. After the drain we flush the effects
|
|
630
|
-
// that work scheduled. When a full iteration schedules no effects, the queue
|
|
631
|
-
// is quiescent and we return. Contract: microtask-scheduled work + effect
|
|
632
|
-
// cascades pending at await time settle; TIMER-scheduled work does not
|
|
633
|
-
// (see the doc above — bounded by design). The iteration cap is a
|
|
634
|
-
// documented backstop for self-perpetuating schedulers, not a silent hang.
|
|
635
|
-
for (let i = 0; i < 50; i++) {
|
|
636
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
637
|
-
if (pendingEffects.size === 0)
|
|
638
|
-
return; // the microtask drain scheduled nothing
|
|
639
|
-
flush();
|
|
640
|
-
}
|
|
641
|
-
diag('N303', 'tick() iteration cap (50) reached with effects still pending — ' +
|
|
642
|
-
'something keeps scheduling reactive work every task (a ' +
|
|
643
|
-
'self-perpetuating scheduler?). Returning with work still queued.');
|
|
644
|
-
}
|
|
645
|
-
//# sourceMappingURL=signal.js.map
|
package/dist/signal.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"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"}
|