@async/framework 0.11.15 → 0.11.17
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/CHANGELOG.md +27 -0
- package/README.md +10 -14
- package/browser.d.ts +45 -3
- package/browser.js +746 -47
- package/browser.min.js +1 -1
- package/browser.ts +746 -47
- package/browser.umd.js +746 -47
- package/browser.umd.min.js +1 -1
- package/framework.d.ts +45 -3
- package/framework.ts +746 -47
- package/package.json +24 -2
- package/runtime/events.d.ts +48 -0
- package/runtime/events.js +208 -0
- package/runtime/shared.js +85 -0
- package/runtime/signals.d.ts +31 -0
- package/runtime/signals.js +209 -0
- package/runtime.d.ts +72 -0
- package/runtime.js +63 -0
- package/server.js +746 -47
package/browser.ts
CHANGED
|
@@ -6095,7 +6095,19 @@ const __appModule = (() => {
|
|
|
6095
6095
|
})();
|
|
6096
6096
|
|
|
6097
6097
|
const __boundaryReceiverModule = (() => {
|
|
6098
|
+
const { normalizeAttributeConfig, readAttribute } = __attributesModule;
|
|
6099
|
+
const { renderTemplate } = __htmlModule;
|
|
6098
6100
|
const defaultRecentLimit = 50;
|
|
6101
|
+
const builtBackpatchAttribute = "data-async-backpatch";
|
|
6102
|
+
const pendingTargetAttribute = "data-pending-id";
|
|
6103
|
+
const revealOrders = new Set(["as-ready", "forwards", "backwards", "together"]);
|
|
6104
|
+
const revealTails = new Set(["collapsed", "hidden"]);
|
|
6105
|
+
const structuralAttributeNames = new Set(["innerhtml", "outerhtml", "textcontent", "children", "childnodes"]);
|
|
6106
|
+
|
|
6107
|
+
const AsyncStream = Object.freeze({
|
|
6108
|
+
applyScript,
|
|
6109
|
+
applyCurrentScript
|
|
6110
|
+
});
|
|
6099
6111
|
|
|
6100
6112
|
function createBoundaryReceiver(options = {}) {
|
|
6101
6113
|
const loader = options.loader;
|
|
@@ -6103,6 +6115,7 @@ const __boundaryReceiverModule = (() => {
|
|
|
6103
6115
|
const cache = options.cache ?? loader?.cache;
|
|
6104
6116
|
const scheduler = options.scheduler ?? loader?.scheduler;
|
|
6105
6117
|
const router = options.router ?? loader?.router;
|
|
6118
|
+
const attributes = normalizeAttributeConfig(options.attributes ?? loader?.attributes);
|
|
6106
6119
|
const recentLimit = options.recentLimit ?? defaultRecentLimit;
|
|
6107
6120
|
const throwOnError = options.throwOnError === true;
|
|
6108
6121
|
const onApply = typeof options.onApply === "function" ? options.onApply : undefined;
|
|
@@ -6120,6 +6133,7 @@ const __boundaryReceiverModule = (() => {
|
|
|
6120
6133
|
}
|
|
6121
6134
|
|
|
6122
6135
|
const boundaries = new Map();
|
|
6136
|
+
const revealGroups = new Map();
|
|
6123
6137
|
const recent = [];
|
|
6124
6138
|
let destroyed = false;
|
|
6125
6139
|
|
|
@@ -6168,6 +6182,7 @@ const __boundaryReceiverModule = (() => {
|
|
|
6168
6182
|
return {
|
|
6169
6183
|
destroyed,
|
|
6170
6184
|
boundaries: snapshot,
|
|
6185
|
+
reveal: inspectRevealGroups(revealGroups),
|
|
6171
6186
|
recent: recent.map((entry) => ({ ...entry }))
|
|
6172
6187
|
};
|
|
6173
6188
|
},
|
|
@@ -6175,6 +6190,7 @@ const __boundaryReceiverModule = (() => {
|
|
|
6175
6190
|
reset(boundary) {
|
|
6176
6191
|
if (boundary === undefined) {
|
|
6177
6192
|
boundaries.clear();
|
|
6193
|
+
revealGroups.clear();
|
|
6178
6194
|
recent.length = 0;
|
|
6179
6195
|
return receiver;
|
|
6180
6196
|
}
|
|
@@ -6185,12 +6201,20 @@ const __boundaryReceiverModule = (() => {
|
|
|
6185
6201
|
recent.splice(index, 1);
|
|
6186
6202
|
}
|
|
6187
6203
|
}
|
|
6204
|
+
for (const group of revealGroups.values()) {
|
|
6205
|
+
for (const [index, item] of group.pending) {
|
|
6206
|
+
if (item.normalized.boundary === boundary) {
|
|
6207
|
+
group.pending.delete(index);
|
|
6208
|
+
}
|
|
6209
|
+
}
|
|
6210
|
+
}
|
|
6188
6211
|
return receiver;
|
|
6189
6212
|
},
|
|
6190
6213
|
|
|
6191
6214
|
destroy() {
|
|
6192
6215
|
destroyed = true;
|
|
6193
6216
|
boundaries.clear();
|
|
6217
|
+
revealGroups.clear();
|
|
6194
6218
|
recent.length = 0;
|
|
6195
6219
|
}
|
|
6196
6220
|
};
|
|
@@ -6198,32 +6222,10 @@ const __boundaryReceiverModule = (() => {
|
|
|
6198
6222
|
return receiver;
|
|
6199
6223
|
|
|
6200
6224
|
async function applyBoundaryPatch(record, normalized, patch) {
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
seq: normalized.seq,
|
|
6206
|
-
lastSeq: record.lastSeq
|
|
6207
|
-
};
|
|
6208
|
-
record.ignored += 1;
|
|
6209
|
-
record.lastStatus = result.status;
|
|
6210
|
-
remember(result);
|
|
6211
|
-
onIgnore?.(result, patch);
|
|
6212
|
-
return result;
|
|
6213
|
-
}
|
|
6214
|
-
|
|
6215
|
-
if (normalized.parentScope !== undefined && isScopeDestroyed(normalized.parentScope)) {
|
|
6216
|
-
const result = {
|
|
6217
|
-
status: "ignored-destroyed",
|
|
6218
|
-
boundary: normalized.boundary,
|
|
6219
|
-
seq: normalized.seq,
|
|
6220
|
-
parentScope: normalized.parentScope
|
|
6221
|
-
};
|
|
6222
|
-
record.ignored += 1;
|
|
6223
|
-
record.lastStatus = result.status;
|
|
6224
|
-
remember(result);
|
|
6225
|
-
onIgnore?.(result, patch);
|
|
6226
|
-
return result;
|
|
6225
|
+
const ignored = preflightIgnoredResult(record, normalized);
|
|
6226
|
+
if (ignored) {
|
|
6227
|
+
rememberIgnored(record, ignored, patch);
|
|
6228
|
+
return ignored;
|
|
6227
6229
|
}
|
|
6228
6230
|
|
|
6229
6231
|
if (Object.hasOwn(normalized, "error")) {
|
|
@@ -6245,35 +6247,91 @@ const __boundaryReceiverModule = (() => {
|
|
|
6245
6247
|
return result;
|
|
6246
6248
|
}
|
|
6247
6249
|
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
for (const [path, value] of Object.entries(normalized.signals)) {
|
|
6253
|
-
signals.set(path, value);
|
|
6254
|
-
}
|
|
6250
|
+
applyStateEffects(normalized);
|
|
6251
|
+
|
|
6252
|
+
if (normalized.reveal) {
|
|
6253
|
+
return await applyRevealPatch(record, normalized, patch);
|
|
6255
6254
|
}
|
|
6256
6255
|
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6256
|
+
return await commitBoundaryPatch(record, normalized, patch, { stateApplied: true });
|
|
6257
|
+
}
|
|
6258
|
+
|
|
6259
|
+
async function applyRevealPatch(record, normalized, patch) {
|
|
6260
|
+
const group = revealGroup(normalized.reveal);
|
|
6261
|
+
const index = normalized.reveal.index;
|
|
6262
|
+
if (group.committed.has(index)) {
|
|
6263
|
+
throw new TypeError(`Reveal group "${group.id}" already committed index ${index}.`);
|
|
6264
|
+
}
|
|
6265
|
+
if (group.pending.has(index)) {
|
|
6266
|
+
throw new TypeError(`Reveal group "${group.id}" already has a pending patch for index ${index}.`);
|
|
6267
|
+
}
|
|
6268
|
+
|
|
6269
|
+
const item = { record, normalized, patch };
|
|
6270
|
+
group.pending.set(index, item);
|
|
6271
|
+
const ready = takeReadyRevealItems(group);
|
|
6272
|
+
if (!ready.includes(item)) {
|
|
6273
|
+
const result = {
|
|
6274
|
+
status: "buffered",
|
|
6275
|
+
boundary: normalized.boundary,
|
|
6276
|
+
seq: normalized.seq,
|
|
6277
|
+
reveal: revealResultMetadata(normalized.reveal)
|
|
6278
|
+
};
|
|
6279
|
+
record.lastStatus = result.status;
|
|
6280
|
+
remember(result);
|
|
6281
|
+
updateRevealTail(group);
|
|
6282
|
+
return result;
|
|
6283
|
+
}
|
|
6284
|
+
|
|
6285
|
+
let currentResult;
|
|
6286
|
+
for (const readyItem of ready) {
|
|
6287
|
+
const result = await commitBoundaryPatch(readyItem.record, readyItem.normalized, readyItem.patch, {
|
|
6288
|
+
stateApplied: true
|
|
6289
|
+
});
|
|
6290
|
+
group.committed.add(readyItem.normalized.reveal.index);
|
|
6291
|
+
if (readyItem === item) {
|
|
6292
|
+
currentResult = result;
|
|
6260
6293
|
}
|
|
6261
|
-
|
|
6294
|
+
}
|
|
6295
|
+
updateRevealTail(group);
|
|
6296
|
+
return currentResult;
|
|
6297
|
+
}
|
|
6298
|
+
|
|
6299
|
+
async function commitBoundaryPatch(record, normalized, patch, options = {}) {
|
|
6300
|
+
const ignored = preflightIgnoredResult(record, normalized);
|
|
6301
|
+
if (ignored) {
|
|
6302
|
+
rememberIgnored(record, ignored, patch);
|
|
6303
|
+
return ignored;
|
|
6304
|
+
}
|
|
6305
|
+
|
|
6306
|
+
if (!options.stateApplied) {
|
|
6307
|
+
applyStateEffects(normalized);
|
|
6262
6308
|
}
|
|
6263
6309
|
|
|
6310
|
+
let boundaryElement;
|
|
6311
|
+
let replacementCount = 0;
|
|
6264
6312
|
if (normalized.html != null) {
|
|
6265
|
-
loader.swap(normalized.boundary, normalized.html);
|
|
6313
|
+
boundaryElement = loader.swap(normalized.boundary, normalized.html);
|
|
6314
|
+
}
|
|
6315
|
+
if (normalized.replace) {
|
|
6316
|
+
boundaryElement ??= findBoundaryElement(loader.root, normalized.boundary, attributes);
|
|
6317
|
+
replacementCount = applyReplacements(boundaryElement, normalized.replace);
|
|
6318
|
+
}
|
|
6319
|
+
|
|
6320
|
+
let attrs;
|
|
6321
|
+
if (normalized.attrs) {
|
|
6322
|
+
boundaryElement ??= findBoundaryElement(loader.root, normalized.boundary, attributes);
|
|
6323
|
+
attrs = applyAttributePatches(boundaryElement, normalized.attrs);
|
|
6266
6324
|
}
|
|
6267
6325
|
|
|
6268
6326
|
await flushScheduler(scheduler, normalized.scope);
|
|
6269
6327
|
|
|
6270
6328
|
if (normalized.redirect) {
|
|
6271
|
-
const result = {
|
|
6329
|
+
const result = withPatchMetadata({
|
|
6272
6330
|
status: "redirected",
|
|
6273
6331
|
boundary: normalized.boundary,
|
|
6274
6332
|
seq: normalized.seq,
|
|
6275
6333
|
redirect: normalized.redirect
|
|
6276
|
-
};
|
|
6334
|
+
}, attrs, replacementCount);
|
|
6277
6335
|
await followRedirect(normalized.redirect, router, loader);
|
|
6278
6336
|
record.applied += 1;
|
|
6279
6337
|
record.lastSeq = normalized.seq;
|
|
@@ -6283,11 +6341,11 @@ const __boundaryReceiverModule = (() => {
|
|
|
6283
6341
|
return result;
|
|
6284
6342
|
}
|
|
6285
6343
|
|
|
6286
|
-
const result = {
|
|
6344
|
+
const result = withPatchMetadata({
|
|
6287
6345
|
status: "applied",
|
|
6288
6346
|
boundary: normalized.boundary,
|
|
6289
6347
|
seq: normalized.seq
|
|
6290
|
-
};
|
|
6348
|
+
}, attrs, replacementCount);
|
|
6291
6349
|
record.applied += 1;
|
|
6292
6350
|
record.lastSeq = normalized.seq;
|
|
6293
6351
|
record.lastStatus = result.status;
|
|
@@ -6296,6 +6354,157 @@ const __boundaryReceiverModule = (() => {
|
|
|
6296
6354
|
return result;
|
|
6297
6355
|
}
|
|
6298
6356
|
|
|
6357
|
+
function applyStateEffects(normalized) {
|
|
6358
|
+
if (normalized.signals) {
|
|
6359
|
+
if (!signals || typeof signals.set !== "function") {
|
|
6360
|
+
throw new Error("Boundary patch includes signals, but no signal registry is available.");
|
|
6361
|
+
}
|
|
6362
|
+
for (const [path, value] of Object.entries(normalized.signals)) {
|
|
6363
|
+
signals.set(path, value);
|
|
6364
|
+
}
|
|
6365
|
+
}
|
|
6366
|
+
|
|
6367
|
+
if (normalized.cache?.browser) {
|
|
6368
|
+
if (!cache || typeof cache.restore !== "function") {
|
|
6369
|
+
throw new Error("Boundary patch includes browser cache, but no cache registry is available.");
|
|
6370
|
+
}
|
|
6371
|
+
cache.restore(normalized.cache.browser);
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
|
|
6375
|
+
function applyReplacements(boundaryElement, replacements) {
|
|
6376
|
+
let applied = 0;
|
|
6377
|
+
for (const replacement of replacements) {
|
|
6378
|
+
if (replacement.mode === "boundary") {
|
|
6379
|
+
const target = findBoundaryElement(loader.root, replacement.target, attributes);
|
|
6380
|
+
if (!containsOrEquals(boundaryElement, target)) {
|
|
6381
|
+
throw new Error(`Boundary replacement target "${replacement.target}" is outside boundary "${boundaryIdFor(boundaryElement, attributes)}".`);
|
|
6382
|
+
}
|
|
6383
|
+
loader.swap(replacement.target, replacement.html);
|
|
6384
|
+
applied += 1;
|
|
6385
|
+
continue;
|
|
6386
|
+
}
|
|
6387
|
+
|
|
6388
|
+
const target = findUniqueScopedElement(
|
|
6389
|
+
boundaryElement,
|
|
6390
|
+
(element) => element.getAttribute?.(pendingTargetAttribute) === replacement.target,
|
|
6391
|
+
`Pending replacement target "${replacement.target}"`
|
|
6392
|
+
);
|
|
6393
|
+
const fragment = toFragment(replacement.html, ownerDocumentOf(boundaryElement));
|
|
6394
|
+
const inserted = [...fragment.childNodes];
|
|
6395
|
+
target.replaceWith(fragment);
|
|
6396
|
+
for (const node of inserted) {
|
|
6397
|
+
if (node.nodeType === 1 || node.nodeType === 11) {
|
|
6398
|
+
loader.scan?.(node);
|
|
6399
|
+
}
|
|
6400
|
+
}
|
|
6401
|
+
applied += 1;
|
|
6402
|
+
}
|
|
6403
|
+
return applied;
|
|
6404
|
+
}
|
|
6405
|
+
|
|
6406
|
+
function applyAttributePatches(boundaryElement, attrs) {
|
|
6407
|
+
let applied = 0;
|
|
6408
|
+
for (const attr of attrs.items) {
|
|
6409
|
+
const target = attrs.kind === "built"
|
|
6410
|
+
? resolveBuiltAttrTarget(boundaryElement, attr.target)
|
|
6411
|
+
: resolveNamedAttrTarget(boundaryElement, attr.target);
|
|
6412
|
+
setPatchedAttribute(target, attr.name, attr.value);
|
|
6413
|
+
applied += 1;
|
|
6414
|
+
}
|
|
6415
|
+
return {
|
|
6416
|
+
applied,
|
|
6417
|
+
ignored: 0
|
|
6418
|
+
};
|
|
6419
|
+
}
|
|
6420
|
+
|
|
6421
|
+
function resolveBuiltAttrTarget(boundaryElement, targetIndex) {
|
|
6422
|
+
const targets = scopedElements(boundaryElement)
|
|
6423
|
+
.filter((element) => element.hasAttribute?.(builtBackpatchAttribute));
|
|
6424
|
+
const target = targets[targetIndex];
|
|
6425
|
+
if (!target) {
|
|
6426
|
+
throw new Error(`Built attribute patch target ${targetIndex} was not found in boundary "${boundaryIdFor(boundaryElement, attributes)}".`);
|
|
6427
|
+
}
|
|
6428
|
+
return target;
|
|
6429
|
+
}
|
|
6430
|
+
|
|
6431
|
+
function resolveNamedAttrTarget(boundaryElement, targetName) {
|
|
6432
|
+
return findUniqueScopedElement(
|
|
6433
|
+
boundaryElement,
|
|
6434
|
+
(element) => readAttribute(element, attributes, "async", "patch") === targetName,
|
|
6435
|
+
`Attribute patch target "${targetName}"`
|
|
6436
|
+
);
|
|
6437
|
+
}
|
|
6438
|
+
|
|
6439
|
+
function findUniqueScopedElement(boundaryElement, predicate, label) {
|
|
6440
|
+
const matches = scopedElements(boundaryElement).filter(predicate);
|
|
6441
|
+
if (matches.length === 0) {
|
|
6442
|
+
throw new Error(`${label} was not found.`);
|
|
6443
|
+
}
|
|
6444
|
+
if (matches.length > 1) {
|
|
6445
|
+
throw new Error(`${label} is ambiguous.`);
|
|
6446
|
+
}
|
|
6447
|
+
return matches[0];
|
|
6448
|
+
}
|
|
6449
|
+
|
|
6450
|
+
function scopedElements(boundaryElement) {
|
|
6451
|
+
return elementsIn(boundaryElement)
|
|
6452
|
+
.filter((element) => !isNestedBoundaryElement(element, boundaryElement, attributes));
|
|
6453
|
+
}
|
|
6454
|
+
|
|
6455
|
+
function revealGroup(reveal) {
|
|
6456
|
+
const existing = revealGroups.get(reveal.group);
|
|
6457
|
+
if (existing) {
|
|
6458
|
+
if (existing.count !== reveal.count || existing.order !== reveal.order || existing.tail !== reveal.tail) {
|
|
6459
|
+
throw new TypeError(`Reveal group "${reveal.group}" metadata does not match earlier patches.`);
|
|
6460
|
+
}
|
|
6461
|
+
return existing;
|
|
6462
|
+
}
|
|
6463
|
+
|
|
6464
|
+
const group = {
|
|
6465
|
+
id: reveal.group,
|
|
6466
|
+
count: reveal.count,
|
|
6467
|
+
order: reveal.order,
|
|
6468
|
+
tail: reveal.tail,
|
|
6469
|
+
pending: new Map(),
|
|
6470
|
+
committed: new Set(),
|
|
6471
|
+
nextForward: 0,
|
|
6472
|
+
nextBackward: reveal.count - 1
|
|
6473
|
+
};
|
|
6474
|
+
revealGroups.set(reveal.group, group);
|
|
6475
|
+
return group;
|
|
6476
|
+
}
|
|
6477
|
+
|
|
6478
|
+
function updateRevealTail(group) {
|
|
6479
|
+
if (!group.tail) {
|
|
6480
|
+
return;
|
|
6481
|
+
}
|
|
6482
|
+
const container = findRevealContainer(loader.root, group.id, attributes);
|
|
6483
|
+
if (!container) {
|
|
6484
|
+
return;
|
|
6485
|
+
}
|
|
6486
|
+
const children = directChildBoundaryElements(container, attributes).slice(0, group.count);
|
|
6487
|
+
if (children.length === 0) {
|
|
6488
|
+
return;
|
|
6489
|
+
}
|
|
6490
|
+
|
|
6491
|
+
const pending = [];
|
|
6492
|
+
for (let index = 0; index < children.length; index += 1) {
|
|
6493
|
+
if (!group.committed.has(index)) {
|
|
6494
|
+
pending.push(index);
|
|
6495
|
+
} else {
|
|
6496
|
+
setTailHidden(children[index], false);
|
|
6497
|
+
}
|
|
6498
|
+
}
|
|
6499
|
+
|
|
6500
|
+
const visiblePending = group.tail === "collapsed" && pending.length > 0
|
|
6501
|
+
? pendingOrderFor(group, pending)[0]
|
|
6502
|
+
: undefined;
|
|
6503
|
+
for (const index of pending) {
|
|
6504
|
+
setTailHidden(children[index], group.tail === "hidden" || index !== visiblePending);
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6507
|
+
|
|
6299
6508
|
function boundaryRecord(boundary) {
|
|
6300
6509
|
if (!boundaries.has(boundary)) {
|
|
6301
6510
|
boundaries.set(boundary, {
|
|
@@ -6310,6 +6519,34 @@ const __boundaryReceiverModule = (() => {
|
|
|
6310
6519
|
return boundaries.get(boundary);
|
|
6311
6520
|
}
|
|
6312
6521
|
|
|
6522
|
+
function preflightIgnoredResult(record, normalized) {
|
|
6523
|
+
if (normalized.seq <= record.lastSeq) {
|
|
6524
|
+
return {
|
|
6525
|
+
status: "ignored-stale",
|
|
6526
|
+
boundary: normalized.boundary,
|
|
6527
|
+
seq: normalized.seq,
|
|
6528
|
+
lastSeq: record.lastSeq
|
|
6529
|
+
};
|
|
6530
|
+
}
|
|
6531
|
+
|
|
6532
|
+
if (normalized.parentScope !== undefined && isScopeDestroyed(normalized.parentScope)) {
|
|
6533
|
+
return {
|
|
6534
|
+
status: "ignored-destroyed",
|
|
6535
|
+
boundary: normalized.boundary,
|
|
6536
|
+
seq: normalized.seq,
|
|
6537
|
+
parentScope: normalized.parentScope
|
|
6538
|
+
};
|
|
6539
|
+
}
|
|
6540
|
+
return null;
|
|
6541
|
+
}
|
|
6542
|
+
|
|
6543
|
+
function rememberIgnored(record, result, patch) {
|
|
6544
|
+
record.ignored += 1;
|
|
6545
|
+
record.lastStatus = result.status;
|
|
6546
|
+
remember(result);
|
|
6547
|
+
onIgnore?.(result, patch);
|
|
6548
|
+
}
|
|
6549
|
+
|
|
6313
6550
|
function remember(result) {
|
|
6314
6551
|
if (recentLimit === 0) {
|
|
6315
6552
|
return;
|
|
@@ -6321,6 +6558,132 @@ const __boundaryReceiverModule = (() => {
|
|
|
6321
6558
|
}
|
|
6322
6559
|
}
|
|
6323
6560
|
|
|
6561
|
+
function applyScript(script, options = {}) {
|
|
6562
|
+
if (!script || typeof script !== "object" || typeof script.textContent !== "string") {
|
|
6563
|
+
throw new TypeError("AsyncStream.applyScript(script) requires a JSON script element.");
|
|
6564
|
+
}
|
|
6565
|
+
const attributes = normalizeAttributeConfig(options.attributes ?? options.receiver?.attributes);
|
|
6566
|
+
const patch = parseStreamPatch(script.textContent);
|
|
6567
|
+
const root = options.root ?? script.ownerDocument ?? globalThis.document;
|
|
6568
|
+
const resolved = resolveStreamPatch(patch, { root, attributes });
|
|
6569
|
+
const receiver = resolveReceiver(options);
|
|
6570
|
+
return receiver.apply(resolved);
|
|
6571
|
+
}
|
|
6572
|
+
|
|
6573
|
+
function applyCurrentScript(scriptOrOptions, maybeOptions) {
|
|
6574
|
+
const script = isElementLike(scriptOrOptions)
|
|
6575
|
+
? scriptOrOptions
|
|
6576
|
+
: globalThis.document?.currentScript;
|
|
6577
|
+
const options = isElementLike(scriptOrOptions) ? maybeOptions ?? {} : scriptOrOptions ?? {};
|
|
6578
|
+
return applyScript(script, options);
|
|
6579
|
+
}
|
|
6580
|
+
|
|
6581
|
+
function resolveReceiver(options = {}) {
|
|
6582
|
+
if (options.receiver && typeof options.receiver.apply === "function") {
|
|
6583
|
+
return options.receiver;
|
|
6584
|
+
}
|
|
6585
|
+
const runtime = options.runtime ?? globalThis.Async?.runtime;
|
|
6586
|
+
const loader = options.loader ?? runtime?.loader;
|
|
6587
|
+
if (!loader) {
|
|
6588
|
+
throw new TypeError("AsyncStream requires receiver, loader, or runtime.loader.");
|
|
6589
|
+
}
|
|
6590
|
+
return createBoundaryReceiver({
|
|
6591
|
+
loader,
|
|
6592
|
+
signals: options.signals ?? runtime?.signals,
|
|
6593
|
+
cache: options.cache ?? runtime?.browser?.cache,
|
|
6594
|
+
scheduler: options.scheduler ?? runtime?.scheduler,
|
|
6595
|
+
router: options.router ?? runtime?.router,
|
|
6596
|
+
attributes: options.attributes ?? runtime?.attributes ?? loader.attributes
|
|
6597
|
+
});
|
|
6598
|
+
}
|
|
6599
|
+
|
|
6600
|
+
function parseStreamPatch(source) {
|
|
6601
|
+
try {
|
|
6602
|
+
return JSON.parse(source);
|
|
6603
|
+
} catch (error) {
|
|
6604
|
+
throw new TypeError(`Async stream patch JSON is invalid: ${error.message}`);
|
|
6605
|
+
}
|
|
6606
|
+
}
|
|
6607
|
+
|
|
6608
|
+
function resolveStreamPatch(patch, { root, attributes }) {
|
|
6609
|
+
if (!patch || typeof patch !== "object" || Array.isArray(patch)) {
|
|
6610
|
+
throw new TypeError("Async stream patch JSON must be an object.");
|
|
6611
|
+
}
|
|
6612
|
+
const resolved = { ...patch };
|
|
6613
|
+
if (patch.replace !== undefined) {
|
|
6614
|
+
resolved.replace = resolveStreamReplacements(patch.replace, root, attributes);
|
|
6615
|
+
}
|
|
6616
|
+
const synthesizedReveal = synthesizeRevealMetadata(resolved, root, attributes);
|
|
6617
|
+
if (patch.reveal !== undefined && synthesizedReveal && !sameRevealMetadata(patch.reveal, synthesizedReveal)) {
|
|
6618
|
+
throw new TypeError("Explicit stream reveal metadata conflicts with DOM reveal metadata.");
|
|
6619
|
+
}
|
|
6620
|
+
if (patch.reveal === undefined && synthesizedReveal) {
|
|
6621
|
+
resolved.reveal = synthesizedReveal;
|
|
6622
|
+
}
|
|
6623
|
+
return resolved;
|
|
6624
|
+
}
|
|
6625
|
+
|
|
6626
|
+
function resolveStreamReplacements(value, root, attributes) {
|
|
6627
|
+
const replacements = Array.isArray(value) ? value : [value];
|
|
6628
|
+
return replacements.map((replacement) => {
|
|
6629
|
+
if (!isPlainObject(replacement)) {
|
|
6630
|
+
throw new TypeError("Stream replacement records must be objects.");
|
|
6631
|
+
}
|
|
6632
|
+
if (replacement.template === undefined || Object.hasOwn(replacement, "html")) {
|
|
6633
|
+
return replacement;
|
|
6634
|
+
}
|
|
6635
|
+
const template = findStreamTemplate(root, replacement.template, attributes);
|
|
6636
|
+
if (!template) {
|
|
6637
|
+
throw new Error(`Stream template "${replacement.template}" was not found.`);
|
|
6638
|
+
}
|
|
6639
|
+
return {
|
|
6640
|
+
...replacement,
|
|
6641
|
+
html: template.innerHTML
|
|
6642
|
+
};
|
|
6643
|
+
});
|
|
6644
|
+
}
|
|
6645
|
+
|
|
6646
|
+
function findStreamTemplate(root, id, attributes) {
|
|
6647
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
6648
|
+
throw new TypeError("Stream replacement template must be a non-empty string.");
|
|
6649
|
+
}
|
|
6650
|
+
return elementsIn(root)
|
|
6651
|
+
.find((element) => element.tagName === "TEMPLATE" && readAttribute(element, attributes, "async", "stream-template") === id)
|
|
6652
|
+
?? null;
|
|
6653
|
+
}
|
|
6654
|
+
|
|
6655
|
+
function synthesizeRevealMetadata(patch, root, attributes) {
|
|
6656
|
+
if (typeof patch.boundary !== "string" || patch.boundary.length === 0) {
|
|
6657
|
+
return null;
|
|
6658
|
+
}
|
|
6659
|
+
const boundary = findBoundaryElement(root, patch.boundary, attributes, { required: false });
|
|
6660
|
+
const container = boundary?.parentElement;
|
|
6661
|
+
const group = container ? readAttribute(container, attributes, "async", "reveal") : null;
|
|
6662
|
+
if (!group) {
|
|
6663
|
+
return null;
|
|
6664
|
+
}
|
|
6665
|
+
const children = directChildBoundaryElements(container, attributes);
|
|
6666
|
+
const index = children.indexOf(boundary);
|
|
6667
|
+
if (index === -1) {
|
|
6668
|
+
return null;
|
|
6669
|
+
}
|
|
6670
|
+
return {
|
|
6671
|
+
group,
|
|
6672
|
+
index,
|
|
6673
|
+
count: children.length,
|
|
6674
|
+
order: readAttribute(container, attributes, "async", "reveal-order") || "as-ready",
|
|
6675
|
+
tail: readAttribute(container, attributes, "async", "reveal-tail") || undefined
|
|
6676
|
+
};
|
|
6677
|
+
}
|
|
6678
|
+
|
|
6679
|
+
function sameRevealMetadata(left, right) {
|
|
6680
|
+
return left?.group === right.group &&
|
|
6681
|
+
left?.index === right.index &&
|
|
6682
|
+
left?.count === right.count &&
|
|
6683
|
+
(left?.order ?? "as-ready") === right.order &&
|
|
6684
|
+
left?.tail === right.tail;
|
|
6685
|
+
}
|
|
6686
|
+
|
|
6324
6687
|
function validatePatch(patch) {
|
|
6325
6688
|
if (!patch || typeof patch !== "object" || Array.isArray(patch)) {
|
|
6326
6689
|
throw new TypeError("receiver.apply(patch) requires a boundary patch object.");
|
|
@@ -6350,16 +6713,127 @@ const __boundaryReceiverModule = (() => {
|
|
|
6350
6713
|
throw new TypeError("Boundary patch scope must be a string.");
|
|
6351
6714
|
}
|
|
6352
6715
|
|
|
6716
|
+
const normalized = { ...patch };
|
|
6717
|
+
if (patch.attrs !== undefined) {
|
|
6718
|
+
normalized.attrs = normalizeAttributePatches(patch.attrs);
|
|
6719
|
+
}
|
|
6720
|
+
if (patch.replace !== undefined) {
|
|
6721
|
+
normalized.replace = normalizeReplacements(patch.replace);
|
|
6722
|
+
}
|
|
6723
|
+
if (patch.reveal !== undefined) {
|
|
6724
|
+
normalized.reveal = normalizeRevealMetadata(patch.reveal);
|
|
6725
|
+
}
|
|
6726
|
+
|
|
6353
6727
|
const hasHtml = Object.hasOwn(patch, "html") && patch.html != null;
|
|
6354
6728
|
const hasSignals = patch.signals && Object.keys(patch.signals).length > 0;
|
|
6355
6729
|
const hasBrowserCache = patch.cache?.browser && Object.keys(patch.cache.browser).length > 0;
|
|
6356
6730
|
const hasRedirect = Boolean(patch.redirect);
|
|
6357
6731
|
const hasError = Object.hasOwn(patch, "error");
|
|
6358
|
-
|
|
6359
|
-
|
|
6732
|
+
const hasAttrs = normalized.attrs?.items.length > 0;
|
|
6733
|
+
const hasReplace = normalized.replace?.length > 0;
|
|
6734
|
+
if (!hasHtml && !hasSignals && !hasBrowserCache && !hasRedirect && !hasError && !hasAttrs && !hasReplace) {
|
|
6735
|
+
throw new TypeError("Boundary patch must include html, replace, attrs, signals, cache.browser, redirect, or error.");
|
|
6360
6736
|
}
|
|
6361
6737
|
|
|
6362
|
-
return
|
|
6738
|
+
return normalized;
|
|
6739
|
+
}
|
|
6740
|
+
|
|
6741
|
+
function normalizeAttributePatches(attrs) {
|
|
6742
|
+
if (!Array.isArray(attrs)) {
|
|
6743
|
+
throw new TypeError("Boundary patch attrs must be an array.");
|
|
6744
|
+
}
|
|
6745
|
+
if (attrs.length === 0) {
|
|
6746
|
+
return { kind: "built", items: [] };
|
|
6747
|
+
}
|
|
6748
|
+
const named = Array.isArray(attrs[0]);
|
|
6749
|
+
if (named) {
|
|
6750
|
+
return {
|
|
6751
|
+
kind: "named",
|
|
6752
|
+
items: attrs.map((tuple) => normalizeNamedAttributePatch(tuple))
|
|
6753
|
+
};
|
|
6754
|
+
}
|
|
6755
|
+
if (attrs.some(Array.isArray)) {
|
|
6756
|
+
throw new TypeError("Boundary patch attrs cannot mix built triples and no-build tuples.");
|
|
6757
|
+
}
|
|
6758
|
+
if (attrs.length % 3 !== 0) {
|
|
6759
|
+
throw new TypeError("Built attribute patch triples must have a length divisible by 3.");
|
|
6760
|
+
}
|
|
6761
|
+
const items = [];
|
|
6762
|
+
for (let index = 0; index < attrs.length; index += 3) {
|
|
6763
|
+
const target = attrs[index];
|
|
6764
|
+
const name = attrs[index + 1];
|
|
6765
|
+
const value = attrs[index + 2];
|
|
6766
|
+
assertBuiltTarget(target);
|
|
6767
|
+
assertAttributeName(name);
|
|
6768
|
+
assertAttributeValue(value);
|
|
6769
|
+
items.push({ target, name, value });
|
|
6770
|
+
}
|
|
6771
|
+
return { kind: "built", items };
|
|
6772
|
+
}
|
|
6773
|
+
|
|
6774
|
+
function normalizeNamedAttributePatch(tuple) {
|
|
6775
|
+
if (!Array.isArray(tuple) || tuple.length !== 3) {
|
|
6776
|
+
throw new TypeError("No-build attribute patches must be [targetName, attrName, value] tuples.");
|
|
6777
|
+
}
|
|
6778
|
+
const [target, name, value] = tuple;
|
|
6779
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
6780
|
+
throw new TypeError("No-build attribute patch target names must be non-empty strings.");
|
|
6781
|
+
}
|
|
6782
|
+
assertAttributeName(name);
|
|
6783
|
+
assertAttributeValue(value);
|
|
6784
|
+
return { target, name, value };
|
|
6785
|
+
}
|
|
6786
|
+
|
|
6787
|
+
function normalizeReplacements(value) {
|
|
6788
|
+
const replacements = Array.isArray(value) ? value : [value];
|
|
6789
|
+
return replacements.map((replacement) => {
|
|
6790
|
+
if (!isPlainObject(replacement)) {
|
|
6791
|
+
throw new TypeError("Boundary patch replace records must be objects.");
|
|
6792
|
+
}
|
|
6793
|
+
if (typeof replacement.target !== "string" || replacement.target.length === 0) {
|
|
6794
|
+
throw new TypeError("Boundary patch replace target must be a non-empty string.");
|
|
6795
|
+
}
|
|
6796
|
+
if (replacement.mode !== undefined && replacement.mode !== "pending" && replacement.mode !== "boundary") {
|
|
6797
|
+
throw new TypeError("Boundary patch replace mode must be \"pending\" or \"boundary\".");
|
|
6798
|
+
}
|
|
6799
|
+
if (!Object.hasOwn(replacement, "html") || replacement.html == null) {
|
|
6800
|
+
throw new TypeError("Boundary patch replace records must include html.");
|
|
6801
|
+
}
|
|
6802
|
+
return {
|
|
6803
|
+
target: replacement.target,
|
|
6804
|
+
html: replacement.html,
|
|
6805
|
+
mode: replacement.mode ?? "pending"
|
|
6806
|
+
};
|
|
6807
|
+
});
|
|
6808
|
+
}
|
|
6809
|
+
|
|
6810
|
+
function normalizeRevealMetadata(reveal) {
|
|
6811
|
+
if (!isPlainObject(reveal)) {
|
|
6812
|
+
throw new TypeError("Boundary patch reveal metadata must be an object.");
|
|
6813
|
+
}
|
|
6814
|
+
const order = reveal.order ?? "as-ready";
|
|
6815
|
+
if (typeof reveal.group !== "string" || reveal.group.length === 0) {
|
|
6816
|
+
throw new TypeError("Reveal group must be a non-empty string.");
|
|
6817
|
+
}
|
|
6818
|
+
if (!Number.isInteger(reveal.count) || reveal.count < 1) {
|
|
6819
|
+
throw new TypeError("Reveal count must be a positive integer.");
|
|
6820
|
+
}
|
|
6821
|
+
if (!Number.isInteger(reveal.index) || reveal.index < 0 || reveal.index >= reveal.count) {
|
|
6822
|
+
throw new TypeError("Reveal index must be an integer from 0 to count - 1.");
|
|
6823
|
+
}
|
|
6824
|
+
if (!revealOrders.has(order)) {
|
|
6825
|
+
throw new TypeError("Reveal order must be as-ready, forwards, backwards, or together.");
|
|
6826
|
+
}
|
|
6827
|
+
if (reveal.tail !== undefined && !revealTails.has(reveal.tail)) {
|
|
6828
|
+
throw new TypeError("Reveal tail must be collapsed or hidden.");
|
|
6829
|
+
}
|
|
6830
|
+
return {
|
|
6831
|
+
group: reveal.group,
|
|
6832
|
+
index: reveal.index,
|
|
6833
|
+
count: reveal.count,
|
|
6834
|
+
order,
|
|
6835
|
+
tail: reveal.tail
|
|
6836
|
+
};
|
|
6363
6837
|
}
|
|
6364
6838
|
|
|
6365
6839
|
function assertBoundary(boundary) {
|
|
@@ -6368,6 +6842,41 @@ const __boundaryReceiverModule = (() => {
|
|
|
6368
6842
|
}
|
|
6369
6843
|
}
|
|
6370
6844
|
|
|
6845
|
+
function assertBuiltTarget(target) {
|
|
6846
|
+
if (!Number.isInteger(target) || target < 0) {
|
|
6847
|
+
throw new TypeError("Built attribute patch target indexes must be non-negative integers.");
|
|
6848
|
+
}
|
|
6849
|
+
}
|
|
6850
|
+
|
|
6851
|
+
function assertAttributeName(name) {
|
|
6852
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
6853
|
+
throw new TypeError("Attribute patch names must be non-empty strings.");
|
|
6854
|
+
}
|
|
6855
|
+
const normalized = name.toLowerCase();
|
|
6856
|
+
if (
|
|
6857
|
+
normalized.startsWith("on") ||
|
|
6858
|
+
structuralAttributeNames.has(normalized) ||
|
|
6859
|
+
/[\s<>"'=]/.test(name)
|
|
6860
|
+
) {
|
|
6861
|
+
throw new TypeError(`Attribute patch name "${name}" is not allowed.`);
|
|
6862
|
+
}
|
|
6863
|
+
}
|
|
6864
|
+
|
|
6865
|
+
function assertAttributeValue(value) {
|
|
6866
|
+
const type = typeof value;
|
|
6867
|
+
if (value != null && type !== "string" && type !== "number" && type !== "boolean") {
|
|
6868
|
+
throw new TypeError("Attribute patch values must be strings, numbers, booleans, null, or undefined.");
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6871
|
+
|
|
6872
|
+
function setPatchedAttribute(element, name, value) {
|
|
6873
|
+
if (value === false || value == null) {
|
|
6874
|
+
element.removeAttribute(name);
|
|
6875
|
+
return;
|
|
6876
|
+
}
|
|
6877
|
+
element.setAttribute(name, value === true ? "" : String(value));
|
|
6878
|
+
}
|
|
6879
|
+
|
|
6371
6880
|
async function flushScheduler(scheduler, scope) {
|
|
6372
6881
|
if (!scheduler) {
|
|
6373
6882
|
return;
|
|
@@ -6390,6 +6899,90 @@ const __boundaryReceiverModule = (() => {
|
|
|
6390
6899
|
location?.assign?.(redirect);
|
|
6391
6900
|
}
|
|
6392
6901
|
|
|
6902
|
+
function takeReadyRevealItems(group) {
|
|
6903
|
+
if (group.order === "as-ready") {
|
|
6904
|
+
return takePendingIndexes(group, [...group.pending.keys()].sort((left, right) => left - right));
|
|
6905
|
+
}
|
|
6906
|
+
if (group.order === "forwards") {
|
|
6907
|
+
const indexes = [];
|
|
6908
|
+
while (group.pending.has(group.nextForward)) {
|
|
6909
|
+
indexes.push(group.nextForward);
|
|
6910
|
+
group.nextForward += 1;
|
|
6911
|
+
}
|
|
6912
|
+
return takePendingIndexes(group, indexes);
|
|
6913
|
+
}
|
|
6914
|
+
if (group.order === "backwards") {
|
|
6915
|
+
const indexes = [];
|
|
6916
|
+
while (group.pending.has(group.nextBackward)) {
|
|
6917
|
+
indexes.push(group.nextBackward);
|
|
6918
|
+
group.nextBackward -= 1;
|
|
6919
|
+
}
|
|
6920
|
+
return takePendingIndexes(group, indexes);
|
|
6921
|
+
}
|
|
6922
|
+
if (group.committed.size + group.pending.size < group.count) {
|
|
6923
|
+
return [];
|
|
6924
|
+
}
|
|
6925
|
+
const indexes = [];
|
|
6926
|
+
for (let index = 0; index < group.count; index += 1) {
|
|
6927
|
+
if (group.pending.has(index)) {
|
|
6928
|
+
indexes.push(index);
|
|
6929
|
+
}
|
|
6930
|
+
}
|
|
6931
|
+
return takePendingIndexes(group, indexes);
|
|
6932
|
+
}
|
|
6933
|
+
|
|
6934
|
+
function takePendingIndexes(group, indexes) {
|
|
6935
|
+
const items = [];
|
|
6936
|
+
for (const index of indexes) {
|
|
6937
|
+
const item = group.pending.get(index);
|
|
6938
|
+
if (item) {
|
|
6939
|
+
group.pending.delete(index);
|
|
6940
|
+
items.push(item);
|
|
6941
|
+
}
|
|
6942
|
+
}
|
|
6943
|
+
return items;
|
|
6944
|
+
}
|
|
6945
|
+
|
|
6946
|
+
function pendingOrderFor(group, pending) {
|
|
6947
|
+
return group.order === "backwards"
|
|
6948
|
+
? pending.slice().sort((left, right) => right - left)
|
|
6949
|
+
: pending.slice().sort((left, right) => left - right);
|
|
6950
|
+
}
|
|
6951
|
+
|
|
6952
|
+
function inspectRevealGroups(groups) {
|
|
6953
|
+
const inspected = {};
|
|
6954
|
+
for (const [id, group] of groups) {
|
|
6955
|
+
inspected[id] = {
|
|
6956
|
+
count: group.count,
|
|
6957
|
+
order: group.order,
|
|
6958
|
+
tail: group.tail,
|
|
6959
|
+
pending: [...group.pending.keys()].sort((left, right) => left - right),
|
|
6960
|
+
committed: [...group.committed].sort((left, right) => left - right)
|
|
6961
|
+
};
|
|
6962
|
+
}
|
|
6963
|
+
return inspected;
|
|
6964
|
+
}
|
|
6965
|
+
|
|
6966
|
+
function revealResultMetadata(reveal) {
|
|
6967
|
+
return {
|
|
6968
|
+
group: reveal.group,
|
|
6969
|
+
index: reveal.index,
|
|
6970
|
+
count: reveal.count,
|
|
6971
|
+
order: reveal.order,
|
|
6972
|
+
tail: reveal.tail
|
|
6973
|
+
};
|
|
6974
|
+
}
|
|
6975
|
+
|
|
6976
|
+
function withPatchMetadata(result, attrs, replacementCount) {
|
|
6977
|
+
if (attrs) {
|
|
6978
|
+
result.attrs = attrs;
|
|
6979
|
+
}
|
|
6980
|
+
if (replacementCount > 0) {
|
|
6981
|
+
result.replace = { applied: replacementCount };
|
|
6982
|
+
}
|
|
6983
|
+
return result;
|
|
6984
|
+
}
|
|
6985
|
+
|
|
6393
6986
|
function toStableError(value) {
|
|
6394
6987
|
if (value instanceof Error) {
|
|
6395
6988
|
return value;
|
|
@@ -6415,13 +7008,118 @@ const __boundaryReceiverModule = (() => {
|
|
|
6415
7008
|
if (result.status === "redirected") {
|
|
6416
7009
|
entry.redirect = result.redirect;
|
|
6417
7010
|
}
|
|
7011
|
+
if (result.status === "buffered") {
|
|
7012
|
+
entry.reveal = result.reveal;
|
|
7013
|
+
}
|
|
7014
|
+
if (result.attrs) {
|
|
7015
|
+
entry.attrs = { ...result.attrs };
|
|
7016
|
+
}
|
|
7017
|
+
if (result.replace) {
|
|
7018
|
+
entry.replace = { ...result.replace };
|
|
7019
|
+
}
|
|
6418
7020
|
return entry;
|
|
6419
7021
|
}
|
|
6420
7022
|
|
|
7023
|
+
function findBoundaryElement(root, boundaryId, attributes, options = {}) {
|
|
7024
|
+
const boundary = elementsIn(root)
|
|
7025
|
+
.find((element) => boundaryIdFor(element, attributes) === String(boundaryId));
|
|
7026
|
+
if (!boundary && options.required !== false) {
|
|
7027
|
+
throw new Error(`Boundary "${boundaryId}" was not found.`);
|
|
7028
|
+
}
|
|
7029
|
+
return boundary ?? null;
|
|
7030
|
+
}
|
|
7031
|
+
|
|
7032
|
+
function boundaryIdFor(element, attributes) {
|
|
7033
|
+
if (element?.tagName === "ASYNC-SUSPENSE" && element.hasAttribute?.("for")) {
|
|
7034
|
+
return element.getAttribute("for");
|
|
7035
|
+
}
|
|
7036
|
+
return readAttribute(element, attributes, "async", "boundary");
|
|
7037
|
+
}
|
|
7038
|
+
|
|
7039
|
+
function directChildBoundaryElements(container, attributes) {
|
|
7040
|
+
return [...(container?.children ?? [])]
|
|
7041
|
+
.filter((element) => boundaryIdFor(element, attributes) != null);
|
|
7042
|
+
}
|
|
7043
|
+
|
|
7044
|
+
function findRevealContainer(root, group, attributes) {
|
|
7045
|
+
return elementsIn(root)
|
|
7046
|
+
.find((element) => readAttribute(element, attributes, "async", "reveal") === group)
|
|
7047
|
+
?? null;
|
|
7048
|
+
}
|
|
7049
|
+
|
|
7050
|
+
function isNestedBoundaryElement(element, boundaryElement, attributes) {
|
|
7051
|
+
if (element === boundaryElement) {
|
|
7052
|
+
return false;
|
|
7053
|
+
}
|
|
7054
|
+
if (boundaryIdFor(element, attributes) != null) {
|
|
7055
|
+
return true;
|
|
7056
|
+
}
|
|
7057
|
+
let parent = element.parentElement;
|
|
7058
|
+
while (parent && parent !== boundaryElement) {
|
|
7059
|
+
if (boundaryIdFor(parent, attributes) != null) {
|
|
7060
|
+
return true;
|
|
7061
|
+
}
|
|
7062
|
+
parent = parent.parentElement;
|
|
7063
|
+
}
|
|
7064
|
+
return false;
|
|
7065
|
+
}
|
|
7066
|
+
|
|
7067
|
+
function setTailHidden(element, hidden) {
|
|
7068
|
+
if (hidden) {
|
|
7069
|
+
element.setAttribute("hidden", "");
|
|
7070
|
+
if ("hidden" in element) {
|
|
7071
|
+
element.hidden = true;
|
|
7072
|
+
}
|
|
7073
|
+
return;
|
|
7074
|
+
}
|
|
7075
|
+
element.removeAttribute("hidden");
|
|
7076
|
+
if ("hidden" in element) {
|
|
7077
|
+
element.hidden = false;
|
|
7078
|
+
}
|
|
7079
|
+
}
|
|
7080
|
+
|
|
7081
|
+
function containsOrEquals(parent, child) {
|
|
7082
|
+
return parent === child || parent.contains?.(child);
|
|
7083
|
+
}
|
|
7084
|
+
|
|
7085
|
+
function ownerDocumentOf(element) {
|
|
7086
|
+
return element.ownerDocument ?? globalThis.document;
|
|
7087
|
+
}
|
|
7088
|
+
|
|
7089
|
+
function toFragment(value, documentRef) {
|
|
7090
|
+
if (value?.nodeType === 11) {
|
|
7091
|
+
return value.cloneNode(true);
|
|
7092
|
+
}
|
|
7093
|
+
if (value?.tagName === "TEMPLATE") {
|
|
7094
|
+
return value.content.cloneNode(true);
|
|
7095
|
+
}
|
|
7096
|
+
if (value?.nodeType) {
|
|
7097
|
+
const fragment = documentRef.createDocumentFragment();
|
|
7098
|
+
fragment.append(value.cloneNode(true));
|
|
7099
|
+
return fragment;
|
|
7100
|
+
}
|
|
7101
|
+
const template = documentRef.createElement("template");
|
|
7102
|
+
template.innerHTML = typeof value === "string" ? value : renderTemplate(value);
|
|
7103
|
+
return template.content.cloneNode(true);
|
|
7104
|
+
}
|
|
7105
|
+
|
|
7106
|
+
function elementsIn(scope) {
|
|
7107
|
+
const elements = [];
|
|
7108
|
+
if (scope?.nodeType === 1) {
|
|
7109
|
+
elements.push(scope);
|
|
7110
|
+
}
|
|
7111
|
+
elements.push(...(scope?.querySelectorAll?.("*") ?? []));
|
|
7112
|
+
return elements;
|
|
7113
|
+
}
|
|
7114
|
+
|
|
7115
|
+
function isElementLike(value) {
|
|
7116
|
+
return Boolean(value?.nodeType === 1 && typeof value.textContent === "string");
|
|
7117
|
+
}
|
|
7118
|
+
|
|
6421
7119
|
function isPlainObject(value) {
|
|
6422
7120
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
6423
7121
|
}
|
|
6424
|
-
return { createBoundaryReceiver };
|
|
7122
|
+
return { createBoundaryReceiver, AsyncStream };
|
|
6425
7123
|
})();
|
|
6426
7124
|
|
|
6427
7125
|
const __delayModule = (() => {
|
|
@@ -6531,6 +7229,7 @@ const { defineApp: defineApp } = __appModule;
|
|
|
6531
7229
|
const { readSnapshot: readSnapshot } = __appModule;
|
|
6532
7230
|
const { attributeName: attributeName } = __attributesModule;
|
|
6533
7231
|
const { defineAttributeConfig: defineAttributeConfig } = __attributesModule;
|
|
7232
|
+
const { AsyncStream: AsyncStream } = __boundaryReceiverModule;
|
|
6534
7233
|
const { createBoundaryReceiver: createBoundaryReceiver } = __boundaryReceiverModule;
|
|
6535
7234
|
const { createCacheRegistry: createCacheRegistry } = __cacheModule;
|
|
6536
7235
|
const { defineCache: defineCache } = __cacheModule;
|
|
@@ -6563,4 +7262,4 @@ const { createSignalRegistry: createSignalRegistry } = __signalsModule;
|
|
|
6563
7262
|
const { effect: effect } = __signalsModule;
|
|
6564
7263
|
const { signal: signal } = __signalsModule;
|
|
6565
7264
|
|
|
6566
|
-
export { asyncSignal, Async, createApp, defineApp, readSnapshot, attributeName, defineAttributeConfig, createBoundaryReceiver, createCacheRegistry, defineCache, component, createComponentRegistry, defineComponent, delay, defineAsyncContainerElement, defineAsyncSuspenseElement, createHandlerRegistry, html, createLazyRegistry, defineRegistrySnapshot, Loader, AsyncLoader, createPartialRegistry, createRegistryStore, createRouteRegistry, createRouter, defineRoute, route, createScheduler, applyServerResult, createServerProxy, resolveServerCommandArguments, unwrapServerResult, computed, createSignal, createSignalRegistry, effect, signal };
|
|
7265
|
+
export { asyncSignal, Async, createApp, defineApp, readSnapshot, attributeName, defineAttributeConfig, AsyncStream, createBoundaryReceiver, createCacheRegistry, defineCache, component, createComponentRegistry, defineComponent, delay, defineAsyncContainerElement, defineAsyncSuspenseElement, createHandlerRegistry, html, createLazyRegistry, defineRegistrySnapshot, Loader, AsyncLoader, createPartialRegistry, createRegistryStore, createRouteRegistry, createRouter, defineRoute, route, createScheduler, applyServerResult, createServerProxy, resolveServerCommandArguments, unwrapServerResult, computed, createSignal, createSignalRegistry, effect, signal };
|