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/encoding.js
CHANGED
|
@@ -1,96 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
function unsupported() {
|
|
3
|
-
throw new SignalSerializationError(
|
|
4
|
-
"Signal request arguments and seeds require acyclic plain data: undefined, null, booleans, finite numbers, strings, dense arrays, and plain objects with enumerable string data properties."
|
|
5
|
-
);
|
|
6
|
-
}
|
|
7
|
-
function encodeSignalValue(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
8
|
-
if (value === void 0) return ["undefined"];
|
|
9
|
-
if (value === null) return ["null"];
|
|
10
|
-
if (typeof value === "boolean") return ["boolean", value];
|
|
11
|
-
if (typeof value === "string") return ["string", value];
|
|
12
|
-
if (typeof value === "number") {
|
|
13
|
-
if (!Number.isFinite(value)) return unsupported();
|
|
14
|
-
return ["number", Object.is(value, -0) ? "-0" : value];
|
|
15
|
-
}
|
|
16
|
-
if (typeof value !== "object" || ancestors.has(value)) return unsupported();
|
|
17
|
-
const prototype = Object.getPrototypeOf(value);
|
|
18
|
-
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {
|
|
19
|
-
return unsupported();
|
|
20
|
-
}
|
|
21
|
-
ancestors.add(value);
|
|
22
|
-
try {
|
|
23
|
-
if (Array.isArray(value)) {
|
|
24
|
-
const keys2 = Reflect.ownKeys(value);
|
|
25
|
-
if (keys2.length !== value.length + 1) return unsupported();
|
|
26
|
-
const items = [];
|
|
27
|
-
for (let i = 0; i < value.length; i++) {
|
|
28
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, String(i));
|
|
29
|
-
if (!descriptor || !descriptor.enumerable || !("value" in descriptor)) return unsupported();
|
|
30
|
-
items.push(encodeSignalValue(descriptor.value, ancestors));
|
|
31
|
-
}
|
|
32
|
-
return ["array", items];
|
|
33
|
-
}
|
|
34
|
-
const keys = Reflect.ownKeys(value);
|
|
35
|
-
if (keys.some((key) => typeof key !== "string")) return unsupported();
|
|
36
|
-
const entries = [];
|
|
37
|
-
for (const key of keys.sort()) {
|
|
38
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
39
|
-
if (!descriptor.enumerable || !("value" in descriptor)) return unsupported();
|
|
40
|
-
entries.push([key, encodeSignalValue(descriptor.value, ancestors)]);
|
|
41
|
-
}
|
|
42
|
-
return ["object", entries];
|
|
43
|
-
} finally {
|
|
44
|
-
ancestors.delete(value);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function decodeSignalValue(encoded) {
|
|
48
|
-
if (!Array.isArray(encoded)) return unsupported();
|
|
49
|
-
const [tag, value] = encoded;
|
|
50
|
-
switch (tag) {
|
|
51
|
-
case "undefined":
|
|
52
|
-
if (encoded.length !== 1) return unsupported();
|
|
53
|
-
return void 0;
|
|
54
|
-
case "null":
|
|
55
|
-
if (encoded.length !== 1) return unsupported();
|
|
56
|
-
return null;
|
|
57
|
-
case "boolean":
|
|
58
|
-
if (encoded.length !== 2 || typeof value !== "boolean") return unsupported();
|
|
59
|
-
return value;
|
|
60
|
-
case "number":
|
|
61
|
-
if (encoded.length !== 2) return unsupported();
|
|
62
|
-
if (value === "-0") return -0;
|
|
63
|
-
if (typeof value !== "number" || !Number.isFinite(value) || Object.is(value, -0)) {
|
|
64
|
-
return unsupported();
|
|
65
|
-
}
|
|
66
|
-
return value;
|
|
67
|
-
case "string":
|
|
68
|
-
if (encoded.length !== 2 || typeof value !== "string") return unsupported();
|
|
69
|
-
return value;
|
|
70
|
-
case "array":
|
|
71
|
-
if (encoded.length !== 2 || !Array.isArray(value)) return unsupported();
|
|
72
|
-
return Object.freeze(value.map((item) => decodeSignalValue(item)));
|
|
73
|
-
case "object": {
|
|
74
|
-
if (encoded.length !== 2 || !Array.isArray(value)) return unsupported();
|
|
75
|
-
const object = {};
|
|
76
|
-
let previous;
|
|
77
|
-
for (const entry of value) {
|
|
78
|
-
if (!Array.isArray(entry) || entry.length !== 2 || typeof entry[0] !== "string" || previous !== void 0 && entry[0] <= previous) {
|
|
79
|
-
return unsupported();
|
|
80
|
-
}
|
|
81
|
-
previous = entry[0];
|
|
82
|
-
Object.defineProperty(object, entry[0], {
|
|
83
|
-
value: decodeSignalValue(entry[1]),
|
|
84
|
-
enumerable: true
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
return Object.freeze(object);
|
|
88
|
-
}
|
|
89
|
-
default:
|
|
90
|
-
return unsupported();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
1
|
+
import { decodeSignalValue, encodeSignalValue, snapshotSignalValue } from "../data-encoding.js";
|
|
93
2
|
export {
|
|
94
3
|
decodeSignalValue,
|
|
95
|
-
encodeSignalValue
|
|
4
|
+
encodeSignalValue,
|
|
5
|
+
snapshotSignalValue
|
|
96
6
|
};
|
package/dist/signals/engine.d.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { ScopedNode, endSignalBatch, startSignalBatch, type GraphOwner, type NodeState, type SignalObserver, type SignalReadMode } from './graph.js';
|
|
1
|
+
import { ScopedNode, endSignalBatch, startSignalBatch, type GraphOwner, type CandidateProducer, type NodeState, type SignalObserver, type SignalReadMode, type SignalCandidateFrame } from './graph.js';
|
|
2
2
|
import { type NativeSerializedScope } from './read-protocol.js';
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
3
|
+
import type { initializeResource, QueryDefinition, RequestEntry, ResourceBinding } from './requests.js';
|
|
4
|
+
import type { StreamFrameIdentity, StreamedSignalResultFrame } from '../streamed-signals-protocol.js';
|
|
5
|
+
import type { AdoptionFrame, DerivedSignal, DerivedCompute, DerivedOptions, QueryRequest, Resource, Scope, ScopeInspection, ScopeOptions, ScopeSeed, skip, SignalHandle, SignalSeedEntry, SignalTraceEvent, WritableSignal } from './types.js';
|
|
5
6
|
interface DecodedSeedEntry {
|
|
6
7
|
readonly entry: SignalSeedEntry;
|
|
7
8
|
readonly value: unknown;
|
|
8
9
|
}
|
|
10
|
+
/** Owner lifecycle shared by scalar and asynchronous declaration implementations. */
|
|
11
|
+
export interface DerivedBindingLifecycle {
|
|
12
|
+
suspend(): boolean;
|
|
13
|
+
resume(): void;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
forkCandidate?(target: ScopedNode, frame: SignalCandidateFrame): CandidateProducer | undefined;
|
|
16
|
+
}
|
|
17
|
+
type DerivedBindingFactory<T> = new (owner: ScopeImpl, node: ScopedNode<T>, compute: DerivedCompute<T>, options?: DerivedOptions) => DerivedBindingLifecycle;
|
|
9
18
|
interface FrameData {
|
|
10
19
|
readonly owner: ScopeImpl;
|
|
11
20
|
readonly entries: Map<string, DecodedSeedEntry>;
|
|
@@ -19,6 +28,14 @@ export declare class ScopeImpl implements Scope, GraphOwner {
|
|
|
19
28
|
readonly requests: Map<string, RequestEntry>;
|
|
20
29
|
readonly queryDefinitions: Map<string, QueryDefinition>;
|
|
21
30
|
readonly resources: Map<ScopedNode<any>, ResourceBinding<any>>;
|
|
31
|
+
readonly streamedSelections: Map<string, StreamFrameIdentity>;
|
|
32
|
+
readonly streamedFrames: Map<string, StreamedSignalResultFrame[]>;
|
|
33
|
+
readonly streamedFailures: Map<string, {
|
|
34
|
+
identity: StreamFrameIdentity;
|
|
35
|
+
error: Error;
|
|
36
|
+
}>;
|
|
37
|
+
private readonly streamedReady;
|
|
38
|
+
readonly derivedBindings: Map<ScopedNode<any>, DerivedBindingLifecycle>;
|
|
22
39
|
readonly frames: Set<AdoptionFrameImpl>;
|
|
23
40
|
private readonly seedEntries;
|
|
24
41
|
private readonly traceLimit;
|
|
@@ -26,18 +43,36 @@ export declare class ScopeImpl implements Scope, GraphOwner {
|
|
|
26
43
|
private sequence;
|
|
27
44
|
private lifetime;
|
|
28
45
|
private disposed;
|
|
46
|
+
readBarrier: Promise<void> | undefined;
|
|
47
|
+
/** Internal document lifecycle: mark every owner before cancellation runs user code. */
|
|
48
|
+
suspendReads(): void;
|
|
49
|
+
resumeReads(): void;
|
|
29
50
|
constructor(key: string, options: ScopeOptions, seedable?: boolean);
|
|
30
51
|
get scopeKey(): string;
|
|
31
52
|
get epoch(): number;
|
|
32
53
|
get retired(): boolean;
|
|
33
54
|
private createNode;
|
|
55
|
+
private declaredNode;
|
|
34
56
|
private initialSeed;
|
|
35
57
|
private retainedSeed;
|
|
36
58
|
private initializeRetention;
|
|
37
59
|
private consumeSeed;
|
|
38
60
|
signal$<T>(key: string, initial: T): WritableSignal<T>;
|
|
61
|
+
createSignalDeclaration<T>(key: string, initial: T, preferInitial?: boolean): WritableSignal<T>;
|
|
39
62
|
derived$<T>(key: string, compute: (() => T) & (T extends PromiseLike<unknown> ? never : unknown)): DerivedSignal<T>;
|
|
40
|
-
|
|
63
|
+
/** Candidate state is private; the ordinary node/binding maps stay untouched. */
|
|
64
|
+
forkCandidate(node: ScopedNode, target: ScopedNode, frame: SignalCandidateFrame): CandidateProducer | undefined;
|
|
65
|
+
createDerivedDeclaration<T>(key: string, compute: DerivedCompute<T>, options: DerivedOptions | undefined, Binding: DerivedBindingFactory<T>): DerivedSignal<T>;
|
|
66
|
+
createResourceDeclaration<T>(key: string, describe: () => QueryRequest<T> | typeof skip, initialize: typeof initializeResource, unique?: boolean): Resource<T>;
|
|
67
|
+
bindStreamedSelection(identity: StreamFrameIdentity): boolean;
|
|
68
|
+
isStreamedSelectionPending(identity: StreamFrameIdentity): boolean;
|
|
69
|
+
whenStreamedSelectionReady(identity: StreamFrameIdentity, ready: () => void): () => void;
|
|
70
|
+
streamedSelectionReady(binding: ResourceBinding): void;
|
|
71
|
+
retainCompletedStreamedResult(identity: StreamFrameIdentity, frames: StreamedSignalResultFrame[]): boolean;
|
|
72
|
+
discardCompletedStreamedSelection(identity: StreamFrameIdentity): void;
|
|
73
|
+
acceptStreamedResult(frame: StreamedSignalResultFrame): boolean;
|
|
74
|
+
failStreamedResult(identity: StreamFrameIdentity, error: Error): boolean;
|
|
75
|
+
private flushStreamedResult;
|
|
41
76
|
private own;
|
|
42
77
|
get<T>(handle$: SignalHandle<T>): T;
|
|
43
78
|
set<T>(handle$: WritableSignal<T>, value: T | ((previous: T) => T)): void;
|
|
@@ -70,4 +105,18 @@ declare class AdoptionFrameImpl implements AdoptionFrame {
|
|
|
70
105
|
export declare function createScope(options: ScopeOptions): Scope;
|
|
71
106
|
/** Only the native hook adapter may create a component-owned, non-serializable scope. */
|
|
72
107
|
export declare function createLocalScope(scopeKey: string): Scope;
|
|
108
|
+
export declare function createDeclaredSignalCell<T>(owner: Scope, key: string, initial: T, preferInitial?: boolean): WritableSignal<T>;
|
|
109
|
+
export declare function createDerivedCellWith<T>(owner: Scope, key: string, compute: DerivedCompute<T>, options: DerivedOptions | undefined, Binding: DerivedBindingFactory<T>): DerivedSignal<T>;
|
|
110
|
+
export declare function createResourceCellWith<T>(owner: Scope, key: string, describe: () => QueryRequest<T> | typeof skip, initialize: typeof initializeResource, unique?: boolean): Resource<T>;
|
|
111
|
+
export declare function adoptResourceValue<T>(handle$: SignalHandle<T>, requestKey: string | undefined, value: T): boolean;
|
|
112
|
+
/** @internal Return the concrete owner for a proven runtime handle. */
|
|
113
|
+
export declare function getSignalScope(handle$: SignalHandle<unknown>): Scope | undefined;
|
|
114
|
+
/** @internal Exact selection generation used to pin an optimistic query write. */
|
|
115
|
+
export declare function getResourceSelectionAuthority(handle$: SignalHandle<unknown>): object | undefined;
|
|
116
|
+
/** @internal Bind receiver-owned selection authority before result delivery. */
|
|
117
|
+
export declare function bindScopeStreamedSelection(owner: Scope, identity: StreamFrameIdentity): boolean;
|
|
118
|
+
/** @internal Publish a receiver-validated result into an exact current request. */
|
|
119
|
+
export declare function acceptScopeStreamedResult(owner: Scope, frame: StreamedSignalResultFrame): boolean;
|
|
120
|
+
/** @internal Fail one exact streamed attempt after receiver timeout or rejection. */
|
|
121
|
+
export declare function failScopeStreamedResult(owner: Scope, identity: StreamFrameIdentity, error: Error): boolean;
|
|
73
122
|
export { startSignalBatch, endSignalBatch };
|
package/dist/signals/engine.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import { decodeSignalValue, encodeSignalValue } from "./encoding.js";
|
|
2
|
-
import {
|
|
1
|
+
import { decodeSignalValue, encodeSignalValue, snapshotSignalValue } from "./encoding.js";
|
|
2
|
+
import {
|
|
3
|
+
ScopeDisposedError,
|
|
4
|
+
SignalFrameError,
|
|
5
|
+
SignalSerializationError,
|
|
6
|
+
SignalStreamError
|
|
7
|
+
} from "./errors.js";
|
|
8
|
+
import { sameStreamFrameIdentity } from "../streamed-signals-protocol.js";
|
|
3
9
|
import {
|
|
4
10
|
ScopedNode,
|
|
11
|
+
CandidateUnsupportedError,
|
|
5
12
|
assertAlive,
|
|
6
13
|
assertWritable,
|
|
7
14
|
derivedState,
|
|
@@ -26,9 +33,6 @@ import {
|
|
|
26
33
|
registerNativeBatchHooks,
|
|
27
34
|
reportNativeRead
|
|
28
35
|
} from "./read-protocol.js";
|
|
29
|
-
import {
|
|
30
|
-
initializeResource
|
|
31
|
-
} from "./requests.js";
|
|
32
36
|
let activeFrames;
|
|
33
37
|
registerNativeBatchHooks({ startBatch: startSignalBatch, endBatch: endSignalBatch });
|
|
34
38
|
function requireKey(key, label) {
|
|
@@ -48,7 +52,7 @@ function seedState(seed) {
|
|
|
48
52
|
});
|
|
49
53
|
}
|
|
50
54
|
function decodeSeed(scopeKey, seed) {
|
|
51
|
-
seed =
|
|
55
|
+
seed = snapshotSignalValue(seed);
|
|
52
56
|
if (!seed || seed.version !== 1 || seed.scopeKey !== scopeKey || !Array.isArray(seed.entries)) {
|
|
53
57
|
throw new SignalFrameError(`A signal seed must match scope "${scopeKey}" and version 1.`);
|
|
54
58
|
}
|
|
@@ -69,10 +73,11 @@ function decodeSeed(scopeKey, seed) {
|
|
|
69
73
|
if (!entry.request || typeof entry.request.queryKey !== "string" || !entry.request.queryKey.trim() || !["promise", "stream"].includes(entry.request.kind)) {
|
|
70
74
|
throw new SignalFrameError("Async seed entries require a query identity.");
|
|
71
75
|
}
|
|
76
|
+
decodeSignalValue(entry.request.argument);
|
|
72
77
|
request = {
|
|
73
78
|
queryKey: entry.request.queryKey,
|
|
74
79
|
kind: entry.request.kind,
|
|
75
|
-
argument:
|
|
80
|
+
argument: entry.request.argument
|
|
76
81
|
};
|
|
77
82
|
} else if (entry.request !== void 0) {
|
|
78
83
|
throw new SignalFrameError("Only async seed entries may contain a query identity.");
|
|
@@ -82,7 +87,7 @@ function decodeSeed(scopeKey, seed) {
|
|
|
82
87
|
entry: {
|
|
83
88
|
key: entry.key,
|
|
84
89
|
kind: entry.kind,
|
|
85
|
-
value:
|
|
90
|
+
value: entry.value,
|
|
86
91
|
complete: entry.complete,
|
|
87
92
|
...read !== "value" ? { read } : {},
|
|
88
93
|
...entry.available === false ? { available: false } : {},
|
|
@@ -113,6 +118,11 @@ class ScopeImpl {
|
|
|
113
118
|
requests = /* @__PURE__ */ new Map();
|
|
114
119
|
queryDefinitions = /* @__PURE__ */ new Map();
|
|
115
120
|
resources = /* @__PURE__ */ new Map();
|
|
121
|
+
streamedSelections = /* @__PURE__ */ new Map();
|
|
122
|
+
streamedFrames = /* @__PURE__ */ new Map();
|
|
123
|
+
streamedFailures = /* @__PURE__ */ new Map();
|
|
124
|
+
streamedReady = /* @__PURE__ */ new Map();
|
|
125
|
+
derivedBindings = /* @__PURE__ */ new Map();
|
|
116
126
|
frames = /* @__PURE__ */ new Set();
|
|
117
127
|
seedEntries;
|
|
118
128
|
traceLimit;
|
|
@@ -120,6 +130,39 @@ class ScopeImpl {
|
|
|
120
130
|
sequence = 0;
|
|
121
131
|
lifetime = 0;
|
|
122
132
|
disposed = false;
|
|
133
|
+
readBarrier;
|
|
134
|
+
/** Internal document lifecycle: mark every owner before cancellation runs user code. */
|
|
135
|
+
suspendReads() {
|
|
136
|
+
if (this.disposed || this.readBarrier === void 0) return;
|
|
137
|
+
for (const key of this.streamedSelections.keys()) {
|
|
138
|
+
if (this.streamedFrames.get(key)?.at(-1)?.kind === "complete") continue;
|
|
139
|
+
this.streamedSelections.delete(key);
|
|
140
|
+
this.streamedFrames.delete(key);
|
|
141
|
+
this.streamedReady.delete(key);
|
|
142
|
+
}
|
|
143
|
+
this.streamedFailures.clear();
|
|
144
|
+
for (const entry of this.requests.values()) entry.stopAttempt();
|
|
145
|
+
for (const binding of this.derivedBindings.values()) binding.suspend();
|
|
146
|
+
}
|
|
147
|
+
resumeReads() {
|
|
148
|
+
if (this.disposed || this.readBarrier !== void 0) return;
|
|
149
|
+
signalBatch(() => {
|
|
150
|
+
for (const [node, binding] of this.resources) {
|
|
151
|
+
refreshNode(node);
|
|
152
|
+
const identity = this.streamedSelections.get(node.key);
|
|
153
|
+
if (identity && this.streamedFrames.has(node.key) && binding.bindStreamedSelection(identity)) {
|
|
154
|
+
this.flushStreamedResult(node, binding);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
for (const entry of this.requests.values()) {
|
|
158
|
+
if (this.readBarrier !== void 0) break;
|
|
159
|
+
if (!entry.active && !entry.state.snapshot.complete && entry.state.snapshot.status !== "error" && entry.consumers.size) {
|
|
160
|
+
entry.start(entry.state.snapshot.status !== "ready");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
for (const binding of this.derivedBindings.values()) binding.resume();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
123
166
|
get scopeKey() {
|
|
124
167
|
return this.key;
|
|
125
168
|
}
|
|
@@ -129,9 +172,9 @@ class ScopeImpl {
|
|
|
129
172
|
get retired() {
|
|
130
173
|
return this.disposed;
|
|
131
174
|
}
|
|
132
|
-
createNode(key, kind) {
|
|
175
|
+
createNode(key, kind, allowDuringRead = false) {
|
|
133
176
|
assertAlive(this);
|
|
134
|
-
if (this.seedable) assertWritable();
|
|
177
|
+
if (this.seedable && !allowDuringRead) assertWritable();
|
|
135
178
|
requireKey(key, "Signal key");
|
|
136
179
|
if (this.nodes.has(key))
|
|
137
180
|
throw new TypeError(`Signal key "${key}" already exists in this scope.`);
|
|
@@ -145,6 +188,18 @@ class ScopeImpl {
|
|
|
145
188
|
this.nodes.set(key, node);
|
|
146
189
|
return node;
|
|
147
190
|
}
|
|
191
|
+
declaredNode(key, kind) {
|
|
192
|
+
assertAlive(this);
|
|
193
|
+
requireKey(key, "Signal key");
|
|
194
|
+
const existing = this.nodes.get(key);
|
|
195
|
+
if (existing) {
|
|
196
|
+
if (existing.kind !== kind) {
|
|
197
|
+
throw new TypeError(`Signal key "${key}" already has kind "${existing.kind}".`);
|
|
198
|
+
}
|
|
199
|
+
return [existing, false];
|
|
200
|
+
}
|
|
201
|
+
return [this.createNode(key, kind, true), true];
|
|
202
|
+
}
|
|
148
203
|
initialSeed(key) {
|
|
149
204
|
return this.seedEntries.get(seedKey(key)) ?? this.seedEntries.get(seedKey(key, "snapshot"));
|
|
150
205
|
}
|
|
@@ -174,28 +229,182 @@ class ScopeImpl {
|
|
|
174
229
|
this.consumeSeed(key);
|
|
175
230
|
return node;
|
|
176
231
|
}
|
|
232
|
+
createSignalDeclaration(key, initial, preferInitial = false) {
|
|
233
|
+
const [node, created] = this.declaredNode(key, "signal");
|
|
234
|
+
if (!created) return node;
|
|
235
|
+
const seed = this.initialSeed(key) ?? this.retainedSeed(key);
|
|
236
|
+
node.state = readyState(seed && !preferInitial ? seed.value : initial);
|
|
237
|
+
node.lastState = node.state;
|
|
238
|
+
node.last = node.state.snapshot.value;
|
|
239
|
+
node.hasLast = true;
|
|
240
|
+
this.consumeSeed(key);
|
|
241
|
+
return node;
|
|
242
|
+
}
|
|
177
243
|
derived$(key, compute) {
|
|
178
244
|
if (typeof compute !== "function") throw new TypeError("derived$ requires a function.");
|
|
179
245
|
const node = this.createNode(key, "derived");
|
|
180
|
-
node.compute = () => derivedState(
|
|
246
|
+
node.compute = (target) => derivedState(target, compute);
|
|
181
247
|
this.initializeRetention(node);
|
|
182
248
|
this.consumeSeed(key);
|
|
183
249
|
return node;
|
|
184
250
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
251
|
+
/** Candidate state is private; the ordinary node/binding maps stay untouched. */
|
|
252
|
+
forkCandidate(node, target, frame) {
|
|
253
|
+
if (this.nodes.get(node.key) !== node || this.readBarrier || this.frames.size) {
|
|
254
|
+
throw new CandidateUnsupportedError("Candidate frames require live, non-adopting nodes.");
|
|
255
|
+
}
|
|
256
|
+
const resource = this.resources.get(node);
|
|
257
|
+
if (resource) return resource.forkCandidate(target);
|
|
258
|
+
const binding = this.derivedBindings.get(node);
|
|
259
|
+
if (binding) {
|
|
260
|
+
if (!binding.forkCandidate) {
|
|
261
|
+
throw new CandidateUnsupportedError(
|
|
262
|
+
"Async derived candidates are not supported by this prototype."
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
return binding.forkCandidate(target, frame);
|
|
266
|
+
}
|
|
267
|
+
target.compute = node.compute;
|
|
268
|
+
}
|
|
269
|
+
createDerivedDeclaration(key, compute, options, Binding) {
|
|
270
|
+
if (typeof compute !== "function") throw new TypeError("derived$ requires a function.");
|
|
271
|
+
const [node, created] = this.declaredNode(key, "derived");
|
|
272
|
+
if (!created) return node;
|
|
273
|
+
const binding = new Binding(this, node, compute, options);
|
|
274
|
+
this.derivedBindings.set(node, binding);
|
|
275
|
+
this.initializeRetention(node);
|
|
276
|
+
this.consumeSeed(key);
|
|
277
|
+
return node;
|
|
278
|
+
}
|
|
279
|
+
createResourceDeclaration(key, describe, initialize, unique = false) {
|
|
280
|
+
if (typeof describe !== "function")
|
|
281
|
+
throw new TypeError("A query resource requires a description.");
|
|
282
|
+
let node;
|
|
283
|
+
if (unique) node = this.createNode(key, "async");
|
|
284
|
+
else {
|
|
285
|
+
const [declared, created] = this.declaredNode(key, "async");
|
|
286
|
+
if (!created) return declared;
|
|
287
|
+
node = declared;
|
|
288
|
+
}
|
|
188
289
|
const seed = this.initialSeed(key);
|
|
189
290
|
const retained = this.retainedSeed(key);
|
|
190
291
|
this.initializeRetention(node);
|
|
191
292
|
signalBatch(() => {
|
|
192
|
-
const binding =
|
|
293
|
+
const binding = initialize(this, node, describe, seed, retained);
|
|
193
294
|
this.resources.set(node, binding);
|
|
194
295
|
refreshNode(node);
|
|
296
|
+
this.flushStreamedResult(node, binding);
|
|
195
297
|
});
|
|
196
298
|
this.consumeSeed(key);
|
|
197
299
|
return node;
|
|
198
300
|
}
|
|
301
|
+
bindStreamedSelection(identity) {
|
|
302
|
+
assertAlive(this);
|
|
303
|
+
const node = this.nodes.get(identity.nodeKey);
|
|
304
|
+
if (node && node.kind !== "async") return false;
|
|
305
|
+
const previous = this.streamedSelections.get(identity.nodeKey);
|
|
306
|
+
if (previous && !sameStreamFrameIdentity(previous, identity)) {
|
|
307
|
+
this.streamedFrames.delete(identity.nodeKey);
|
|
308
|
+
this.streamedFailures.delete(identity.nodeKey);
|
|
309
|
+
this.streamedReady.delete(identity.nodeKey);
|
|
310
|
+
}
|
|
311
|
+
this.streamedSelections.set(identity.nodeKey, identity);
|
|
312
|
+
if (!node) return true;
|
|
313
|
+
return this.resources.get(node)?.bindStreamedSelection(identity) === true;
|
|
314
|
+
}
|
|
315
|
+
isStreamedSelectionPending(identity) {
|
|
316
|
+
const selected = this.streamedSelections.get(identity.nodeKey);
|
|
317
|
+
const node = this.nodes.get(identity.nodeKey);
|
|
318
|
+
return !this.retired && selected !== void 0 && sameStreamFrameIdentity(selected, identity) && node?.kind === "async" && this.resources.get(node)?.isStreamedSelectionReady(selected) === false;
|
|
319
|
+
}
|
|
320
|
+
whenStreamedSelectionReady(identity, ready) {
|
|
321
|
+
const node = this.nodes.get(identity.nodeKey);
|
|
322
|
+
if (node && this.resources.get(node)?.isStreamedSelectionReady(identity)) return () => {
|
|
323
|
+
};
|
|
324
|
+
const registration = { identity, ready };
|
|
325
|
+
this.streamedReady.set(identity.nodeKey, registration);
|
|
326
|
+
return () => {
|
|
327
|
+
if (this.streamedReady.get(identity.nodeKey) === registration)
|
|
328
|
+
this.streamedReady.delete(identity.nodeKey);
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
streamedSelectionReady(binding) {
|
|
332
|
+
if (this.readBarrier !== void 0 || this.retired) return;
|
|
333
|
+
this.flushStreamedResult(binding.node, binding);
|
|
334
|
+
const registration = this.streamedReady.get(binding.node.key);
|
|
335
|
+
if (registration && binding.isStreamedSelectionReady(registration.identity)) {
|
|
336
|
+
this.streamedReady.delete(binding.node.key);
|
|
337
|
+
registration.ready();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
retainCompletedStreamedResult(identity, frames) {
|
|
341
|
+
if (!this.isStreamedSelectionPending(identity) || frames.at(-1)?.kind !== "complete")
|
|
342
|
+
return false;
|
|
343
|
+
const previous = this.streamedFrames.get(identity.nodeKey);
|
|
344
|
+
if (previous?.at(-1)?.kind === "complete") return false;
|
|
345
|
+
let sequence = previous?.length ?? 0;
|
|
346
|
+
for (const frame of frames) {
|
|
347
|
+
if (!sameStreamFrameIdentity(identity, frame.identity) || frame.sequence !== sequence++)
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
if (previous) previous.push(...frames);
|
|
351
|
+
else this.streamedFrames.set(identity.nodeKey, frames);
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
discardCompletedStreamedSelection(identity) {
|
|
355
|
+
if (this.streamedSelections.get(identity.nodeKey) !== identity || this.streamedFrames.get(identity.nodeKey)?.at(-1)?.kind !== "complete")
|
|
356
|
+
return;
|
|
357
|
+
this.streamedFrames.delete(identity.nodeKey);
|
|
358
|
+
this.streamedSelections.delete(identity.nodeKey);
|
|
359
|
+
this.streamedReady.delete(identity.nodeKey);
|
|
360
|
+
this.streamedFailures.delete(identity.nodeKey);
|
|
361
|
+
}
|
|
362
|
+
acceptStreamedResult(frame) {
|
|
363
|
+
assertAlive(this);
|
|
364
|
+
const selected = this.streamedSelections.get(frame.identity.nodeKey);
|
|
365
|
+
if (!selected || !sameStreamFrameIdentity(selected, frame.identity)) return false;
|
|
366
|
+
const node = this.nodes.get(frame.identity.nodeKey);
|
|
367
|
+
if (!node) {
|
|
368
|
+
let frames = this.streamedFrames.get(frame.identity.nodeKey);
|
|
369
|
+
if (!frames) this.streamedFrames.set(frame.identity.nodeKey, frames = []);
|
|
370
|
+
frames.push(frame);
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
if (node.kind !== "async") return false;
|
|
374
|
+
return this.resources.get(node)?.acceptStreamed(frame) === true;
|
|
375
|
+
}
|
|
376
|
+
failStreamedResult(identity, error) {
|
|
377
|
+
assertAlive(this);
|
|
378
|
+
const selected = this.streamedSelections.get(identity.nodeKey);
|
|
379
|
+
if (!selected || !sameStreamFrameIdentity(selected, identity)) return false;
|
|
380
|
+
const node = this.nodes.get(identity.nodeKey);
|
|
381
|
+
if (!node) {
|
|
382
|
+
this.streamedFailures.set(identity.nodeKey, { identity, error });
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
if (node.kind !== "async") return false;
|
|
386
|
+
return this.resources.get(node)?.failStreamed(identity, error) === true;
|
|
387
|
+
}
|
|
388
|
+
flushStreamedResult(node, binding) {
|
|
389
|
+
if (this.readBarrier !== void 0) return;
|
|
390
|
+
const identity = this.streamedSelections.get(node.key);
|
|
391
|
+
if (!identity || !binding.isStreamedSelectionReady(identity)) return;
|
|
392
|
+
const frames = this.streamedFrames.get(node.key);
|
|
393
|
+
if (frames) {
|
|
394
|
+
this.streamedFrames.delete(node.key);
|
|
395
|
+
for (const frame of frames) {
|
|
396
|
+
if (!binding.acceptStreamed(frame)) {
|
|
397
|
+
binding.failStreamed(identity, new SignalStreamError("identity"));
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const failure = this.streamedFailures.get(node.key);
|
|
403
|
+
if (failure) {
|
|
404
|
+
this.streamedFailures.delete(node.key);
|
|
405
|
+
binding.failStreamed(failure.identity, failure.error);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
199
408
|
own(handle$) {
|
|
200
409
|
assertAlive(this);
|
|
201
410
|
if (!(handle$ instanceof ScopedNode) || handle$.owner !== this) {
|
|
@@ -204,7 +413,8 @@ class ScopeImpl {
|
|
|
204
413
|
return handle$;
|
|
205
414
|
}
|
|
206
415
|
get(handle$) {
|
|
207
|
-
|
|
416
|
+
const node = this.own(handle$);
|
|
417
|
+
return strictValue(readNode(node), node.key);
|
|
208
418
|
}
|
|
209
419
|
set(handle$, value) {
|
|
210
420
|
this.own(handle$).set(value);
|
|
@@ -381,6 +591,12 @@ class ScopeImpl {
|
|
|
381
591
|
this.lifetime++;
|
|
382
592
|
for (const resource of this.resources.values()) resource.dispose();
|
|
383
593
|
this.resources.clear();
|
|
594
|
+
this.streamedSelections.clear();
|
|
595
|
+
this.streamedFrames.clear();
|
|
596
|
+
this.streamedFailures.clear();
|
|
597
|
+
this.streamedReady.clear();
|
|
598
|
+
for (const binding of this.derivedBindings.values()) binding.dispose();
|
|
599
|
+
this.derivedBindings.clear();
|
|
384
600
|
this.requests.clear();
|
|
385
601
|
this.queryDefinitions.clear();
|
|
386
602
|
for (const frame of this.frames) frame.release();
|
|
@@ -512,10 +728,53 @@ function createScope(options) {
|
|
|
512
728
|
function createLocalScope(scopeKey) {
|
|
513
729
|
return new ScopeImpl(scopeKey, { scopeKey }, false);
|
|
514
730
|
}
|
|
731
|
+
function createDeclaredSignalCell(owner, key, initial, preferInitial = false) {
|
|
732
|
+
if (!(owner instanceof ScopeImpl)) throw new TypeError("A direct signal needs an Octane scope.");
|
|
733
|
+
return owner.createSignalDeclaration(key, initial, preferInitial);
|
|
734
|
+
}
|
|
735
|
+
function createDerivedCellWith(owner, key, compute, options, Binding) {
|
|
736
|
+
if (!(owner instanceof ScopeImpl))
|
|
737
|
+
throw new TypeError("A direct derived signal needs an Octane scope.");
|
|
738
|
+
return owner.createDerivedDeclaration(key, compute, options, Binding);
|
|
739
|
+
}
|
|
740
|
+
function createResourceCellWith(owner, key, describe, initialize, unique = false) {
|
|
741
|
+
if (!(owner instanceof ScopeImpl)) throw new TypeError("A direct query needs an Octane scope.");
|
|
742
|
+
return owner.createResourceDeclaration(key, describe, initialize, unique);
|
|
743
|
+
}
|
|
744
|
+
function adoptResourceValue(handle$, requestKey, value) {
|
|
745
|
+
if (!(handle$ instanceof ScopedNode) || !(handle$.owner instanceof ScopeImpl)) return false;
|
|
746
|
+
const binding = handle$.owner.resources.get(handle$);
|
|
747
|
+
return binding ? binding.adopt(requestKey, value) : false;
|
|
748
|
+
}
|
|
749
|
+
function getSignalScope(handle$) {
|
|
750
|
+
return handle$ instanceof ScopedNode && handle$.owner instanceof ScopeImpl ? handle$.owner : void 0;
|
|
751
|
+
}
|
|
752
|
+
function getResourceSelectionAuthority(handle$) {
|
|
753
|
+
if (!(handle$ instanceof ScopedNode) || !(handle$.owner instanceof ScopeImpl)) return;
|
|
754
|
+
return handle$.owner.resources.get(handle$)?.authority;
|
|
755
|
+
}
|
|
756
|
+
function bindScopeStreamedSelection(owner, identity) {
|
|
757
|
+
return owner instanceof ScopeImpl ? owner.bindStreamedSelection(identity) : false;
|
|
758
|
+
}
|
|
759
|
+
function acceptScopeStreamedResult(owner, frame) {
|
|
760
|
+
return owner instanceof ScopeImpl ? owner.acceptStreamedResult(frame) : false;
|
|
761
|
+
}
|
|
762
|
+
function failScopeStreamedResult(owner, identity, error) {
|
|
763
|
+
return owner instanceof ScopeImpl ? owner.failStreamedResult(identity, error) : false;
|
|
764
|
+
}
|
|
515
765
|
export {
|
|
516
766
|
ScopeImpl,
|
|
767
|
+
acceptScopeStreamedResult,
|
|
768
|
+
adoptResourceValue,
|
|
769
|
+
bindScopeStreamedSelection,
|
|
770
|
+
createDeclaredSignalCell,
|
|
771
|
+
createDerivedCellWith,
|
|
517
772
|
createLocalScope,
|
|
773
|
+
createResourceCellWith,
|
|
518
774
|
createScope,
|
|
519
775
|
endSignalBatch,
|
|
776
|
+
failScopeStreamedResult,
|
|
777
|
+
getResourceSelectionAuthority,
|
|
778
|
+
getSignalScope,
|
|
520
779
|
startSignalBatch
|
|
521
780
|
};
|
package/dist/signals/errors.d.ts
CHANGED
|
@@ -7,9 +7,16 @@ export declare class SignalWriteError extends Error {
|
|
|
7
7
|
export declare class SignalCycleError extends Error {
|
|
8
8
|
constructor(key: string);
|
|
9
9
|
}
|
|
10
|
+
export declare class SignalIdleError extends Error {
|
|
11
|
+
constructor(key: string);
|
|
12
|
+
}
|
|
10
13
|
export declare class SignalFrameError extends Error {
|
|
11
14
|
constructor(message: string);
|
|
12
15
|
}
|
|
16
|
+
export declare class SignalStreamError extends Error {
|
|
17
|
+
readonly code: string;
|
|
18
|
+
constructor(code: string);
|
|
19
|
+
}
|
|
13
20
|
export declare class SignalSerializationError extends Error {
|
|
14
21
|
constructor(message: string);
|
|
15
22
|
}
|
package/dist/signals/errors.js
CHANGED
|
@@ -16,12 +16,26 @@ class SignalCycleError extends Error {
|
|
|
16
16
|
this.name = "SignalCycleError";
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
class SignalIdleError extends Error {
|
|
20
|
+
constructor(key) {
|
|
21
|
+
super(`Signal "${key}" has no selected value.`);
|
|
22
|
+
this.name = "SignalIdleError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
19
25
|
class SignalFrameError extends Error {
|
|
20
26
|
constructor(message) {
|
|
21
27
|
super(message);
|
|
22
28
|
this.name = "SignalFrameError";
|
|
23
29
|
}
|
|
24
30
|
}
|
|
31
|
+
class SignalStreamError extends Error {
|
|
32
|
+
code;
|
|
33
|
+
constructor(code) {
|
|
34
|
+
super(`Streamed signal failed with code "${code}".`);
|
|
35
|
+
this.code = code;
|
|
36
|
+
this.name = "SignalStreamError";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
25
39
|
class SignalSerializationError extends Error {
|
|
26
40
|
constructor(message) {
|
|
27
41
|
super(message);
|
|
@@ -32,6 +46,8 @@ export {
|
|
|
32
46
|
ScopeDisposedError,
|
|
33
47
|
SignalCycleError,
|
|
34
48
|
SignalFrameError,
|
|
49
|
+
SignalIdleError,
|
|
35
50
|
SignalSerializationError,
|
|
51
|
+
SignalStreamError,
|
|
36
52
|
SignalWriteError
|
|
37
53
|
};
|