react-fine-grained-signals 0.1.1 → 0.2.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/LICENSE-ALIEN-SIGNALS.txt +21 -0
- package/README.ja.md +17 -10
- package/README.md +18 -10
- package/dist/base-WD_74mfC.js +55 -0
- package/dist/base-WD_74mfC.js.map +1 -0
- package/dist/core-runtime-2jSE9Tz5.js +1354 -0
- package/dist/core-runtime-2jSE9Tz5.js.map +1 -0
- package/dist/index.d.ts +20 -25
- package/dist/index.js +4 -4
- package/dist/{jsx-Xp5q2y97.d.ts → jsx-BQGrTir3.d.ts} +40 -5
- package/dist/jsx-P6volZdr.js +1833 -0
- package/dist/jsx-P6volZdr.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +3 -3
- package/dist/jsx-dev-runtime.js +1 -1
- package/dist/jsx-runtime.d.ts +4 -4
- package/dist/jsx-runtime.js +1 -1
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +2 -2
- package/dist/use-signals-C1K8-vJX.js +169 -0
- package/dist/use-signals-C1K8-vJX.js.map +1 -0
- package/dist/use-signals-CJYcdFdL.d.ts +11 -0
- package/dist/utils.d.ts +14 -15
- package/dist/utils.js +6 -6
- package/dist/utils.js.map +1 -1
- package/package.json +22 -18
- package/dist/base-BZTnpU8U.js +0 -286
- package/dist/base-BZTnpU8U.js.map +0 -1
- package/dist/hooks-BFIWh7AD.js +0 -914
- package/dist/hooks-BFIWh7AD.js.map +0 -1
- package/dist/jsx-D9U6dSwL.js +0 -730
- package/dist/jsx-D9U6dSwL.js.map +0 -1
- package/dist/render-tracking-DCzw57BW.js +0 -96
- package/dist/render-tracking-DCzw57BW.js.map +0 -1
- package/dist/use-signals-8i2B-94o.js +0 -173
- package/dist/use-signals-8i2B-94o.js.map +0 -1
- package/dist/use-signals-CBDbbAbV.d.ts +0 -24
|
@@ -0,0 +1,1354 @@
|
|
|
1
|
+
import { createReactiveSystem } from "alien-signals/system";
|
|
2
|
+
//#region src/core/execution-owner.ts
|
|
3
|
+
const UNTRACKED_OWNER = Symbol.for("react-fine-grained-signals.untracked-owner.v2");
|
|
4
|
+
function isGraphExecutionOwner(owner) {
|
|
5
|
+
return typeof owner === "object" && owner !== null && owner.kind === "graph";
|
|
6
|
+
}
|
|
7
|
+
function isRenderExecutionOwner(owner) {
|
|
8
|
+
return typeof owner === "object" && owner !== null && owner.kind === "render";
|
|
9
|
+
}
|
|
10
|
+
const CONTEXT_KEY = Symbol.for("react-fine-grained-signals.shared-execution-owner.v2");
|
|
11
|
+
const globalObject = globalThis;
|
|
12
|
+
const existing = globalObject[CONTEXT_KEY];
|
|
13
|
+
if (existing !== void 0 && existing.version !== 2) throw new Error("Incompatible RFSG shared execution owner");
|
|
14
|
+
const executionContext = existing ?? {
|
|
15
|
+
version: 2,
|
|
16
|
+
owner: void 0,
|
|
17
|
+
frames: []
|
|
18
|
+
};
|
|
19
|
+
executionContext.frames ??= [];
|
|
20
|
+
if (existing === void 0) Object.defineProperty(globalObject, CONTEXT_KEY, {
|
|
21
|
+
value: executionContext,
|
|
22
|
+
enumerable: false,
|
|
23
|
+
configurable: false,
|
|
24
|
+
writable: false
|
|
25
|
+
});
|
|
26
|
+
/** Temporarily changes lexical ownership inside one synchronous call. */
|
|
27
|
+
function withSynchronousExecutionOwner(owner, callback) {
|
|
28
|
+
const previous = executionContext.owner;
|
|
29
|
+
executionContext.owner = owner;
|
|
30
|
+
try {
|
|
31
|
+
return callback();
|
|
32
|
+
} finally {
|
|
33
|
+
executionContext.owner = previous;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function pushExecutionOwner(owner) {
|
|
37
|
+
const frame = {
|
|
38
|
+
owner,
|
|
39
|
+
active: true
|
|
40
|
+
};
|
|
41
|
+
executionContext.frames.push(frame);
|
|
42
|
+
executionContext.owner = owner;
|
|
43
|
+
let active = true;
|
|
44
|
+
return () => {
|
|
45
|
+
if (!active) return;
|
|
46
|
+
active = false;
|
|
47
|
+
frame.active = false;
|
|
48
|
+
while (executionContext.frames.at(-1)?.active === false) executionContext.frames.pop();
|
|
49
|
+
executionContext.owner = executionContext.frames.at(-1)?.owner;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/core/interop-context.mts
|
|
54
|
+
const READABLE_INTEROP_V1$1 = Symbol.for("react-fine-grained-signals.readable-interop.v1");
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/core/foreign-readable-v1.mts
|
|
57
|
+
/** A render owner records another copy's read under its protocol object itself. */
|
|
58
|
+
function isReadableProtocol(value) {
|
|
59
|
+
return typeof value === "object" && value !== null && Reflect.get(value, "version") === 1 && typeof Reflect.get(value, "getRevision") === "function" && typeof Reflect.get(value, "subscribe") === "function";
|
|
60
|
+
}
|
|
61
|
+
function observeRevision(node) {
|
|
62
|
+
return node.renderRevision ??= 0;
|
|
63
|
+
}
|
|
64
|
+
function createForeignReadableAdapter({ runtimeToken, makeNode, mutableFlag, dirtyFlag, getActiveSubscriber, link, propagate, shallowPropagate, flush, isRunning, isBatching, effect, own }) {
|
|
65
|
+
const readableNodes = /* @__PURE__ */ new WeakMap();
|
|
66
|
+
const foreignNodes = /* @__PURE__ */ new WeakMap();
|
|
67
|
+
const localReadable = Symbol("localReadable");
|
|
68
|
+
function getLocalReadableRevision() {
|
|
69
|
+
const readable = this[localReadable];
|
|
70
|
+
const node = readableNodes.get(readable);
|
|
71
|
+
try {
|
|
72
|
+
withSynchronousExecutionOwner(UNTRACKED_OWNER, () => readable.value);
|
|
73
|
+
} catch {}
|
|
74
|
+
return observeRevision(node);
|
|
75
|
+
}
|
|
76
|
+
function subscribeLocalReadable(listener) {
|
|
77
|
+
const readable = this[localReadable];
|
|
78
|
+
const node = readableNodes.get(readable);
|
|
79
|
+
const revision = observeRevision(node);
|
|
80
|
+
let initial = true;
|
|
81
|
+
return {
|
|
82
|
+
unsubscribe: effect(() => {
|
|
83
|
+
try {
|
|
84
|
+
readable.value;
|
|
85
|
+
} catch {}
|
|
86
|
+
if (initial) initial = false;
|
|
87
|
+
else listener(observeRevision(node));
|
|
88
|
+
}),
|
|
89
|
+
revision
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function advance(node, revision) {
|
|
93
|
+
if (revision === node.pendingRevision) return false;
|
|
94
|
+
node.pendingRevision = revision;
|
|
95
|
+
node.flags = mutableFlag | dirtyFlag;
|
|
96
|
+
if (node.subs !== void 0) propagate(node.subs, isRunning());
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
function observeForeignRevision(node, revision) {
|
|
100
|
+
if (advance(node, revision)) {
|
|
101
|
+
node.revision = revision;
|
|
102
|
+
node.flags = mutableFlag;
|
|
103
|
+
if (node.subs !== void 0) shallowPropagate(node.subs);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function ensureForeignNode(protocol, observedRevision) {
|
|
107
|
+
let node = foreignNodes.get(protocol);
|
|
108
|
+
if (node === void 0) {
|
|
109
|
+
node = makeNode("external", mutableFlag, {
|
|
110
|
+
protocol,
|
|
111
|
+
revision: observedRevision,
|
|
112
|
+
pendingRevision: observedRevision,
|
|
113
|
+
unsubscribe: void 0
|
|
114
|
+
});
|
|
115
|
+
foreignNodes.set(protocol, node);
|
|
116
|
+
}
|
|
117
|
+
observeForeignRevision(node, observedRevision);
|
|
118
|
+
const subscriber = getActiveSubscriber();
|
|
119
|
+
if (subscriber?.kind === "computed") subscriber.foreignDependent = true;
|
|
120
|
+
if (subscriber !== void 0) link(node, subscriber);
|
|
121
|
+
if (subscriber?.kind === "effect" && activateForeignNode(node)) subscriber.flags |= 128;
|
|
122
|
+
return node;
|
|
123
|
+
}
|
|
124
|
+
function activateForeignNode(node) {
|
|
125
|
+
if (node.unsubscribe === void 0) {
|
|
126
|
+
const subscription = node.protocol.subscribe((revision) => {
|
|
127
|
+
if (revision !== node.revision) advance(node, revision);
|
|
128
|
+
if (!isBatching()) flush();
|
|
129
|
+
});
|
|
130
|
+
node.unsubscribe = subscription.unsubscribe;
|
|
131
|
+
if (advance(node, subscription.revision)) {
|
|
132
|
+
if (!isBatching()) flush();
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const graphOwner = {
|
|
138
|
+
version: 2,
|
|
139
|
+
kind: "graph",
|
|
140
|
+
runtimeToken,
|
|
141
|
+
add(protocol, revision) {
|
|
142
|
+
ensureForeignNode(protocol, revision);
|
|
143
|
+
},
|
|
144
|
+
own
|
|
145
|
+
};
|
|
146
|
+
function withGraphOwner(callback) {
|
|
147
|
+
const owner = executionContext.owner;
|
|
148
|
+
if (isGraphExecutionOwner(owner) && owner.runtimeToken === runtimeToken) return callback();
|
|
149
|
+
return withSynchronousExecutionOwner(graphOwner, callback);
|
|
150
|
+
}
|
|
151
|
+
function publishForeignReadable(readable, node, owner) {
|
|
152
|
+
if (owner === UNTRACKED_OWNER || (isGraphExecutionOwner(owner) || isRenderExecutionOwner(owner)) && owner.runtimeToken === runtimeToken) return;
|
|
153
|
+
const protocol = node.readableProtocol;
|
|
154
|
+
if (protocol !== void 0) {
|
|
155
|
+
if (isGraphExecutionOwner(owner) || isRenderExecutionOwner(owner)) owner.add(protocol, observeRevision(node));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function attachProtocol(readable, node) {
|
|
159
|
+
readableNodes.set(readable, node);
|
|
160
|
+
const protocol = {
|
|
161
|
+
version: 1,
|
|
162
|
+
runtimeToken,
|
|
163
|
+
[localReadable]: readable,
|
|
164
|
+
getRevision: getLocalReadableRevision,
|
|
165
|
+
subscribe: subscribeLocalReadable
|
|
166
|
+
};
|
|
167
|
+
node.readableProtocol = protocol;
|
|
168
|
+
Object.defineProperty(readable, READABLE_INTEROP_V1$1, {
|
|
169
|
+
value: protocol,
|
|
170
|
+
enumerable: false,
|
|
171
|
+
writable: false,
|
|
172
|
+
configurable: false
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function getReadableRevision(readable) {
|
|
176
|
+
const node = readableNodes.get(readable);
|
|
177
|
+
if (node !== void 0) return observeRevision(node);
|
|
178
|
+
const protocolValue = Reflect.get(readable, READABLE_INTEROP_V1$1);
|
|
179
|
+
if (isReadableProtocol(protocolValue)) return protocolValue.getRevision();
|
|
180
|
+
throw new TypeError("Unknown candidate readable");
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
attachProtocol,
|
|
184
|
+
ensureForeignNode,
|
|
185
|
+
activateForeignNode,
|
|
186
|
+
observeForeignRevision,
|
|
187
|
+
getNodeForReadable: (value) => readableNodes.get(value),
|
|
188
|
+
getReadableRevision,
|
|
189
|
+
observeRevision,
|
|
190
|
+
publishForeignReadable,
|
|
191
|
+
graphOwner,
|
|
192
|
+
withGraphOwner
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/core/interop.ts
|
|
197
|
+
const READABLE_INTEROP_V1 = Symbol.for("react-fine-grained-signals.readable-interop.v1");
|
|
198
|
+
const SHARED_CONTEXT_V1 = Symbol.for("react-fine-grained-signals.shared-interop-context.v1");
|
|
199
|
+
let cachedContext;
|
|
200
|
+
/** Resolve the tiny same-global context shared by duplicate module copies. */
|
|
201
|
+
function getSharedInteropContext() {
|
|
202
|
+
if (cachedContext !== void 0) return cachedContext;
|
|
203
|
+
const globalObject = globalThis;
|
|
204
|
+
const existing = globalObject[SHARED_CONTEXT_V1];
|
|
205
|
+
if (existing !== void 0) {
|
|
206
|
+
if (existing.version !== 1 || typeof existing.speculativeDepth !== "number") throw new Error("Incompatible react-fine-grained-signals interop context");
|
|
207
|
+
cachedContext = existing;
|
|
208
|
+
return existing;
|
|
209
|
+
}
|
|
210
|
+
const context = {
|
|
211
|
+
version: 1,
|
|
212
|
+
speculativeDepth: 0,
|
|
213
|
+
speculativeDeepReadEpoch: 0
|
|
214
|
+
};
|
|
215
|
+
Object.defineProperty(globalObject, SHARED_CONTEXT_V1, {
|
|
216
|
+
value: context,
|
|
217
|
+
enumerable: false,
|
|
218
|
+
configurable: false,
|
|
219
|
+
writable: false
|
|
220
|
+
});
|
|
221
|
+
cachedContext = context;
|
|
222
|
+
return context;
|
|
223
|
+
}
|
|
224
|
+
function getReadableInterop(readable) {
|
|
225
|
+
const protocol = readable[READABLE_INTEROP_V1];
|
|
226
|
+
if (protocol === void 0 || typeof protocol !== "object" || protocol === null) return;
|
|
227
|
+
const candidate = protocol;
|
|
228
|
+
return candidate.version === 1 && typeof candidate.getRevision === "function" && typeof candidate.subscribe === "function" && typeof candidate.runtimeToken === "object" && candidate.runtimeToken !== null ? candidate : void 0;
|
|
229
|
+
}
|
|
230
|
+
function attachReadableInterop(readable, protocol) {
|
|
231
|
+
Object.defineProperty(readable, READABLE_INTEROP_V1, {
|
|
232
|
+
value: protocol,
|
|
233
|
+
enumerable: false,
|
|
234
|
+
configurable: false,
|
|
235
|
+
writable: false
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function withInteropRenderCollector(collector, callback) {
|
|
239
|
+
const context = getSharedInteropContext();
|
|
240
|
+
const previous = context.renderCollector;
|
|
241
|
+
context.renderCollector = collector;
|
|
242
|
+
try {
|
|
243
|
+
return callback();
|
|
244
|
+
} finally {
|
|
245
|
+
context.renderCollector = previous;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function withoutInteropRenderCollector(callback) {
|
|
249
|
+
return withInteropRenderCollector(void 0, callback);
|
|
250
|
+
}
|
|
251
|
+
function isInteropSpeculative() {
|
|
252
|
+
return getSharedInteropContext().speculativeDepth > 0;
|
|
253
|
+
}
|
|
254
|
+
/** Marks speculative deep reads whose per-key dependencies were not collected. */
|
|
255
|
+
function markInteropSpeculativeDeepRead() {
|
|
256
|
+
const context = getSharedInteropContext();
|
|
257
|
+
context.speculativeDeepReadEpoch = (context.speculativeDeepReadEpoch ?? 0) + 1;
|
|
258
|
+
}
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/core/render-tracking.ts
|
|
261
|
+
let activeRenderCollector;
|
|
262
|
+
/** Returns whether a React render is currently collecting signal reads. */
|
|
263
|
+
function hasActiveRenderCollector() {
|
|
264
|
+
return activeRenderCollector !== void 0;
|
|
265
|
+
}
|
|
266
|
+
/** Replaces the current render collector and returns the previous collector. */
|
|
267
|
+
function setActiveRenderCollector(collector) {
|
|
268
|
+
const previous = activeRenderCollector;
|
|
269
|
+
activeRenderCollector = collector;
|
|
270
|
+
return previous;
|
|
271
|
+
}
|
|
272
|
+
/** Records a dependency and reports whether render collection was active. */
|
|
273
|
+
function trackRenderDependency(dependency, observedVersion) {
|
|
274
|
+
if (activeRenderCollector === void 0) return false;
|
|
275
|
+
activeRenderCollector.add(dependency, observedVersion ?? dependency.getRenderVersion());
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
/** Runs a callback without adding its reads to the active React render. */
|
|
279
|
+
function untrackedRender(callback) {
|
|
280
|
+
const previous = setActiveRenderCollector();
|
|
281
|
+
try {
|
|
282
|
+
const owner = executionContext.owner;
|
|
283
|
+
const run = () => withoutInteropRenderCollector(callback);
|
|
284
|
+
if (owner !== void 0 && typeof owner !== "symbol" && owner.kind === "graph") return run();
|
|
285
|
+
return withSynchronousExecutionOwner(UNTRACKED_OWNER, run);
|
|
286
|
+
} finally {
|
|
287
|
+
setActiveRenderCollector(previous);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Invokes one subscription listener, keeping its failure from cancelling the
|
|
292
|
+
* listeners queued behind it. Without this, a single throwing subscriber
|
|
293
|
+
* aborts the rest of the notify cycle, so unrelated components silently miss
|
|
294
|
+
* the update that was being delivered. Reported the same way as the other
|
|
295
|
+
* background-callback failures in this codebase (`readBoundSignal` in
|
|
296
|
+
* src/runtime/jsx.ts): `console.error(message, { cause })`.
|
|
297
|
+
*/
|
|
298
|
+
function notifyListener(listener) {
|
|
299
|
+
try {
|
|
300
|
+
listener();
|
|
301
|
+
} catch (error) {
|
|
302
|
+
console.error("react-fine-grained-signals: a render-subscription listener threw; continuing with the remaining listeners.", { cause: error });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//#endregion
|
|
306
|
+
//#region src/core/signal-brand.ts
|
|
307
|
+
/**
|
|
308
|
+
* Package-wide identity marker shared by public signal wrappers and deep proxies.
|
|
309
|
+
*
|
|
310
|
+
* The key names a *generation* of the cross-copy contract; the number stored
|
|
311
|
+
* under it is that generation's minor version. A minor version only ever widens
|
|
312
|
+
* the contract, so anything from the minimum upwards is trusted; a change that
|
|
313
|
+
* an older copy could not honour takes a new key instead.
|
|
314
|
+
*
|
|
315
|
+
* v0.1.x used `react-fine-grained-signals.signal` and trusted every version
|
|
316
|
+
* from 1 upwards. A v0.2 signal is only reactive under the v2 shared execution
|
|
317
|
+
* owner and the ReadableInterop V1 protocol, neither of which a v0.1.x copy
|
|
318
|
+
* knows, so reusing that key with a larger number would have let v0.1.x
|
|
319
|
+
* recognize v0.2 signals (and v0.2 recognize v0.1.x ones) and then silently
|
|
320
|
+
* never update. A separate key makes each generation reject the other's
|
|
321
|
+
* signals outright: JSX and `isSignal` fail loudly instead of going stale.
|
|
322
|
+
*/
|
|
323
|
+
const SIGNAL_BRAND = Symbol.for("react-fine-grained-signals.signal.v2");
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/core/alien-derived-runtime-core.mts
|
|
326
|
+
const None = 0;
|
|
327
|
+
const Mutable = 1;
|
|
328
|
+
const Watching = 2;
|
|
329
|
+
const RecursedCheck = 4;
|
|
330
|
+
const Dirty = 16;
|
|
331
|
+
const Pending = 32;
|
|
332
|
+
const HasChildEffect = 64;
|
|
333
|
+
function createAlienDerivedRuntime() {
|
|
334
|
+
const runtimeToken = {};
|
|
335
|
+
let renderAdapter;
|
|
336
|
+
let activeRenderAttempt;
|
|
337
|
+
let activeSub;
|
|
338
|
+
let speculativeChildren;
|
|
339
|
+
let cycle = 0;
|
|
340
|
+
let runDepth = 0;
|
|
341
|
+
let batchDepth = 0;
|
|
342
|
+
let flushIndex = 0;
|
|
343
|
+
let queuedLength = 0;
|
|
344
|
+
const queue = [];
|
|
345
|
+
const { link: alienLink, unlink: alienUnlink, propagate, checkDirty, shallowPropagate } = createReactiveSystem({
|
|
346
|
+
update(rawNode) {
|
|
347
|
+
const node = rawNode;
|
|
348
|
+
if (node.kind === "external") {
|
|
349
|
+
const changed = node.revision !== node.pendingRevision;
|
|
350
|
+
node.revision = node.pendingRevision;
|
|
351
|
+
node.flags = Mutable;
|
|
352
|
+
return changed;
|
|
353
|
+
}
|
|
354
|
+
if (node.kind === "computed") return updateComputed(node);
|
|
355
|
+
if (node.kind === "source") return updateSource(node);
|
|
356
|
+
node.flags = Mutable;
|
|
357
|
+
return true;
|
|
358
|
+
},
|
|
359
|
+
notify(rawEffect) {
|
|
360
|
+
let current = rawEffect;
|
|
361
|
+
let insertIndex = queuedLength;
|
|
362
|
+
const firstInsertedIndex = insertIndex;
|
|
363
|
+
do {
|
|
364
|
+
const effect = current;
|
|
365
|
+
queue[insertIndex++] = effect;
|
|
366
|
+
effect.flags &= -3;
|
|
367
|
+
current = effect.subs?.sub;
|
|
368
|
+
if (current === void 0 || !(current.flags & Watching)) break;
|
|
369
|
+
} while (true);
|
|
370
|
+
queuedLength = insertIndex;
|
|
371
|
+
let leftIndex = firstInsertedIndex;
|
|
372
|
+
while (leftIndex < --insertIndex) {
|
|
373
|
+
const left = queue[leftIndex];
|
|
374
|
+
queue[leftIndex++] = queue[insertIndex];
|
|
375
|
+
queue[insertIndex] = left;
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
unwatched(rawNode) {
|
|
379
|
+
const node = rawNode;
|
|
380
|
+
if (node.kind === "external") {
|
|
381
|
+
node.unsubscribe?.();
|
|
382
|
+
node.unsubscribe = void 0;
|
|
383
|
+
} else if (node.kind === "computed") {
|
|
384
|
+
if (node.depsTail !== void 0) {
|
|
385
|
+
node.flags = 17;
|
|
386
|
+
disposeDeps(node);
|
|
387
|
+
}
|
|
388
|
+
} else if (node.kind === "effect") disposeEffect(node);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
function linkNode(dependency, subscriber, version) {
|
|
392
|
+
alienLink(dependency, subscriber, version);
|
|
393
|
+
}
|
|
394
|
+
function unlinkNode(linkage, subscriber) {
|
|
395
|
+
return alienUnlink(linkage, subscriber);
|
|
396
|
+
}
|
|
397
|
+
function makeNode(kind, flags, fields = {}) {
|
|
398
|
+
return {
|
|
399
|
+
kind,
|
|
400
|
+
flags,
|
|
401
|
+
deps: void 0,
|
|
402
|
+
depsTail: void 0,
|
|
403
|
+
subs: void 0,
|
|
404
|
+
subsTail: void 0,
|
|
405
|
+
renderRevision: 0,
|
|
406
|
+
...fields
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
const foreignAdapter = createForeignReadableAdapter({
|
|
410
|
+
runtimeToken,
|
|
411
|
+
makeNode,
|
|
412
|
+
mutableFlag: Mutable,
|
|
413
|
+
dirtyFlag: Dirty,
|
|
414
|
+
getActiveSubscriber: () => activeSub,
|
|
415
|
+
link: (node, subscriber) => linkNode(node, subscriber, cycle),
|
|
416
|
+
propagate,
|
|
417
|
+
shallowPropagate,
|
|
418
|
+
flush: () => flush(),
|
|
419
|
+
isRunning: () => !!runDepth,
|
|
420
|
+
isBatching: () => !!batchDepth,
|
|
421
|
+
effect: (callback) => detachedEffect(callback),
|
|
422
|
+
own: adopt
|
|
423
|
+
});
|
|
424
|
+
const renderDependencies = /* @__PURE__ */ new WeakMap();
|
|
425
|
+
const deepSignalNodes = /* @__PURE__ */ new WeakSet();
|
|
426
|
+
const deepWatchedNodes = /* @__PURE__ */ new WeakSet();
|
|
427
|
+
function getRenderDependency(readable, node) {
|
|
428
|
+
if (!renderDependencies.has(readable)) {
|
|
429
|
+
node.getRenderVersion = () => foreignAdapter.observeRevision(node);
|
|
430
|
+
node.subscribeRender = (listener) => {
|
|
431
|
+
let initial = true;
|
|
432
|
+
let version = foreignAdapter.observeRevision(node);
|
|
433
|
+
return detachedEffect(() => {
|
|
434
|
+
try {
|
|
435
|
+
readable.value;
|
|
436
|
+
} catch {}
|
|
437
|
+
const nextVersion = foreignAdapter.observeRevision(node);
|
|
438
|
+
if (initial) initial = false;
|
|
439
|
+
else if (nextVersion !== version) listener();
|
|
440
|
+
version = nextVersion;
|
|
441
|
+
});
|
|
442
|
+
};
|
|
443
|
+
renderDependencies.set(readable, node);
|
|
444
|
+
}
|
|
445
|
+
return renderDependencies.get(readable);
|
|
446
|
+
}
|
|
447
|
+
function readSource(source) {
|
|
448
|
+
if (source.flags & Dirty && updateSource(source)) {
|
|
449
|
+
if (source.subs !== void 0) shallowPropagate(source.subs);
|
|
450
|
+
}
|
|
451
|
+
if (activeSub !== void 0) linkNode(source, activeSub, cycle);
|
|
452
|
+
return source.currentValue;
|
|
453
|
+
}
|
|
454
|
+
function readSourceUntracked(source) {
|
|
455
|
+
if (source.flags & Dirty && updateSource(source)) {
|
|
456
|
+
if (source.subs !== void 0) shallowPropagate(source.subs);
|
|
457
|
+
}
|
|
458
|
+
return source.currentValue;
|
|
459
|
+
}
|
|
460
|
+
function isForeignOwner(owner) {
|
|
461
|
+
return (isGraphExecutionOwner(owner) || isRenderExecutionOwner(owner)) && owner.runtimeToken !== runtimeToken;
|
|
462
|
+
}
|
|
463
|
+
const attachProtocol = foreignAdapter.attachProtocol;
|
|
464
|
+
const ensureForeignNode = foreignAdapter.ensureForeignNode;
|
|
465
|
+
const graphOwner = foreignAdapter.graphOwner;
|
|
466
|
+
function withGraphOwner(callback) {
|
|
467
|
+
const owner = executionContext.owner;
|
|
468
|
+
const previousAttempt = activeRenderAttempt;
|
|
469
|
+
const alreadyOwned = isGraphExecutionOwner(owner) && owner.runtimeToken === runtimeToken;
|
|
470
|
+
if (previousAttempt === void 0 && alreadyOwned) return callback();
|
|
471
|
+
activeRenderAttempt = void 0;
|
|
472
|
+
if (!alreadyOwned) executionContext.owner = graphOwner;
|
|
473
|
+
try {
|
|
474
|
+
return callback();
|
|
475
|
+
} finally {
|
|
476
|
+
if (!alreadyOwned) executionContext.owner = owner;
|
|
477
|
+
activeRenderAttempt = previousAttempt;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function configureRenderAdapter(adapter) {
|
|
481
|
+
renderAdapter = adapter;
|
|
482
|
+
}
|
|
483
|
+
function withRenderAttempt(attempt, callback) {
|
|
484
|
+
const restore = pushRenderAttempt(attempt);
|
|
485
|
+
try {
|
|
486
|
+
return callback();
|
|
487
|
+
} finally {
|
|
488
|
+
restore();
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function pushRenderAttempt(attempt) {
|
|
492
|
+
const previous = activeRenderAttempt;
|
|
493
|
+
activeRenderAttempt = attempt;
|
|
494
|
+
let active = true;
|
|
495
|
+
return () => {
|
|
496
|
+
if (!active) return;
|
|
497
|
+
active = false;
|
|
498
|
+
if (activeRenderAttempt === attempt) activeRenderAttempt = previous;
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function getActiveRenderAttempt() {
|
|
502
|
+
return activeRenderAttempt;
|
|
503
|
+
}
|
|
504
|
+
const getNodeForReadable = foreignAdapter.getNodeForReadable;
|
|
505
|
+
const getReadableRevision = foreignAdapter.getReadableRevision;
|
|
506
|
+
function isComputedClean(node) {
|
|
507
|
+
if (node.foreignDependent) refreshForeignDependencies(node, /* @__PURE__ */ new Set());
|
|
508
|
+
return node.initialized === true && !(node.flags & 48);
|
|
509
|
+
}
|
|
510
|
+
function getDependencyRevision(dependency) {
|
|
511
|
+
return isReadableProtocol(dependency) ? dependency.getRevision() : getReadableRevision(dependency);
|
|
512
|
+
}
|
|
513
|
+
function promoteComputed(readable, node, entry) {
|
|
514
|
+
if (node.initialized) return true;
|
|
515
|
+
const computed = node;
|
|
516
|
+
const hadForeignDependencies = computed.foreignDependent;
|
|
517
|
+
const dependencies = [];
|
|
518
|
+
const revisions = [];
|
|
519
|
+
for (const [dependency, revision] of entry.dependencies) {
|
|
520
|
+
let protocol = dependency;
|
|
521
|
+
if (!isReadableProtocol(dependency)) {
|
|
522
|
+
if (getReadableRevision(dependency) !== revision) return false;
|
|
523
|
+
const dependencyNode = foreignAdapter.getNodeForReadable(dependency);
|
|
524
|
+
if (dependencyNode !== void 0) {
|
|
525
|
+
if (dependencyNode.kind === "computed" && !isComputedClean(dependencyNode)) return false;
|
|
526
|
+
if (dependencyNode.kind === "source") readSourceUntracked(dependencyNode);
|
|
527
|
+
dependencies.push(dependencyNode);
|
|
528
|
+
revisions.push(revision);
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
protocol = Reflect.get(dependency, READABLE_INTEROP_V1$1);
|
|
532
|
+
if (!isReadableProtocol(protocol)) return false;
|
|
533
|
+
} else if (dependency.getRevision() !== revision) return false;
|
|
534
|
+
dependencies.push(protocol);
|
|
535
|
+
revisions.push(revision);
|
|
536
|
+
}
|
|
537
|
+
disposeDeps(computed);
|
|
538
|
+
computed.depsTail = void 0;
|
|
539
|
+
const previousSub = activeSub;
|
|
540
|
+
activeSub = computed;
|
|
541
|
+
cycle += 1;
|
|
542
|
+
try {
|
|
543
|
+
for (let index = 0; index < dependencies.length; index += 1) {
|
|
544
|
+
const dependency = dependencies[index];
|
|
545
|
+
if (dependency.kind === void 0) ensureForeignNode(dependency, revisions[index]);
|
|
546
|
+
else linkNode(dependency, computed, cycle);
|
|
547
|
+
}
|
|
548
|
+
} finally {
|
|
549
|
+
activeSub = previousSub;
|
|
550
|
+
}
|
|
551
|
+
recomputeForeignDependencies(computed);
|
|
552
|
+
if (hadForeignDependencies !== computed.foreignDependent) updateForeignDependencyAncestors(computed);
|
|
553
|
+
computed.value = entry.value;
|
|
554
|
+
computed.error = entry.error;
|
|
555
|
+
computed.hasError = entry.hasError;
|
|
556
|
+
computed.initialized = true;
|
|
557
|
+
computed.flags = Mutable;
|
|
558
|
+
computed.renderRevision = computed.renderRevision + 1 | 0;
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
561
|
+
function hasSubscribers(readable) {
|
|
562
|
+
return foreignAdapter.getNodeForReadable(readable)?.subs !== void 0;
|
|
563
|
+
}
|
|
564
|
+
function hasActiveSubscriber() {
|
|
565
|
+
return activeSub !== void 0;
|
|
566
|
+
}
|
|
567
|
+
function getBatchDepth() {
|
|
568
|
+
return batchDepth;
|
|
569
|
+
}
|
|
570
|
+
function updateSource(source) {
|
|
571
|
+
source.flags = Mutable;
|
|
572
|
+
return !Object.is(source.currentValue, source.currentValue = source.pendingValue);
|
|
573
|
+
}
|
|
574
|
+
function readComputed(computed, track = true) {
|
|
575
|
+
if (computed.foreignDependent) refreshForeignDependencies(computed, /* @__PURE__ */ new Set());
|
|
576
|
+
if (computed.flags & RecursedCheck) throw new Error("Computed cycle detected");
|
|
577
|
+
const flags = computed.flags;
|
|
578
|
+
if (flags & Dirty || flags & Pending && (computed.deps !== void 0 && checkDirty(computed.deps, computed) || (computed.flags = flags & -33, false))) {
|
|
579
|
+
if (updateComputed(computed) && computed.subs !== void 0) shallowPropagate(computed.subs);
|
|
580
|
+
} else if (!flags) updateComputed(computed);
|
|
581
|
+
if (track && activeSub !== void 0) {
|
|
582
|
+
linkNode(computed, activeSub, cycle);
|
|
583
|
+
if (activeSub.kind === "computed" && computed.foreignDependent) activeSub.foreignDependent = true;
|
|
584
|
+
if (activeSub.kind === "effect" && computed.foreignDependent) activateForeignDependencies(computed, /* @__PURE__ */ new Set());
|
|
585
|
+
}
|
|
586
|
+
if (computed.hasError) throw computed.error;
|
|
587
|
+
return computed.value;
|
|
588
|
+
}
|
|
589
|
+
function refreshForeignDependencies(node, visited) {
|
|
590
|
+
if (visited.has(node)) return;
|
|
591
|
+
visited.add(node);
|
|
592
|
+
for (let dependency = node.deps; dependency !== void 0; dependency = dependency.nextDep) {
|
|
593
|
+
const dep = dependency.dep;
|
|
594
|
+
if (dep.kind === "external") foreignAdapter.observeForeignRevision(dep, dep.protocol.getRevision());
|
|
595
|
+
else if (dep.kind === "computed" && dep.foreignDependent) refreshForeignDependencies(dep, visited);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
function activateForeignDependencies(node, visited) {
|
|
599
|
+
if (visited.has(node)) return;
|
|
600
|
+
visited.add(node);
|
|
601
|
+
let dependency = node.deps;
|
|
602
|
+
while (dependency !== void 0) {
|
|
603
|
+
const dep = dependency.dep;
|
|
604
|
+
if (dep.kind === "external") foreignAdapter.activateForeignNode(dep);
|
|
605
|
+
else if (dep.kind === "computed") activateForeignDependencies(dep, visited);
|
|
606
|
+
dependency = dependency.nextDep;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function updateComputed(computed) {
|
|
610
|
+
if (computed.flags & HasChildEffect) disposeChildEffects(computed);
|
|
611
|
+
computed.depsTail = void 0;
|
|
612
|
+
computed.flags = 5;
|
|
613
|
+
const previous = activeSub;
|
|
614
|
+
activeSub = computed;
|
|
615
|
+
let changed = !computed.initialized;
|
|
616
|
+
const hadError = computed.hasError;
|
|
617
|
+
const hadForeignDependencies = computed.foreignDependent;
|
|
618
|
+
const previousValue = computed.value;
|
|
619
|
+
computed.foreignDependent = false;
|
|
620
|
+
try {
|
|
621
|
+
cycle += 1;
|
|
622
|
+
try {
|
|
623
|
+
computed.value = withGraphOwner(computed.getter);
|
|
624
|
+
computed.error = void 0;
|
|
625
|
+
computed.hasError = false;
|
|
626
|
+
} catch (error) {
|
|
627
|
+
computed.value = void 0;
|
|
628
|
+
computed.error = error;
|
|
629
|
+
computed.hasError = true;
|
|
630
|
+
}
|
|
631
|
+
computed.initialized = true;
|
|
632
|
+
changed = changed || hadError || computed.hasError || !Object.is(previousValue, computed.value);
|
|
633
|
+
if (changed && computed.renderRevision !== void 0) computed.renderRevision = computed.renderRevision + 1 | 0;
|
|
634
|
+
return changed;
|
|
635
|
+
} finally {
|
|
636
|
+
activeSub = previous;
|
|
637
|
+
computed.flags &= -5;
|
|
638
|
+
purgeDeps(computed);
|
|
639
|
+
recomputeForeignDependencies(computed);
|
|
640
|
+
if (hadForeignDependencies !== computed.foreignDependent) updateForeignDependencyAncestors(computed);
|
|
641
|
+
if (computed.foreignDependent && computed.subs !== void 0 && isWatchedByEffect(computed, /* @__PURE__ */ new Set())) activateForeignDependencies(computed, /* @__PURE__ */ new Set());
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function isWatchedByEffect(node, visited) {
|
|
645
|
+
if (visited.has(node)) return false;
|
|
646
|
+
visited.add(node);
|
|
647
|
+
for (let link = node.subs; link !== void 0; link = link.nextSub) {
|
|
648
|
+
const subscriber = link.sub;
|
|
649
|
+
if (subscriber.kind === "effect" ? subscriber.flags !== None : isWatchedByEffect(subscriber, visited)) return true;
|
|
650
|
+
}
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
function disposeChildEffects(sub) {
|
|
654
|
+
let link = sub.depsTail;
|
|
655
|
+
while (link !== void 0) {
|
|
656
|
+
const previous = link.prevDep;
|
|
657
|
+
if (link.dep.kind === "effect") unlinkNode(link, sub);
|
|
658
|
+
link = previous;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function recomputeForeignDependencies(computed) {
|
|
662
|
+
let dependency = computed.deps;
|
|
663
|
+
let foreignDependent = false;
|
|
664
|
+
while (dependency !== void 0) {
|
|
665
|
+
const dep = dependency.dep;
|
|
666
|
+
if (dep.kind === "external" || dep.kind === "computed" && dep.foreignDependent) {
|
|
667
|
+
foreignDependent = true;
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
dependency = dependency.nextDep;
|
|
671
|
+
}
|
|
672
|
+
computed.foreignDependent = foreignDependent;
|
|
673
|
+
}
|
|
674
|
+
function updateForeignDependencyAncestors(computed) {
|
|
675
|
+
let link = computed.subs;
|
|
676
|
+
while (link !== void 0) {
|
|
677
|
+
const subscriber = link.sub;
|
|
678
|
+
if (subscriber.kind === "computed") {
|
|
679
|
+
const computedSubscriber = subscriber;
|
|
680
|
+
const wasForeignDependent = computedSubscriber.foreignDependent;
|
|
681
|
+
recomputeForeignDependencies(computedSubscriber);
|
|
682
|
+
if (wasForeignDependent !== computedSubscriber.foreignDependent) updateForeignDependencyAncestors(computedSubscriber);
|
|
683
|
+
}
|
|
684
|
+
link = link.nextSub;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
function runEffect(effect) {
|
|
688
|
+
const flags = effect.flags;
|
|
689
|
+
if (flags & Dirty || flags & Pending && effect.deps !== void 0 && checkDirty(effect.deps, effect)) {
|
|
690
|
+
if (flags & HasChildEffect) disposeChildEffects(effect);
|
|
691
|
+
if (effect.cleanup !== void 0) {
|
|
692
|
+
try {
|
|
693
|
+
runCleanup(effect);
|
|
694
|
+
} catch (error) {
|
|
695
|
+
reportFailure(error);
|
|
696
|
+
}
|
|
697
|
+
if (!effect.flags) return;
|
|
698
|
+
}
|
|
699
|
+
effect.depsTail = void 0;
|
|
700
|
+
effect.flags = 6;
|
|
701
|
+
const previous = activeSub;
|
|
702
|
+
activeSub = effect;
|
|
703
|
+
try {
|
|
704
|
+
cycle += 1;
|
|
705
|
+
runDepth += 1;
|
|
706
|
+
const cleanup = withGraphOwner(effect.fn);
|
|
707
|
+
effect.cleanup = typeof cleanup === "function" ? cleanup : void 0;
|
|
708
|
+
if (!effect.flags && effect.cleanup !== void 0) runCleanup(effect);
|
|
709
|
+
} finally {
|
|
710
|
+
runDepth -= 1;
|
|
711
|
+
activeSub = previous;
|
|
712
|
+
effect.flags &= -5;
|
|
713
|
+
settleDeps(effect);
|
|
714
|
+
}
|
|
715
|
+
} else if (effect.deps !== void 0) effect.flags = Watching | flags & HasChildEffect;
|
|
716
|
+
}
|
|
717
|
+
function settleDeps(effect) {
|
|
718
|
+
if (effect.flags === None) effect.depsTail = void 0;
|
|
719
|
+
purgeDeps(effect);
|
|
720
|
+
}
|
|
721
|
+
function flush() {
|
|
722
|
+
try {
|
|
723
|
+
while (flushIndex < queuedLength) {
|
|
724
|
+
const effect = queue[flushIndex];
|
|
725
|
+
queue[flushIndex++] = void 0;
|
|
726
|
+
try {
|
|
727
|
+
runEffect(effect);
|
|
728
|
+
} catch (error) {
|
|
729
|
+
reportFailure(error);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
} finally {
|
|
733
|
+
while (flushIndex < queuedLength) {
|
|
734
|
+
const effect = queue[flushIndex];
|
|
735
|
+
queue[flushIndex++] = void 0;
|
|
736
|
+
effect.flags |= 10;
|
|
737
|
+
}
|
|
738
|
+
flushIndex = 0;
|
|
739
|
+
queuedLength = 0;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
function reportFailure(error) {
|
|
743
|
+
try {
|
|
744
|
+
console.error("react-fine-grained-signals: an effect() callback threw; the error is contained and reported here so this flush can finish.", { cause: error });
|
|
745
|
+
} catch {}
|
|
746
|
+
try {
|
|
747
|
+
const report = globalThis.reportError;
|
|
748
|
+
if (typeof report === "function") report.call(globalThis, error);
|
|
749
|
+
} catch {}
|
|
750
|
+
}
|
|
751
|
+
function disposeDeps(sub) {
|
|
752
|
+
let depLink = sub.depsTail;
|
|
753
|
+
while (depLink !== void 0) {
|
|
754
|
+
const previous = depLink.prevDep;
|
|
755
|
+
unlinkNode(depLink, sub);
|
|
756
|
+
depLink = previous;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
function purgeDeps(sub) {
|
|
760
|
+
const tail = sub.depsTail;
|
|
761
|
+
let depLink = tail === void 0 ? sub.deps : tail.nextDep;
|
|
762
|
+
while (depLink !== void 0) depLink = unlinkNode(depLink, sub);
|
|
763
|
+
}
|
|
764
|
+
function runCleanup(effect) {
|
|
765
|
+
const cleanup = effect.cleanup;
|
|
766
|
+
effect.cleanup = void 0;
|
|
767
|
+
const previous = activeSub;
|
|
768
|
+
activeSub = void 0;
|
|
769
|
+
try {
|
|
770
|
+
return withSynchronousExecutionOwner(UNTRACKED_OWNER, cleanup);
|
|
771
|
+
} finally {
|
|
772
|
+
activeSub = previous;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
function disposeEffect(effect) {
|
|
776
|
+
effect.flags = None;
|
|
777
|
+
disposeDeps(effect);
|
|
778
|
+
const ownerLink = effect.subs;
|
|
779
|
+
if (ownerLink !== void 0) unlinkNode(ownerLink, ownerLink.sub);
|
|
780
|
+
if (effect.cleanup !== void 0) try {
|
|
781
|
+
runCleanup(effect);
|
|
782
|
+
} catch (error) {
|
|
783
|
+
reportFailure(error);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
function detachedEffect(fn) {
|
|
787
|
+
return effect(fn, true);
|
|
788
|
+
}
|
|
789
|
+
function effect(fn, detached) {
|
|
790
|
+
const node = makeNode("effect", 6, {
|
|
791
|
+
fn,
|
|
792
|
+
cleanup: void 0
|
|
793
|
+
});
|
|
794
|
+
const dispose = () => disposeEffect(node);
|
|
795
|
+
const previous = activeSub;
|
|
796
|
+
if (!detached) {
|
|
797
|
+
const owner = executionContext.owner;
|
|
798
|
+
if (previous === void 0 && speculativeChildren === void 0 && (isGraphExecutionOwner(owner) || isRenderExecutionOwner(owner)) && owner.runtimeToken !== runtimeToken) owner.own?.(dispose);
|
|
799
|
+
else adopt(dispose, node);
|
|
800
|
+
}
|
|
801
|
+
try {
|
|
802
|
+
activeSub = node;
|
|
803
|
+
runDepth += 1;
|
|
804
|
+
try {
|
|
805
|
+
const cleanup = withGraphOwner(fn);
|
|
806
|
+
node.cleanup = typeof cleanup === "function" ? cleanup : void 0;
|
|
807
|
+
} catch (error) {
|
|
808
|
+
node.cleanup = void 0;
|
|
809
|
+
reportFailure(error);
|
|
810
|
+
} finally {
|
|
811
|
+
runDepth -= 1;
|
|
812
|
+
activeSub = previous;
|
|
813
|
+
node.flags &= -5;
|
|
814
|
+
purgeDeps(node);
|
|
815
|
+
}
|
|
816
|
+
} catch (error) {
|
|
817
|
+
reportFailure(error);
|
|
818
|
+
}
|
|
819
|
+
if (!runDepth && !batchDepth) {
|
|
820
|
+
if (node.flags & 128) runEffect(node);
|
|
821
|
+
if (queuedLength) flush();
|
|
822
|
+
}
|
|
823
|
+
return dispose;
|
|
824
|
+
}
|
|
825
|
+
function adopt(disposeChild, child = makeNode("effect", Watching, { cleanup: disposeChild })) {
|
|
826
|
+
if (activeSub !== void 0) {
|
|
827
|
+
linkNode(child, activeSub, 0);
|
|
828
|
+
activeSub.flags |= HasChildEffect;
|
|
829
|
+
} else speculativeChildren?.push(disposeChild);
|
|
830
|
+
}
|
|
831
|
+
function evaluateSpeculatively(computed, entry) {
|
|
832
|
+
const previousSub = activeSub;
|
|
833
|
+
const previousChildren = speculativeChildren;
|
|
834
|
+
const children = [];
|
|
835
|
+
const getter = computed.getter;
|
|
836
|
+
activeSub = void 0;
|
|
837
|
+
speculativeChildren = children;
|
|
838
|
+
try {
|
|
839
|
+
entry.value = getter();
|
|
840
|
+
} catch (error) {
|
|
841
|
+
entry.error = error;
|
|
842
|
+
entry.hasError = true;
|
|
843
|
+
} finally {
|
|
844
|
+
activeSub = previousSub;
|
|
845
|
+
speculativeChildren = previousChildren;
|
|
846
|
+
for (const disposeChild of children) disposeChild();
|
|
847
|
+
}
|
|
848
|
+
return children.length > 0;
|
|
849
|
+
}
|
|
850
|
+
function batch(fn) {
|
|
851
|
+
batchDepth += 1;
|
|
852
|
+
try {
|
|
853
|
+
return fn();
|
|
854
|
+
} finally {
|
|
855
|
+
batchDepth -= 1;
|
|
856
|
+
if (!batchDepth) flush();
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function untracked(fn) {
|
|
860
|
+
const previous = activeSub;
|
|
861
|
+
const previousAttempt = activeRenderAttempt;
|
|
862
|
+
activeSub = void 0;
|
|
863
|
+
activeRenderAttempt = void 0;
|
|
864
|
+
try {
|
|
865
|
+
return withSynchronousExecutionOwner(UNTRACKED_OWNER, fn);
|
|
866
|
+
} finally {
|
|
867
|
+
activeRenderAttempt = previousAttempt;
|
|
868
|
+
activeSub = previous;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
const brandDescriptor = () => ({
|
|
872
|
+
value: 1,
|
|
873
|
+
enumerable: false,
|
|
874
|
+
writable: false,
|
|
875
|
+
configurable: false
|
|
876
|
+
});
|
|
877
|
+
function registerHelperBrand(value) {
|
|
878
|
+
Object.defineProperty(value, SIGNAL_BRAND, brandDescriptor());
|
|
879
|
+
}
|
|
880
|
+
function inlineWrite(node, value) {
|
|
881
|
+
if (!Object.is(node.pendingValue, node.pendingValue = value)) {
|
|
882
|
+
if (node.renderRevision !== void 0) node.renderRevision = node.renderRevision + 1 | 0;
|
|
883
|
+
node.flags = 17;
|
|
884
|
+
const subscribers = node.subs;
|
|
885
|
+
if (subscribers !== void 0) {
|
|
886
|
+
propagate(subscribers, !!runDepth);
|
|
887
|
+
if (!batchDepth) flush();
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
function inlineDeepSignalWrite(node, value) {
|
|
892
|
+
deepWatchedNodes.delete(node);
|
|
893
|
+
inlineWrite(node, value);
|
|
894
|
+
}
|
|
895
|
+
class HelperBrandSignal {
|
|
896
|
+
#node;
|
|
897
|
+
constructor(node, branded = true) {
|
|
898
|
+
this.#node = node;
|
|
899
|
+
if (branded) registerHelperBrand(this);
|
|
900
|
+
attachProtocol(this, node);
|
|
901
|
+
}
|
|
902
|
+
get value() {
|
|
903
|
+
const node = this.#node;
|
|
904
|
+
const currentOwner = executionContext.owner;
|
|
905
|
+
if (currentOwner === void 0) {
|
|
906
|
+
const value = readSource(node);
|
|
907
|
+
if (activeRenderCollector !== void 0) trackRenderDependency(getRenderDependency(this, node));
|
|
908
|
+
return value;
|
|
909
|
+
}
|
|
910
|
+
if (currentOwner === graphOwner) return readSource(node);
|
|
911
|
+
const attempt = activeRenderAttempt;
|
|
912
|
+
if (attempt !== void 0 && isRenderExecutionOwner(currentOwner) && currentOwner.runtimeToken === runtimeToken && renderAdapter !== void 0) {
|
|
913
|
+
foreignAdapter.observeRevision(node);
|
|
914
|
+
return renderAdapter.readSource(this, node, attempt);
|
|
915
|
+
}
|
|
916
|
+
if (currentOwner === UNTRACKED_OWNER) return readSourceUntracked(node);
|
|
917
|
+
if (isForeignOwner(currentOwner)) {
|
|
918
|
+
const value = readSourceUntracked(node);
|
|
919
|
+
foreignAdapter.publishForeignReadable(this, node, currentOwner);
|
|
920
|
+
return value;
|
|
921
|
+
}
|
|
922
|
+
return readSource(node);
|
|
923
|
+
}
|
|
924
|
+
set value(value) {
|
|
925
|
+
inlineWrite(this.#node, value);
|
|
926
|
+
}
|
|
927
|
+
peek() {
|
|
928
|
+
return this.#node.pendingValue;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
/** Internal DeepSignal root and per-property version sources have a distinct
|
|
932
|
+
* write entry point because their liveness markers must be cleared before any
|
|
933
|
+
* write, including an Object.is-equal write. Ordinary branded signals never
|
|
934
|
+
* pay that bookkeeping cost. */
|
|
935
|
+
class DeepSignalRuntimeSource {
|
|
936
|
+
#node;
|
|
937
|
+
constructor(node) {
|
|
938
|
+
this.#node = node;
|
|
939
|
+
attachProtocol(this, node);
|
|
940
|
+
}
|
|
941
|
+
get value() {
|
|
942
|
+
const node = this.#node;
|
|
943
|
+
const currentOwner = executionContext.owner;
|
|
944
|
+
if (currentOwner === void 0) {
|
|
945
|
+
const value = readSource(node);
|
|
946
|
+
if (activeRenderCollector !== void 0) trackRenderDependency(getRenderDependency(this, node));
|
|
947
|
+
return value;
|
|
948
|
+
}
|
|
949
|
+
if (currentOwner === graphOwner) return readSource(node);
|
|
950
|
+
const attempt = activeRenderAttempt;
|
|
951
|
+
if (attempt !== void 0 && isRenderExecutionOwner(currentOwner) && currentOwner.runtimeToken === runtimeToken && renderAdapter !== void 0) {
|
|
952
|
+
foreignAdapter.observeRevision(node);
|
|
953
|
+
return renderAdapter.readSource(this, node, attempt);
|
|
954
|
+
}
|
|
955
|
+
if (currentOwner === UNTRACKED_OWNER) return readSourceUntracked(node);
|
|
956
|
+
if (isForeignOwner(currentOwner)) {
|
|
957
|
+
const value = readSourceUntracked(node);
|
|
958
|
+
foreignAdapter.publishForeignReadable(this, node, currentOwner);
|
|
959
|
+
return value;
|
|
960
|
+
}
|
|
961
|
+
return readSource(node);
|
|
962
|
+
}
|
|
963
|
+
set value(value) {
|
|
964
|
+
inlineDeepSignalWrite(this.#node, value);
|
|
965
|
+
}
|
|
966
|
+
peek() {
|
|
967
|
+
return this.#node.pendingValue;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
function createBrandedSignal(makeReadable, initialValue) {
|
|
971
|
+
return new makeReadable(makeNode("source", Mutable, {
|
|
972
|
+
currentValue: initialValue,
|
|
973
|
+
pendingValue: initialValue
|
|
974
|
+
}));
|
|
975
|
+
}
|
|
976
|
+
const signalClassBrandHelper = (initialValue) => createBrandedSignal(HelperBrandSignal, initialValue);
|
|
977
|
+
class HelperBrandComputed {
|
|
978
|
+
#node;
|
|
979
|
+
constructor(node, branded = true) {
|
|
980
|
+
this.#node = node;
|
|
981
|
+
if (branded) registerHelperBrand(this);
|
|
982
|
+
attachProtocol(this, node);
|
|
983
|
+
}
|
|
984
|
+
get value() {
|
|
985
|
+
const node = this.#node;
|
|
986
|
+
const currentOwner = executionContext.owner;
|
|
987
|
+
if (currentOwner === graphOwner) return readComputed(node);
|
|
988
|
+
const attempt = activeRenderAttempt;
|
|
989
|
+
if (attempt !== void 0 && isRenderExecutionOwner(currentOwner) && currentOwner.runtimeToken === runtimeToken && renderAdapter !== void 0) {
|
|
990
|
+
foreignAdapter.observeRevision(node);
|
|
991
|
+
return renderAdapter.readComputed(this, node, attempt);
|
|
992
|
+
}
|
|
993
|
+
const owner = currentOwner;
|
|
994
|
+
const foreign = owner !== void 0 && isForeignOwner(owner);
|
|
995
|
+
try {
|
|
996
|
+
return readComputed(node, owner !== UNTRACKED_OWNER && !foreign);
|
|
997
|
+
} finally {
|
|
998
|
+
if (owner === void 0) {
|
|
999
|
+
if (activeRenderCollector !== void 0) trackRenderDependency(getRenderDependency(this, node));
|
|
1000
|
+
} else if (foreign) foreignAdapter.publishForeignReadable(this, node, owner);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
peek() {
|
|
1004
|
+
return untracked(() => readComputed(this.#node));
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
function createBrandedComputed(makeReadable, getter) {
|
|
1008
|
+
return new makeReadable(makeNode("computed", None, {
|
|
1009
|
+
getter,
|
|
1010
|
+
value: void 0,
|
|
1011
|
+
error: void 0,
|
|
1012
|
+
hasError: false,
|
|
1013
|
+
initialized: false
|
|
1014
|
+
}));
|
|
1015
|
+
}
|
|
1016
|
+
const computedClassBrandHelper = (getter) => createBrandedComputed(HelperBrandComputed, getter);
|
|
1017
|
+
function hasBrandAndPeek(value) {
|
|
1018
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1019
|
+
const version = Reflect.get(value, SIGNAL_BRAND);
|
|
1020
|
+
return typeof version === "number" && version >= 1 && typeof Reflect.get(value, "peek") === "function";
|
|
1021
|
+
}
|
|
1022
|
+
const isSignalBrandHelper = hasBrandAndPeek;
|
|
1023
|
+
function createDeepSignal(initialValue) {
|
|
1024
|
+
const node = makeNode("source", Mutable, {
|
|
1025
|
+
currentValue: initialValue,
|
|
1026
|
+
pendingValue: initialValue
|
|
1027
|
+
});
|
|
1028
|
+
const readable = new DeepSignalRuntimeSource(node);
|
|
1029
|
+
deepSignalNodes.add(node);
|
|
1030
|
+
return readable;
|
|
1031
|
+
}
|
|
1032
|
+
function createDeepSignalVersion(initialValue) {
|
|
1033
|
+
const node = makeNode("source", Mutable, {
|
|
1034
|
+
currentValue: initialValue,
|
|
1035
|
+
pendingValue: initialValue
|
|
1036
|
+
});
|
|
1037
|
+
const readable = new DeepSignalRuntimeSource(node);
|
|
1038
|
+
deepSignalNodes.add(node);
|
|
1039
|
+
return readable;
|
|
1040
|
+
}
|
|
1041
|
+
function markDeepSignalWatched(readable) {
|
|
1042
|
+
const node = foreignAdapter.getNodeForReadable(readable);
|
|
1043
|
+
if (node !== void 0) deepWatchedNodes.add(node);
|
|
1044
|
+
}
|
|
1045
|
+
function hasDeepSignalSubscribers(readable) {
|
|
1046
|
+
const node = foreignAdapter.getNodeForReadable(readable);
|
|
1047
|
+
return node !== void 0 && (deepWatchedNodes.has(node) || deepSignalNodes.has(node) && hasSubscribers(readable));
|
|
1048
|
+
}
|
|
1049
|
+
function getRenderVersion(readable) {
|
|
1050
|
+
return foreignAdapter.getReadableRevision(readable);
|
|
1051
|
+
}
|
|
1052
|
+
function subscribeReadables(readables, notify) {
|
|
1053
|
+
let initial = true;
|
|
1054
|
+
return detachedEffect(() => {
|
|
1055
|
+
for (const readable of readables) try {
|
|
1056
|
+
readable.value;
|
|
1057
|
+
} catch {}
|
|
1058
|
+
if (initial) initial = false;
|
|
1059
|
+
else notify();
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
return {
|
|
1063
|
+
runtimeToken,
|
|
1064
|
+
graphOwner,
|
|
1065
|
+
configureRenderAdapter,
|
|
1066
|
+
withRenderAttempt,
|
|
1067
|
+
pushRenderAttempt,
|
|
1068
|
+
getActiveRenderAttempt,
|
|
1069
|
+
getNodeForReadable,
|
|
1070
|
+
getReadableRevision,
|
|
1071
|
+
getDependencyRevision,
|
|
1072
|
+
isComputedClean,
|
|
1073
|
+
promoteComputed,
|
|
1074
|
+
evaluateSpeculatively,
|
|
1075
|
+
adopt,
|
|
1076
|
+
hasSubscribers,
|
|
1077
|
+
hasActiveSubscriber,
|
|
1078
|
+
getBatchDepth,
|
|
1079
|
+
signal: signalClassBrandHelper,
|
|
1080
|
+
computed: computedClassBrandHelper,
|
|
1081
|
+
effect,
|
|
1082
|
+
detachedEffect,
|
|
1083
|
+
batch,
|
|
1084
|
+
untracked,
|
|
1085
|
+
SIGNAL_BRAND,
|
|
1086
|
+
isSignal: isSignalBrandHelper,
|
|
1087
|
+
createDeepSignal,
|
|
1088
|
+
createDeepSignalVersion,
|
|
1089
|
+
markDeepSignalWatched,
|
|
1090
|
+
hasDeepSignalSubscribers,
|
|
1091
|
+
getRenderVersion,
|
|
1092
|
+
subscribeReadables
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
//#endregion
|
|
1096
|
+
//#region src/core/render-runtime.mts
|
|
1097
|
+
function createAlienDerivedRenderAdapter(core) {
|
|
1098
|
+
let activeSpeculativeComputed;
|
|
1099
|
+
const readablesByNode = /* @__PURE__ */ new WeakMap();
|
|
1100
|
+
const collectorFrames = [];
|
|
1101
|
+
let baseRenderCollector;
|
|
1102
|
+
function addDependency(attempt, dependency, revision) {
|
|
1103
|
+
const node = core.getNodeForReadable(dependency);
|
|
1104
|
+
if (node !== void 0) readablesByNode.set(node, dependency);
|
|
1105
|
+
if (activeSpeculativeComputed !== void 0) activeSpeculativeComputed.dependencies.set(dependency, revision);
|
|
1106
|
+
else attempt.add(dependency, revision);
|
|
1107
|
+
}
|
|
1108
|
+
function readSource(readable, node, attempt) {
|
|
1109
|
+
addDependency(attempt, readable, node.renderRevision);
|
|
1110
|
+
return node.pendingValue;
|
|
1111
|
+
}
|
|
1112
|
+
function readComputed(readable, node, attempt) {
|
|
1113
|
+
if (activeSpeculativeComputed !== void 0) {
|
|
1114
|
+
const restoreAttempt = core.pushRenderAttempt(void 0);
|
|
1115
|
+
try {
|
|
1116
|
+
return readable.value;
|
|
1117
|
+
} finally {
|
|
1118
|
+
addDependency(attempt, readable, node.renderRevision);
|
|
1119
|
+
restoreAttempt();
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
addDependency(attempt, readable, node.renderRevision);
|
|
1123
|
+
const cache = attempt.computedCache;
|
|
1124
|
+
let entry = cache.get(node);
|
|
1125
|
+
if (entry !== void 0 && isEntryCurrent(entry)) {
|
|
1126
|
+
if (entry.hasError) throw entry.error;
|
|
1127
|
+
return entry.value;
|
|
1128
|
+
}
|
|
1129
|
+
if (core.isComputedClean(node)) {
|
|
1130
|
+
if (node.hasError) throw node.error;
|
|
1131
|
+
return node.value;
|
|
1132
|
+
}
|
|
1133
|
+
entry = {
|
|
1134
|
+
dependencies: /* @__PURE__ */ new Map(),
|
|
1135
|
+
value: void 0,
|
|
1136
|
+
error: void 0,
|
|
1137
|
+
hasError: false,
|
|
1138
|
+
canPromote: false
|
|
1139
|
+
};
|
|
1140
|
+
cache.set(node, entry);
|
|
1141
|
+
const previous = activeSpeculativeComputed;
|
|
1142
|
+
activeSpeculativeComputed = entry;
|
|
1143
|
+
const deepReadEpoch = attempt.speculativeDeepReadEpoch;
|
|
1144
|
+
let createdEffects = false;
|
|
1145
|
+
try {
|
|
1146
|
+
createdEffects = core.evaluateSpeculatively(node, entry);
|
|
1147
|
+
} finally {
|
|
1148
|
+
activeSpeculativeComputed = previous;
|
|
1149
|
+
entry.canPromote = !createdEffects && deepReadEpoch === attempt.speculativeDeepReadEpoch;
|
|
1150
|
+
}
|
|
1151
|
+
if (entry.hasError) throw entry.error;
|
|
1152
|
+
return entry.value;
|
|
1153
|
+
}
|
|
1154
|
+
function isEntryCurrent(entry) {
|
|
1155
|
+
for (const [dependency, revision] of entry.dependencies) {
|
|
1156
|
+
const node = core.getNodeForReadable(dependency);
|
|
1157
|
+
if (node === void 0) {
|
|
1158
|
+
if (core.getDependencyRevision(dependency) !== revision) return false;
|
|
1159
|
+
} else if (node.renderRevision !== revision || node.kind === "computed" && !core.isComputedClean(node)) return false;
|
|
1160
|
+
}
|
|
1161
|
+
return true;
|
|
1162
|
+
}
|
|
1163
|
+
core.configureRenderAdapter({
|
|
1164
|
+
readSource,
|
|
1165
|
+
readComputed
|
|
1166
|
+
});
|
|
1167
|
+
function createRenderAttempt() {
|
|
1168
|
+
return {
|
|
1169
|
+
dependencies: /* @__PURE__ */ new Map(),
|
|
1170
|
+
computedCache: /* @__PURE__ */ new Map(),
|
|
1171
|
+
speculativeDeepReadEpoch: 0,
|
|
1172
|
+
add(dependency, revision) {
|
|
1173
|
+
if (!this.dependencies.has(dependency)) this.dependencies.set(dependency, revision);
|
|
1174
|
+
},
|
|
1175
|
+
markSpeculativeDeepRead() {
|
|
1176
|
+
this.speculativeDeepReadEpoch += 1;
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
function createRenderOwner(attempt, scopePolicy = "managed") {
|
|
1181
|
+
return {
|
|
1182
|
+
version: 2,
|
|
1183
|
+
kind: "render",
|
|
1184
|
+
scopePolicy,
|
|
1185
|
+
runtimeToken: core.runtimeToken,
|
|
1186
|
+
add(protocol, revision) {
|
|
1187
|
+
addDependency(attempt, protocol, revision);
|
|
1188
|
+
},
|
|
1189
|
+
isSpeculative() {
|
|
1190
|
+
return activeSpeculativeComputed !== void 0;
|
|
1191
|
+
},
|
|
1192
|
+
markSpeculativeDeepRead() {
|
|
1193
|
+
attempt.markSpeculativeDeepRead();
|
|
1194
|
+
},
|
|
1195
|
+
own: core.adopt
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
function pushRenderScope(attempt, scopePolicy = "managed") {
|
|
1199
|
+
const parent = executionContext.owner;
|
|
1200
|
+
if (isRenderExecutionOwner(parent) && !(parent.scopePolicy === "managed" && scopePolicy === "managed")) parent.closeScope?.();
|
|
1201
|
+
const restoreAttempt = core.pushRenderAttempt(attempt);
|
|
1202
|
+
const owner = createRenderOwner(attempt, scopePolicy);
|
|
1203
|
+
const restoreOwner = pushExecutionOwner(owner);
|
|
1204
|
+
const collector = { add(dependency, revision) {
|
|
1205
|
+
addDependency(attempt, dependency, revision);
|
|
1206
|
+
} };
|
|
1207
|
+
if (collectorFrames.length === 0) baseRenderCollector = activeRenderCollector;
|
|
1208
|
+
const frame = {
|
|
1209
|
+
collector,
|
|
1210
|
+
active: true
|
|
1211
|
+
};
|
|
1212
|
+
collectorFrames.push(frame);
|
|
1213
|
+
setActiveRenderCollector(collector);
|
|
1214
|
+
let active = true;
|
|
1215
|
+
const restoreScope = () => {
|
|
1216
|
+
if (!active) return;
|
|
1217
|
+
active = false;
|
|
1218
|
+
frame.active = false;
|
|
1219
|
+
while (collectorFrames.at(-1)?.active === false) collectorFrames.pop();
|
|
1220
|
+
setActiveRenderCollector(collectorFrames.at(-1)?.collector ?? baseRenderCollector);
|
|
1221
|
+
if (collectorFrames.length === 0) baseRenderCollector = void 0;
|
|
1222
|
+
restoreAttempt();
|
|
1223
|
+
restoreOwner();
|
|
1224
|
+
};
|
|
1225
|
+
owner.closeScope = restoreScope;
|
|
1226
|
+
return restoreScope;
|
|
1227
|
+
}
|
|
1228
|
+
function withRenderScope(attempt, callback, scopePolicy = "managed") {
|
|
1229
|
+
const restore = pushRenderScope(attempt, scopePolicy);
|
|
1230
|
+
try {
|
|
1231
|
+
return callback();
|
|
1232
|
+
} finally {
|
|
1233
|
+
restore();
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
function promoteRenderAttempt(attempt) {
|
|
1237
|
+
for (const [node, entry] of attempt.computedCache) {
|
|
1238
|
+
if (!entry.canPromote) continue;
|
|
1239
|
+
const readable = readablesByNode.get(node);
|
|
1240
|
+
if (readable === void 0 || !core.promoteComputed(readable, node, entry)) return false;
|
|
1241
|
+
}
|
|
1242
|
+
return true;
|
|
1243
|
+
}
|
|
1244
|
+
function settleRenderAttempt(attempt) {
|
|
1245
|
+
let stable = true;
|
|
1246
|
+
for (const [dependency, revision] of attempt.dependencies) {
|
|
1247
|
+
const currentRevision = getRenderVersion(dependency);
|
|
1248
|
+
if (currentRevision === revision) continue;
|
|
1249
|
+
const node = core.getNodeForReadable(dependency);
|
|
1250
|
+
const entry = node === void 0 ? void 0 : attempt.computedCache.get(node);
|
|
1251
|
+
if (node === void 0 || entry === void 0 || node.initialized !== true || entry.hasError !== node.hasError || !entry.hasError && !Object.is(entry.value, node.value)) {
|
|
1252
|
+
stable = false;
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
attempt.dependencies.set(dependency, currentRevision);
|
|
1256
|
+
}
|
|
1257
|
+
return stable;
|
|
1258
|
+
}
|
|
1259
|
+
function getRenderVersion(readable) {
|
|
1260
|
+
if (isReadableProtocol(readable) || core.getNodeForReadable(readable) !== void 0 || Reflect.get(readable, READABLE_INTEROP_V1$1) !== void 0) return core.getDependencyRevision(readable);
|
|
1261
|
+
const getVersion = Reflect.get(readable, "getRenderVersion");
|
|
1262
|
+
if (typeof getVersion === "function") return getVersion.call(readable);
|
|
1263
|
+
throw new TypeError("Unknown render dependency");
|
|
1264
|
+
}
|
|
1265
|
+
function hasActiveRenderOwner() {
|
|
1266
|
+
return isRenderExecutionOwner(executionContext.owner);
|
|
1267
|
+
}
|
|
1268
|
+
function isSpeculative() {
|
|
1269
|
+
const owner = executionContext.owner;
|
|
1270
|
+
if (isGraphExecutionOwner(owner) || owner === UNTRACKED_OWNER) return false;
|
|
1271
|
+
return isRenderExecutionOwner(owner) && (owner.isSpeculative?.() === true || activeSpeculativeComputed !== void 0);
|
|
1272
|
+
}
|
|
1273
|
+
function markSpeculativeDeepRead() {
|
|
1274
|
+
const attempt = core.getActiveRenderAttempt();
|
|
1275
|
+
if (attempt !== void 0) attempt.markSpeculativeDeepRead();
|
|
1276
|
+
else if (isRenderExecutionOwner(executionContext.owner)) executionContext.owner.markSpeculativeDeepRead?.();
|
|
1277
|
+
}
|
|
1278
|
+
function subscribeReadables(readables, notify) {
|
|
1279
|
+
let initial = true;
|
|
1280
|
+
return core.detachedEffect(() => {
|
|
1281
|
+
for (const readable of readables) try {
|
|
1282
|
+
readable.value;
|
|
1283
|
+
} catch {}
|
|
1284
|
+
if (initial) initial = false;
|
|
1285
|
+
else notify();
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
function captureRenderSnapshot(readable) {
|
|
1289
|
+
const attempt = createRenderAttempt();
|
|
1290
|
+
let value;
|
|
1291
|
+
withRenderScope(attempt, () => {
|
|
1292
|
+
value = readable.value;
|
|
1293
|
+
});
|
|
1294
|
+
return {
|
|
1295
|
+
value,
|
|
1296
|
+
dependencies: attempt.dependencies,
|
|
1297
|
+
attempt
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
function getExecutionOwner() {
|
|
1301
|
+
return executionContext.owner;
|
|
1302
|
+
}
|
|
1303
|
+
return {
|
|
1304
|
+
createRenderAttempt,
|
|
1305
|
+
createRenderOwner,
|
|
1306
|
+
pushRenderScope,
|
|
1307
|
+
withRenderScope,
|
|
1308
|
+
promoteRenderAttempt,
|
|
1309
|
+
settleRenderAttempt,
|
|
1310
|
+
getRenderVersion,
|
|
1311
|
+
hasActiveRenderOwner,
|
|
1312
|
+
isSpeculative,
|
|
1313
|
+
markSpeculativeDeepRead,
|
|
1314
|
+
subscribeReadables,
|
|
1315
|
+
captureRenderSnapshot,
|
|
1316
|
+
getExecutionOwner
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
//#endregion
|
|
1320
|
+
//#region src/core/reactive-runtime.ts
|
|
1321
|
+
/** Builds one Alien-derived graph and its separate owner/render adapters. */
|
|
1322
|
+
function createReactiveRuntime() {
|
|
1323
|
+
const graph = createAlienDerivedRuntime();
|
|
1324
|
+
const render = createAlienDerivedRenderAdapter(graph);
|
|
1325
|
+
return {
|
|
1326
|
+
runtimeToken: graph.runtimeToken,
|
|
1327
|
+
graphOwner: graph.graphOwner,
|
|
1328
|
+
getNodeForReadable: graph.getNodeForReadable,
|
|
1329
|
+
renderAdapter: render,
|
|
1330
|
+
signal: graph.signal,
|
|
1331
|
+
computed: graph.computed,
|
|
1332
|
+
effect: graph.effect,
|
|
1333
|
+
detachedEffect: graph.detachedEffect,
|
|
1334
|
+
batch: graph.batch,
|
|
1335
|
+
untracked: graph.untracked,
|
|
1336
|
+
hasSubscribers: graph.hasSubscribers,
|
|
1337
|
+
hasActiveSubscriber: graph.hasActiveSubscriber,
|
|
1338
|
+
getBatchDepth: graph.getBatchDepth,
|
|
1339
|
+
createDeepSignal: graph.createDeepSignal,
|
|
1340
|
+
createDeepSignalVersion: graph.createDeepSignalVersion,
|
|
1341
|
+
markDeepSignalWatched: graph.markDeepSignalWatched,
|
|
1342
|
+
hasDeepSignalSubscribers: graph.hasDeepSignalSubscribers,
|
|
1343
|
+
isSpeculative: render.isSpeculative,
|
|
1344
|
+
markSpeculativeDeepRead: render.markSpeculativeDeepRead
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
//#endregion
|
|
1348
|
+
//#region src/core/core-runtime.ts
|
|
1349
|
+
/** The single graph used by this package's public signal APIs. */
|
|
1350
|
+
const coreRuntime = createReactiveRuntime();
|
|
1351
|
+
//#endregion
|
|
1352
|
+
export { untrackedRender as a, getSharedInteropContext as c, UNTRACKED_OWNER as d, executionContext as f, notifyListener as i, isInteropSpeculative as l, SIGNAL_BRAND as n, attachReadableInterop as o, hasActiveRenderCollector as r, getReadableInterop as s, coreRuntime as t, markInteropSpeculativeDeepRead as u };
|
|
1353
|
+
|
|
1354
|
+
//# sourceMappingURL=core-runtime-2jSE9Tz5.js.map
|