octane 0.6.2 → 0.6.3
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/dist/cjs/dom-binding-handoff.cjs +2 -1
- package/dist/cjs/dom-binding-protocol.cjs +4 -3
- package/dist/cjs/dom-binding-styles.cjs +3 -2
- package/dist/cjs/dom-bindings.cjs +24 -23
- package/dist/cjs/error-codes.client.generated.cjs +2 -1
- package/dist/cjs/error-codes.server.generated.cjs +2 -1
- package/dist/cjs/hydration/event-capture.cjs +2 -1
- package/dist/cjs/independent-hydration-protocol.cjs +3 -2
- package/dist/cjs/runtime.cjs +169 -155
- package/dist/cjs/runtime.server.cjs +40 -34
- package/dist/cjs/signals/control-binding.cjs +7 -6
- package/dist/cjs/signals/derived-facade.cjs +2 -1
- package/dist/cjs/signals/document-owner.cjs +4 -3
- package/dist/cjs/signals/facade.cjs +10 -9
- package/dist/cjs/signals/graph.cjs +5 -4
- package/dist/cjs/signals/native-read-client.cjs +4 -3
- package/dist/cjs/signals/owner-context.cjs +4 -3
- package/dist/cjs/signals/query-attempt-observer.cjs +2 -1
- package/dist/cjs/signals/query-facade.cjs +2 -1
- package/dist/cjs/signals/scalar-computations.cjs +2 -1
- package/dist/cjs/signals/transition-action.cjs +10 -9
- package/dist/cjs/signals/transition-candidate.cjs +2 -1
- package/dist/cjs/version.cjs +1 -1
- package/dist/compiler/compile.js +380 -12
- package/dist/node/aria-diagnostics.js +92 -0
- package/dist/node/behavior-form-submissions.js +228 -0
- package/dist/node/behavior-root-types.js +0 -0
- package/dist/node/behavior-root.js +746 -0
- package/dist/node/class-names.js +25 -0
- package/dist/node/compatibility.js +10 -0
- package/dist/node/component-flags.js +23 -0
- package/dist/node/constants.js +113 -0
- package/dist/node/context-epoch.js +13 -0
- package/dist/node/context-identity.js +46 -0
- package/dist/node/css.js +80 -0
- package/dist/node/data-encoding.js +134 -0
- package/dist/node/devtools-hook.js +229 -0
- package/dist/node/dom-binding-claims.js +4 -0
- package/dist/node/dom-binding-classes.js +152 -0
- package/dist/node/dom-binding-controls.js +6 -0
- package/dist/node/dom-binding-handoff.js +77 -0
- package/dist/node/dom-binding-program.js +1617 -0
- package/dist/node/dom-binding-projections.js +204 -0
- package/dist/node/dom-binding-protocol.js +130 -0
- package/dist/node/dom-binding-signals.js +135 -0
- package/dist/node/dom-binding-styles.js +280 -0
- package/dist/node/dom-bindings.js +1087 -0
- package/dist/node/dom-focused-move.js +46 -0
- package/dist/node/dom-stage.js +878 -0
- package/dist/node/dom-tables.js +382 -0
- package/dist/node/error-codes.client.generated.js +1066 -0
- package/dist/node/error-codes.server.generated.js +736 -0
- package/dist/node/error-message.js +27 -0
- package/dist/node/event-names.js +15 -0
- package/dist/node/form-diagnostics.js +96 -0
- package/dist/node/form-submission.js +43 -0
- package/dist/node/has-own.js +4 -0
- package/dist/node/head-ownership.js +31 -0
- package/dist/node/hook-slot-cache.js +91 -0
- package/dist/node/host-property-diagnostics.js +189 -0
- package/dist/node/html-tree-validation.js +193 -0
- package/dist/node/hydration/condition.js +15 -0
- package/dist/node/hydration/control-capture.js +237 -0
- package/dist/node/hydration/document-lifecycle.js +89 -0
- package/dist/node/hydration/event-capture.js +362 -0
- package/dist/node/hydration/idle.js +23 -0
- package/dist/node/hydration/independent-island.js +317 -0
- package/dist/node/hydration/index.js +74 -0
- package/dist/node/hydration/interaction-config.js +61 -0
- package/dist/node/hydration/interaction.js +35 -0
- package/dist/node/hydration/load.js +15 -0
- package/dist/node/hydration/media.js +33 -0
- package/dist/node/hydration/native-intent.js +68 -0
- package/dist/node/hydration/never.js +12 -0
- package/dist/node/hydration/stream-delivery.js +345 -0
- package/dist/node/hydration/stream-receiver.js +190 -0
- package/dist/node/hydration/stream-result-receiver.js +276 -0
- package/dist/node/hydration/streamed-signals.js +186 -0
- package/dist/node/hydration/types.js +0 -0
- package/dist/node/hydration/visible.js +69 -0
- package/dist/node/hydration-markers.js +44 -0
- package/dist/node/independent-hydration-protocol.js +91 -0
- package/dist/node/index.js +461 -0
- package/dist/node/internal/client.js +7 -0
- package/dist/node/internal/context.js +5 -0
- package/dist/node/internal/server.js +5 -0
- package/dist/node/internal/signal-read.js +4 -0
- package/dist/node/method-dep.js +25 -0
- package/dist/node/profiling.js +432 -0
- package/dist/node/public-types.js +0 -0
- package/dist/node/react/fiber-adapter.js +57 -0
- package/dist/node/react/index.js +397 -0
- package/dist/node/react/react-compat-envelope.js +78 -0
- package/dist/node/react/react-compat-server.js +129 -0
- package/dist/node/react/react-compat-shared.js +104 -0
- package/dist/node/react/react-compat.js +223 -0
- package/dist/node/react/server.js +81 -0
- package/dist/node/react/shared.js +75 -0
- package/dist/node/renderer-bridge.js +35 -0
- package/dist/node/resize-observer.js +105 -0
- package/dist/node/resource-hint-diagnostics.js +67 -0
- package/dist/node/runtime-tags.js +22 -0
- package/dist/node/runtime.js +28881 -0
- package/dist/node/runtime.server.js +8016 -0
- package/dist/node/sanitize-url.js +34 -0
- package/dist/node/server/early-signals.js +54 -0
- package/dist/node/server/index.js +336 -0
- package/dist/node/server/rpc-batch.js +129 -0
- package/dist/node/server/rpc-stream.js +125 -0
- package/dist/node/server/rpc.js +48 -0
- package/dist/node/server/signal-query-observation.js +134 -0
- package/dist/node/server/streamed-region.js +31 -0
- package/dist/node/server/streamed-signals.js +557 -0
- package/dist/node/server-call.js +75 -0
- package/dist/node/server-rpc-batch-client.js +119 -0
- package/dist/node/server-rpc-client.js +108 -0
- package/dist/node/server-rpc-protocol.js +109 -0
- package/dist/node/server-rpc-stream-client.js +98 -0
- package/dist/node/shared-value-helpers.js +40 -0
- package/dist/node/signals/actions.js +463 -0
- package/dist/node/signals/client.js +22 -0
- package/dist/node/signals/computations.js +452 -0
- package/dist/node/signals/control-binding.js +388 -0
- package/dist/node/signals/control-handoff.js +12 -0
- package/dist/node/signals/derived-facade.js +25 -0
- package/dist/node/signals/document-owner.js +48 -0
- package/dist/node/signals/early-values.js +124 -0
- package/dist/node/signals/encoding.js +6 -0
- package/dist/node/signals/engine.js +668 -0
- package/dist/node/signals/errors.js +54 -0
- package/dist/node/signals/facade.js +441 -0
- package/dist/node/signals/graph.js +817 -0
- package/dist/node/signals/handle-protocol.js +11 -0
- package/dist/node/signals/index.js +87 -0
- package/dist/node/signals/native-read-client.js +319 -0
- package/dist/node/signals/native-read-collector.js +132 -0
- package/dist/node/signals/native-read-events.js +45 -0
- package/dist/node/signals/native-read-inspection.js +20 -0
- package/dist/node/signals/native-read-retry.js +30 -0
- package/dist/node/signals/native-read-seeds.js +243 -0
- package/dist/node/signals/native-read-server.js +99 -0
- package/dist/node/signals/owner-context.js +88 -0
- package/dist/node/signals/query-attempt-observer.js +42 -0
- package/dist/node/signals/query-facade.js +41 -0
- package/dist/node/signals/read-protocol.js +125 -0
- package/dist/node/signals/requests.js +716 -0
- package/dist/node/signals/scalar-computations.js +57 -0
- package/dist/node/signals/scope-streams.js +147 -0
- package/dist/node/signals/server.js +22 -0
- package/dist/node/signals/transition-action.js +555 -0
- package/dist/node/signals/transition-candidate.js +101 -0
- package/dist/node/signals/transition-coordinator.js +255 -0
- package/dist/node/signals/transition-state.js +82 -0
- package/dist/node/signals/types.js +20 -0
- package/dist/node/static/index.js +10 -0
- package/dist/node/stream-protocol.js +114 -0
- package/dist/node/streamed-signals-protocol.js +130 -0
- package/dist/node/style-values.js +96 -0
- package/dist/node/sub-slot.js +35 -0
- package/dist/node/testing.js +14 -0
- package/dist/node/trusted-html.js +6 -0
- package/dist/node/tsrx-iterable.js +5 -0
- package/dist/node/tsrx-spread.js +10 -0
- package/dist/node/universal-core.js +10010 -0
- package/dist/node/universal-dom-boundary.js +237 -0
- package/dist/node/universal-native.js +28 -0
- package/dist/node/universal.js +17 -0
- package/dist/node/version.js +4 -0
- package/dist/runtime.d.ts +18 -0
- package/dist/runtime.js +13 -2
- package/dist/runtime.server.d.ts +7 -0
- package/dist/runtime.server.js +4 -0
- package/dist/version.js +1 -1
- package/package.json +62 -1
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createScope } from "./engine.js";
|
|
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";
|
|
27
|
+
import {
|
|
28
|
+
ScopeDisposedError,
|
|
29
|
+
SignalCycleError,
|
|
30
|
+
SignalFrameError,
|
|
31
|
+
SignalIdleError,
|
|
32
|
+
SignalSerializationError,
|
|
33
|
+
SignalStreamError,
|
|
34
|
+
SignalWriteError
|
|
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";
|
|
44
|
+
export {
|
|
45
|
+
ActionUncertainError,
|
|
46
|
+
QUERY_REQUEST,
|
|
47
|
+
SIGNAL_BINDING_IDENTITY,
|
|
48
|
+
SIGNAL_BINDING_READ,
|
|
49
|
+
SIGNAL_BINDING_SUBSCRIBE,
|
|
50
|
+
SIGNAL_HANDLE,
|
|
51
|
+
ScopeDisposedError,
|
|
52
|
+
SignalCycleError,
|
|
53
|
+
SignalFrameError,
|
|
54
|
+
SignalIdleError,
|
|
55
|
+
SignalSerializationError,
|
|
56
|
+
SignalStreamError,
|
|
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,
|
|
71
|
+
createScope,
|
|
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
|
|
87
|
+
};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
const __octaneDev = process.env.NODE_ENV !== "production";
|
|
2
|
+
import { createNativeReadCollector, validateNativeReadWitness } from "./native-read-collector.js";
|
|
3
|
+
import { NATIVE_TRANSITION_CONSUMER } from "./read-protocol.js";
|
|
4
|
+
import { inspectNativeReadWitness } from "./native-read-inspection.js";
|
|
5
|
+
function __octaneNoArgError(code) {
|
|
6
|
+
return "Minified Octane error #" + code + "; visit https://octanejs.dev/errors/" + code + " for the full message or use a development build for full errors and additional helpful warnings.";
|
|
7
|
+
}
|
|
8
|
+
function createNativeReadDriver(host) {
|
|
9
|
+
const consumers = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
const captures = /* @__PURE__ */ new WeakMap();
|
|
11
|
+
const frames = [];
|
|
12
|
+
let depth = 0;
|
|
13
|
+
let publications = null;
|
|
14
|
+
let ownerPublications = null;
|
|
15
|
+
let unpublishedRefs = null;
|
|
16
|
+
let deferredRefs = null;
|
|
17
|
+
function forgetUnpublishedRef(target2) {
|
|
18
|
+
const unpublished = unpublishedRefs?.get(target2);
|
|
19
|
+
if (unpublished === void 0)
|
|
20
|
+
return;
|
|
21
|
+
unpublishedRefs.delete(target2);
|
|
22
|
+
const pending = deferredRefs?.get(unpublished.owner);
|
|
23
|
+
pending?.delete(target2);
|
|
24
|
+
if (pending?.size === 0)
|
|
25
|
+
deferredRefs.delete(unpublished.owner);
|
|
26
|
+
}
|
|
27
|
+
function release(candidate) {
|
|
28
|
+
if (!candidate.active)
|
|
29
|
+
return;
|
|
30
|
+
candidate.active = false;
|
|
31
|
+
const consumer = candidate.consumer;
|
|
32
|
+
consumer.pending.delete(candidate);
|
|
33
|
+
for (const source of candidate.reads.keys()) {
|
|
34
|
+
const subscription = consumer.subscriptions.get(source);
|
|
35
|
+
if (subscription !== void 0 && --subscription.leases === 0) {
|
|
36
|
+
consumer.subscriptions.delete(source);
|
|
37
|
+
subscription.dispose();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
candidate.reads.clear();
|
|
41
|
+
}
|
|
42
|
+
function disposeConsumer(consumer) {
|
|
43
|
+
if (consumer.disposed)
|
|
44
|
+
return;
|
|
45
|
+
consumer.disposed = true;
|
|
46
|
+
host.retire?.(consumer.block);
|
|
47
|
+
if (consumer.committed !== null)
|
|
48
|
+
release(consumer.committed);
|
|
49
|
+
consumer.committed = null;
|
|
50
|
+
for (const candidate of consumer.pending)
|
|
51
|
+
release(candidate);
|
|
52
|
+
consumer.pending.clear();
|
|
53
|
+
consumers.delete(consumer.scope);
|
|
54
|
+
}
|
|
55
|
+
function getConsumer(scope, block) {
|
|
56
|
+
let consumer = consumers.get(scope);
|
|
57
|
+
if (consumer === void 0) {
|
|
58
|
+
consumer = {
|
|
59
|
+
scope,
|
|
60
|
+
block,
|
|
61
|
+
disposed: false,
|
|
62
|
+
notify: () => {
|
|
63
|
+
if (!consumer.disposed && !consumer.block.disposed)
|
|
64
|
+
host.schedule(consumer.block);
|
|
65
|
+
},
|
|
66
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
67
|
+
committed: null,
|
|
68
|
+
pending: /* @__PURE__ */ new Set()
|
|
69
|
+
};
|
|
70
|
+
consumers.set(scope, consumer);
|
|
71
|
+
const owned = consumer;
|
|
72
|
+
if (host.prepare !== void 0) {
|
|
73
|
+
Object.assign(owned.notify, {
|
|
74
|
+
[NATIVE_TRANSITION_CONSUMER]: {
|
|
75
|
+
active: () => !owned.disposed && !owned.block.disposed,
|
|
76
|
+
prepare: () => host.prepare(owned.block)
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
host.cleanup(scope, () => disposeConsumer(owned));
|
|
81
|
+
}
|
|
82
|
+
return consumer;
|
|
83
|
+
}
|
|
84
|
+
function getCandidate(frame, scope) {
|
|
85
|
+
const candidates = frame.candidates ??= /* @__PURE__ */ new Map();
|
|
86
|
+
let candidate = candidates.get(scope);
|
|
87
|
+
if (candidate === void 0) {
|
|
88
|
+
const consumer = getConsumer(scope, frame.block);
|
|
89
|
+
candidate = { consumer, reads: /* @__PURE__ */ new Map(), mixed: false, active: true };
|
|
90
|
+
consumer.pending.add(candidate);
|
|
91
|
+
candidates.set(scope, candidate);
|
|
92
|
+
}
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
const collector = createNativeReadCollector((owner, source, version) => {
|
|
96
|
+
const frame = frames[depth - 1];
|
|
97
|
+
if (frame === void 0 || frame.block === null)
|
|
98
|
+
return;
|
|
99
|
+
const candidate = getCandidate(frame, owner);
|
|
100
|
+
const previous = candidate.reads.get(source);
|
|
101
|
+
if (previous !== void 0) {
|
|
102
|
+
if (previous !== version)
|
|
103
|
+
candidate.mixed = true;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
candidate.reads.set(source, version);
|
|
107
|
+
const consumer = candidate.consumer;
|
|
108
|
+
let subscription = consumer.subscriptions.get(source);
|
|
109
|
+
if (subscription === void 0) {
|
|
110
|
+
subscription = { leases: 0, dispose: source.subscribe(consumer.notify) };
|
|
111
|
+
consumer.subscriptions.set(source, subscription);
|
|
112
|
+
}
|
|
113
|
+
subscription.leases++;
|
|
114
|
+
});
|
|
115
|
+
function put(target2, candidate) {
|
|
116
|
+
const consumer = candidate.consumer;
|
|
117
|
+
const previous = target2.get(consumer);
|
|
118
|
+
if (previous !== void 0 && previous !== candidate)
|
|
119
|
+
release(previous);
|
|
120
|
+
target2.set(consumer, candidate);
|
|
121
|
+
}
|
|
122
|
+
function target(capture) {
|
|
123
|
+
let candidates = captures.get(capture);
|
|
124
|
+
if (candidates === void 0)
|
|
125
|
+
captures.set(capture, candidates = /* @__PURE__ */ new Map());
|
|
126
|
+
return candidates;
|
|
127
|
+
}
|
|
128
|
+
function validate(candidates) {
|
|
129
|
+
if (candidates !== null && candidates !== void 0) {
|
|
130
|
+
for (const candidate of candidates.values()) {
|
|
131
|
+
if (candidate.active && !candidate.consumer.disposed && !validateNativeReadWitness(candidate))
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
function accept(candidates) {
|
|
138
|
+
if (candidates === null || candidates === void 0)
|
|
139
|
+
return;
|
|
140
|
+
for (const candidate of candidates.values()) {
|
|
141
|
+
const consumer = candidate.consumer;
|
|
142
|
+
if (!candidate.active || consumer.disposed)
|
|
143
|
+
continue;
|
|
144
|
+
const previous = consumer.committed;
|
|
145
|
+
consumer.pending.delete(candidate);
|
|
146
|
+
consumer.committed = candidate;
|
|
147
|
+
if (previous !== null)
|
|
148
|
+
release(previous);
|
|
149
|
+
}
|
|
150
|
+
candidates.clear();
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
/** Selected-node inspection reads this Scope's existing records only. */
|
|
154
|
+
inspectScope(scope) {
|
|
155
|
+
const consumer = consumers.get(scope);
|
|
156
|
+
if (consumer === void 0 || consumer.disposed)
|
|
157
|
+
return null;
|
|
158
|
+
return {
|
|
159
|
+
block: consumer.block,
|
|
160
|
+
committed: consumer.committed === null ? null : inspectNativeReadWitness(consumer.committed),
|
|
161
|
+
pending: Array.from(consumer.pending, inspectNativeReadWitness)
|
|
162
|
+
};
|
|
163
|
+
},
|
|
164
|
+
/** Receipt stamps exist only for a capture that actually read native data. */
|
|
165
|
+
stampPublication(owner, queues) {
|
|
166
|
+
const publication = { owner, generation: owner.generation };
|
|
167
|
+
(ownerPublications ??= /* @__PURE__ */ new WeakMap()).set(owner, publication);
|
|
168
|
+
const receipts = publications ??= /* @__PURE__ */ new WeakMap();
|
|
169
|
+
for (const queue of queues)
|
|
170
|
+
for (const entry of queue)
|
|
171
|
+
receipts.set(entry, publication);
|
|
172
|
+
},
|
|
173
|
+
hasPublication(owner) {
|
|
174
|
+
return ownerPublications?.has(owner) === true;
|
|
175
|
+
},
|
|
176
|
+
/** Reveals enumerate current refs after their candidate was already accepted. */
|
|
177
|
+
stampQueuedPublication(owner, entry) {
|
|
178
|
+
const publication = ownerPublications?.get(owner);
|
|
179
|
+
if (publication !== void 0)
|
|
180
|
+
publications.set(entry, publication);
|
|
181
|
+
},
|
|
182
|
+
publicationCurrent(entry) {
|
|
183
|
+
const publication = publications?.get(entry);
|
|
184
|
+
return publication === void 0 || !publication.owner.disposed && publication.owner.generation === publication.generation;
|
|
185
|
+
},
|
|
186
|
+
deferRef(entry, target2, ref) {
|
|
187
|
+
const publication = publications?.get(entry);
|
|
188
|
+
if (publication === void 0 || publication.owner.disposed)
|
|
189
|
+
return;
|
|
190
|
+
forgetUnpublishedRef(target2);
|
|
191
|
+
const owner = publication.owner;
|
|
192
|
+
(unpublishedRefs ??= /* @__PURE__ */ new WeakMap()).set(target2, { owner, entry, ref });
|
|
193
|
+
const owners = deferredRefs ??= /* @__PURE__ */ new WeakMap();
|
|
194
|
+
let pending = owners.get(owner);
|
|
195
|
+
if (pending === void 0)
|
|
196
|
+
owners.set(owner, pending = /* @__PURE__ */ new Map());
|
|
197
|
+
pending.set(target2, entry);
|
|
198
|
+
},
|
|
199
|
+
unpublishedRef(target2, ref) {
|
|
200
|
+
const unpublished = unpublishedRefs?.get(target2);
|
|
201
|
+
return unpublished !== void 0 && unpublished.ref === ref;
|
|
202
|
+
},
|
|
203
|
+
forgetUnpublishedRef,
|
|
204
|
+
deferredRefEntries(owner) {
|
|
205
|
+
return deferredRefs?.get(owner);
|
|
206
|
+
},
|
|
207
|
+
clearDeferredRefs(owner) {
|
|
208
|
+
ownerPublications?.delete(owner);
|
|
209
|
+
const pending = deferredRefs?.get(owner);
|
|
210
|
+
if (pending === void 0)
|
|
211
|
+
return;
|
|
212
|
+
for (const target2 of pending.keys())
|
|
213
|
+
forgetUnpublishedRef(target2);
|
|
214
|
+
},
|
|
215
|
+
pruneDeferredRefs(owner) {
|
|
216
|
+
const pending = deferredRefs?.get(owner);
|
|
217
|
+
if (pending === void 0)
|
|
218
|
+
return;
|
|
219
|
+
for (const [target2, entry] of pending) {
|
|
220
|
+
if (host.refDisposed(entry))
|
|
221
|
+
forgetUnpublishedRef(target2);
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
replayDeferredRefs: host.replayRefs,
|
|
225
|
+
beginRender(block) {
|
|
226
|
+
const frame = frames[depth++] ??= { block: null, collectorToken: -1, candidates: null };
|
|
227
|
+
frame.block = block;
|
|
228
|
+
frame.collectorToken = collector.beginRender(block);
|
|
229
|
+
frame.candidates = null;
|
|
230
|
+
if (consumers.has(block))
|
|
231
|
+
getCandidate(frame, block);
|
|
232
|
+
},
|
|
233
|
+
endRender(block, completed, suspended) {
|
|
234
|
+
const frame = frames[depth - 1];
|
|
235
|
+
if (frame === void 0 || frame.block !== block)
|
|
236
|
+
return;
|
|
237
|
+
try {
|
|
238
|
+
if (frame.candidates !== null) {
|
|
239
|
+
if (completed) {
|
|
240
|
+
const capture = host.capture();
|
|
241
|
+
if (capture === null)
|
|
242
|
+
throw new Error(__octaneDev ? "A completed native render requires a renderer transaction." : __octaneNoArgError(167));
|
|
243
|
+
const destination = target(capture);
|
|
244
|
+
for (const candidate of frame.candidates.values())
|
|
245
|
+
put(destination, candidate);
|
|
246
|
+
} else {
|
|
247
|
+
for (const candidate of frame.candidates.values()) {
|
|
248
|
+
if (suspended && candidate.active)
|
|
249
|
+
host.suspended(block, candidate);
|
|
250
|
+
release(candidate);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
} finally {
|
|
255
|
+
collector.endRender(frame.collectorToken);
|
|
256
|
+
frame.block = null;
|
|
257
|
+
frame.candidates = null;
|
|
258
|
+
depth--;
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
beginScope(scope, block) {
|
|
262
|
+
if (collector.isDetached())
|
|
263
|
+
return collector.beginScope(scope);
|
|
264
|
+
if (host.capture() === null)
|
|
265
|
+
throw new Error(__octaneDev ? "Native reads require a renderer transaction." : __octaneNoArgError(168));
|
|
266
|
+
if (depth === 0 || frames[depth - 1].block !== block)
|
|
267
|
+
this.beginRender(block);
|
|
268
|
+
const frame = frames[depth - 1];
|
|
269
|
+
if (scope !== block && consumers.has(scope))
|
|
270
|
+
getCandidate(frame, scope);
|
|
271
|
+
return collector.beginScope(scope);
|
|
272
|
+
},
|
|
273
|
+
endScope(token) {
|
|
274
|
+
collector.endScope(token);
|
|
275
|
+
},
|
|
276
|
+
pauseLifecycle() {
|
|
277
|
+
return collector.suspend(true);
|
|
278
|
+
},
|
|
279
|
+
resumeLifecycle(token) {
|
|
280
|
+
collector.resume(token, true);
|
|
281
|
+
},
|
|
282
|
+
beginWitness: collector.beginWitness,
|
|
283
|
+
finishWitness: collector.finishWitness,
|
|
284
|
+
replay: collector.replay,
|
|
285
|
+
validateCapture(capture) {
|
|
286
|
+
return validate(captures.get(capture));
|
|
287
|
+
},
|
|
288
|
+
acceptCapture(capture) {
|
|
289
|
+
const candidates = captures.get(capture);
|
|
290
|
+
const native = candidates !== void 0 && candidates.size > 0;
|
|
291
|
+
captures.delete(capture);
|
|
292
|
+
accept(candidates);
|
|
293
|
+
return native;
|
|
294
|
+
},
|
|
295
|
+
spliceCapture(capture, parent) {
|
|
296
|
+
const candidates = captures.get(capture);
|
|
297
|
+
if (candidates === void 0)
|
|
298
|
+
return;
|
|
299
|
+
if (parent === null)
|
|
300
|
+
throw new Error(__octaneDev ? "A native capture must be accepted before publication." : __octaneNoArgError(169));
|
|
301
|
+
captures.delete(capture);
|
|
302
|
+
const destination = target(parent);
|
|
303
|
+
for (const candidate of candidates.values())
|
|
304
|
+
put(destination, candidate);
|
|
305
|
+
},
|
|
306
|
+
discardCapture(capture) {
|
|
307
|
+
const candidates = captures.get(capture);
|
|
308
|
+
if (candidates === void 0)
|
|
309
|
+
return;
|
|
310
|
+
captures.delete(capture);
|
|
311
|
+
for (const candidate of candidates.values())
|
|
312
|
+
release(candidate);
|
|
313
|
+
candidates.clear();
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
export {
|
|
318
|
+
createNativeReadDriver
|
|
319
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
beginNativeWriteGuard,
|
|
3
|
+
endNativeWriteGuard,
|
|
4
|
+
getNativeReadObserver,
|
|
5
|
+
isNativeWriteGuarded,
|
|
6
|
+
setNativeReadObserver
|
|
7
|
+
} from "./read-protocol.js";
|
|
8
|
+
function createNativeReadCollector(onRead) {
|
|
9
|
+
let owner = null;
|
|
10
|
+
let scopeDepth = 0;
|
|
11
|
+
let witnessDepth = 0;
|
|
12
|
+
let witnessBase = 0;
|
|
13
|
+
let detachedWitness = false;
|
|
14
|
+
const scopes = [];
|
|
15
|
+
const witnesses = [];
|
|
16
|
+
const observe = (source, version) => {
|
|
17
|
+
if (owner !== null) onRead(owner, source, version);
|
|
18
|
+
for (let i = witnessBase; i < witnessDepth; i++) {
|
|
19
|
+
const frame = witnesses[i];
|
|
20
|
+
const reads = frame.reads ??= /* @__PURE__ */ new Map();
|
|
21
|
+
const previous = reads.get(source);
|
|
22
|
+
if (previous === void 0) reads.set(source, version);
|
|
23
|
+
else if (previous !== version) frame.mixed = true;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function enter(next, guarded, allowWrites = false, keepDetached = false) {
|
|
27
|
+
const token = scopeDepth++;
|
|
28
|
+
const frame = scopes[token] ??= {
|
|
29
|
+
owner: null,
|
|
30
|
+
observer: null,
|
|
31
|
+
guard: false,
|
|
32
|
+
witnessBase: 0,
|
|
33
|
+
detached: false
|
|
34
|
+
};
|
|
35
|
+
frame.owner = owner;
|
|
36
|
+
frame.detached = detachedWitness;
|
|
37
|
+
if (!keepDetached) detachedWitness = false;
|
|
38
|
+
if (detachedWitness) next = null;
|
|
39
|
+
frame.observer = setNativeReadObserver(next !== null || detachedWitness ? observe : null);
|
|
40
|
+
frame.guard = guarded ? beginNativeWriteGuard() : isNativeWriteGuarded();
|
|
41
|
+
if (allowWrites) endNativeWriteGuard(false);
|
|
42
|
+
frame.witnessBase = witnessBase;
|
|
43
|
+
if (!detachedWitness && next !== owner) witnessBase = witnessDepth;
|
|
44
|
+
owner = next;
|
|
45
|
+
return token;
|
|
46
|
+
}
|
|
47
|
+
function leave(token, guarded) {
|
|
48
|
+
if (token < 0) return;
|
|
49
|
+
const frame = scopes[token];
|
|
50
|
+
owner = frame.owner;
|
|
51
|
+
witnessBase = frame.witnessBase;
|
|
52
|
+
detachedWitness = frame.detached;
|
|
53
|
+
setNativeReadObserver(frame.observer);
|
|
54
|
+
if (guarded) endNativeWriteGuard(frame.guard);
|
|
55
|
+
frame.owner = null;
|
|
56
|
+
frame.observer = null;
|
|
57
|
+
scopeDepth = token;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
isDetached() {
|
|
61
|
+
return detachedWitness;
|
|
62
|
+
},
|
|
63
|
+
beginScope(next) {
|
|
64
|
+
if (next === owner && !detachedWitness && getNativeReadObserver() === observe && isNativeWriteGuarded())
|
|
65
|
+
return -1;
|
|
66
|
+
return enter(next, true, false, true);
|
|
67
|
+
},
|
|
68
|
+
endScope(token) {
|
|
69
|
+
leave(token, true);
|
|
70
|
+
},
|
|
71
|
+
/** Own parameters, the component body, and returned-output normalization. */
|
|
72
|
+
beginRender(next = null) {
|
|
73
|
+
const token = enter(next, true);
|
|
74
|
+
witnessBase = witnessDepth;
|
|
75
|
+
return token;
|
|
76
|
+
},
|
|
77
|
+
endRender(token) {
|
|
78
|
+
leave(token, true);
|
|
79
|
+
},
|
|
80
|
+
/** A child Block cannot accidentally add its reads to its parent. */
|
|
81
|
+
suspend(allowWrites = false) {
|
|
82
|
+
const token = enter(null, false, allowWrites);
|
|
83
|
+
witnessBase = witnessDepth;
|
|
84
|
+
return token;
|
|
85
|
+
},
|
|
86
|
+
resume(token, allowWrites = false) {
|
|
87
|
+
leave(token, allowWrites);
|
|
88
|
+
},
|
|
89
|
+
beginWitness(detached = false) {
|
|
90
|
+
if (owner === null && !detached && !detachedWitness) return -1;
|
|
91
|
+
let contextToken = -1;
|
|
92
|
+
if (detached) {
|
|
93
|
+
contextToken = enter(null, true);
|
|
94
|
+
detachedWitness = true;
|
|
95
|
+
witnessBase = witnessDepth;
|
|
96
|
+
setNativeReadObserver(observe);
|
|
97
|
+
}
|
|
98
|
+
const token = witnessDepth++;
|
|
99
|
+
const frame = witnesses[token] ??= { reads: null, mixed: false, contextToken: -1 };
|
|
100
|
+
frame.reads = null;
|
|
101
|
+
frame.mixed = false;
|
|
102
|
+
frame.contextToken = contextToken;
|
|
103
|
+
return token;
|
|
104
|
+
},
|
|
105
|
+
finishWitness(token, completed) {
|
|
106
|
+
if (token < 0) return null;
|
|
107
|
+
const frame = witnesses[token];
|
|
108
|
+
const reads = frame.reads;
|
|
109
|
+
frame.reads = null;
|
|
110
|
+
witnessDepth = token;
|
|
111
|
+
if (frame.contextToken >= 0) leave(frame.contextToken, true);
|
|
112
|
+
frame.contextToken = -1;
|
|
113
|
+
return completed && reads !== null ? { reads, mixed: frame.mixed } : null;
|
|
114
|
+
},
|
|
115
|
+
replay(witness) {
|
|
116
|
+
if (witness === null || witness === void 0) return;
|
|
117
|
+
for (const [source, version] of witness.reads) observe(source, version);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function validateNativeReadWitness(witness) {
|
|
122
|
+
if (witness === null || witness === void 0) return true;
|
|
123
|
+
if (witness.mixed) return false;
|
|
124
|
+
for (const [source, version] of witness.reads) {
|
|
125
|
+
if (source.getVersion() !== version) return false;
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
createNativeReadCollector,
|
|
131
|
+
validateNativeReadWitness
|
|
132
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { beginNativeBatch, endNativeBatch } from "./read-protocol.js";
|
|
2
|
+
let events = null;
|
|
3
|
+
function beginNativeEventBatch(event) {
|
|
4
|
+
const existing = events?.get(event);
|
|
5
|
+
if (existing !== void 0) {
|
|
6
|
+
existing.depth++;
|
|
7
|
+
return existing;
|
|
8
|
+
}
|
|
9
|
+
const hooks = beginNativeBatch();
|
|
10
|
+
if (hooks === null) return null;
|
|
11
|
+
const batch = { hooks, depth: 1, closed: false };
|
|
12
|
+
(events ??= /* @__PURE__ */ new WeakMap()).set(event, batch);
|
|
13
|
+
return batch;
|
|
14
|
+
}
|
|
15
|
+
function finish(event, batch) {
|
|
16
|
+
if (batch.closed) return;
|
|
17
|
+
batch.closed = true;
|
|
18
|
+
if (events?.get(event) === batch) events.delete(event);
|
|
19
|
+
const hooks = batch.hooks;
|
|
20
|
+
batch.hooks = null;
|
|
21
|
+
endNativeBatch(hooks);
|
|
22
|
+
}
|
|
23
|
+
function endNativeEventBatch(event, batch, waitsForBubble, onError) {
|
|
24
|
+
if (batch === null || batch.closed || --batch.depth !== 0) return;
|
|
25
|
+
if (!waitsForBubble) {
|
|
26
|
+
finish(event, batch);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const fallback = () => {
|
|
30
|
+
if (batch.depth !== 0 || batch.closed) return;
|
|
31
|
+
try {
|
|
32
|
+
finish(event, batch);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
onError(error);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const target = event.target;
|
|
38
|
+
const checkableChange = event.type === "change" && target?.localName === "input" && (target.type === "checkbox" || target.type === "radio");
|
|
39
|
+
if (checkableChange) setTimeout(fallback, 0);
|
|
40
|
+
else queueMicrotask(fallback);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
beginNativeEventBatch,
|
|
44
|
+
endNativeEventBatch
|
|
45
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function inspectNativeReadSource(source, observedVersion) {
|
|
2
|
+
return {
|
|
3
|
+
observedVersion,
|
|
4
|
+
currentVersion: source.getVersion(),
|
|
5
|
+
source: source.inspect?.() ?? null
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function inspectNativeReadWitness(witness) {
|
|
9
|
+
return {
|
|
10
|
+
mixed: witness.mixed,
|
|
11
|
+
reads: Array.from(
|
|
12
|
+
witness.reads,
|
|
13
|
+
([source, version]) => inspectNativeReadSource(source, version)
|
|
14
|
+
)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
inspectNativeReadSource,
|
|
19
|
+
inspectNativeReadWitness
|
|
20
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { inspectNativeReadSource } from "./native-read-inspection.js";
|
|
2
|
+
function createNativeReadRetry(notify) {
|
|
3
|
+
const sources = /* @__PURE__ */ new Map();
|
|
4
|
+
let generation = 0;
|
|
5
|
+
return {
|
|
6
|
+
/** Retry leases have no accepted read revision and expose no values. */
|
|
7
|
+
inspect() {
|
|
8
|
+
return Array.from(sources.keys(), (source) => inspectNativeReadSource(source, null));
|
|
9
|
+
},
|
|
10
|
+
get generation() {
|
|
11
|
+
return generation;
|
|
12
|
+
},
|
|
13
|
+
track(witness) {
|
|
14
|
+
let invalid = witness.mixed;
|
|
15
|
+
for (const [source, version] of witness.reads) {
|
|
16
|
+
if (!sources.has(source)) sources.set(source, source.subscribe(notify));
|
|
17
|
+
if (source.getVersion() !== version) invalid = true;
|
|
18
|
+
}
|
|
19
|
+
if (invalid) notify();
|
|
20
|
+
},
|
|
21
|
+
clear() {
|
|
22
|
+
generation++;
|
|
23
|
+
for (const dispose of sources.values()) dispose();
|
|
24
|
+
sources.clear();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
createNativeReadRetry
|
|
30
|
+
};
|