@solidjs/web 2.0.0-beta.31 → 2.0.0-beta.32
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 +1 -6
- package/dist/dev.cjs +234 -45
- package/dist/dev.js +221 -42
- package/dist/server.cjs +456 -123
- package/dist/server.js +445 -120
- package/dist/web.cjs +234 -45
- package/dist/web.js +221 -42
- package/frames/dist/client.cjs +217 -112
- package/frames/dist/client.dev.cjs +217 -112
- package/frames/dist/client.dev.js +218 -113
- package/frames/dist/client.js +218 -113
- package/frames/dist/server.cjs +488 -177
- package/frames/dist/server.js +489 -179
- package/package.json +55 -4
- package/serialization/dist/serialization.cjs +8 -0
- package/serialization/dist/serialization.js +1 -0
- package/serialization/types/index.d.ts +173 -6
- package/serialization/types-cjs/index.d.cts +173 -6
- package/server-functions/dist/client.cjs +46 -9
- package/server-functions/dist/client.js +47 -11
- package/server-functions/dist/rich-args.cjs +11 -0
- package/server-functions/dist/rich-args.js +9 -0
- package/server-functions/dist/server.cjs +275 -126
- package/server-functions/dist/server.dev.cjs +1053 -0
- package/server-functions/dist/server.dev.js +1021 -0
- package/server-functions/dist/server.js +273 -127
- package/server-functions/package.json +10 -0
- package/server-functions/rich-args/package.json +20 -0
- package/storage/types/index.d.ts +1 -1
- package/storage/types-cjs/index.d.cts +1 -1
- package/types/client.d.ts +127 -6
- package/types/core.d.ts +3 -1
- package/types/frames/client.d.ts +15 -1
- package/types/frames/frame-client.d.ts +37 -7
- package/types/frames/frame-sink.d.ts +26 -3
- package/types/frames/frame-transport.d.ts +39 -7
- package/types/frames/serializer.d.ts +173 -6
- package/types/frames/server.d.ts +22 -0
- package/types/index.d.ts +2 -3
- package/types/response.d.ts +45 -0
- package/types/serializer.d.ts +173 -6
- package/types/server-functions/client.d.ts +1 -0
- package/types/server-functions/rich-args.d.ts +10 -0
- package/types/server-functions/server.d.ts +98 -0
- package/types/server-functions/shared.d.ts +22 -0
- package/types/server-mock.d.ts +171 -59
- package/types/server.d.ts +188 -36
- package/types-cjs/client.d.cts +127 -6
- package/types-cjs/core.d.cts +3 -1
- package/types-cjs/frames/client.d.cts +15 -1
- package/types-cjs/frames/frame-client.d.cts +37 -7
- package/types-cjs/frames/frame-sink.d.cts +26 -3
- package/types-cjs/frames/frame-transport.d.cts +39 -7
- package/types-cjs/frames/serializer.d.cts +173 -6
- package/types-cjs/frames/server.d.cts +22 -0
- package/types-cjs/index.d.cts +2 -3
- package/types-cjs/response.d.cts +45 -0
- package/types-cjs/serializer.d.cts +173 -6
- package/types-cjs/server-functions/client.d.cts +1 -0
- package/types-cjs/server-functions/rich-args.d.cts +10 -0
- package/types-cjs/server-functions/server.d.cts +98 -0
- package/types-cjs/server-functions/shared.d.cts +22 -0
- package/types-cjs/server-mock.d.cts +171 -59
- package/types-cjs/server.d.cts +188 -36
|
@@ -96,9 +96,7 @@ function createFrameHost(options = {}) {
|
|
|
96
96
|
if (store.version !== undefined && version < store.version) return false;
|
|
97
97
|
if (store.version === undefined || version > store.version) {
|
|
98
98
|
store.version = version;
|
|
99
|
-
|
|
100
|
-
if (key.startsWith("seg:") || key === ":error") delete store.records[key];
|
|
101
|
-
}
|
|
99
|
+
clearStreamRecords(store.records);
|
|
102
100
|
}
|
|
103
101
|
Object.assign(store.records, records);
|
|
104
102
|
return true;
|
|
@@ -176,6 +174,7 @@ class FrameImpl {
|
|
|
176
174
|
#store = Object.create(null);
|
|
177
175
|
#appliedRootValue;
|
|
178
176
|
#hasContent = false;
|
|
177
|
+
#errorNotified = false;
|
|
179
178
|
#revealed = new Set();
|
|
180
179
|
#fallbackShown = new Set();
|
|
181
180
|
#slots;
|
|
@@ -195,10 +194,12 @@ class FrameImpl {
|
|
|
195
194
|
#claimTree = (node, direct) => {
|
|
196
195
|
const handlers = claimHandlers();
|
|
197
196
|
if (!handlers) return;
|
|
198
|
-
|
|
199
|
-
const scope = this.#options.ownerScope;
|
|
200
|
-
scope ? scope(run) : run();
|
|
197
|
+
this.#scoped(() => direct ? claimNode(handlers, node) : claimTree(handlers, node));
|
|
201
198
|
};
|
|
199
|
+
#scoped(fn) {
|
|
200
|
+
const scope = this.#options.ownerScope;
|
|
201
|
+
return scope ? scope(fn) : fn();
|
|
202
|
+
}
|
|
202
203
|
constructor(element, start, end, options = {}) {
|
|
203
204
|
this.#element = element;
|
|
204
205
|
this.#start = start;
|
|
@@ -259,15 +260,9 @@ class FrameImpl {
|
|
|
259
260
|
return;
|
|
260
261
|
} else if (v > this.#version) {
|
|
261
262
|
this.#version = v;
|
|
262
|
-
this.#
|
|
263
|
-
this.#fallbackShown.clear();
|
|
264
|
-
for (const key of Object.keys(this.#store)) {
|
|
265
|
-
if (key.startsWith("seg:") || key === ":error") {
|
|
266
|
-
delete this.#store[key];
|
|
267
|
-
}
|
|
268
|
-
}
|
|
263
|
+
this.#resetStreamState();
|
|
269
264
|
}
|
|
270
|
-
for (const key
|
|
265
|
+
for (const key in write.r) {
|
|
271
266
|
const incoming = write.r[key];
|
|
272
267
|
if (incoming && incoming.kind === "slot" && key.charCodeAt(0) === 115 && key.startsWith("slot:")) {
|
|
273
268
|
const existing = this.#store[key];
|
|
@@ -279,6 +274,12 @@ class FrameImpl {
|
|
|
279
274
|
}
|
|
280
275
|
this.#flush();
|
|
281
276
|
}
|
|
277
|
+
#resetStreamState(root) {
|
|
278
|
+
this.#revealed.clear();
|
|
279
|
+
this.#fallbackShown.clear();
|
|
280
|
+
this.#errorNotified = false;
|
|
281
|
+
clearStreamRecords(this.#store, root);
|
|
282
|
+
}
|
|
282
283
|
#flush() {
|
|
283
284
|
if (this.#disposed) return;
|
|
284
285
|
const version = this.#version;
|
|
@@ -289,10 +290,14 @@ class FrameImpl {
|
|
|
289
290
|
this.#appliedRootValue = root.value;
|
|
290
291
|
this.#applied(version, reason);
|
|
291
292
|
}
|
|
293
|
+
if (this.#store[":error"] && !this.#errorNotified) {
|
|
294
|
+
this.#errorNotified = true;
|
|
295
|
+
this.#applied(version, "error");
|
|
296
|
+
}
|
|
292
297
|
let progressed = true;
|
|
293
298
|
while (progressed) {
|
|
294
299
|
progressed = false;
|
|
295
|
-
for (const key
|
|
300
|
+
for (const key in this.#store) {
|
|
296
301
|
const name = segmentName(key);
|
|
297
302
|
if (name === null || this.#revealed.has(name)) continue;
|
|
298
303
|
if (this.#segmentReady(name)) {
|
|
@@ -301,7 +306,7 @@ class FrameImpl {
|
|
|
301
306
|
progressed = true;
|
|
302
307
|
}
|
|
303
308
|
}
|
|
304
|
-
for (const key
|
|
309
|
+
for (const key in this.#store) {
|
|
305
310
|
const m = /^seg:([^:]+):fallback$/.exec(key);
|
|
306
311
|
if (!m) continue;
|
|
307
312
|
const name = m[1];
|
|
@@ -313,7 +318,7 @@ class FrameImpl {
|
|
|
313
318
|
}
|
|
314
319
|
}
|
|
315
320
|
}
|
|
316
|
-
for (const key
|
|
321
|
+
for (const key in this.#store) {
|
|
317
322
|
if (this.#processedAssets.has(key) || !key.endsWith(":assets")) continue;
|
|
318
323
|
this.#processedAssets.add(key);
|
|
319
324
|
const record = this.#store[key];
|
|
@@ -345,6 +350,7 @@ class FrameImpl {
|
|
|
345
350
|
const callback = this.#resolveSlot(propOf(occurrence));
|
|
346
351
|
if (!callback) continue;
|
|
347
352
|
const record = this.#resolveSlotRecord(occurrence);
|
|
353
|
+
if (record && record.kind === "slot" && this.#refsUnresolved(record.args)) continue;
|
|
348
354
|
const prev = this.#slotNodes.get(occurrence);
|
|
349
355
|
const prevFirst = Array.isArray(prev) ? prev[0] : prev;
|
|
350
356
|
const zombie = this.#mountedSlots.has(occurrence) && prevFirst && !prevFirst.parentNode;
|
|
@@ -400,15 +406,7 @@ class FrameImpl {
|
|
|
400
406
|
const cleanups = this.#slotCleanups.get(occurrence) ?? [];
|
|
401
407
|
let existing = [];
|
|
402
408
|
let end = null;
|
|
403
|
-
if (start)
|
|
404
|
-
const endData = slotEnd(occurrence);
|
|
405
|
-
let n = start.nextSibling;
|
|
406
|
-
while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
|
|
407
|
-
existing.push(n);
|
|
408
|
-
n = n.nextSibling;
|
|
409
|
-
}
|
|
410
|
-
end = n;
|
|
411
|
-
}
|
|
409
|
+
if (start) end = eachInRange(start, occurrence, n => existing.push(n));
|
|
412
410
|
const ctx = {
|
|
413
411
|
frame: this.#options.claimScope ?? this.#options.id,
|
|
414
412
|
key: occurrence,
|
|
@@ -423,23 +421,16 @@ class FrameImpl {
|
|
|
423
421
|
} : undefined
|
|
424
422
|
};
|
|
425
423
|
const props = record && record.kind === "slot" ? this.#resolveArgs(occurrence, record.args) : {};
|
|
426
|
-
const
|
|
427
|
-
const content = scope ? scope(() => callback(props, ctx)) : callback(props, ctx);
|
|
424
|
+
const content = this.#scoped(() => callback(props, ctx));
|
|
428
425
|
this.#slotArgs.set(occurrence, record);
|
|
429
426
|
if (cleanups.length) this.#slotCleanups.set(occurrence, cleanups);
|
|
430
427
|
if (content == null) return null;
|
|
431
428
|
return Array.isArray(content) ? content : [content];
|
|
432
429
|
}
|
|
433
430
|
#replaceRange(key, start, nodes) {
|
|
434
|
-
const end = slotEnd(key);
|
|
435
431
|
const parent = start.parentNode;
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const next = n.nextSibling;
|
|
439
|
-
parent.removeChild(n);
|
|
440
|
-
n = next;
|
|
441
|
-
}
|
|
442
|
-
for (const node of nodes) parent.insertBefore(node, n);
|
|
432
|
+
const end = eachInRange(start, key, n => parent.removeChild(n));
|
|
433
|
+
for (const node of nodes) parent.insertBefore(node, end);
|
|
443
434
|
}
|
|
444
435
|
#unmountSlot(key) {
|
|
445
436
|
this.#mountedSlots.delete(key);
|
|
@@ -451,9 +442,7 @@ class FrameImpl {
|
|
|
451
442
|
this.#runSlotCleanups(key);
|
|
452
443
|
const regions = this.#slotRegions.get(key);
|
|
453
444
|
if (regions) {
|
|
454
|
-
|
|
455
|
-
frame
|
|
456
|
-
} of regions.values()) frame?.dispose();
|
|
445
|
+
disposeRegions(regions);
|
|
457
446
|
this.#slotRegions.delete(key);
|
|
458
447
|
}
|
|
459
448
|
}
|
|
@@ -463,15 +452,26 @@ class FrameImpl {
|
|
|
463
452
|
this.#slotCleanups.delete(key);
|
|
464
453
|
for (const fn of cleanups) fn();
|
|
465
454
|
}
|
|
455
|
+
#refsUnresolved(args) {
|
|
456
|
+
const {
|
|
457
|
+
host,
|
|
458
|
+
id
|
|
459
|
+
} = this.#options;
|
|
460
|
+
if (host) for (const key in args) {
|
|
461
|
+
if (isDataRef(args[key]) && host.resolve(args[key], id) === undefined) return true;
|
|
462
|
+
}
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
#regionsFor(slotKey) {
|
|
466
|
+
let regions = this.#slotRegions.get(slotKey);
|
|
467
|
+
if (!regions) this.#slotRegions.set(slotKey, regions = new Map());
|
|
468
|
+
return regions;
|
|
469
|
+
}
|
|
466
470
|
#resolveArgs(slotKey, args) {
|
|
467
471
|
const host = this.#options.host;
|
|
468
|
-
|
|
469
|
-
if (!regions) {
|
|
470
|
-
regions = new Map();
|
|
471
|
-
this.#slotRegions.set(slotKey, regions);
|
|
472
|
-
}
|
|
472
|
+
const regions = this.#regionsFor(slotKey);
|
|
473
473
|
const props = {};
|
|
474
|
-
for (const key
|
|
474
|
+
for (const key in args) {
|
|
475
475
|
const value = args[key];
|
|
476
476
|
if (isDataRef(value)) {
|
|
477
477
|
const resolved = host ? host.resolve(value, this.#options.id) : undefined;
|
|
@@ -501,17 +501,8 @@ class FrameImpl {
|
|
|
501
501
|
}
|
|
502
502
|
#discoverRegions(slotKey, start) {
|
|
503
503
|
if (!start) return;
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
regions = new Map();
|
|
507
|
-
this.#slotRegions.set(slotKey, regions);
|
|
508
|
-
}
|
|
509
|
-
const endData = slotEnd(slotKey);
|
|
510
|
-
let n = start.nextSibling;
|
|
511
|
-
while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
|
|
512
|
-
collectRegionElements(n, regions);
|
|
513
|
-
n = n.nextSibling;
|
|
514
|
-
}
|
|
504
|
+
const regions = this.#regionsFor(slotKey);
|
|
505
|
+
eachInRange(start, slotKey, n => collectRegionElements(n, regions));
|
|
515
506
|
}
|
|
516
507
|
#refArgsUnchanged(occurrence, record) {
|
|
517
508
|
const old = this.#slotArgs.get(occurrence);
|
|
@@ -527,11 +518,11 @@ class FrameImpl {
|
|
|
527
518
|
const va = a[key];
|
|
528
519
|
const vb = b[key];
|
|
529
520
|
if (va === vb) continue;
|
|
530
|
-
if (
|
|
531
|
-
if (
|
|
532
|
-
if (typeof va.$ref === "string" && typeof vb.$ref === "string" && cache && key in cache) {
|
|
521
|
+
if (isFrameRef(va) && isFrameRef(vb)) continue;
|
|
522
|
+
if (isDataRef(va) && isDataRef(vb) && cache && key in cache) {
|
|
533
523
|
const host = this.#options.host;
|
|
534
524
|
const next = host ? host.resolve(vb, this.#options.id) : undefined;
|
|
525
|
+
if (isAsyncLike(next) || isAsyncLike(cache[key])) return false;
|
|
535
526
|
try {
|
|
536
527
|
if (JSON.stringify(next) === JSON.stringify(cache[key])) continue;
|
|
537
528
|
} catch (e) {
|
|
@@ -547,7 +538,7 @@ class FrameImpl {
|
|
|
547
538
|
if (!args) return;
|
|
548
539
|
const regions = this.#slotRegions.get(occurrence);
|
|
549
540
|
if (!regions) return;
|
|
550
|
-
for (const key
|
|
541
|
+
for (const key in args) {
|
|
551
542
|
const value = args[key];
|
|
552
543
|
if (!isFrameRef(value)) continue;
|
|
553
544
|
const entry = regions.get(key);
|
|
@@ -597,11 +588,8 @@ class FrameImpl {
|
|
|
597
588
|
this.#element.setAttribute(FRAME_ID_ATTR, id);
|
|
598
589
|
}
|
|
599
590
|
this.#version = undefined;
|
|
600
|
-
this.#
|
|
601
|
-
this.#
|
|
602
|
-
for (const key of Object.keys(this.#store)) {
|
|
603
|
-
if (key.startsWith("seg:") || key === ":error") delete this.#store[key];
|
|
604
|
-
}
|
|
591
|
+
this.#appliedRootValue = undefined;
|
|
592
|
+
this.#resetStreamState(true);
|
|
605
593
|
if (host) host.register(id, this);
|
|
606
594
|
}
|
|
607
595
|
rebase() {
|
|
@@ -621,11 +609,7 @@ class FrameImpl {
|
|
|
621
609
|
}
|
|
622
610
|
for (const key of [...this.#slotCleanups.keys()]) this.#runSlotCleanups(key);
|
|
623
611
|
for (const key of this.#mountedSlots) this.#removeSlotRecord(key);
|
|
624
|
-
for (const regions of this.#slotRegions.values())
|
|
625
|
-
for (const {
|
|
626
|
-
frame
|
|
627
|
-
} of regions.values()) frame?.dispose();
|
|
628
|
-
}
|
|
612
|
+
for (const regions of this.#slotRegions.values()) disposeRegions(regions);
|
|
629
613
|
this.#slotRegions.clear();
|
|
630
614
|
this.#mountedSlots.clear();
|
|
631
615
|
}
|
|
@@ -647,13 +631,7 @@ class FrameImpl {
|
|
|
647
631
|
}
|
|
648
632
|
}
|
|
649
633
|
#clearContent() {
|
|
650
|
-
|
|
651
|
-
let n = this.#firstContent();
|
|
652
|
-
while (n && n !== this.#end) {
|
|
653
|
-
const next = n.nextSibling;
|
|
654
|
-
parent.removeChild(n);
|
|
655
|
-
n = next;
|
|
656
|
-
}
|
|
634
|
+
removeUntil(this.#parent(), this.#firstContent(), this.#end);
|
|
657
635
|
}
|
|
658
636
|
#claimContent() {
|
|
659
637
|
if (!claimHandlers()) return;
|
|
@@ -670,9 +648,7 @@ class FrameImpl {
|
|
|
670
648
|
const assets = this.#store[`seg:${name}:assets`];
|
|
671
649
|
if (assets && assets.styles) {
|
|
672
650
|
let ready = true;
|
|
673
|
-
for (const entry of assets.styles)
|
|
674
|
-
if (!ensureStylesheet(entry, this.#styleFlush)) ready = false;
|
|
675
|
-
}
|
|
651
|
+
for (const entry of assets.styles) ready = ensureStylesheet(entry, this.#styleFlush) && ready;
|
|
676
652
|
if (!ready) return false;
|
|
677
653
|
}
|
|
678
654
|
if (!this.#findPlaceholder(name)) return false;
|
|
@@ -689,12 +665,7 @@ class FrameImpl {
|
|
|
689
665
|
console.error(`Frame fragment placeholder "${name}" is missing its closing comment ` + `(<!--${placeholderId(name)}-->); revealed content will be appended at the end of ` + `its parent instead of in place. Likely an HTML-rewriting layer stripped the ` + `comment, or invalid nesting split the placeholder range.`, tpl);
|
|
690
666
|
}
|
|
691
667
|
const parent = tpl.parentNode;
|
|
692
|
-
|
|
693
|
-
while (n && n !== closing) {
|
|
694
|
-
const next = n.nextSibling;
|
|
695
|
-
parent.removeChild(n);
|
|
696
|
-
n = next;
|
|
697
|
-
}
|
|
668
|
+
removeUntil(parent, tpl.nextSibling, closing);
|
|
698
669
|
if (this.#options.reveal) {
|
|
699
670
|
const fallbackFrag = tpl.content.cloneNode(true);
|
|
700
671
|
this.#claimTree(fallbackFrag);
|
|
@@ -743,9 +714,7 @@ function createFrameElement(options) {
|
|
|
743
714
|
const frame = new FrameImpl(el, null, null, options);
|
|
744
715
|
return {
|
|
745
716
|
element: el,
|
|
746
|
-
|
|
747
|
-
return frame;
|
|
748
|
-
},
|
|
717
|
+
frame,
|
|
749
718
|
dispose() {
|
|
750
719
|
frame.dispose();
|
|
751
720
|
el.remove();
|
|
@@ -765,15 +734,30 @@ function segmentName(key) {
|
|
|
765
734
|
const m = /^seg:([^:]+)$/.exec(key);
|
|
766
735
|
return m ? m[1] : null;
|
|
767
736
|
}
|
|
737
|
+
function isAsyncLike(v) {
|
|
738
|
+
return !!v && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
739
|
+
}
|
|
768
740
|
function propOf(occurrence) {
|
|
769
741
|
const hash = occurrence.indexOf("#");
|
|
770
742
|
return hash === -1 ? occurrence : occurrence.slice(0, hash);
|
|
771
743
|
}
|
|
772
744
|
function isDataRef(value) {
|
|
773
|
-
return
|
|
745
|
+
return !!value && typeof value.$ref === "string";
|
|
774
746
|
}
|
|
775
747
|
function isFrameRef(value) {
|
|
776
|
-
return
|
|
748
|
+
return !!value && typeof value.$frame === "string";
|
|
749
|
+
}
|
|
750
|
+
function disposeRegions(regions) {
|
|
751
|
+
for (const {
|
|
752
|
+
frame
|
|
753
|
+
} of regions.values()) frame?.dispose();
|
|
754
|
+
}
|
|
755
|
+
function removeUntil(parent, n, stop) {
|
|
756
|
+
while (n && n !== stop) {
|
|
757
|
+
const next = n.nextSibling;
|
|
758
|
+
parent.removeChild(n);
|
|
759
|
+
n = next;
|
|
760
|
+
}
|
|
777
761
|
}
|
|
778
762
|
function parseFragment(html) {
|
|
779
763
|
const template = document.createElement("template");
|
|
@@ -781,9 +765,8 @@ function parseFragment(html) {
|
|
|
781
765
|
return template.content;
|
|
782
766
|
}
|
|
783
767
|
function findHeadElement(selector, attr, value) {
|
|
784
|
-
const
|
|
785
|
-
|
|
786
|
-
if (nodes[i].getAttribute(attr) === value) return nodes[i];
|
|
768
|
+
for (const node of document.head.querySelectorAll(selector)) {
|
|
769
|
+
if (node.getAttribute(attr) === value) return node;
|
|
787
770
|
}
|
|
788
771
|
return null;
|
|
789
772
|
}
|
|
@@ -832,7 +815,7 @@ function applyInlineStyles(inlineStyles) {
|
|
|
832
815
|
}
|
|
833
816
|
}
|
|
834
817
|
function isPlaceholderStart(node, id) {
|
|
835
|
-
return node.
|
|
818
|
+
return node.tagName === "TEMPLATE" && node.id === id;
|
|
836
819
|
}
|
|
837
820
|
function rangeClose(start, id) {
|
|
838
821
|
let n = start.nextSibling;
|
|
@@ -889,6 +872,21 @@ function renameRegion(entry, childId) {
|
|
|
889
872
|
entry.childId = childId;
|
|
890
873
|
if (entry.frame) entry.frame.rebind(childId);else entry.element.setAttribute(FRAME_ID_ATTR, childId);
|
|
891
874
|
}
|
|
875
|
+
function eachInRange(start, key, cb) {
|
|
876
|
+
const end = slotEnd(key);
|
|
877
|
+
let n = start.nextSibling;
|
|
878
|
+
while (n && !(n.nodeType === COMMENT_NODE && n.data === end)) {
|
|
879
|
+
const next = n.nextSibling;
|
|
880
|
+
cb(n);
|
|
881
|
+
n = next;
|
|
882
|
+
}
|
|
883
|
+
return n;
|
|
884
|
+
}
|
|
885
|
+
function clearStreamRecords(records, root) {
|
|
886
|
+
for (const key in records) {
|
|
887
|
+
if (key.startsWith("seg:") || key === ":error" || root && key === "") delete records[key];
|
|
888
|
+
}
|
|
889
|
+
}
|
|
892
890
|
function argsEquivalent(a, b) {
|
|
893
891
|
if (a === b) return true;
|
|
894
892
|
if (!a || !b) return false;
|
|
@@ -899,9 +897,7 @@ function argsEquivalent(a, b) {
|
|
|
899
897
|
const va = a[key];
|
|
900
898
|
const vb = b[key];
|
|
901
899
|
if (va === vb) continue;
|
|
902
|
-
if (va &&
|
|
903
|
-
continue;
|
|
904
|
-
}
|
|
900
|
+
if (isFrameRef(va) && va.$frame === vb?.$frame) continue;
|
|
905
901
|
return false;
|
|
906
902
|
}
|
|
907
903
|
return true;
|
|
@@ -1273,7 +1269,7 @@ function createServerComponentHandler({
|
|
|
1273
1269
|
showing(address, functionId) {
|
|
1274
1270
|
bindingFor(address, functionId);
|
|
1275
1271
|
const comp = componentFor(functionId);
|
|
1276
|
-
if ((typeof comp === "function" || typeof comp === "object"
|
|
1272
|
+
if (comp && (typeof comp === "function" || typeof comp === "object") && !comp[COMPONENT_BINDING]) {
|
|
1277
1273
|
comp[COMPONENT_BINDING] = {
|
|
1278
1274
|
component: comp,
|
|
1279
1275
|
address
|
|
@@ -1365,6 +1361,9 @@ function createJSONDataTable(options) {
|
|
|
1365
1361
|
};
|
|
1366
1362
|
}
|
|
1367
1363
|
|
|
1364
|
+
function asyncArg(value) {
|
|
1365
|
+
return value;
|
|
1366
|
+
}
|
|
1368
1367
|
let sharedHost;
|
|
1369
1368
|
const tables = new Map();
|
|
1370
1369
|
function tableFor(id) {
|
|
@@ -1441,8 +1440,26 @@ function claimRender(prefix, existing, render) {
|
|
|
1441
1440
|
function liveSlotProps(initial, ctx) {
|
|
1442
1441
|
const [args, setArgs] = solidJs.createSignal(initial);
|
|
1443
1442
|
ctx.onUpdate(next => setArgs(() => next));
|
|
1443
|
+
return slotArgsProxy(args);
|
|
1444
|
+
}
|
|
1445
|
+
function isAsyncValue(v) {
|
|
1446
|
+
return v !== null && typeof v === "object" && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
1447
|
+
}
|
|
1448
|
+
function slotArgsProxy(args) {
|
|
1449
|
+
const owner = solidJs.getOwner();
|
|
1450
|
+
const asyncReads = new Map();
|
|
1444
1451
|
return new Proxy({}, {
|
|
1445
|
-
get: (_, key) =>
|
|
1452
|
+
get: (_, key) => {
|
|
1453
|
+
const v = args()[key];
|
|
1454
|
+
if (!isAsyncValue(v)) return v;
|
|
1455
|
+
let read = asyncReads.get(key);
|
|
1456
|
+
if (!read) {
|
|
1457
|
+
const make = () => solidJs.createMemo(() => args()[key]);
|
|
1458
|
+
read = owner ? solidJs.runWithOwner(owner, make) : make();
|
|
1459
|
+
asyncReads.set(key, read);
|
|
1460
|
+
}
|
|
1461
|
+
return read();
|
|
1462
|
+
},
|
|
1446
1463
|
has: (_, key) => key in args(),
|
|
1447
1464
|
ownKeys: () => Reflect.ownKeys(args()),
|
|
1448
1465
|
getOwnPropertyDescriptor: (_, key) => key in args() ? {
|
|
@@ -1460,6 +1477,7 @@ function isReactiveContent(value) {
|
|
|
1460
1477
|
}
|
|
1461
1478
|
function slotsFor(props) {
|
|
1462
1479
|
const bindings = new Map();
|
|
1480
|
+
const fillScopes = new Map();
|
|
1463
1481
|
return new Proxy({}, {
|
|
1464
1482
|
get(_, prop) {
|
|
1465
1483
|
if (typeof prop !== "string" || !(prop in props)) return undefined;
|
|
@@ -1470,6 +1488,19 @@ function slotsFor(props) {
|
|
|
1470
1488
|
bindings.delete(key);
|
|
1471
1489
|
prev.dispose();
|
|
1472
1490
|
}
|
|
1491
|
+
const prevFill = key !== undefined && fillScopes.get(key);
|
|
1492
|
+
if (prevFill) {
|
|
1493
|
+
fillScopes.delete(key);
|
|
1494
|
+
prevFill.dispose();
|
|
1495
|
+
}
|
|
1496
|
+
const fillOwner = streamInvoke ? solidJs.createOwner() : null;
|
|
1497
|
+
if (fillOwner && key !== undefined && ctx) {
|
|
1498
|
+
fillScopes.set(key, fillOwner);
|
|
1499
|
+
ctx.onCleanup(() => {
|
|
1500
|
+
if (fillScopes.get(key) === fillOwner) fillScopes.delete(key);
|
|
1501
|
+
fillOwner.dispose();
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1473
1504
|
const settle = out => {
|
|
1474
1505
|
const existing = ctx && ctx.existing || [];
|
|
1475
1506
|
if (existing.length) {
|
|
@@ -1482,13 +1513,13 @@ function slotsFor(props) {
|
|
|
1482
1513
|
const evaluate = () => {
|
|
1483
1514
|
const v = props[prop];
|
|
1484
1515
|
if (typeof v === "function" && ctx && ctx.invoked) {
|
|
1485
|
-
return v(ctx.onUpdate ? liveSlotProps(slotProps, ctx) : slotProps);
|
|
1516
|
+
return v(ctx.onUpdate ? liveSlotProps(slotProps, ctx) : slotArgsProxy(() => slotProps));
|
|
1486
1517
|
}
|
|
1487
1518
|
return v;
|
|
1488
1519
|
};
|
|
1489
1520
|
const adopted = !!(ctx && ctx.frame && ctx.adopted && ctx.existing && ctx.existing.length);
|
|
1490
1521
|
const prefix = ctx && ctx.frame ? `sc-${ctx.frame}-${ctx.key}-` : "";
|
|
1491
|
-
const value = adopted ? claimRender(prefix, ctx.existing, evaluate) : evaluate();
|
|
1522
|
+
const value = fillOwner ? solidJs.runWithOwner(fillOwner, () => adopted ? claimRender(prefix, ctx.existing, evaluate) : evaluate()) : adopted ? claimRender(prefix, ctx.existing, evaluate) : evaluate();
|
|
1492
1523
|
if (!isReactiveContent(value)) {
|
|
1493
1524
|
return settle(normalizeSlotContent(value));
|
|
1494
1525
|
}
|
|
@@ -1513,29 +1544,61 @@ function slotsFor(props) {
|
|
|
1513
1544
|
function revealSeam(owner) {
|
|
1514
1545
|
return seam => solidJs.runWithOwner(owner, () => web$1.insert(seam.before.parentNode, solidJs.createLoadingBoundary(() => seam.content(), () => seam.fallback), seam.before));
|
|
1515
1546
|
}
|
|
1547
|
+
let streamInvoke = false;
|
|
1516
1548
|
function boundaryScope(owner) {
|
|
1517
|
-
return fn =>
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1549
|
+
return fn => {
|
|
1550
|
+
if (solidJs.getOwner()) return fn();
|
|
1551
|
+
streamInvoke = true;
|
|
1552
|
+
try {
|
|
1553
|
+
return solidJs.runWithOwner(owner, fn);
|
|
1554
|
+
} finally {
|
|
1555
|
+
streamInvoke = false;
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1521
1558
|
}
|
|
1522
1559
|
function boundaryComponent(host, fnId) {
|
|
1523
1560
|
return (props, binding) => {
|
|
1524
1561
|
const owner = solidJs.getOwner();
|
|
1562
|
+
const id = binding ? binding() : fnId;
|
|
1563
|
+
let applied = !tables.has(id);
|
|
1564
|
+
let release;
|
|
1565
|
+
const arm = () => new Promise(r => release = r);
|
|
1566
|
+
const mountGate = applied ? undefined : arm();
|
|
1567
|
+
let setGate;
|
|
1525
1568
|
const {
|
|
1526
1569
|
element,
|
|
1527
1570
|
frame,
|
|
1528
1571
|
dispose
|
|
1529
1572
|
} = createFrameElement({
|
|
1530
1573
|
host,
|
|
1531
|
-
id
|
|
1574
|
+
id,
|
|
1532
1575
|
slots: slotsFor(props),
|
|
1533
1576
|
ownerScope: boundaryScope(owner),
|
|
1534
|
-
reveal: revealSeam(owner)
|
|
1577
|
+
reveal: revealSeam(owner),
|
|
1578
|
+
onApply: () => {
|
|
1579
|
+
applied = true;
|
|
1580
|
+
if (release) {
|
|
1581
|
+
release();
|
|
1582
|
+
release = undefined;
|
|
1583
|
+
}
|
|
1584
|
+
setGate && setGate(undefined);
|
|
1585
|
+
}
|
|
1535
1586
|
});
|
|
1536
|
-
|
|
1587
|
+
const [gatePromise, setGatePromise] = solidJs.createSignal(applied ? undefined : mountGate);
|
|
1588
|
+
setGate = setGatePromise;
|
|
1589
|
+
if (binding) {
|
|
1590
|
+
solidJs.createRenderEffect(binding, (address, prev) => {
|
|
1591
|
+
if (prev !== undefined && address !== prev && tables.has(address)) {
|
|
1592
|
+
applied = false;
|
|
1593
|
+
setGatePromise(arm());
|
|
1594
|
+
}
|
|
1595
|
+
frame.rebind(address);
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1537
1598
|
solidJs.onCleanup(dispose);
|
|
1538
|
-
return element;
|
|
1599
|
+
if (applied && !binding) return element;
|
|
1600
|
+
const gate = solidJs.createMemo(() => gatePromise());
|
|
1601
|
+
return solidJs.createMemo(() => (gate(), element));
|
|
1539
1602
|
};
|
|
1540
1603
|
}
|
|
1541
1604
|
const claimedBoundaries = new Set();
|
|
@@ -1603,6 +1666,17 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1603
1666
|
claimedBoundaries.add(id);
|
|
1604
1667
|
const address = binding ? binding() : documentAddress(id);
|
|
1605
1668
|
const appliedRecords = new Set();
|
|
1669
|
+
const claimedFragments = new Set();
|
|
1670
|
+
const claimRegionFragments = root => {
|
|
1671
|
+
const fr = globalThis._$HY?.fr;
|
|
1672
|
+
if (!fr || !fr.claim) return;
|
|
1673
|
+
root.querySelectorAll('template[id^="pl-"]').forEach(tpl => {
|
|
1674
|
+
const fragId = tpl.id.slice(3);
|
|
1675
|
+
if (claimedFragments.has(fragId)) return;
|
|
1676
|
+
claimedFragments.add(fragId);
|
|
1677
|
+
fr.claim(fragId);
|
|
1678
|
+
});
|
|
1679
|
+
};
|
|
1606
1680
|
const drainRecords = () => {
|
|
1607
1681
|
const hy = globalThis._$HY;
|
|
1608
1682
|
if (!hy || !hy.r) return;
|
|
@@ -1634,8 +1708,20 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1634
1708
|
}
|
|
1635
1709
|
}
|
|
1636
1710
|
};
|
|
1711
|
+
claimRegionFragments(el);
|
|
1712
|
+
const fr = globalThis._$HY?.fr;
|
|
1713
|
+
const unsubscribe = fr ? fr.subscribe((_fragId, parent) => {
|
|
1714
|
+
if (fr.claim && parent && el.contains(parent)) claimRegionFragments(parent);
|
|
1715
|
+
drainRecords();
|
|
1716
|
+
}) : undefined;
|
|
1717
|
+
solidJs.onCleanup(() => {
|
|
1718
|
+
unsubscribe && unsubscribe();
|
|
1719
|
+
if (fr && fr.release) for (const fragId of claimedFragments) fr.release(fragId);
|
|
1720
|
+
});
|
|
1637
1721
|
drainRecords();
|
|
1638
1722
|
const owner = solidJs.getOwner();
|
|
1723
|
+
let release;
|
|
1724
|
+
let setGate;
|
|
1639
1725
|
const frame = createFrame(el, {
|
|
1640
1726
|
adopt: true,
|
|
1641
1727
|
host,
|
|
@@ -1643,6 +1729,13 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1643
1729
|
slots: slotsFor(props),
|
|
1644
1730
|
ownerScope: boundaryScope(owner),
|
|
1645
1731
|
reveal: revealSeam(owner),
|
|
1732
|
+
onApply: () => {
|
|
1733
|
+
if (release) {
|
|
1734
|
+
release();
|
|
1735
|
+
release = undefined;
|
|
1736
|
+
}
|
|
1737
|
+
setGate && setGate(undefined);
|
|
1738
|
+
},
|
|
1646
1739
|
...{
|
|
1647
1740
|
recordsPending: () => {
|
|
1648
1741
|
if (document.readyState === "loading") return true;
|
|
@@ -1653,7 +1746,19 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1653
1746
|
claimScope: id
|
|
1654
1747
|
}
|
|
1655
1748
|
});
|
|
1656
|
-
if (binding)
|
|
1749
|
+
if (binding) {
|
|
1750
|
+
const arm = () => new Promise(r => release = r);
|
|
1751
|
+
const [gatePromise, setGatePromise] = solidJs.createSignal(undefined);
|
|
1752
|
+
setGate = setGatePromise;
|
|
1753
|
+
const gate = solidJs.createMemo(() => gatePromise());
|
|
1754
|
+
solidJs.createRenderEffect(binding, (address, prev) => {
|
|
1755
|
+
if (prev !== undefined && address !== prev && tables.has(address)) {
|
|
1756
|
+
setGatePromise(arm());
|
|
1757
|
+
}
|
|
1758
|
+
frame.rebind(address);
|
|
1759
|
+
});
|
|
1760
|
+
solidJs.createRenderEffect(() => (gate(), undefined), () => {});
|
|
1761
|
+
}
|
|
1657
1762
|
solidJs.onCleanup(() => frame.dispose());
|
|
1658
1763
|
return el;
|
|
1659
1764
|
}
|
|
@@ -1697,10 +1802,10 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1697
1802
|
exports.FRAME_APPLIED_EVENT = FRAME_APPLIED_EVENT;
|
|
1698
1803
|
exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
|
|
1699
1804
|
exports.applyFrameResponse = applyFrameResponse;
|
|
1805
|
+
exports.asyncArg = asyncArg;
|
|
1700
1806
|
exports.createFrame = createFrame;
|
|
1701
1807
|
exports.createFrameElement = createFrameElement;
|
|
1702
1808
|
exports.createFrameHost = createFrameHost;
|
|
1703
|
-
exports.createJSONDataTable = createJSONDataTable;
|
|
1704
1809
|
exports.createServerComponentHandler = createServerComponentHandler;
|
|
1705
1810
|
exports.getFrameHost = getFrameHost;
|
|
1706
1811
|
exports.installServerComponents = installServerComponents;
|