octane 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/behavior-form-submissions.d.ts +12 -0
- package/dist/behavior-form-submissions.js +228 -0
- package/dist/behavior-root-types.d.ts +93 -0
- package/dist/behavior-root-types.js +0 -0
- package/dist/behavior-root.d.ts +10 -2
- package/dist/behavior-root.js +128 -119
- package/dist/cjs/behavior-form-submissions.cjs +232 -0
- package/dist/cjs/behavior-root.cjs +129 -119
- package/dist/cjs/context-identity.cjs +29 -0
- package/dist/cjs/dom-bindings.cjs +266 -19
- package/dist/cjs/dom-stage.cjs +24 -18
- package/dist/cjs/error-codes.server.generated.cjs +5 -0
- package/dist/cjs/form-submission.cjs +74 -0
- package/dist/cjs/hydration/control-capture.cjs +2 -1
- package/dist/cjs/hydration/event-capture.cjs +77 -4
- package/dist/cjs/hydration/native-intent.cjs +95 -0
- package/dist/cjs/hydration-markers.cjs +12 -0
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/runtime.cjs +317 -401
- package/dist/cjs/runtime.server.cjs +193 -44
- package/dist/cjs/server/early-signals.cjs +20 -5
- package/dist/cjs/server/index.cjs +2 -0
- package/dist/cjs/server/streamed-region.cjs +2 -1
- package/dist/cjs/server/streamed-signals.cjs +41 -9
- package/dist/cjs/signals/client.cjs +1 -6
- package/dist/cjs/signals/engine.cjs +92 -197
- package/dist/cjs/signals/facade.cjs +6 -4
- package/dist/cjs/signals/native-read-seeds.cjs +131 -10
- package/dist/cjs/signals/requests.cjs +16 -16
- package/dist/cjs/signals/scope-streams.cjs +170 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/compiler/client-only-server.js +1 -28
- package/dist/compiler/compile-renderer-boundaries.js +1 -22
- package/dist/compiler/compile-universal.js +30 -31
- package/dist/compiler/compile.js +932 -401
- package/dist/compiler/dom-binding-fixed-props.js +11 -1
- package/dist/compiler/dom-binding-program.js +7 -5
- package/dist/compiler/dom-bindings.js +135 -21
- package/dist/compiler/generated-origin.js +46 -0
- package/dist/compiler/hydrate-boundaries.js +124 -52
- package/dist/compiler/plain-hook-memo.js +5 -1
- package/dist/compiler/pure-factories.js +66 -0
- package/dist/compiler/register.js +4 -1
- package/dist/compiler/slot-hooks.js +113 -186
- package/dist/compiler/typescript-lowering.js +763 -0
- package/dist/compiler/void-roots.js +239 -0
- package/dist/compiler/volar.LICENSES.txt +1 -1
- package/dist/compiler/volar.js +820 -175
- package/dist/context-identity.d.ts +14 -0
- package/dist/context-identity.js +28 -0
- package/dist/dom-binding-program.d.ts +2 -2
- package/dist/dom-binding-signals.d.ts +2 -0
- package/dist/dom-binding-signals.js +30 -1
- package/dist/dom-bindings.d.ts +8 -0
- package/dist/dom-bindings.js +265 -19
- package/dist/dom-stage.js +24 -18
- package/dist/error-codes.server.generated.d.ts +1 -0
- package/dist/error-codes.server.generated.js +5 -0
- package/dist/form-submission.d.ts +66 -0
- package/dist/form-submission.js +43 -0
- package/dist/hydration/control-capture.d.ts +4 -2
- package/dist/hydration/control-capture.js +2 -1
- package/dist/hydration/event-capture.d.ts +6 -0
- package/dist/hydration/event-capture.js +79 -4
- package/dist/hydration/idle.js +1 -0
- package/dist/hydration/independent-island.d.ts +7 -1
- package/dist/hydration/independent-island.js +91 -15
- package/dist/hydration/media.js +1 -0
- package/dist/hydration/native-intent.d.ts +29 -0
- package/dist/hydration/native-intent.js +68 -0
- package/dist/hydration/streamed-signals.d.ts +2 -2
- package/dist/hydration/streamed-signals.js +2 -0
- package/dist/hydration/types.d.ts +5 -0
- package/dist/hydration/visible.js +1 -0
- package/dist/hydration-markers.d.ts +8 -0
- package/dist/hydration-markers.js +8 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -0
- package/dist/runtime.d.ts +34 -41
- package/dist/runtime.js +320 -406
- package/dist/runtime.server.d.ts +33 -5
- package/dist/runtime.server.js +200 -46
- package/dist/server/early-signals.d.ts +3 -1
- package/dist/server/early-signals.js +25 -5
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/streamed-region.d.ts +3 -0
- package/dist/server/streamed-region.js +2 -1
- package/dist/server/streamed-signals.js +41 -9
- package/dist/signals/client.js +3 -8
- package/dist/signals/engine.d.ts +12 -25
- package/dist/signals/engine.js +93 -204
- package/dist/signals/facade.js +6 -4
- package/dist/signals/native-read-seeds.d.ts +23 -4
- package/dist/signals/native-read-seeds.js +129 -10
- package/dist/signals/requests.d.ts +8 -5
- package/dist/signals/requests.js +16 -16
- package/dist/signals/scope-streams.d.ts +37 -0
- package/dist/signals/scope-streams.js +147 -0
- package/dist/tsrx-iterable.d.ts +7 -6
- package/dist/tsrx-iterable.js +3 -2
- package/dist/universal-core.js +16 -4
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/dist/cjs/signals/diagnostic-local-hook.cjs +0 -37
- package/dist/compiler/local-void-roots.js +0 -154
- package/dist/signals/diagnostic-local-hook.d.ts +0 -8
- package/dist/signals/diagnostic-local-hook.js +0 -12
package/dist/behavior-root.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { adoptBindings, mountBindings, unbound } from "./dom-bindings.js";
|
|
2
|
+
import { captureFormSubmissions } from "./behavior-form-submissions.js";
|
|
2
3
|
const documentRegistries = /* @__PURE__ */ new WeakMap();
|
|
3
|
-
const
|
|
4
|
+
const DEFAULT_DOM = {
|
|
5
|
+
element: isElement,
|
|
6
|
+
parent: (node) => node.parentElement,
|
|
7
|
+
contains: (container, element, document) => element.ownerDocument === document && (element === container || container.contains(element)),
|
|
8
|
+
matches: (element, selector) => element.matches(selector),
|
|
9
|
+
query: (element, selector) => element.querySelectorAll(selector),
|
|
10
|
+
target: targetElement
|
|
11
|
+
};
|
|
12
|
+
function registryFor(document) {
|
|
13
|
+
let registry = documentRegistries.get(document);
|
|
14
|
+
if (registry === void 0) {
|
|
15
|
+
registry = { roots: /* @__PURE__ */ new Map(), ranges: /* @__PURE__ */ new Map() };
|
|
16
|
+
documentRegistries.set(document, registry);
|
|
17
|
+
}
|
|
18
|
+
return registry;
|
|
19
|
+
}
|
|
20
|
+
const CANCELED = /* @__PURE__ */ Symbol("behavior.canceled");
|
|
4
21
|
function createReadiness() {
|
|
5
22
|
let resolvePromise;
|
|
6
23
|
let rejectPromise;
|
|
@@ -41,44 +58,30 @@ function linkSignal(signal, controller) {
|
|
|
41
58
|
function waitUntilReady(source, signal) {
|
|
42
59
|
if (signal.aborted) {
|
|
43
60
|
void Promise.resolve(source).then(void 0, () => void 0);
|
|
44
|
-
return Promise.resolve(
|
|
61
|
+
return Promise.resolve();
|
|
45
62
|
}
|
|
46
63
|
return new Promise((resolve, reject) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
settled = true;
|
|
51
|
-
resolve(CANCELED);
|
|
64
|
+
const complete = () => {
|
|
65
|
+
signal.removeEventListener("abort", complete);
|
|
66
|
+
resolve();
|
|
52
67
|
};
|
|
53
|
-
signal.addEventListener("abort",
|
|
54
|
-
Promise.resolve(source).then(
|
|
55
|
-
(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
signal.removeEventListener("abort", cancel);
|
|
59
|
-
resolve(value);
|
|
60
|
-
},
|
|
61
|
-
(error) => {
|
|
62
|
-
if (settled) return;
|
|
63
|
-
settled = true;
|
|
64
|
-
signal.removeEventListener("abort", cancel);
|
|
65
|
-
reject(error);
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
+
signal.addEventListener("abort", complete);
|
|
69
|
+
Promise.resolve(source).then(complete, (error) => {
|
|
70
|
+
signal.removeEventListener("abort", complete);
|
|
71
|
+
reject(error);
|
|
72
|
+
});
|
|
68
73
|
});
|
|
69
74
|
}
|
|
70
75
|
function trackPending(root, promise) {
|
|
71
76
|
root.pending.add(promise);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
() => root.pending.delete(promise)
|
|
75
|
-
);
|
|
77
|
+
const remove = () => root.pending.delete(promise);
|
|
78
|
+
void promise.then(remove, remove);
|
|
76
79
|
}
|
|
77
80
|
function isElement(value) {
|
|
78
81
|
return typeof value === "object" && value !== null && value.nodeType === 1;
|
|
79
82
|
}
|
|
80
|
-
function contains(root, element) {
|
|
81
|
-
return
|
|
83
|
+
function contains(root, element, container = root.container) {
|
|
84
|
+
return root.dom.contains(container, element, root.document);
|
|
82
85
|
}
|
|
83
86
|
function assertActiveRoot(root) {
|
|
84
87
|
if (root.disposed || root.controller.signal.aborted) {
|
|
@@ -86,7 +89,7 @@ function assertActiveRoot(root) {
|
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
function assertContainedElement(root, element, label) {
|
|
89
|
-
if (!
|
|
92
|
+
if (!root.dom.element(element) || !contains(root, element)) {
|
|
90
93
|
throw new Error(`${label} must belong to the behavior root container and document.`);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
@@ -98,28 +101,28 @@ function nearestRange(root, element) {
|
|
|
98
101
|
return range;
|
|
99
102
|
}
|
|
100
103
|
if (current === root.container) return void 0;
|
|
101
|
-
current = current
|
|
104
|
+
current = root.dom.parent(current);
|
|
102
105
|
}
|
|
103
106
|
return void 0;
|
|
104
107
|
}
|
|
105
108
|
function matchesTarget(record, element) {
|
|
106
|
-
return typeof record.entry.target === "string" ?
|
|
109
|
+
return typeof record.entry.target === "string" ? record.root.dom.matches(element, record.entry.target) : record.entry.target === element;
|
|
107
110
|
}
|
|
108
111
|
function rangeMatches(record, range) {
|
|
109
112
|
return record.entry.owner === void 0 || range !== void 0 && Object.is(record.entry.owner, range.owner);
|
|
110
113
|
}
|
|
111
114
|
function dependsOnRange(record, range) {
|
|
112
|
-
if (record.
|
|
115
|
+
if (record.waiting.has(range)) return true;
|
|
113
116
|
if (record.entry.owner === void 0 || !Object.is(record.entry.owner, range.owner) || !contains(record.root, range.element)) {
|
|
114
117
|
return false;
|
|
115
118
|
}
|
|
116
119
|
if (typeof record.entry.target !== "string") {
|
|
117
|
-
return
|
|
120
|
+
return contains(record.root, record.entry.target, range.element) && nearestRange(record.root, record.entry.target) === range;
|
|
118
121
|
}
|
|
119
|
-
if (
|
|
122
|
+
if (record.root.dom.matches(range.element, record.entry.target) && nearestRange(record.root, range.element) === range) {
|
|
120
123
|
return true;
|
|
121
124
|
}
|
|
122
|
-
for (const element of range.element
|
|
125
|
+
for (const element of record.root.dom.query(range.element, record.entry.target)) {
|
|
123
126
|
if (nearestRange(record.root, element) === range) return true;
|
|
124
127
|
}
|
|
125
128
|
return false;
|
|
@@ -135,7 +138,7 @@ function adoptionContext(adoption, event) {
|
|
|
135
138
|
function finishPendingAdoption(adoption) {
|
|
136
139
|
if (!adoption.pending) return;
|
|
137
140
|
adoption.pending = false;
|
|
138
|
-
adoption.entry.
|
|
141
|
+
adoption.entry.pendingCount--;
|
|
139
142
|
}
|
|
140
143
|
function disposeAdoption(adoption) {
|
|
141
144
|
if (adoption.disposed) return;
|
|
@@ -151,19 +154,19 @@ function disposeAdoption(adoption) {
|
|
|
151
154
|
}
|
|
152
155
|
function flushQueuedEvents(record) {
|
|
153
156
|
if (record.status !== "active" || record.captureDepth) return;
|
|
154
|
-
const queue = record.
|
|
155
|
-
record.
|
|
157
|
+
const queue = record.queue;
|
|
158
|
+
record.flushDepth++;
|
|
156
159
|
try {
|
|
157
|
-
while (record.
|
|
158
|
-
const index = record.
|
|
160
|
+
while (record.head < queue.length) {
|
|
161
|
+
const index = record.head;
|
|
159
162
|
const queued = queue[index];
|
|
160
|
-
if (queued.payload === CANCELED || !contains(record.root, queued.element)) {
|
|
161
|
-
record.
|
|
163
|
+
if (queued.payload === CANCELED || !(queued.valid?.() ?? contains(record.root, queued.element))) {
|
|
164
|
+
record.head = index + 1;
|
|
162
165
|
continue;
|
|
163
166
|
}
|
|
164
167
|
const range = nearestRange(record.root, queued.element);
|
|
165
168
|
if (range !== queued.range || !rangeMatches(record, range)) {
|
|
166
|
-
record.
|
|
169
|
+
record.head = index + 1;
|
|
167
170
|
continue;
|
|
168
171
|
}
|
|
169
172
|
if (range?.status === "pending") return;
|
|
@@ -172,8 +175,9 @@ function flushQueuedEvents(record) {
|
|
|
172
175
|
adoption = adoptElement(record, queued.element, range, queued.event);
|
|
173
176
|
}
|
|
174
177
|
if (adoption === void 0 || adoption.pending) return;
|
|
175
|
-
if (record.
|
|
176
|
-
record.
|
|
178
|
+
if (record.head !== index || queue[index] !== queued) continue;
|
|
179
|
+
record.head = index + 1;
|
|
180
|
+
if (queued.valid?.() === false) continue;
|
|
177
181
|
record.entry.handleEvent?.(
|
|
178
182
|
queued.event,
|
|
179
183
|
queued.element,
|
|
@@ -182,34 +186,34 @@ function flushQueuedEvents(record) {
|
|
|
182
186
|
);
|
|
183
187
|
}
|
|
184
188
|
} finally {
|
|
185
|
-
record.
|
|
186
|
-
if (record.
|
|
187
|
-
const consumed = record.
|
|
189
|
+
record.flushDepth--;
|
|
190
|
+
if (record.flushDepth === 0 && record.head !== 0) {
|
|
191
|
+
const consumed = record.head;
|
|
188
192
|
if (consumed >= queue.length) {
|
|
189
193
|
queue.length = 0;
|
|
190
|
-
record.
|
|
194
|
+
record.head = 0;
|
|
191
195
|
} else if (consumed >= queue.length - consumed) {
|
|
192
196
|
queue.splice(0, consumed);
|
|
193
|
-
record.
|
|
197
|
+
record.head = 0;
|
|
194
198
|
}
|
|
195
199
|
}
|
|
196
200
|
}
|
|
197
201
|
}
|
|
198
202
|
function completeBehavior(record) {
|
|
199
|
-
if (record.status !== "active" || !record.
|
|
200
|
-
for (const range of
|
|
203
|
+
if (record.status !== "active" || !record.scanned) return;
|
|
204
|
+
for (const range of record.waiting) {
|
|
201
205
|
if (range.status === "pending") return;
|
|
202
|
-
record.
|
|
206
|
+
record.waiting.delete(range);
|
|
203
207
|
}
|
|
204
|
-
if (record.
|
|
208
|
+
if (record.pendingCount !== 0) return;
|
|
205
209
|
flushQueuedEvents(record);
|
|
206
|
-
if (record.
|
|
207
|
-
record.
|
|
210
|
+
if (record.queue.length !== 0) return;
|
|
211
|
+
record.ready.resolve();
|
|
208
212
|
}
|
|
209
213
|
function failBehavior(record, error) {
|
|
210
214
|
if (record.status === "disposed" || record.status === "failed") return;
|
|
211
215
|
record.status = "failed";
|
|
212
|
-
record.
|
|
216
|
+
record.ready.reject(error);
|
|
213
217
|
disposeBehavior(record);
|
|
214
218
|
}
|
|
215
219
|
function adoptElement(record, element, range, event) {
|
|
@@ -217,7 +221,7 @@ function adoptElement(record, element, range, event) {
|
|
|
217
221
|
return void 0;
|
|
218
222
|
}
|
|
219
223
|
if (range?.status === "pending") {
|
|
220
|
-
record.
|
|
224
|
+
record.waiting.add(range);
|
|
221
225
|
return void 0;
|
|
222
226
|
}
|
|
223
227
|
const existing = record.adoptions.get(element);
|
|
@@ -251,7 +255,7 @@ function adoptElement(record, element, range, event) {
|
|
|
251
255
|
}
|
|
252
256
|
if (typeof result === "object" && result !== null && typeof result.then === "function") {
|
|
253
257
|
adoption.pending = true;
|
|
254
|
-
record.
|
|
258
|
+
record.pendingCount++;
|
|
255
259
|
const settled = Promise.resolve(result).then(
|
|
256
260
|
(cleanup) => {
|
|
257
261
|
finishPendingAdoption(adoption);
|
|
@@ -271,24 +275,26 @@ function adoptElement(record, element, range, event) {
|
|
|
271
275
|
failBehavior(record, error);
|
|
272
276
|
}
|
|
273
277
|
);
|
|
274
|
-
const cancelable = waitUntilReady(settled, adoption.controller.signal)
|
|
278
|
+
const cancelable = waitUntilReady(settled, adoption.controller.signal);
|
|
275
279
|
trackPending(record.root, cancelable);
|
|
276
280
|
}
|
|
277
281
|
return adoption;
|
|
278
282
|
}
|
|
279
283
|
function reconcileBehavior(record) {
|
|
280
284
|
if (record.status !== "active") return;
|
|
281
|
-
record.
|
|
285
|
+
record.waiting.clear();
|
|
282
286
|
for (const [element, adoption] of [...record.adoptions]) {
|
|
283
|
-
const
|
|
284
|
-
|
|
287
|
+
const contained = contains(record.root, element);
|
|
288
|
+
const range = contained ? nearestRange(record.root, element) : void 0;
|
|
289
|
+
if (!contained || !matchesTarget(record, element) || !rangeMatches(record, range) || range !== adoption.range || range?.status === "pending") {
|
|
285
290
|
disposeAdoption(adoption);
|
|
286
291
|
}
|
|
287
292
|
}
|
|
288
293
|
let elements;
|
|
289
294
|
if (typeof record.entry.target === "string") {
|
|
290
|
-
elements = Array.from(record.root.
|
|
291
|
-
if (record.root.
|
|
295
|
+
elements = Array.from(record.root.dom.query(record.root.container, record.entry.target));
|
|
296
|
+
if (record.root.dom.matches(record.root.container, record.entry.target))
|
|
297
|
+
elements.unshift(record.root.container);
|
|
292
298
|
} else {
|
|
293
299
|
elements = contains(record.root, record.entry.target) ? [record.entry.target] : [];
|
|
294
300
|
}
|
|
@@ -296,15 +302,16 @@ function reconcileBehavior(record) {
|
|
|
296
302
|
const range = nearestRange(record.root, element);
|
|
297
303
|
if (!rangeMatches(record, range)) continue;
|
|
298
304
|
if (range?.status === "pending") {
|
|
299
|
-
record.
|
|
305
|
+
record.waiting.add(range);
|
|
300
306
|
continue;
|
|
301
307
|
}
|
|
302
308
|
adoptElement(record, element, range);
|
|
303
309
|
}
|
|
304
|
-
record.
|
|
310
|
+
record.scanned = true;
|
|
305
311
|
completeBehavior(record);
|
|
306
312
|
}
|
|
307
313
|
function refreshDocument(registry) {
|
|
314
|
+
registry.capture?.flush();
|
|
308
315
|
for (const root of [...registry.roots.values()]) {
|
|
309
316
|
if (root.disposed) continue;
|
|
310
317
|
for (const record of [...root.behaviors]) reconcileBehavior(record);
|
|
@@ -327,7 +334,8 @@ function targetElement(event) {
|
|
|
327
334
|
}
|
|
328
335
|
function handleDelegatedEvent(root, event) {
|
|
329
336
|
if (root.disposed) return;
|
|
330
|
-
|
|
337
|
+
if (root.registry.capture?.skip(root, event)) return;
|
|
338
|
+
const target = root.dom.target(event);
|
|
331
339
|
if (target === null || !contains(root, target)) return;
|
|
332
340
|
for (const record of [...root.behaviors]) {
|
|
333
341
|
if (record.status === "disposed" || record.status === "failed" || !record.entry.events?.includes(event.type)) {
|
|
@@ -339,15 +347,15 @@ function handleDelegatedEvent(root, event) {
|
|
|
339
347
|
matched = null;
|
|
340
348
|
break;
|
|
341
349
|
}
|
|
342
|
-
matched = matched
|
|
350
|
+
matched = root.dom.parent(matched);
|
|
343
351
|
}
|
|
344
352
|
if (matched === null || !contains(root, matched)) continue;
|
|
345
353
|
const range = nearestRange(root, matched);
|
|
346
354
|
if (!rangeMatches(record, range)) continue;
|
|
347
355
|
if (record.entry.captureEvent !== void 0) {
|
|
348
356
|
const queued = { event, element: matched, range, payload: CANCELED };
|
|
349
|
-
record.
|
|
350
|
-
if (range?.status === "pending") record.
|
|
357
|
+
record.queue.push(queued);
|
|
358
|
+
if (range?.status === "pending") record.waiting.add(range);
|
|
351
359
|
record.captureDepth = (record.captureDepth ?? 0) + 1;
|
|
352
360
|
try {
|
|
353
361
|
const payload = record.entry.captureEvent(event, matched);
|
|
@@ -363,13 +371,13 @@ function handleDelegatedEvent(root, event) {
|
|
|
363
371
|
continue;
|
|
364
372
|
}
|
|
365
373
|
if (record.status !== "active" || range?.status === "pending") {
|
|
366
|
-
record.
|
|
367
|
-
if (range?.status === "pending") record.
|
|
374
|
+
record.queue.push({ event, element: matched, range });
|
|
375
|
+
if (range?.status === "pending") record.waiting.add(range);
|
|
368
376
|
continue;
|
|
369
377
|
}
|
|
370
378
|
const adoption = record.adoptions.get(matched) ?? adoptElement(record, matched, range, event);
|
|
371
|
-
if (adoption === void 0 || adoption.pending || record.
|
|
372
|
-
record.
|
|
379
|
+
if (adoption === void 0 || adoption.pending || record.queue.length !== 0) {
|
|
380
|
+
record.queue.push({ event, element: matched, range });
|
|
373
381
|
flushQueuedEvents(record);
|
|
374
382
|
continue;
|
|
375
383
|
}
|
|
@@ -408,18 +416,19 @@ function removeUnusedListeners(root) {
|
|
|
408
416
|
}
|
|
409
417
|
function disposeBehavior(record) {
|
|
410
418
|
if (record.status === "disposed") return;
|
|
419
|
+
record.root.registry.capture?.release(record);
|
|
411
420
|
const failed = record.status === "failed";
|
|
412
421
|
record.status = "disposed";
|
|
413
422
|
record.controller.abort();
|
|
414
423
|
for (const unlink of record.unlinks) unlink();
|
|
415
424
|
record.unlinks.length = 0;
|
|
416
425
|
record.root.behaviors.delete(record);
|
|
417
|
-
if (record.entry.id !== void 0 && record.root.
|
|
418
|
-
record.root.
|
|
426
|
+
if (record.entry.id !== void 0 && record.root.byId.get(record.entry.id) === record) {
|
|
427
|
+
record.root.byId.delete(record.entry.id);
|
|
419
428
|
}
|
|
420
|
-
record.
|
|
421
|
-
record.
|
|
422
|
-
record.
|
|
429
|
+
record.queue.length = 0;
|
|
430
|
+
record.head = 0;
|
|
431
|
+
record.waiting.clear();
|
|
423
432
|
let firstError;
|
|
424
433
|
for (const adoption of [...record.adoptions.values()]) {
|
|
425
434
|
try {
|
|
@@ -428,7 +437,7 @@ function disposeBehavior(record) {
|
|
|
428
437
|
firstError ??= error;
|
|
429
438
|
}
|
|
430
439
|
}
|
|
431
|
-
if (!failed) record.
|
|
440
|
+
if (!failed) record.ready.resolve();
|
|
432
441
|
removeUnusedListeners(record.root);
|
|
433
442
|
if (firstError !== void 0) throw firstError;
|
|
434
443
|
}
|
|
@@ -445,14 +454,14 @@ function registerBehavior(root, entry) {
|
|
|
445
454
|
if (typeof entry.target !== "string") {
|
|
446
455
|
assertContainedElement(root, entry.target, "A behavior target");
|
|
447
456
|
} else {
|
|
448
|
-
root.
|
|
457
|
+
root.dom.matches(root.container, entry.target);
|
|
449
458
|
}
|
|
450
|
-
if (entry.id !== void 0 && root.
|
|
459
|
+
if (entry.id !== void 0 && root.byId.has(entry.id)) {
|
|
451
460
|
throw new Error(`A behavior with identity ${JSON.stringify(entry.id)} is already registered.`);
|
|
452
461
|
}
|
|
453
462
|
const dependencies = [];
|
|
454
463
|
for (const id of entry.dependencies ?? []) {
|
|
455
|
-
const dependency = root.
|
|
464
|
+
const dependency = root.byId.get(id);
|
|
456
465
|
if (dependency === void 0) {
|
|
457
466
|
throw new Error(`Behavior dependency ${JSON.stringify(id)} is not registered.`);
|
|
458
467
|
}
|
|
@@ -469,16 +478,16 @@ function registerBehavior(root, entry) {
|
|
|
469
478
|
root,
|
|
470
479
|
entry,
|
|
471
480
|
controller,
|
|
472
|
-
readiness,
|
|
481
|
+
ready: readiness,
|
|
473
482
|
status: "pending",
|
|
474
483
|
adoptions: /* @__PURE__ */ new Map(),
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
484
|
+
pendingCount: 0,
|
|
485
|
+
waiting: /* @__PURE__ */ new Set(),
|
|
486
|
+
queue: [],
|
|
487
|
+
head: 0,
|
|
488
|
+
flushDepth: 0,
|
|
480
489
|
unlinks: [linkSignal(root.controller.signal, controller)],
|
|
481
|
-
|
|
490
|
+
scanned: false
|
|
482
491
|
};
|
|
483
492
|
const registration = {
|
|
484
493
|
...entry.id === void 0 ? {} : { id: entry.id },
|
|
@@ -492,11 +501,12 @@ function registerBehavior(root, entry) {
|
|
|
492
501
|
return registration;
|
|
493
502
|
}
|
|
494
503
|
root.behaviors.add(record);
|
|
495
|
-
if (entry.id !== void 0) root.
|
|
504
|
+
if (entry.id !== void 0) root.byId.set(entry.id, record);
|
|
496
505
|
controller.signal.addEventListener("abort", () => disposeBehavior(record), { once: true });
|
|
497
506
|
try {
|
|
498
507
|
installListeners(root, entry.events);
|
|
499
508
|
ensureObserver(root);
|
|
509
|
+
root.registry.capture?.flush();
|
|
500
510
|
} catch (error) {
|
|
501
511
|
disposeBehavior(record);
|
|
502
512
|
throw error;
|
|
@@ -504,7 +514,7 @@ function registerBehavior(root, entry) {
|
|
|
504
514
|
const blockers = [];
|
|
505
515
|
if (entry.ready !== void 0) blockers.push(entry.ready);
|
|
506
516
|
for (const dependency of dependencies) {
|
|
507
|
-
if (!dependency.
|
|
517
|
+
if (!dependency.ready.settled) blockers.push(dependency.ready.promise);
|
|
508
518
|
}
|
|
509
519
|
if (blockers.length === 0) {
|
|
510
520
|
activateBehavior(record);
|
|
@@ -512,10 +522,7 @@ function registerBehavior(root, entry) {
|
|
|
512
522
|
const gate = Promise.all(
|
|
513
523
|
blockers.map((blocker) => waitUntilReady(blocker, controller.signal))
|
|
514
524
|
).then(
|
|
515
|
-
(
|
|
516
|
-
if (results.includes(CANCELED) || controller.signal.aborted) return;
|
|
517
|
-
activateBehavior(record);
|
|
518
|
-
},
|
|
525
|
+
() => activateBehavior(record),
|
|
519
526
|
(error) => {
|
|
520
527
|
if (!controller.signal.aborted) failBehavior(record, error);
|
|
521
528
|
}
|
|
@@ -535,7 +542,7 @@ function disposeRange(record) {
|
|
|
535
542
|
if (record.root.registry.ranges.get(record.element) === record) {
|
|
536
543
|
record.root.registry.ranges.delete(record.element);
|
|
537
544
|
}
|
|
538
|
-
if (!failed) record.
|
|
545
|
+
if (!failed) record.ready.resolve();
|
|
539
546
|
if (!record.root.disposed) refreshDocument(record.root.registry);
|
|
540
547
|
}
|
|
541
548
|
function registerExternalRange(root, element, options) {
|
|
@@ -561,7 +568,7 @@ function registerExternalRange(root, element, options) {
|
|
|
561
568
|
element,
|
|
562
569
|
owner: options.owner,
|
|
563
570
|
controller,
|
|
564
|
-
readiness,
|
|
571
|
+
ready: readiness,
|
|
565
572
|
status: options.ready === void 0 ? "ready" : "pending",
|
|
566
573
|
unlinks: [linkSignal(root.controller.signal, controller)],
|
|
567
574
|
publicRange: void 0
|
|
@@ -587,8 +594,8 @@ function registerExternalRange(root, element, options) {
|
|
|
587
594
|
readiness.resolve();
|
|
588
595
|
} else {
|
|
589
596
|
const gate = waitUntilReady(options.ready, controller.signal).then(
|
|
590
|
-
(
|
|
591
|
-
if (
|
|
597
|
+
() => {
|
|
598
|
+
if (record.status !== "pending") return;
|
|
592
599
|
record.status = "ready";
|
|
593
600
|
refreshDocument(root.registry);
|
|
594
601
|
readiness.resolve();
|
|
@@ -621,6 +628,7 @@ function registerExternalRange(root, element, options) {
|
|
|
621
628
|
}
|
|
622
629
|
function disposeRoot(root, options = {}) {
|
|
623
630
|
if (root.disposed) return;
|
|
631
|
+
root.registry.capture?.dispose(root);
|
|
624
632
|
const releasedExternalOwnership = root.ranges.size !== 0;
|
|
625
633
|
root.disposed = true;
|
|
626
634
|
root.controller.abort();
|
|
@@ -664,40 +672,33 @@ function disposeRoot(root, options = {}) {
|
|
|
664
672
|
if (firstError !== void 0) throw firstError;
|
|
665
673
|
}
|
|
666
674
|
function attachBehaviorRoot(container, options = {}) {
|
|
667
|
-
|
|
675
|
+
const capture = options.formSubmissions;
|
|
676
|
+
const document = capture === void 0 ? isElement(container) ? container.ownerDocument : null : capture.document(container);
|
|
677
|
+
if (document === null) {
|
|
668
678
|
throw new Error("A behavior root requires an element with an owner document.");
|
|
669
679
|
}
|
|
670
|
-
|
|
671
|
-
let registry = documentRegistries.get(document);
|
|
672
|
-
if (registry === void 0) {
|
|
673
|
-
registry = { roots: /* @__PURE__ */ new Map(), ranges: /* @__PURE__ */ new Map() };
|
|
674
|
-
documentRegistries.set(document, registry);
|
|
675
|
-
}
|
|
680
|
+
let registry = registryFor(document);
|
|
676
681
|
const existing = registry.roots.get(container);
|
|
677
|
-
const canceledReplacement = existing !== void 0 && options.replace && options.signal?.aborted;
|
|
678
682
|
if (existing !== void 0) {
|
|
679
683
|
if (!options.replace) {
|
|
680
684
|
throw new Error(
|
|
681
685
|
"This container already has a behavior root; pass replace: true to replace it."
|
|
682
686
|
);
|
|
683
687
|
}
|
|
684
|
-
if (!
|
|
688
|
+
if (!options.signal?.aborted) {
|
|
685
689
|
disposeRoot(existing);
|
|
686
|
-
registry =
|
|
687
|
-
if (registry === void 0) {
|
|
688
|
-
registry = { roots: /* @__PURE__ */ new Map(), ranges: /* @__PURE__ */ new Map() };
|
|
689
|
-
documentRegistries.set(document, registry);
|
|
690
|
-
}
|
|
690
|
+
registry = registryFor(document);
|
|
691
691
|
}
|
|
692
692
|
}
|
|
693
693
|
const controller = createController(document);
|
|
694
694
|
const record = {
|
|
695
695
|
container,
|
|
696
696
|
document,
|
|
697
|
+
dom: DEFAULT_DOM,
|
|
697
698
|
registry,
|
|
698
699
|
controller,
|
|
699
700
|
behaviors: /* @__PURE__ */ new Set(),
|
|
700
|
-
|
|
701
|
+
byId: /* @__PURE__ */ new Map(),
|
|
701
702
|
ranges: /* @__PURE__ */ new Set(),
|
|
702
703
|
pending: /* @__PURE__ */ new Set(),
|
|
703
704
|
listeners: /* @__PURE__ */ new Map(),
|
|
@@ -710,8 +711,8 @@ function attachBehaviorRoot(container, options = {}) {
|
|
|
710
711
|
signal: controller.signal,
|
|
711
712
|
get ready() {
|
|
712
713
|
const waiting = [...record.pending];
|
|
713
|
-
for (const range of record.ranges) waiting.push(range.
|
|
714
|
-
for (const behavior of record.behaviors) waiting.push(behavior.
|
|
714
|
+
for (const range of record.ranges) waiting.push(range.ready.promise);
|
|
715
|
+
for (const behavior of record.behaviors) waiting.push(behavior.ready.promise);
|
|
715
716
|
const ready = Promise.all(waiting).then(() => void 0);
|
|
716
717
|
void ready.catch(() => void 0);
|
|
717
718
|
return ready;
|
|
@@ -720,18 +721,26 @@ function attachBehaviorRoot(container, options = {}) {
|
|
|
720
721
|
registerBehavior: (entry) => registerBehavior(record, entry),
|
|
721
722
|
dispose: (disposeOptions) => disposeRoot(record, disposeOptions)
|
|
722
723
|
};
|
|
723
|
-
if (!canceledReplacement) registry.roots.set(container, record);
|
|
724
724
|
if (options.signal !== void 0) record.unlinkSignal = linkSignal(options.signal, controller);
|
|
725
725
|
if (controller.signal.aborted) {
|
|
726
726
|
disposeRoot(record);
|
|
727
727
|
} else {
|
|
728
|
+
registry.roots.set(container, record);
|
|
729
|
+
try {
|
|
730
|
+
capture?.(record, flushQueuedEvents, failBehavior, nearestRange, rangeMatches, CANCELED);
|
|
731
|
+
} catch (error) {
|
|
732
|
+
disposeRoot(record);
|
|
733
|
+
throw error;
|
|
734
|
+
}
|
|
728
735
|
controller.signal.addEventListener("abort", () => disposeRoot(record), { once: true });
|
|
736
|
+
if (controller.signal.aborted) disposeRoot(record);
|
|
729
737
|
}
|
|
730
738
|
return root;
|
|
731
739
|
}
|
|
732
740
|
export {
|
|
733
741
|
adoptBindings,
|
|
734
742
|
attachBehaviorRoot,
|
|
743
|
+
captureFormSubmissions,
|
|
735
744
|
mountBindings,
|
|
736
745
|
unbound
|
|
737
746
|
};
|