octane 0.2.12 → 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/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-tables.cjs +4 -94
- package/dist/cjs/error-codes.client.generated.cjs +33 -0
- package/dist/cjs/error-codes.server.generated.cjs +19 -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 +6 -0
- package/dist/cjs/runtime.cjs +2791 -215
- package/dist/cjs/runtime.server.cjs +716 -76
- package/dist/cjs/server/early-signals.cjs +45 -0
- package/dist/cjs/server/index.cjs +44 -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 +163 -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 +32 -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/version.cjs +1 -1
- package/dist/class-names.d.ts +5 -0
- package/dist/class-names.js +25 -0
- package/dist/compiler/bundler.js +34 -6
- package/dist/compiler/compile.js +2234 -559
- 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 +26 -0
- package/dist/compiler/hydrate-boundaries.js +358 -15
- package/dist/compiler/index.d.ts +38 -1
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/native-attribute-reads.js +127 -0
- package/dist/compiler/native-read-diagnostics.js +48 -9
- package/dist/compiler/native-read-types.js +55 -32
- 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.js +57 -10
- 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.d.ts +6 -1
- package/dist/compiler/volar.js +674 -143
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +10 -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-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 +5 -0
- package/dist/error-codes.server.generated.js +19 -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 +2 -0
- package/dist/index.js +4 -0
- package/dist/internal/signal-read.d.ts +1 -0
- package/dist/internal/signal-read.js +4 -0
- package/dist/jsx-runtime.d.ts +45 -6
- package/dist/public-types.d.ts +15 -1
- package/dist/runtime.d.ts +259 -21
- package/dist/runtime.js +2812 -220
- package/dist/runtime.server.d.ts +86 -6
- package/dist/runtime.server.js +712 -76
- package/dist/server/early-signals.d.ts +14 -0
- package/dist/server/early-signals.js +34 -0
- package/dist/server/index.d.ts +10 -2
- package/dist/server/index.js +48 -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 +50 -5
- package/dist/signals/graph.js +170 -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 +32 -3
- package/dist/signals/read-protocol.js +26 -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/version.js +1 -1
- package/package.json +37 -1
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var actions_exports = {};
|
|
20
|
+
__export(actions_exports, {
|
|
21
|
+
ActionUncertainError: () => ActionUncertainError,
|
|
22
|
+
action$: () => action$,
|
|
23
|
+
isActionUncertain: () => isActionUncertain,
|
|
24
|
+
optimistic$: () => optimistic$
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(actions_exports);
|
|
27
|
+
var import_engine = require("./engine.cjs");
|
|
28
|
+
var import_computations = require("./computations.cjs");
|
|
29
|
+
var import_facade = require("./facade.cjs");
|
|
30
|
+
var import_graph = require("./graph.cjs");
|
|
31
|
+
var import_owner_context = require("./owner-context.cjs");
|
|
32
|
+
var import_read_protocol = require("./read-protocol.cjs");
|
|
33
|
+
var import_types = require("./types.cjs");
|
|
34
|
+
const uncertainReceipts = /* @__PURE__ */ new WeakSet();
|
|
35
|
+
const noAuthority = /* @__PURE__ */ Symbol();
|
|
36
|
+
let activeOperation;
|
|
37
|
+
let excludedOperation;
|
|
38
|
+
const managers = /* @__PURE__ */ new WeakMap();
|
|
39
|
+
class OptimisticManager {
|
|
40
|
+
constructor(source) {
|
|
41
|
+
this.source = source;
|
|
42
|
+
const owner = (0, import_engine.getSignalScope)(source);
|
|
43
|
+
if (!owner) throw new TypeError("An optimistic source needs a live Octane scope.");
|
|
44
|
+
this.owner = owner;
|
|
45
|
+
this.version$ = (0, import_engine.createDeclaredSignalCell)(
|
|
46
|
+
this.owner,
|
|
47
|
+
`@octane/optimistic-version/${source.key}`,
|
|
48
|
+
0
|
|
49
|
+
);
|
|
50
|
+
this.view$ = (0, import_computations.createDeclaredDerivedCell)(this.owner, `@octane/optimistic/${source.key}`, () => {
|
|
51
|
+
this.version$.get();
|
|
52
|
+
return this.read();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
source;
|
|
56
|
+
compareAuthority;
|
|
57
|
+
owner;
|
|
58
|
+
version$;
|
|
59
|
+
view$;
|
|
60
|
+
overlays = [];
|
|
61
|
+
read(exclude) {
|
|
62
|
+
const snapshot = this.source.snapshot();
|
|
63
|
+
const selectionAuthority = (0, import_engine.getResourceSelectionAuthority)(this.source);
|
|
64
|
+
for (let index = this.overlays.length - 1; index >= 0; index--) {
|
|
65
|
+
const overlay = this.overlays[index];
|
|
66
|
+
if (overlay.operation !== exclude && overlay.requestKey === snapshot.requestKey && overlay.selectionAuthority === selectionAuthority) {
|
|
67
|
+
return overlay.value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return this.source.get();
|
|
71
|
+
}
|
|
72
|
+
latest(fallback, exclude) {
|
|
73
|
+
const snapshot = this.source.snapshot();
|
|
74
|
+
const selectionAuthority = (0, import_engine.getResourceSelectionAuthority)(this.source);
|
|
75
|
+
for (let index = this.overlays.length - 1; index >= 0; index--) {
|
|
76
|
+
const overlay = this.overlays[index];
|
|
77
|
+
if (overlay.operation !== exclude && overlay.requestKey === snapshot.requestKey && overlay.selectionAuthority === selectionAuthority) {
|
|
78
|
+
return overlay.value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return this.source.latest(fallback);
|
|
82
|
+
}
|
|
83
|
+
snapshot(exclude) {
|
|
84
|
+
const snapshot = this.source.snapshot();
|
|
85
|
+
const selectionAuthority = (0, import_engine.getResourceSelectionAuthority)(this.source);
|
|
86
|
+
for (let index = this.overlays.length - 1; index >= 0; index--) {
|
|
87
|
+
const overlay = this.overlays[index];
|
|
88
|
+
if (overlay.operation !== exclude && overlay.requestKey === snapshot.requestKey && overlay.selectionAuthority === selectionAuthority) {
|
|
89
|
+
return Object.freeze({
|
|
90
|
+
status: "ready",
|
|
91
|
+
value: overlay.value,
|
|
92
|
+
refreshing: snapshot.refreshing,
|
|
93
|
+
connection: snapshot.connection,
|
|
94
|
+
complete: snapshot.complete,
|
|
95
|
+
...snapshot.requestKey === void 0 ? {} : { requestKey: snapshot.requestKey }
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return snapshot;
|
|
100
|
+
}
|
|
101
|
+
apply(operation, value) {
|
|
102
|
+
(0, import_graph.assertWritable)();
|
|
103
|
+
if (operation.status !== "pending") {
|
|
104
|
+
throw new Error(`Action operation "${operation.id}" is no longer writable.`);
|
|
105
|
+
}
|
|
106
|
+
let overlay = operation.targets.get(this);
|
|
107
|
+
const snapshot = this.source.snapshot();
|
|
108
|
+
if (!overlay && snapshot.status !== "ready") {
|
|
109
|
+
throw new Error("An optimistic write requires ready source authority.");
|
|
110
|
+
}
|
|
111
|
+
const previous = this.read();
|
|
112
|
+
const next = typeof value === "function" ? (0, import_graph.untrack)(() => (0, import_graph.pure)(() => value(previous))) : value;
|
|
113
|
+
if (!overlay) {
|
|
114
|
+
overlay = {
|
|
115
|
+
operation,
|
|
116
|
+
requestKey: snapshot.requestKey,
|
|
117
|
+
selectionAuthority: (0, import_engine.getResourceSelectionAuthority)(this.source),
|
|
118
|
+
value: next
|
|
119
|
+
};
|
|
120
|
+
this.overlays.push(overlay);
|
|
121
|
+
operation.targets.set(this, overlay);
|
|
122
|
+
} else {
|
|
123
|
+
overlay.value = next;
|
|
124
|
+
}
|
|
125
|
+
this.publish();
|
|
126
|
+
return overlay;
|
|
127
|
+
}
|
|
128
|
+
remove(operation) {
|
|
129
|
+
const index = this.overlays.findIndex((overlay) => overlay.operation === operation);
|
|
130
|
+
if (index < 0) return;
|
|
131
|
+
this.overlays.splice(index, 1);
|
|
132
|
+
if (!this.owner.retired) this.publish();
|
|
133
|
+
}
|
|
134
|
+
adopt(overlay, value) {
|
|
135
|
+
(0, import_graph.assertWritable)();
|
|
136
|
+
const snapshot = this.source.snapshot();
|
|
137
|
+
if (snapshot.requestKey !== overlay.requestKey || (0, import_engine.getResourceSelectionAuthority)(this.source) !== overlay.selectionAuthority) {
|
|
138
|
+
throw new Error("An action cannot adopt authority for a different query selection.");
|
|
139
|
+
}
|
|
140
|
+
if (this.source.kind !== "async" && this.source.kind !== "signal") {
|
|
141
|
+
throw new TypeError("Only a writable or query source can adopt an authoritative value.");
|
|
142
|
+
}
|
|
143
|
+
if (this.compareAuthority) {
|
|
144
|
+
const current = this.source.latest(noAuthority);
|
|
145
|
+
if (current === noAuthority) {
|
|
146
|
+
throw new Error("An action needs current authority to compare receipt revisions.");
|
|
147
|
+
}
|
|
148
|
+
const order = (0, import_graph.untrack)(() => (0, import_graph.pure)(() => this.compareAuthority(value, current)));
|
|
149
|
+
if (!Number.isFinite(order)) {
|
|
150
|
+
throw new TypeError("An authority revision comparator must return a finite number.");
|
|
151
|
+
}
|
|
152
|
+
if (order <= 0) {
|
|
153
|
+
this.remove(overlay.operation);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (this.source.kind === "async") {
|
|
158
|
+
if (!(0, import_engine.adoptResourceValue)(this.source, overlay.requestKey, value)) {
|
|
159
|
+
throw new Error("The pinned query selection is no longer current.");
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
this.source.set(value);
|
|
163
|
+
}
|
|
164
|
+
this.remove(overlay.operation);
|
|
165
|
+
}
|
|
166
|
+
publish() {
|
|
167
|
+
this.version$.set((version) => version + 1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function managerFor(source$, owner, compareAuthority) {
|
|
171
|
+
const resolved = owner ? (0, import_facade.resolveSignalHandleForOwner)(source$, owner) : (0, import_facade.resolveCurrentSignalHandle)(source$);
|
|
172
|
+
if (!(resolved instanceof import_graph.ScopedNode)) {
|
|
173
|
+
throw new TypeError("optimistic$ requires an Octane signal source.");
|
|
174
|
+
}
|
|
175
|
+
let manager = managers.get(resolved);
|
|
176
|
+
if (!manager) {
|
|
177
|
+
manager = new OptimisticManager(resolved);
|
|
178
|
+
managers.set(resolved, manager);
|
|
179
|
+
}
|
|
180
|
+
if (compareAuthority && manager.compareAuthority !== compareAuthority) {
|
|
181
|
+
if (manager.compareAuthority) {
|
|
182
|
+
throw new Error("An optimistic source cannot use conflicting authority revision policies.");
|
|
183
|
+
}
|
|
184
|
+
manager.compareAuthority = compareAuthority;
|
|
185
|
+
}
|
|
186
|
+
return manager;
|
|
187
|
+
}
|
|
188
|
+
class OptimisticDescriptor {
|
|
189
|
+
constructor(source$, compareAuthority) {
|
|
190
|
+
this.source$ = source$;
|
|
191
|
+
this.compareAuthority = compareAuthority;
|
|
192
|
+
this.key = `optimistic:${source$.key}`;
|
|
193
|
+
}
|
|
194
|
+
source$;
|
|
195
|
+
compareAuthority;
|
|
196
|
+
[import_types.SIGNAL_HANDLE] = true;
|
|
197
|
+
kind = "signal";
|
|
198
|
+
key;
|
|
199
|
+
[import_types.SIGNAL_OWNER_RESOLVE](owner) {
|
|
200
|
+
return this.manager(owner).view$;
|
|
201
|
+
}
|
|
202
|
+
manager(owner) {
|
|
203
|
+
return managerFor(this.source$, owner, this.compareAuthority);
|
|
204
|
+
}
|
|
205
|
+
get() {
|
|
206
|
+
const manager = this.manager(activeOperation?.owner ?? void 0);
|
|
207
|
+
return excludedOperation ? manager.read(excludedOperation) : manager.view$.get();
|
|
208
|
+
}
|
|
209
|
+
[import_types.SIGNAL_BINDING_READ]() {
|
|
210
|
+
return this.manager().view$[import_types.SIGNAL_BINDING_READ]();
|
|
211
|
+
}
|
|
212
|
+
[import_types.SIGNAL_BINDING_SUBSCRIBE](notify, onRetire) {
|
|
213
|
+
const owner = (0, import_owner_context.currentSignalOwner)();
|
|
214
|
+
if (!owner) throw new Error("An optimistic subscription needs an active signal owner.");
|
|
215
|
+
const run = (0, import_owner_context.captureSignalOwner)(owner);
|
|
216
|
+
return this.manager().view$[import_types.SIGNAL_BINDING_SUBSCRIBE](
|
|
217
|
+
(0, import_read_protocol.forwardNativeTransitionConsumer)(notify, () => run(notify)),
|
|
218
|
+
onRetire === void 0 ? void 0 : () => run(onRetire)
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
[import_types.SIGNAL_BINDING_IDENTITY]() {
|
|
222
|
+
return this.source$[import_types.SIGNAL_BINDING_IDENTITY]();
|
|
223
|
+
}
|
|
224
|
+
latest(fallback) {
|
|
225
|
+
return this.manager().latest(fallback, excludedOperation);
|
|
226
|
+
}
|
|
227
|
+
snapshot() {
|
|
228
|
+
const manager = this.manager();
|
|
229
|
+
return excludedOperation ? manager.snapshot(excludedOperation) : manager.view$.snapshot();
|
|
230
|
+
}
|
|
231
|
+
subscribe(notify) {
|
|
232
|
+
const owner = (0, import_owner_context.currentSignalOwner)();
|
|
233
|
+
if (!owner) throw new Error("An optimistic subscription needs an active signal owner.");
|
|
234
|
+
const run = (0, import_owner_context.captureSignalOwner)(owner);
|
|
235
|
+
return this.manager().view$.subscribe(
|
|
236
|
+
(0, import_read_protocol.forwardNativeTransitionConsumer)(notify, () => run(notify))
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
set(value) {
|
|
240
|
+
if (!activeOperation) {
|
|
241
|
+
throw new Error("An optimistic write must belong to action$ or use operation.set().");
|
|
242
|
+
}
|
|
243
|
+
this.apply(activeOperation, value);
|
|
244
|
+
}
|
|
245
|
+
apply(operation, value) {
|
|
246
|
+
const manager = this.manager(operation.owner ?? void 0);
|
|
247
|
+
operation.bind(this, manager);
|
|
248
|
+
manager.apply(operation, value);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
class ActionUncertainError extends Error {
|
|
252
|
+
constructor(operationId2, options) {
|
|
253
|
+
super(`Action operation "${operationId2}" may have been accepted.`, options);
|
|
254
|
+
this.operationId = operationId2;
|
|
255
|
+
this.name = "ActionUncertainError";
|
|
256
|
+
}
|
|
257
|
+
operationId;
|
|
258
|
+
code = "OCTANE_ACTION_UNCERTAIN";
|
|
259
|
+
}
|
|
260
|
+
function operationId(key) {
|
|
261
|
+
const randomUUID = globalThis.crypto?.randomUUID;
|
|
262
|
+
if (typeof randomUUID !== "function") {
|
|
263
|
+
throw new Error("action$ requires crypto.randomUUID() for operation identity.");
|
|
264
|
+
}
|
|
265
|
+
return `${key}:${randomUUID.call(globalThis.crypto)}`;
|
|
266
|
+
}
|
|
267
|
+
function transportIsUncertain(error) {
|
|
268
|
+
return (typeof error === "object" || typeof error === "function") && error !== null && error.code === "OCTANE_RPC_UNCERTAIN";
|
|
269
|
+
}
|
|
270
|
+
class Operation {
|
|
271
|
+
constructor(key) {
|
|
272
|
+
this.key = key;
|
|
273
|
+
this.id = operationId(key);
|
|
274
|
+
}
|
|
275
|
+
key;
|
|
276
|
+
id;
|
|
277
|
+
owner = (0, import_owner_context.currentSignalOwner)();
|
|
278
|
+
status = "pending";
|
|
279
|
+
targets = /* @__PURE__ */ new Map();
|
|
280
|
+
waits;
|
|
281
|
+
descriptors = /* @__PURE__ */ new Map();
|
|
282
|
+
set(signal$, value) {
|
|
283
|
+
if (!(signal$ instanceof OptimisticDescriptor)) {
|
|
284
|
+
throw new TypeError("operation.set() requires a signal from optimistic$().");
|
|
285
|
+
}
|
|
286
|
+
const manager = this.descriptors.get(signal$);
|
|
287
|
+
if (manager) {
|
|
288
|
+
manager.apply(this, value);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
signal$.apply(this, value);
|
|
292
|
+
}
|
|
293
|
+
bind(descriptor, manager) {
|
|
294
|
+
this.descriptors.set(
|
|
295
|
+
descriptor,
|
|
296
|
+
manager
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
adopt(value) {
|
|
300
|
+
if (this.status !== "pending" && this.status !== "uncertain")
|
|
301
|
+
throw new Error(`Action operation "${this.id}" is settled.`);
|
|
302
|
+
if (this.targets.size !== 1) {
|
|
303
|
+
throw new Error("operation.adopt() requires exactly one optimistic source.");
|
|
304
|
+
}
|
|
305
|
+
const [manager, overlay] = this.targets.entries().next().value;
|
|
306
|
+
manager.adopt(overlay, value);
|
|
307
|
+
this.targets.delete(manager);
|
|
308
|
+
this.descriptors.clear();
|
|
309
|
+
this.status = "confirmed";
|
|
310
|
+
this.notifyWaits();
|
|
311
|
+
}
|
|
312
|
+
uncertain() {
|
|
313
|
+
if (this.status !== "pending") throw new Error(`Action operation "${this.id}" is settled.`);
|
|
314
|
+
this.status = "uncertain";
|
|
315
|
+
this.notifyWaits();
|
|
316
|
+
const receipt = Object.freeze({ status: "uncertain", operationId: this.id });
|
|
317
|
+
uncertainReceipts.add(receipt);
|
|
318
|
+
return receipt;
|
|
319
|
+
}
|
|
320
|
+
until(read, options) {
|
|
321
|
+
if (this.status !== "pending") return Promise.reject(new Error("The action is settled."));
|
|
322
|
+
if (typeof read !== "function")
|
|
323
|
+
return Promise.reject(new TypeError("until() requires a read."));
|
|
324
|
+
const timeout = options?.timeout;
|
|
325
|
+
if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout < 0)) {
|
|
326
|
+
return Promise.reject(new RangeError("until() timeout must be a nonnegative number."));
|
|
327
|
+
}
|
|
328
|
+
const managers2 = [...this.targets.keys()];
|
|
329
|
+
if (!managers2.length) {
|
|
330
|
+
return Promise.reject(new Error("until() requires a pinned optimistic source."));
|
|
331
|
+
}
|
|
332
|
+
return new Promise((resolve, reject) => {
|
|
333
|
+
let ended = false;
|
|
334
|
+
let timer;
|
|
335
|
+
const stops = [];
|
|
336
|
+
const finish = (error) => {
|
|
337
|
+
if (ended) return;
|
|
338
|
+
ended = true;
|
|
339
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
340
|
+
for (const stop of stops) stop();
|
|
341
|
+
this.waits?.delete(check);
|
|
342
|
+
if (error === void 0) resolve();
|
|
343
|
+
else reject(error);
|
|
344
|
+
};
|
|
345
|
+
const check = () => {
|
|
346
|
+
if (ended) return;
|
|
347
|
+
if (this.status !== "pending") {
|
|
348
|
+
finish(
|
|
349
|
+
this.status === "confirmed" ? void 0 : new Error(`The action is ${this.status}.`)
|
|
350
|
+
);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (managers2.some((manager) => manager.owner.retired)) {
|
|
354
|
+
finish(new Error("The optimistic owner was retired."));
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const previous = excludedOperation;
|
|
358
|
+
excludedOperation = this;
|
|
359
|
+
try {
|
|
360
|
+
for (const [manager, overlay] of this.targets) {
|
|
361
|
+
if (manager.source.snapshot().requestKey !== overlay.requestKey || (0, import_engine.getResourceSelectionAuthority)(manager.source) !== overlay.selectionAuthority) {
|
|
362
|
+
finish(new Error("The pinned optimistic selection is no longer current."));
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if ((0, import_owner_context.runWithSignalOwner)(managers2[0].owner, read)) finish();
|
|
367
|
+
} catch (error) {
|
|
368
|
+
if (!(0, import_graph.isThenable)(error)) finish(error);
|
|
369
|
+
} finally {
|
|
370
|
+
excludedOperation = previous;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
(this.waits ??= /* @__PURE__ */ new Set()).add(check);
|
|
374
|
+
for (const manager of managers2) stops.push((0, import_graph.subscribeNode)(manager.source, check));
|
|
375
|
+
if (timeout !== void 0) {
|
|
376
|
+
timer = setTimeout(
|
|
377
|
+
() => finish(new Error("The optimistic confirmation timed out.")),
|
|
378
|
+
timeout
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
check();
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
confirm() {
|
|
385
|
+
if (this.status !== "pending") return;
|
|
386
|
+
this.status = "confirmed";
|
|
387
|
+
this.clear();
|
|
388
|
+
this.notifyWaits();
|
|
389
|
+
}
|
|
390
|
+
reject() {
|
|
391
|
+
if (this.status !== "pending" && this.status !== "uncertain") return;
|
|
392
|
+
(0, import_graph.assertWritable)();
|
|
393
|
+
this.status = "rejected";
|
|
394
|
+
this.clear();
|
|
395
|
+
this.notifyWaits();
|
|
396
|
+
}
|
|
397
|
+
notifyWaits() {
|
|
398
|
+
if (this.waits) for (const check of this.waits) check();
|
|
399
|
+
}
|
|
400
|
+
clear() {
|
|
401
|
+
for (const manager of this.targets.keys()) manager.remove(this);
|
|
402
|
+
this.targets.clear();
|
|
403
|
+
this.descriptors.clear();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function optimistic$(source$, options) {
|
|
407
|
+
if (!source$ || typeof source$.get !== "function") {
|
|
408
|
+
throw new TypeError("optimistic$ requires a signal source.");
|
|
409
|
+
}
|
|
410
|
+
if (options?.compareAuthority !== void 0 && typeof options.compareAuthority !== "function") {
|
|
411
|
+
throw new TypeError("An authority revision policy must be a comparator function.");
|
|
412
|
+
}
|
|
413
|
+
return new OptimisticDescriptor(source$, options?.compareAuthority);
|
|
414
|
+
}
|
|
415
|
+
function action$(keyOrHandler, handler) {
|
|
416
|
+
const key = typeof keyOrHandler === "string" ? keyOrHandler : "action";
|
|
417
|
+
const execute = typeof keyOrHandler === "function" ? keyOrHandler : handler;
|
|
418
|
+
if (!key.trim() || typeof execute !== "function") {
|
|
419
|
+
throw new TypeError("action$ requires a handler and an optional nonempty key.");
|
|
420
|
+
}
|
|
421
|
+
return function(...args) {
|
|
422
|
+
const operation = new Operation(key);
|
|
423
|
+
const previous = activeOperation;
|
|
424
|
+
activeOperation = operation;
|
|
425
|
+
let result;
|
|
426
|
+
try {
|
|
427
|
+
result = (0, import_graph.signalBatch)(() => execute.call(this, operation, ...args));
|
|
428
|
+
} catch (error) {
|
|
429
|
+
activeOperation = previous;
|
|
430
|
+
if (transportIsUncertain(error)) {
|
|
431
|
+
operation.uncertain();
|
|
432
|
+
throw new ActionUncertainError(operation.id, { cause: error });
|
|
433
|
+
}
|
|
434
|
+
operation.reject();
|
|
435
|
+
throw error;
|
|
436
|
+
}
|
|
437
|
+
activeOperation = previous;
|
|
438
|
+
let asyncResult;
|
|
439
|
+
try {
|
|
440
|
+
asyncResult = (0, import_graph.isThenable)(result);
|
|
441
|
+
} catch (error) {
|
|
442
|
+
operation.reject();
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
445
|
+
if (!asyncResult) {
|
|
446
|
+
if (!isActionUncertain(result)) operation.confirm();
|
|
447
|
+
return result;
|
|
448
|
+
}
|
|
449
|
+
return Promise.resolve(result).then(
|
|
450
|
+
(value) => {
|
|
451
|
+
if (!isActionUncertain(value)) operation.confirm();
|
|
452
|
+
return value;
|
|
453
|
+
},
|
|
454
|
+
(error) => {
|
|
455
|
+
if (transportIsUncertain(error)) {
|
|
456
|
+
operation.uncertain();
|
|
457
|
+
throw new ActionUncertainError(operation.id, { cause: error });
|
|
458
|
+
}
|
|
459
|
+
operation.reject();
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
);
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function isActionUncertain(value) {
|
|
466
|
+
return value instanceof ActionUncertainError || (typeof value === "object" || typeof value === "function") && value !== null && uncertainReceipts.has(value);
|
|
467
|
+
}
|
|
468
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
469
|
+
0 && (module.exports = {
|
|
470
|
+
ActionUncertainError,
|
|
471
|
+
action$,
|
|
472
|
+
isActionUncertain,
|
|
473
|
+
optimistic$
|
|
474
|
+
});
|
|
@@ -15,12 +15,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
15
|
}
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
18
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
20
|
var client_exports = {};
|
|
20
21
|
__export(client_exports, {
|
|
21
22
|
useSignal$: () => useSignal$
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(client_exports);
|
|
25
|
+
__reExport(client_exports, require("./index.cjs"), module.exports);
|
|
24
26
|
var import_runtime = require("../runtime.cjs");
|
|
25
27
|
var import_engine = require("./engine.cjs");
|
|
26
28
|
function disposeLocalSignal(cell) {
|
|
@@ -41,5 +43,6 @@ function useSignal$(initial, slot) {
|
|
|
41
43
|
}
|
|
42
44
|
// Annotate the CommonJS export names for ESM import in node:
|
|
43
45
|
0 && (module.exports = {
|
|
44
|
-
useSignal
|
|
46
|
+
useSignal$,
|
|
47
|
+
...require("./index.cjs")
|
|
45
48
|
});
|