octane 0.2.11 → 0.2.13
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 +5 -0
- package/dist/behavior-root.d.ts +13 -3
- package/dist/behavior-root.js +28 -5
- package/dist/cjs/behavior-root.cjs +32 -6
- package/dist/cjs/class-names.cjs +49 -0
- package/dist/cjs/constants.cjs +9 -0
- package/dist/cjs/context-epoch.cjs +38 -0
- package/dist/cjs/css.cjs +6 -27
- package/dist/cjs/data-encoding.cjs +160 -0
- package/dist/cjs/dom-binding-handoff.cjs +93 -0
- package/dist/cjs/dom-binding-protocol.cjs +115 -0
- package/dist/cjs/dom-binding-styles.cjs +292 -0
- package/dist/cjs/dom-bindings.cjs +700 -0
- package/dist/cjs/dom-focused-move.cjs +66 -0
- package/dist/cjs/dom-stage.cjs +896 -0
- package/dist/cjs/dom-tables.cjs +4 -94
- package/dist/cjs/error-codes.client.generated.cjs +33 -0
- package/dist/cjs/error-codes.server.generated.cjs +24 -0
- package/dist/cjs/hydration/control-capture.cjs +244 -0
- package/dist/cjs/hydration/event-capture.cjs +125 -43
- package/dist/cjs/hydration/interaction-config.cjs +50 -2
- package/dist/cjs/hydration-markers.cjs +37 -0
- package/dist/cjs/independent-hydration-protocol.cjs +106 -0
- package/dist/cjs/index.cjs +9 -0
- package/dist/cjs/runtime.cjs +6397 -1683
- package/dist/cjs/runtime.server.cjs +1465 -213
- package/dist/cjs/server/early-signals.cjs +45 -0
- package/dist/cjs/server/index.cjs +47 -0
- package/dist/cjs/server/rpc-batch.cjs +149 -0
- package/dist/cjs/server/rpc-stream.cjs +146 -0
- package/dist/cjs/server/rpc.cjs +34 -15
- package/dist/cjs/server/signal-query-observation.cjs +158 -0
- package/dist/cjs/server/streamed-region.cjs +52 -0
- package/dist/cjs/server/streamed-signals.cjs +512 -0
- package/dist/cjs/server-call.cjs +103 -0
- package/dist/cjs/server-rpc-batch-client.cjs +141 -0
- package/dist/cjs/server-rpc-client.cjs +94 -27
- package/dist/cjs/server-rpc-protocol.cjs +141 -0
- package/dist/cjs/server-rpc-stream-client.cjs +118 -0
- package/dist/cjs/signals/actions.cjs +474 -0
- package/dist/cjs/signals/client.cjs +4 -1
- package/dist/cjs/signals/computations.cjs +460 -0
- package/dist/cjs/signals/control-binding.cjs +368 -0
- package/dist/cjs/signals/derived-facade.cjs +50 -0
- package/dist/cjs/signals/document-owner.cjs +71 -0
- package/dist/cjs/signals/early-values.cjs +155 -0
- package/dist/cjs/signals/encoding.cjs +6 -95
- package/dist/cjs/signals/engine.cjs +276 -12
- package/dist/cjs/signals/errors.cjs +18 -0
- package/dist/cjs/signals/facade.cjs +477 -0
- package/dist/cjs/signals/graph.cjs +166 -20
- package/dist/cjs/signals/handle-protocol.cjs +36 -0
- package/dist/cjs/signals/index.cjs +81 -2
- package/dist/cjs/signals/native-read-client.cjs +10 -0
- package/dist/cjs/signals/owner-context.cjs +112 -0
- package/dist/cjs/signals/query-attempt-observer.cjs +68 -0
- package/dist/cjs/signals/query-facade.cjs +72 -0
- package/dist/cjs/signals/read-protocol.cjs +54 -0
- package/dist/cjs/signals/requests.cjs +287 -14
- package/dist/cjs/signals/scalar-computations.cjs +76 -0
- package/dist/cjs/signals/server.cjs +4 -1
- package/dist/cjs/signals/transition-candidate.cjs +567 -0
- package/dist/cjs/signals/transition-state.cjs +106 -0
- package/dist/cjs/signals/types.cjs +50 -0
- package/dist/cjs/stream-protocol.cjs +3 -0
- package/dist/cjs/streamed-signals-protocol.cjs +159 -0
- package/dist/cjs/style-values.cjs +122 -0
- package/dist/cjs/trusted-html.cjs +30 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/class-names.d.ts +5 -0
- package/dist/class-names.js +25 -0
- package/dist/compiler/bundler.js +51 -22
- package/dist/compiler/compile.js +2534 -581
- package/dist/compiler/dom-binding-program.js +935 -0
- package/dist/compiler/dom-binding-request.js +57 -0
- package/dist/compiler/dom-bindings.js +2245 -0
- package/dist/compiler/hook-deps.js +759 -10
- package/dist/compiler/hydrate-boundaries.js +358 -15
- package/dist/compiler/index.d.ts +39 -2
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/native-attribute-reads.js +127 -0
- package/dist/compiler/native-change-diagnostics.js +32 -38
- package/dist/compiler/native-read-diagnostics.js +69 -8
- package/dist/compiler/native-read-types.js +80 -34
- package/dist/compiler/parser.node.js +1 -1
- package/dist/compiler/renderer-boundaries.js +40 -0
- package/dist/compiler/server-context.js +118 -0
- package/dist/compiler/signal-attempt-reads.js +479 -0
- package/dist/compiler/signal-declarations.js +557 -0
- package/dist/compiler/signal-start-reads.js +413 -0
- package/dist/compiler/slot-hooks.d.ts +3 -1
- package/dist/compiler/slot-hooks.js +168 -34
- package/dist/compiler/strong-auto-memo.js +90 -0
- package/dist/compiler/strong-html.js +143 -0
- package/dist/compiler/strong-mode.js +764 -66
- package/dist/compiler/strong-template-policy.js +307 -0
- package/dist/compiler/template-ir.js +200 -0
- package/dist/compiler/typescript.d.ts +2 -0
- package/dist/compiler/typescript.js +2 -0
- package/dist/compiler/vite.d.ts +3 -1
- package/dist/compiler/vite.js +122 -4
- package/dist/compiler/volar.LICENSES.txt +1 -1
- package/dist/compiler/volar.d.ts +6 -1
- package/dist/compiler/volar.js +750 -1433
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +10 -0
- package/dist/context-epoch.d.ts +2 -0
- package/dist/context-epoch.js +13 -0
- package/dist/css.d.ts +2 -5
- package/dist/css.js +2 -23
- package/dist/data-encoding.d.ts +9 -0
- package/dist/data-encoding.js +134 -0
- package/dist/dom-binding-classes.d.ts +15 -0
- package/dist/dom-binding-classes.js +129 -0
- package/dist/dom-binding-controls.d.ts +2 -0
- package/dist/dom-binding-controls.js +6 -0
- package/dist/dom-binding-handoff.d.ts +55 -0
- package/dist/dom-binding-handoff.js +62 -0
- package/dist/dom-binding-program.d.ts +300 -0
- package/dist/dom-binding-program.js +1625 -0
- package/dist/dom-binding-projections.d.ts +15 -0
- package/dist/dom-binding-projections.js +187 -0
- package/dist/dom-binding-protocol.d.ts +13 -0
- package/dist/dom-binding-protocol.js +88 -0
- package/dist/dom-binding-signals.d.ts +21 -0
- package/dist/dom-binding-signals.js +109 -0
- package/dist/dom-binding-styles.d.ts +17 -0
- package/dist/dom-binding-styles.js +272 -0
- package/dist/dom-bindings.d.ts +89 -0
- package/dist/dom-bindings.js +670 -0
- package/dist/dom-focused-move.d.ts +6 -0
- package/dist/dom-focused-move.js +42 -0
- package/dist/dom-stage.d.ts +52 -0
- package/dist/dom-stage.js +872 -0
- package/dist/dom-tables.d.ts +1 -3
- package/dist/dom-tables.js +1 -91
- package/dist/error-codes.client.generated.d.ts +9 -0
- package/dist/error-codes.client.generated.js +33 -0
- package/dist/error-codes.server.generated.d.ts +6 -0
- package/dist/error-codes.server.generated.js +24 -0
- package/dist/hydration/control-capture.d.ts +62 -0
- package/dist/hydration/control-capture.js +223 -0
- package/dist/hydration/document-lifecycle.d.ts +23 -0
- package/dist/hydration/document-lifecycle.js +80 -0
- package/dist/hydration/event-capture.d.ts +20 -1
- package/dist/hydration/event-capture.js +128 -42
- package/dist/hydration/independent-island.d.ts +45 -0
- package/dist/hydration/independent-island.js +233 -0
- package/dist/hydration/index.d.ts +8 -1
- package/dist/hydration/index.js +55 -1
- package/dist/hydration/interaction-config.d.ts +5 -0
- package/dist/hydration/interaction-config.js +44 -1
- package/dist/hydration/stream-delivery.d.ts +32 -0
- package/dist/hydration/stream-delivery.js +333 -0
- package/dist/hydration/stream-receiver.d.ts +26 -0
- package/dist/hydration/stream-receiver.js +204 -0
- package/dist/hydration/stream-result-receiver.d.ts +70 -0
- package/dist/hydration/stream-result-receiver.js +246 -0
- package/dist/hydration/streamed-signals.d.ts +44 -0
- package/dist/hydration/streamed-signals.js +186 -0
- package/dist/hydration/types.d.ts +6 -0
- package/dist/hydration-markers.d.ts +7 -0
- package/dist/hydration-markers.js +10 -0
- package/dist/independent-hydration-protocol.d.ts +31 -0
- package/dist/independent-hydration-protocol.js +80 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/internal/signal-read.d.ts +1 -0
- package/dist/internal/signal-read.js +4 -0
- package/dist/jsx-runtime-strong.d.ts +33 -0
- package/dist/jsx-runtime.d.ts +58 -2
- package/dist/public-types.d.ts +15 -1
- package/dist/runtime.d.ts +297 -23
- package/dist/runtime.js +6405 -1679
- package/dist/runtime.server.d.ts +110 -27
- package/dist/runtime.server.js +1458 -213
- package/dist/server/early-signals.d.ts +14 -0
- package/dist/server/early-signals.js +34 -0
- package/dist/server/index.d.ts +11 -2
- package/dist/server/index.js +50 -1
- package/dist/server/rpc-batch.d.ts +17 -0
- package/dist/server/rpc-batch.js +129 -0
- package/dist/server/rpc-stream.d.ts +9 -0
- package/dist/server/rpc-stream.js +125 -0
- package/dist/server/rpc.d.ts +5 -1
- package/dist/server/rpc.js +37 -13
- package/dist/server/signal-query-observation.d.ts +3 -0
- package/dist/server/signal-query-observation.js +134 -0
- package/dist/server/streamed-region.d.ts +15 -0
- package/dist/server/streamed-region.js +30 -0
- package/dist/server/streamed-signals.d.ts +45 -0
- package/dist/server/streamed-signals.js +488 -0
- package/dist/server-call.d.ts +41 -0
- package/dist/server-call.js +75 -0
- package/dist/server-rpc-batch-client.d.ts +7 -0
- package/dist/server-rpc-batch-client.js +119 -0
- package/dist/server-rpc-client.d.ts +3 -1
- package/dist/server-rpc-client.js +99 -27
- package/dist/server-rpc-protocol.d.ts +47 -0
- package/dist/server-rpc-protocol.js +109 -0
- package/dist/server-rpc-stream-client.d.ts +5 -0
- package/dist/server-rpc-stream-client.js +98 -0
- package/dist/signals/actions.d.ts +12 -0
- package/dist/signals/actions.js +466 -0
- package/dist/signals/client.d.ts +2 -0
- package/dist/signals/client.js +1 -0
- package/dist/signals/computations.d.ts +37 -0
- package/dist/signals/computations.js +455 -0
- package/dist/signals/control-binding.d.ts +31 -0
- package/dist/signals/control-binding.js +353 -0
- package/dist/signals/derived-facade.d.ts +3 -0
- package/dist/signals/derived-facade.js +25 -0
- package/dist/signals/document-owner.d.ts +10 -0
- package/dist/signals/document-owner.js +43 -0
- package/dist/signals/early-values.d.ts +24 -0
- package/dist/signals/early-values.js +124 -0
- package/dist/signals/encoding.d.ts +1 -3
- package/dist/signals/encoding.js +3 -93
- package/dist/signals/engine.d.ts +53 -4
- package/dist/signals/engine.js +275 -16
- package/dist/signals/errors.d.ts +7 -0
- package/dist/signals/errors.js +16 -0
- package/dist/signals/facade.d.ts +74 -0
- package/dist/signals/facade.js +452 -0
- package/dist/signals/graph.d.ts +52 -6
- package/dist/signals/graph.js +174 -19
- package/dist/signals/handle-protocol.d.ts +4 -0
- package/dist/signals/handle-protocol.js +11 -0
- package/dist/signals/index.d.ts +12 -3
- package/dist/signals/index.js +71 -2
- package/dist/signals/native-read-client.d.ts +3 -0
- package/dist/signals/native-read-client.js +10 -0
- package/dist/signals/owner-context.d.ts +22 -0
- package/dist/signals/owner-context.js +77 -0
- package/dist/signals/query-attempt-observer.d.ts +49 -0
- package/dist/signals/query-attempt-observer.js +41 -0
- package/dist/signals/query-facade.d.ts +3 -0
- package/dist/signals/query-facade.js +49 -0
- package/dist/signals/read-protocol.d.ts +37 -2
- package/dist/signals/read-protocol.js +44 -0
- package/dist/signals/requests.d.ts +38 -5
- package/dist/signals/requests.js +298 -15
- package/dist/signals/scalar-computations.d.ts +2 -0
- package/dist/signals/scalar-computations.js +60 -0
- package/dist/signals/server.d.ts +2 -0
- package/dist/signals/server.js +1 -0
- package/dist/signals/transition-candidate.d.ts +71 -0
- package/dist/signals/transition-candidate.js +557 -0
- package/dist/signals/transition-state.d.ts +51 -0
- package/dist/signals/transition-state.js +70 -0
- package/dist/signals/types.d.ts +95 -5
- package/dist/signals/types.js +20 -0
- package/dist/stream-protocol.d.ts +0 -5
- package/dist/stream-protocol.js +3 -0
- package/dist/streamed-signals-protocol.d.ts +60 -0
- package/dist/streamed-signals-protocol.js +130 -0
- package/dist/style-values.d.ts +3 -0
- package/dist/style-values.js +96 -0
- package/dist/trusted-html.d.ts +17 -0
- package/dist/trusted-html.js +6 -0
- package/dist/universal-core.d.ts +6 -0
- package/dist/universal-core.js +214 -202
- package/dist/version.js +1 -1
- package/package.json +48 -5
package/dist/signals/graph.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
activeCandidate,
|
|
3
|
+
candidateWriteCount,
|
|
4
|
+
deferCandidateInvalidation,
|
|
5
|
+
recordCandidateUrgentWrite,
|
|
6
|
+
registerCandidateGraph,
|
|
7
|
+
withoutSignalCandidate
|
|
8
|
+
} from "./transition-state.js";
|
|
1
9
|
import {
|
|
2
10
|
createReactiveSystem
|
|
3
11
|
} from "alien-signals/system";
|
|
@@ -5,16 +13,27 @@ import {
|
|
|
5
13
|
ScopeDisposedError,
|
|
6
14
|
SignalCycleError,
|
|
7
15
|
SignalFrameError,
|
|
16
|
+
SignalIdleError,
|
|
8
17
|
SignalWriteError
|
|
9
18
|
} from "./errors.js";
|
|
10
19
|
import {
|
|
11
20
|
NativeAdoptionMiss,
|
|
21
|
+
NATIVE_DOM_VALUE,
|
|
22
|
+
getNativeCandidate,
|
|
23
|
+
forwardNativeTransitionConsumer,
|
|
12
24
|
getNativeReadObserver,
|
|
13
25
|
getNativeAdoptionResolver,
|
|
14
26
|
isNativeWriteGuarded,
|
|
15
27
|
reportNativeRead,
|
|
16
28
|
setNativeReadObserver
|
|
17
29
|
} from "./read-protocol.js";
|
|
30
|
+
import {
|
|
31
|
+
SIGNAL_BINDING_READ,
|
|
32
|
+
SIGNAL_BINDING_SUBSCRIBE,
|
|
33
|
+
SIGNAL_BINDING_IDENTITY,
|
|
34
|
+
SIGNAL_HANDLE
|
|
35
|
+
} from "./types.js";
|
|
36
|
+
import { CandidateUnsupportedError } from "./transition-state.js";
|
|
18
37
|
const ReactiveFlags = {
|
|
19
38
|
None: 0,
|
|
20
39
|
Mutable: 1,
|
|
@@ -53,7 +72,15 @@ const graph = createReactiveSystem({
|
|
|
53
72
|
node.flags |= ReactiveFlags.Dirty;
|
|
54
73
|
}
|
|
55
74
|
node.owner.trace("invalidate", node);
|
|
56
|
-
if (node.
|
|
75
|
+
if (node.invalidateAttempt) {
|
|
76
|
+
if (deferCandidateInvalidation) {
|
|
77
|
+
const invalidate = node.invalidateAttempt;
|
|
78
|
+
queued.add(() => {
|
|
79
|
+
if (node.invalidateAttempt === invalidate) invalidate();
|
|
80
|
+
});
|
|
81
|
+
} else node.invalidateAttempt();
|
|
82
|
+
queued.add(node);
|
|
83
|
+
} else if (node.kind === "async") queued.add(node);
|
|
57
84
|
} else {
|
|
58
85
|
queued.add(node);
|
|
59
86
|
}
|
|
@@ -94,6 +121,9 @@ function untrack(run) {
|
|
|
94
121
|
setNativeReadObserver(previousObserver);
|
|
95
122
|
}
|
|
96
123
|
}
|
|
124
|
+
function untrackCommitted(run) {
|
|
125
|
+
return withoutSignalCandidate(() => untrack(run));
|
|
126
|
+
}
|
|
97
127
|
function startSignalBatch() {
|
|
98
128
|
batchDepth++;
|
|
99
129
|
}
|
|
@@ -171,6 +201,16 @@ function pendingState(waiting, connection = "none", requestKey, resolveWaiting)
|
|
|
171
201
|
...resolveWaiting ? { resolveWaiting } : {}
|
|
172
202
|
};
|
|
173
203
|
}
|
|
204
|
+
function idleState() {
|
|
205
|
+
return {
|
|
206
|
+
snapshot: {
|
|
207
|
+
status: "idle",
|
|
208
|
+
refreshing: false,
|
|
209
|
+
connection: "none",
|
|
210
|
+
complete: false
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
174
214
|
function sameOwners(a, b) {
|
|
175
215
|
if (a.owners === b.owners) return true;
|
|
176
216
|
if ((a.owners?.size ?? 0) !== (b.owners?.size ?? 0)) return false;
|
|
@@ -270,6 +310,9 @@ class ScopedNode {
|
|
|
270
310
|
owner;
|
|
271
311
|
key;
|
|
272
312
|
kind;
|
|
313
|
+
get [SIGNAL_HANDLE]() {
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
273
316
|
deps;
|
|
274
317
|
depsTail;
|
|
275
318
|
subs;
|
|
@@ -278,6 +321,7 @@ class ScopedNode {
|
|
|
278
321
|
revision = 0;
|
|
279
322
|
state;
|
|
280
323
|
compute;
|
|
324
|
+
invalidateAttempt;
|
|
281
325
|
last;
|
|
282
326
|
lastState;
|
|
283
327
|
hasLast = false;
|
|
@@ -291,18 +335,49 @@ class ScopedNode {
|
|
|
291
335
|
throw new TypeError("Only an async signal can be retried.");
|
|
292
336
|
}
|
|
293
337
|
get() {
|
|
294
|
-
return strictValue(readNode(this));
|
|
338
|
+
return strictValue(readNode(this), this.key);
|
|
339
|
+
}
|
|
340
|
+
[SIGNAL_BINDING_READ]() {
|
|
341
|
+
return readSignalBinding(this);
|
|
342
|
+
}
|
|
343
|
+
[SIGNAL_BINDING_SUBSCRIBE](notify, onRetire) {
|
|
344
|
+
assertAlive(this.owner);
|
|
345
|
+
return attachObserver(
|
|
346
|
+
this,
|
|
347
|
+
onRetire === void 0 ? notify : forwardNativeTransitionConsumer(
|
|
348
|
+
notify,
|
|
349
|
+
() => this.owner.retired ? onRetire() : notify()
|
|
350
|
+
),
|
|
351
|
+
true
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
[SIGNAL_BINDING_IDENTITY]() {
|
|
355
|
+
return { scope: "instance", nodeKey: this.key };
|
|
356
|
+
}
|
|
357
|
+
[NATIVE_DOM_VALUE]() {
|
|
358
|
+
return this.get();
|
|
295
359
|
}
|
|
296
360
|
set(value) {
|
|
297
361
|
assertAlive(this.owner);
|
|
298
362
|
assertWritable();
|
|
299
363
|
if (this.kind !== "signal") throw new TypeError("Only a writable signal accepts set().");
|
|
364
|
+
const candidate = activeCandidate ?? getNativeCandidate();
|
|
365
|
+
if (candidate) {
|
|
366
|
+
candidate.run(() => candidate.write(this, value));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
300
369
|
signalBatch(() => {
|
|
301
|
-
const previous = strictValue(refreshNode(this));
|
|
370
|
+
const previous = strictValue(refreshNode(this), this.key);
|
|
302
371
|
const next = typeof value === "function" ? untrack(() => pure(() => value(previous))) : value;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
372
|
+
const releases = candidateWriteCount ? recordCandidateUrgentWrite(this, value) : void 0;
|
|
373
|
+
try {
|
|
374
|
+
if (!Object.is(previous, next)) {
|
|
375
|
+
publishNode(this, readyState(next));
|
|
376
|
+
this.owner.trace("write", this);
|
|
377
|
+
}
|
|
378
|
+
} finally {
|
|
379
|
+
if (releases) for (const release of releases) release();
|
|
380
|
+
}
|
|
306
381
|
});
|
|
307
382
|
}
|
|
308
383
|
latest(fallback) {
|
|
@@ -352,8 +427,21 @@ function inspectNativeNode(node, read) {
|
|
|
352
427
|
dependencies
|
|
353
428
|
};
|
|
354
429
|
}
|
|
430
|
+
function createNativeSource(node, read) {
|
|
431
|
+
return {
|
|
432
|
+
getVersion: () => activeCandidate && !activeCandidate.observes(node) ? NaN : node.revision,
|
|
433
|
+
subscribe: (notify) => {
|
|
434
|
+
assertAlive(node.owner);
|
|
435
|
+
return attachObserver(node, notify, true);
|
|
436
|
+
},
|
|
437
|
+
serialize: (revision) => node.revision === revision ? node.owner.serializeRead(node, read) : void 0,
|
|
438
|
+
inspect: () => inspectNativeNode(node, read)
|
|
439
|
+
};
|
|
440
|
+
}
|
|
355
441
|
function readNode(node, read = "value") {
|
|
356
442
|
assertAlive(node.owner);
|
|
443
|
+
const candidate = activeCandidate;
|
|
444
|
+
if (candidate) node = candidate.resolve(node);
|
|
357
445
|
const historical = historicalReader?.(node, read);
|
|
358
446
|
if (historical) return historical;
|
|
359
447
|
if (!historicalReader && node.owner.seedable) {
|
|
@@ -365,27 +453,35 @@ function readNode(node, read = "value") {
|
|
|
365
453
|
if (activeNode) graph.link(node, activeNode, trackingCycle);
|
|
366
454
|
if (getNativeReadObserver()) {
|
|
367
455
|
const field = read === "value" ? "nativeSource" : read === "latest" ? "nativeLatestSource" : "nativeSnapshotSource";
|
|
368
|
-
const source = node[field] ??=
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
},
|
|
374
|
-
serialize: (revision) => node.revision === revision ? node.owner.serializeRead(node, read) : void 0,
|
|
375
|
-
inspect: () => inspectNativeNode(node, read)
|
|
376
|
-
};
|
|
377
|
-
reportNativeRead(source, node.revision);
|
|
456
|
+
const source = node[field] ??= createNativeSource(node, read);
|
|
457
|
+
reportNativeRead(
|
|
458
|
+
candidate ? candidate.nativeSource(node, read, source) : source,
|
|
459
|
+
node.revision
|
|
460
|
+
);
|
|
378
461
|
}
|
|
379
462
|
if (observed.owners) for (const owner of observed.owners) assertAlive(owner);
|
|
380
463
|
if (activeNode) recordOwners(node, observed);
|
|
381
464
|
return observed;
|
|
382
465
|
}
|
|
383
|
-
function strictValue(state) {
|
|
466
|
+
function strictValue(state, key = "idle") {
|
|
384
467
|
const snapshot = state.snapshot;
|
|
385
468
|
if (snapshot.status === "ready") return snapshot.value;
|
|
386
469
|
if (snapshot.status === "error") throw snapshot.error;
|
|
470
|
+
if (snapshot.status === "idle") throw new SignalIdleError(key);
|
|
387
471
|
throw state.waiting;
|
|
388
472
|
}
|
|
473
|
+
function readSignalBinding(handle$) {
|
|
474
|
+
const resolveAdoption = getNativeAdoptionResolver();
|
|
475
|
+
if ((historicalReader || resolveAdoption) && handle$ instanceof ScopedNode && handle$.owner.seedable && (historicalReader || resolveAdoption?.(handle$.owner))) {
|
|
476
|
+
return handle$.get();
|
|
477
|
+
}
|
|
478
|
+
const observer = setNativeReadObserver(null);
|
|
479
|
+
try {
|
|
480
|
+
return handle$.get();
|
|
481
|
+
} finally {
|
|
482
|
+
setNativeReadObserver(observer);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
389
485
|
function refreshNode(node) {
|
|
390
486
|
assertAlive(node.owner);
|
|
391
487
|
if (node.evaluating) throw new SignalCycleError(node.key);
|
|
@@ -428,7 +524,7 @@ function evaluate(node) {
|
|
|
428
524
|
let next;
|
|
429
525
|
let owners;
|
|
430
526
|
try {
|
|
431
|
-
next = node.compute();
|
|
527
|
+
next = node.compute(node);
|
|
432
528
|
} catch (error) {
|
|
433
529
|
if (isThenable(error)) {
|
|
434
530
|
const wakeup = node.wakeup ??= createWakeup();
|
|
@@ -497,9 +593,17 @@ function invalidateNode(node) {
|
|
|
497
593
|
function derivedState(node, read) {
|
|
498
594
|
const value = pure(read);
|
|
499
595
|
if (isThenable(value)) throw new TypeError("derived$ requires a synchronous computation.");
|
|
596
|
+
return derivedValueState(node, value);
|
|
597
|
+
}
|
|
598
|
+
function derivedValueState(node, value, activity, additionalDependencies) {
|
|
500
599
|
let refreshing = false;
|
|
501
600
|
let complete = true;
|
|
502
601
|
let connection = "none";
|
|
602
|
+
if (activity) {
|
|
603
|
+
refreshing = activity.refreshing;
|
|
604
|
+
complete = activity.complete;
|
|
605
|
+
connection = activity.connection;
|
|
606
|
+
}
|
|
503
607
|
for (let link = node.deps; link && node.depsTail; link = link.nextDep) {
|
|
504
608
|
const dependency = link.dep.state?.snapshot;
|
|
505
609
|
if (dependency) {
|
|
@@ -512,6 +616,18 @@ function derivedState(node, read) {
|
|
|
512
616
|
}
|
|
513
617
|
if (link === node.depsTail) break;
|
|
514
618
|
}
|
|
619
|
+
if (additionalDependencies) {
|
|
620
|
+
for (const node2 of additionalDependencies) {
|
|
621
|
+
const dependency = node2.state?.snapshot;
|
|
622
|
+
if (!dependency) continue;
|
|
623
|
+
refreshing ||= dependency.refreshing;
|
|
624
|
+
complete &&= dependency.complete;
|
|
625
|
+
if (dependency.connection === "open") connection = "open";
|
|
626
|
+
else if (connection !== "open" && dependency.connection === "connecting")
|
|
627
|
+
connection = "connecting";
|
|
628
|
+
else if (connection === "none" && dependency.connection === "closed") connection = "closed";
|
|
629
|
+
}
|
|
630
|
+
}
|
|
515
631
|
return readyState(value, { refreshing, complete, connection });
|
|
516
632
|
}
|
|
517
633
|
class SignalObserver {
|
|
@@ -535,6 +651,10 @@ function attachObserver(node, notify, native, state) {
|
|
|
535
651
|
node.owner.observers.add(observer);
|
|
536
652
|
return () => stopObserver(observer);
|
|
537
653
|
}
|
|
654
|
+
function subscribeNode(node, notify) {
|
|
655
|
+
const state = untrack(() => refreshNode(node));
|
|
656
|
+
return attachObserver(node, notify, true, state);
|
|
657
|
+
}
|
|
538
658
|
function runObserver(observer) {
|
|
539
659
|
const node = observer.node;
|
|
540
660
|
if (!node || !observer.flags) return;
|
|
@@ -574,6 +694,7 @@ function retireGraph(owner, nodes) {
|
|
|
574
694
|
node.state = errorState(retirementError);
|
|
575
695
|
releaseRetention(node);
|
|
576
696
|
node.compute = void 0;
|
|
697
|
+
node.invalidateAttempt = void 0;
|
|
577
698
|
if (node.kind === "async") node.retry = ScopedNode.prototype.retry;
|
|
578
699
|
if (node.subs) {
|
|
579
700
|
graph.propagate(node.subs, executionDepth !== 0);
|
|
@@ -587,14 +708,45 @@ function retireGraph(owner, nodes) {
|
|
|
587
708
|
retirementError = previousError;
|
|
588
709
|
}
|
|
589
710
|
}
|
|
711
|
+
registerCandidateGraph({
|
|
712
|
+
ScopedNode,
|
|
713
|
+
graph,
|
|
714
|
+
flags: ReactiveFlags,
|
|
715
|
+
historical: () => historicalReader !== void 0,
|
|
716
|
+
link: (from, to) => {
|
|
717
|
+
graph.link(from, to, ++trackingCycle);
|
|
718
|
+
},
|
|
719
|
+
removeQueued: (node) => {
|
|
720
|
+
queued.delete(node);
|
|
721
|
+
},
|
|
722
|
+
assertAlive,
|
|
723
|
+
strictValue,
|
|
724
|
+
refreshNode,
|
|
725
|
+
pure,
|
|
726
|
+
untrack,
|
|
727
|
+
signalBatch,
|
|
728
|
+
publishNode,
|
|
729
|
+
readyState,
|
|
730
|
+
commitState,
|
|
731
|
+
sameState,
|
|
732
|
+
releaseRetainedOwners,
|
|
733
|
+
retainOwners,
|
|
734
|
+
releaseRetention,
|
|
735
|
+
createNativeSource,
|
|
736
|
+
attachObserver
|
|
737
|
+
});
|
|
590
738
|
export {
|
|
739
|
+
CandidateUnsupportedError,
|
|
591
740
|
ScopedNode,
|
|
592
741
|
SignalObserver,
|
|
593
742
|
assertAlive,
|
|
594
743
|
assertWritable,
|
|
744
|
+
attachObserver,
|
|
595
745
|
derivedState,
|
|
746
|
+
derivedValueState,
|
|
596
747
|
endSignalBatch,
|
|
597
748
|
errorState,
|
|
749
|
+
idleState,
|
|
598
750
|
inspectNativeNode,
|
|
599
751
|
invalidateNode,
|
|
600
752
|
isThenable,
|
|
@@ -602,6 +754,7 @@ export {
|
|
|
602
754
|
publishNode,
|
|
603
755
|
pure,
|
|
604
756
|
readNode,
|
|
757
|
+
readSignalBinding,
|
|
605
758
|
readyState,
|
|
606
759
|
refreshNode,
|
|
607
760
|
releaseRetention,
|
|
@@ -612,5 +765,7 @@ export {
|
|
|
612
765
|
startSignalBatch,
|
|
613
766
|
stopObserver,
|
|
614
767
|
strictValue,
|
|
615
|
-
|
|
768
|
+
subscribeNode,
|
|
769
|
+
untrack,
|
|
770
|
+
untrackCommitted
|
|
616
771
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type SignalHandle, type WritableSignal } from './types.js';
|
|
2
|
+
/** Native handle capability checks must not import the graph or create an owner. */
|
|
3
|
+
export declare function isSignalHandle(value: unknown): value is SignalHandle<unknown>;
|
|
4
|
+
export declare function isWritableSignal(value: unknown): value is WritableSignal<unknown>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SIGNAL_HANDLE } from "./types.js";
|
|
2
|
+
function isSignalHandle(value) {
|
|
3
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && value[SIGNAL_HANDLE] === true;
|
|
4
|
+
}
|
|
5
|
+
function isWritableSignal(value) {
|
|
6
|
+
return isSignalHandle(value) && value.kind === "signal" && typeof value.set === "function";
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
isSignalHandle,
|
|
10
|
+
isWritableSignal
|
|
11
|
+
};
|
package/dist/signals/index.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
/** Stable scoped signals. This entry does not import a renderer. */
|
|
2
2
|
export { createScope } from './engine.js';
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export
|
|
3
|
+
export { bindSignalControl } from './control-binding.js';
|
|
4
|
+
export { enableSignalDocument as __enableSignalDocument } from './document-owner.js';
|
|
5
|
+
export { createResource, query } from './requests.js';
|
|
6
|
+
export { ActionUncertainError, action$, isActionUncertain, optimistic$ } from './actions.js';
|
|
7
|
+
export { __derivedAt, derived$ } from './derived-facade.js';
|
|
8
|
+
export { __queryAt, query$ } from './query-facade.js';
|
|
9
|
+
export { isSignalHandle, isWritableSignal } from './handle-protocol.js';
|
|
10
|
+
export { __derivedScalarAt, __signalAt, __startSignalReads, acceptStreamedSignalResult, attachStreamedSignalResult, bindStreamedSignalSelection, readSignalBinding, failStreamedSignalResult, signal$, } from './facade.js';
|
|
11
|
+
export { captureSignalOwner, currentSignalOwner, installSignalOwnerEnvironment, retireSignalOwnerIdentity, runWithSignalOwner, } from './owner-context.js';
|
|
12
|
+
export { ScopeDisposedError, SignalCycleError, SignalFrameError, SignalIdleError, SignalSerializationError, SignalStreamError, SignalWriteError, } from './errors.js';
|
|
13
|
+
export { QUERY_REQUEST, SIGNAL_BINDING_IDENTITY, SIGNAL_BINDING_READ, SIGNAL_BINDING_SUBSCRIBE, SIGNAL_HANDLE, skip, } from './types.js';
|
|
14
|
+
export type { AdoptionFrame, ActionOperation, ActionUncertain, ConnectionState, DerivedCompute, DerivedContext, DerivedOptions, DerivedSignal, EncodedSignalValue, Query, QueryContext, QueryLoadResult, QueryOptions, QueryRequest, QuerySignal, Resource, OptimisticOptions, OptimisticSignal, Scope, ScopeInspection, ScopeOptions, ScopeSeed, SignalHandle, SignalOptions, SignalBindingIdentity, SignalAction, SignalOwner, SignalOwnerEnvironment, SignalOwnerIdentity, SignalRendererOwnerIdentity, SignalSeedEntry, SignalSnapshot, SignalTraceEvent, WritableSignal, } from './types.js';
|
package/dist/signals/index.js
CHANGED
|
@@ -1,18 +1,87 @@
|
|
|
1
1
|
import { createScope } from "./engine.js";
|
|
2
|
-
import {
|
|
2
|
+
import { bindSignalControl } from "./control-binding.js";
|
|
3
|
+
import { enableSignalDocument } from "./document-owner.js";
|
|
4
|
+
import { createResource, query } from "./requests.js";
|
|
5
|
+
import { ActionUncertainError, action$, isActionUncertain, optimistic$ } from "./actions.js";
|
|
6
|
+
import { __derivedAt, derived$ } from "./derived-facade.js";
|
|
7
|
+
import { __queryAt, query$ } from "./query-facade.js";
|
|
8
|
+
import { isSignalHandle, isWritableSignal } from "./handle-protocol.js";
|
|
9
|
+
import {
|
|
10
|
+
__derivedScalarAt,
|
|
11
|
+
__signalAt,
|
|
12
|
+
__startSignalReads,
|
|
13
|
+
acceptStreamedSignalResult,
|
|
14
|
+
attachStreamedSignalResult,
|
|
15
|
+
bindStreamedSignalSelection,
|
|
16
|
+
readSignalBinding,
|
|
17
|
+
failStreamedSignalResult,
|
|
18
|
+
signal$
|
|
19
|
+
} from "./facade.js";
|
|
20
|
+
import {
|
|
21
|
+
captureSignalOwner,
|
|
22
|
+
currentSignalOwner,
|
|
23
|
+
installSignalOwnerEnvironment,
|
|
24
|
+
retireSignalOwnerIdentity,
|
|
25
|
+
runWithSignalOwner
|
|
26
|
+
} from "./owner-context.js";
|
|
3
27
|
import {
|
|
4
28
|
ScopeDisposedError,
|
|
5
29
|
SignalCycleError,
|
|
6
30
|
SignalFrameError,
|
|
31
|
+
SignalIdleError,
|
|
7
32
|
SignalSerializationError,
|
|
33
|
+
SignalStreamError,
|
|
8
34
|
SignalWriteError
|
|
9
35
|
} from "./errors.js";
|
|
36
|
+
import {
|
|
37
|
+
QUERY_REQUEST,
|
|
38
|
+
SIGNAL_BINDING_IDENTITY,
|
|
39
|
+
SIGNAL_BINDING_READ,
|
|
40
|
+
SIGNAL_BINDING_SUBSCRIBE,
|
|
41
|
+
SIGNAL_HANDLE,
|
|
42
|
+
skip
|
|
43
|
+
} from "./types.js";
|
|
10
44
|
export {
|
|
45
|
+
ActionUncertainError,
|
|
46
|
+
QUERY_REQUEST,
|
|
47
|
+
SIGNAL_BINDING_IDENTITY,
|
|
48
|
+
SIGNAL_BINDING_READ,
|
|
49
|
+
SIGNAL_BINDING_SUBSCRIBE,
|
|
50
|
+
SIGNAL_HANDLE,
|
|
11
51
|
ScopeDisposedError,
|
|
12
52
|
SignalCycleError,
|
|
13
53
|
SignalFrameError,
|
|
54
|
+
SignalIdleError,
|
|
14
55
|
SignalSerializationError,
|
|
56
|
+
SignalStreamError,
|
|
15
57
|
SignalWriteError,
|
|
58
|
+
__derivedAt,
|
|
59
|
+
__derivedScalarAt,
|
|
60
|
+
enableSignalDocument as __enableSignalDocument,
|
|
61
|
+
__queryAt,
|
|
62
|
+
__signalAt,
|
|
63
|
+
__startSignalReads,
|
|
64
|
+
acceptStreamedSignalResult,
|
|
65
|
+
action$,
|
|
66
|
+
attachStreamedSignalResult,
|
|
67
|
+
bindSignalControl,
|
|
68
|
+
bindStreamedSignalSelection,
|
|
69
|
+
captureSignalOwner,
|
|
70
|
+
createResource,
|
|
16
71
|
createScope,
|
|
17
|
-
|
|
72
|
+
currentSignalOwner,
|
|
73
|
+
derived$,
|
|
74
|
+
failStreamedSignalResult,
|
|
75
|
+
installSignalOwnerEnvironment,
|
|
76
|
+
isActionUncertain,
|
|
77
|
+
isSignalHandle,
|
|
78
|
+
isWritableSignal,
|
|
79
|
+
optimistic$,
|
|
80
|
+
query,
|
|
81
|
+
query$,
|
|
82
|
+
readSignalBinding,
|
|
83
|
+
retireSignalOwnerIdentity,
|
|
84
|
+
runWithSignalOwner,
|
|
85
|
+
signal$,
|
|
86
|
+
skip
|
|
18
87
|
};
|
|
@@ -4,6 +4,9 @@ interface NativeReadHost {
|
|
|
4
4
|
capture(): object | null;
|
|
5
5
|
cleanup(scope: Scope, dispose: () => void): void;
|
|
6
6
|
schedule(block: Block): void;
|
|
7
|
+
/** Candidate admission renders this exact subscribed owner without notifying it. */
|
|
8
|
+
prepare?(block: Block): void;
|
|
9
|
+
retire?(block: Block): void;
|
|
7
10
|
/** Reuse current ref manifests after a superseding root commits. */
|
|
8
11
|
replayRefs(capture: object, owner: PublicationOwner): boolean;
|
|
9
12
|
refDisposed(entry: object): boolean;
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
createNativeReadCollector,
|
|
3
3
|
validateNativeReadWitness
|
|
4
4
|
} from "./native-read-collector.js";
|
|
5
|
+
import { NATIVE_TRANSITION_CONSUMER } from "./read-protocol.js";
|
|
5
6
|
import { inspectNativeReadWitness } from "./native-read-inspection.js";
|
|
6
7
|
function createNativeReadDriver(host) {
|
|
7
8
|
const consumers = /* @__PURE__ */ new WeakMap();
|
|
@@ -37,6 +38,7 @@ function createNativeReadDriver(host) {
|
|
|
37
38
|
function disposeConsumer(consumer) {
|
|
38
39
|
if (consumer.disposed) return;
|
|
39
40
|
consumer.disposed = true;
|
|
41
|
+
host.retire?.(consumer.block);
|
|
40
42
|
if (consumer.committed !== null) release(consumer.committed);
|
|
41
43
|
consumer.committed = null;
|
|
42
44
|
for (const candidate of consumer.pending) release(candidate);
|
|
@@ -59,6 +61,14 @@ function createNativeReadDriver(host) {
|
|
|
59
61
|
};
|
|
60
62
|
consumers.set(scope, consumer);
|
|
61
63
|
const owned = consumer;
|
|
64
|
+
if (host.prepare !== void 0) {
|
|
65
|
+
Object.assign(owned.notify, {
|
|
66
|
+
[NATIVE_TRANSITION_CONSUMER]: {
|
|
67
|
+
active: () => !owned.disposed && !owned.block.disposed,
|
|
68
|
+
prepare: () => host.prepare(owned.block)
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
62
72
|
host.cleanup(scope, () => disposeConsumer(owned));
|
|
63
73
|
}
|
|
64
74
|
return consumer;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SignalOwner, SignalOwnerEnvironment } from './types.js';
|
|
2
|
+
declare let installedEnvironment: SignalOwnerEnvironment | undefined;
|
|
3
|
+
declare let synchronousOwner: SignalOwner | null;
|
|
4
|
+
/** @internal Live capability guards; reading them never installs a default owner. */
|
|
5
|
+
export { installedEnvironment as activeSignalOwnerEnvironment, synchronousOwner as activeSynchronousSignalOwner, };
|
|
6
|
+
/** Install a concurrency-safe owner carrier without importing the signal engine. */
|
|
7
|
+
export declare function installSignalOwnerEnvironment(environment: SignalOwnerEnvironment): () => void;
|
|
8
|
+
export declare function currentSignalOwner(): SignalOwner | null;
|
|
9
|
+
/** @internal Distinguish an active owner frame from the lazy document fallback. */
|
|
10
|
+
export declare function currentExplicitSignalOwner(): SignalOwner | null;
|
|
11
|
+
/** @internal Client renderer installs its lazy document owner, never a last-root owner. */
|
|
12
|
+
export declare function installDefaultSignalOwner(current: () => SignalOwner | null): () => void;
|
|
13
|
+
/** Enter an owner for a synchronous declaration, read, write, or callback. */
|
|
14
|
+
export declare function runWithSignalOwner<T>(owner: SignalOwner, callback: () => T): T;
|
|
15
|
+
/** @internal Synchronous SSR entry without retaining a callback frame per component. */
|
|
16
|
+
export declare function enterSynchronousSignalOwner(owner: SignalOwner): SignalOwner | null | undefined;
|
|
17
|
+
/** @internal Pair with a successful synchronous entry in a finally block. */
|
|
18
|
+
export declare function restoreSynchronousSignalOwner(previous: SignalOwner | null): void;
|
|
19
|
+
export declare function captureSignalOwner(owner: SignalOwner): <T>(callback: () => T) => T;
|
|
20
|
+
/** Retire renderer-created identity state without linking the renderer to the engine. */
|
|
21
|
+
export declare function retireSignalOwnerIdentity(owner: SignalOwner): void;
|
|
22
|
+
export declare function installSignalOwnerRetirement(retire: (owner: SignalOwner) => void): () => void;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
let installedEnvironment;
|
|
2
|
+
let synchronousOwner = null;
|
|
3
|
+
let defaultOwner;
|
|
4
|
+
let retireOwner;
|
|
5
|
+
function installSignalOwnerEnvironment(environment) {
|
|
6
|
+
if (!environment || typeof environment.current !== "function" || typeof environment.run !== "function" || typeof environment.capture !== "function") {
|
|
7
|
+
throw new TypeError("A signal owner environment requires current, run, and capture.");
|
|
8
|
+
}
|
|
9
|
+
const previous = installedEnvironment;
|
|
10
|
+
installedEnvironment = environment;
|
|
11
|
+
return () => {
|
|
12
|
+
if (installedEnvironment === environment) installedEnvironment = previous;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function currentSignalOwner() {
|
|
16
|
+
if (installedEnvironment !== void 0) return installedEnvironment.current() ?? synchronousOwner;
|
|
17
|
+
return synchronousOwner ?? defaultOwner?.() ?? null;
|
|
18
|
+
}
|
|
19
|
+
function currentExplicitSignalOwner() {
|
|
20
|
+
return installedEnvironment?.current() ?? synchronousOwner;
|
|
21
|
+
}
|
|
22
|
+
function installDefaultSignalOwner(current) {
|
|
23
|
+
if (typeof current !== "function")
|
|
24
|
+
throw new TypeError("A default signal owner requires a provider.");
|
|
25
|
+
const previous = defaultOwner;
|
|
26
|
+
defaultOwner = current;
|
|
27
|
+
return () => {
|
|
28
|
+
if (defaultOwner === current) defaultOwner = previous;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function runWithSignalOwner(owner, callback) {
|
|
32
|
+
if (typeof callback !== "function") throw new TypeError("A signal owner callback is required.");
|
|
33
|
+
if (installedEnvironment) return installedEnvironment.run(owner, callback);
|
|
34
|
+
const previous = synchronousOwner;
|
|
35
|
+
synchronousOwner = owner;
|
|
36
|
+
try {
|
|
37
|
+
return callback();
|
|
38
|
+
} finally {
|
|
39
|
+
synchronousOwner = previous;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function enterSynchronousSignalOwner(owner) {
|
|
43
|
+
if (installedEnvironment !== void 0) return void 0;
|
|
44
|
+
const previous = synchronousOwner;
|
|
45
|
+
synchronousOwner = owner;
|
|
46
|
+
return previous;
|
|
47
|
+
}
|
|
48
|
+
function restoreSynchronousSignalOwner(previous) {
|
|
49
|
+
synchronousOwner = previous;
|
|
50
|
+
}
|
|
51
|
+
function captureSignalOwner(owner) {
|
|
52
|
+
return installedEnvironment?.capture(owner) ?? ((callback) => runWithSignalOwner(owner, callback));
|
|
53
|
+
}
|
|
54
|
+
function retireSignalOwnerIdentity(owner) {
|
|
55
|
+
retireOwner?.(owner);
|
|
56
|
+
}
|
|
57
|
+
function installSignalOwnerRetirement(retire) {
|
|
58
|
+
const previous = retireOwner;
|
|
59
|
+
retireOwner = retire;
|
|
60
|
+
return () => {
|
|
61
|
+
if (retireOwner === retire) retireOwner = previous;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
installedEnvironment as activeSignalOwnerEnvironment,
|
|
66
|
+
synchronousOwner as activeSynchronousSignalOwner,
|
|
67
|
+
captureSignalOwner,
|
|
68
|
+
currentExplicitSignalOwner,
|
|
69
|
+
currentSignalOwner,
|
|
70
|
+
enterSynchronousSignalOwner,
|
|
71
|
+
installDefaultSignalOwner,
|
|
72
|
+
installSignalOwnerEnvironment,
|
|
73
|
+
installSignalOwnerRetirement,
|
|
74
|
+
restoreSynchronousSignalOwner,
|
|
75
|
+
retireSignalOwnerIdentity,
|
|
76
|
+
runWithSignalOwner
|
|
77
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { SignalRendererOwnerIdentity } from './types.js';
|
|
2
|
+
export interface ServerSignalQueryAttempt {
|
|
3
|
+
readonly ownerKey: string;
|
|
4
|
+
readonly instanceKey: string;
|
|
5
|
+
readonly nodeKey: string;
|
|
6
|
+
readonly selectionKey: string;
|
|
7
|
+
readonly attempt: number;
|
|
8
|
+
readonly kind: 'promise' | 'stream';
|
|
9
|
+
readonly result: unknown;
|
|
10
|
+
readonly signal: AbortSignal;
|
|
11
|
+
readonly isCurrent: () => boolean;
|
|
12
|
+
/** Stop retaining and backpressuring this renderer observation. */
|
|
13
|
+
readonly release: () => void;
|
|
14
|
+
}
|
|
15
|
+
export type ServerSignalQueryAttemptObserver = (attempt: ServerSignalQueryAttempt) => void;
|
|
16
|
+
export interface ServerSignalQueryAttemptObserverContext {
|
|
17
|
+
readonly owner: SignalRendererOwnerIdentity;
|
|
18
|
+
readonly observe: ServerSignalQueryAttemptObserver;
|
|
19
|
+
readonly createObservations: () => ServerSignalQueryAttemptObservations;
|
|
20
|
+
}
|
|
21
|
+
export interface ServerSignalQueryAttemptSource {
|
|
22
|
+
readonly nodeKey: string;
|
|
23
|
+
readonly selectionKey: string;
|
|
24
|
+
readonly attempt: number;
|
|
25
|
+
readonly kind: 'promise' | 'stream';
|
|
26
|
+
readonly result: unknown;
|
|
27
|
+
readonly isCurrent: () => boolean;
|
|
28
|
+
}
|
|
29
|
+
/** The shared request engine owns a lease, not the server's transport mirrors. */
|
|
30
|
+
export interface ServerSignalQueryAttemptObservations {
|
|
31
|
+
observe(context: ServerSignalQueryAttemptObserverContext, source: ServerSignalQueryAttemptSource): void;
|
|
32
|
+
publish(value: unknown): Promise<void> | undefined;
|
|
33
|
+
complete(): void;
|
|
34
|
+
fail(error: unknown): void;
|
|
35
|
+
retire(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Install a synchronous renderer observation context around authored server
|
|
39
|
+
* signal work. The context is restored before a returned promise can suspend,
|
|
40
|
+
* so concurrent requests cannot inherit one another's observer.
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare function runWithServerSignalQueryAttemptObserver<T>(owner: SignalRendererOwnerIdentity, observe: ServerSignalQueryAttemptObserver, createObservations: () => ServerSignalQueryAttemptObservations, callback: () => T): T;
|
|
45
|
+
/** @internal Keep the browser/query fast path allocation-free when no server observer matches. */
|
|
46
|
+
export declare function serverSignalQueryAttemptObserver(scopeKey: string): ServerSignalQueryAttemptObserverContext | undefined;
|
|
47
|
+
export declare function hasServerSignalQueryAttemptObserver(scopeKey: string): boolean;
|
|
48
|
+
/** @internal Preserve observation across a pending query description, not an async context. */
|
|
49
|
+
export declare function captureCurrentServerSignalQueryAttemptObserver(scopeKey: string): (<T>(callback: () => T) => T) | undefined;
|