@solidjs/web 2.0.0-beta.24 → 2.0.0-beta.26
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/dev.cjs +11 -8
- package/dist/dev.js +11 -8
- package/dist/web.cjs +11 -8
- package/dist/web.js +11 -8
- package/frames/dist/client.cjs +135 -208
- package/frames/dist/client.dev.cjs +1408 -0
- package/frames/dist/client.dev.js +1396 -0
- package/frames/dist/client.js +136 -209
- package/frames/dist/server.cjs +106 -78
- package/frames/dist/server.js +106 -78
- package/package.json +27 -6
- package/server-functions/dist/client.cjs +3 -3
- package/server-functions/dist/client.js +3 -3
- package/server-functions/dist/server.cjs +3 -3
- package/server-functions/dist/server.js +3 -3
- package/types/frames/client.d.ts +13 -49
- package/types/frames/frame-client.d.ts +34 -28
- package/types/frames/server.d.ts +1 -20
- package/types-cjs/frames/client.d.cts +13 -49
- package/types-cjs/frames/frame-client.d.cts +34 -28
- package/types-cjs/frames/server.d.cts +1 -20
package/frames/dist/client.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { getOwner, onCleanup,
|
|
1
|
+
import { getOwner, runWithOwner, onCleanup, createLoadingBoundary, sharedConfig, createOwner } from 'solid-js';
|
|
2
|
+
import { insert } from '@solidjs/web';
|
|
3
|
+
import { configureServerFunctionsClient } from '@solidjs/web/server-functions/client';
|
|
2
4
|
import { fromCrossJSON, Feature } from 'seroval';
|
|
3
5
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
4
6
|
|
|
@@ -63,22 +65,6 @@ function chunkToRecords(chunk) {
|
|
|
63
65
|
args: chunk.args
|
|
64
66
|
}
|
|
65
67
|
};
|
|
66
|
-
case "template":
|
|
67
|
-
return {
|
|
68
|
-
[`tpl:${chunk.key}`]: {
|
|
69
|
-
kind: "template",
|
|
70
|
-
html: chunk.html,
|
|
71
|
-
fields: chunk.fields
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
case "block":
|
|
75
|
-
return {
|
|
76
|
-
[`seg:${chunk.key}`]: {
|
|
77
|
-
kind: "block",
|
|
78
|
-
template: `tpl:${chunk.template}`,
|
|
79
|
-
values: chunk.values
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
68
|
case "complete":
|
|
83
69
|
return {
|
|
84
70
|
":complete": true
|
|
@@ -272,7 +258,7 @@ class FrameImpl {
|
|
|
272
258
|
this.#revealed.clear();
|
|
273
259
|
this.#fallbackShown.clear();
|
|
274
260
|
for (const key of Object.keys(this.#store)) {
|
|
275
|
-
if (key.startsWith("seg:") || key
|
|
261
|
+
if (key.startsWith("seg:") || key === ":error") {
|
|
276
262
|
delete this.#store[key];
|
|
277
263
|
}
|
|
278
264
|
}
|
|
@@ -341,10 +327,14 @@ class FrameImpl {
|
|
|
341
327
|
if (record !== undefined) return record;
|
|
342
328
|
return this.#options.resolveSlotRecord?.(occurrence);
|
|
343
329
|
}
|
|
344
|
-
#
|
|
330
|
+
#removeSlotRecord(occurrence) {
|
|
331
|
+
const key = `slot:${occurrence}`;
|
|
332
|
+
if (key in this.#store) delete this.#store[key];else this.#options.removeSlotRecord?.(occurrence);
|
|
333
|
+
}
|
|
334
|
+
#syncSlots(root) {
|
|
345
335
|
if (!this.#slots && !this.#options.resolveSlot) return;
|
|
346
336
|
const found = new Map();
|
|
347
|
-
this.#collectSlots(found);
|
|
337
|
+
if (root) collectSlots(root, found);else this.#collectSlots(found);
|
|
348
338
|
for (const [occurrence, start] of found) {
|
|
349
339
|
const callback = this.#resolveSlot(propOf(occurrence));
|
|
350
340
|
if (!callback) continue;
|
|
@@ -357,6 +347,7 @@ class FrameImpl {
|
|
|
357
347
|
this.#runSlotCleanups(occurrence);
|
|
358
348
|
}
|
|
359
349
|
if (!this.#mountedSlots.has(occurrence)) {
|
|
350
|
+
if (this.#options.adopt) this.#discoverRegions(occurrence, start);
|
|
360
351
|
const nodes = this.#invokeSlot(occurrence, callback, record, start, this.#options.adopt);
|
|
361
352
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
362
353
|
this.#slotNodes.set(occurrence, nodes);
|
|
@@ -374,8 +365,10 @@ class FrameImpl {
|
|
|
374
365
|
this.#bindRegions(occurrence);
|
|
375
366
|
}
|
|
376
367
|
}
|
|
377
|
-
|
|
378
|
-
|
|
368
|
+
if (!root) {
|
|
369
|
+
for (const occurrence of [...this.#mountedSlots]) {
|
|
370
|
+
if (!found.has(occurrence)) this.#unmountSlot(occurrence);
|
|
371
|
+
}
|
|
379
372
|
}
|
|
380
373
|
}
|
|
381
374
|
#invokeSlot(occurrence, callback, record, start, adopted) {
|
|
@@ -388,6 +381,13 @@ class FrameImpl {
|
|
|
388
381
|
existing: start ? rangeInterior(start, slotEnd(occurrence)) : []
|
|
389
382
|
};
|
|
390
383
|
const props = record && record.kind === "slot" ? this.#resolveArgs(occurrence, record.args) : {};
|
|
384
|
+
const regions = this.#slotRegions.get(occurrence);
|
|
385
|
+
if (regions) {
|
|
386
|
+
for (const entry of regions.values()) {
|
|
387
|
+
const argKey = entry.childId.slice(entry.childId.lastIndexOf(".") + 1);
|
|
388
|
+
if (!(argKey in props)) props[argKey] = entry.element;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
391
|
const content = callback(props, ctx);
|
|
392
392
|
this.#slotArgs.set(occurrence, record);
|
|
393
393
|
if (cleanups.length) this.#slotCleanups.set(occurrence, cleanups);
|
|
@@ -410,7 +410,7 @@ class FrameImpl {
|
|
|
410
410
|
this.#slotNodes.delete(key);
|
|
411
411
|
this.#slotArgs.delete(key);
|
|
412
412
|
this.#slotResolvedRefs.delete(key);
|
|
413
|
-
|
|
413
|
+
this.#removeSlotRecord(key);
|
|
414
414
|
this.#runSlotCleanups(key);
|
|
415
415
|
const regions = this.#slotRegions.get(key);
|
|
416
416
|
if (regions) {
|
|
@@ -444,29 +444,17 @@ class FrameImpl {
|
|
|
444
444
|
cache[key] = resolved;
|
|
445
445
|
props[key] = resolved;
|
|
446
446
|
} else if (isFrameRef(value)) {
|
|
447
|
-
const fragment = document.createDocumentFragment();
|
|
448
447
|
let entry = regions.get(value.$frame);
|
|
449
448
|
if (!entry) {
|
|
450
|
-
const
|
|
451
|
-
const end = document.createComment(`frame:${value.$frame}:end`);
|
|
449
|
+
const element = makeFrameElement(value.$frame);
|
|
452
450
|
entry = {
|
|
453
451
|
childId: value.$frame,
|
|
454
|
-
|
|
455
|
-
end,
|
|
452
|
+
element,
|
|
456
453
|
frame: undefined
|
|
457
454
|
};
|
|
458
455
|
regions.set(value.$frame, entry);
|
|
459
|
-
fragment.append(start, end);
|
|
460
|
-
} else {
|
|
461
|
-
let n = entry.start;
|
|
462
|
-
while (n) {
|
|
463
|
-
const next = n.nextSibling;
|
|
464
|
-
fragment.append(n);
|
|
465
|
-
if (n === entry.end) break;
|
|
466
|
-
n = next;
|
|
467
|
-
}
|
|
468
456
|
}
|
|
469
|
-
props[key] =
|
|
457
|
+
props[key] = entry.element;
|
|
470
458
|
} else {
|
|
471
459
|
props[key] = value;
|
|
472
460
|
}
|
|
@@ -480,49 +468,12 @@ class FrameImpl {
|
|
|
480
468
|
regions = new Map();
|
|
481
469
|
this.#slotRegions.set(slotKey, regions);
|
|
482
470
|
}
|
|
483
|
-
const doc = start.ownerDocument;
|
|
484
471
|
const endData = slotEnd(slotKey);
|
|
485
|
-
const comments = [];
|
|
486
472
|
let n = start.nextSibling;
|
|
487
473
|
while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
|
|
488
|
-
|
|
489
|
-
const walker = doc.createTreeWalker(n, 128 );
|
|
490
|
-
let c;
|
|
491
|
-
while (c = walker.nextNode()) comments.push(c);
|
|
492
|
-
}
|
|
474
|
+
collectRegionElements(n, regions);
|
|
493
475
|
n = n.nextSibling;
|
|
494
476
|
}
|
|
495
|
-
let depth = 0;
|
|
496
|
-
let openId = null;
|
|
497
|
-
let openStart = null;
|
|
498
|
-
for (const c of comments) {
|
|
499
|
-
const data = c.data;
|
|
500
|
-
if (!data.startsWith("frame:")) continue;
|
|
501
|
-
if (data.endsWith(":start")) {
|
|
502
|
-
const childId = data.slice(6, -6);
|
|
503
|
-
if (!childId) continue;
|
|
504
|
-
if (depth === 0) {
|
|
505
|
-
openId = childId;
|
|
506
|
-
openStart = c;
|
|
507
|
-
}
|
|
508
|
-
depth++;
|
|
509
|
-
} else if (data.endsWith(":end")) {
|
|
510
|
-
const childId = data.slice(6, -4);
|
|
511
|
-
if (!childId) continue;
|
|
512
|
-
if (depth > 0) {
|
|
513
|
-
depth--;
|
|
514
|
-
if (depth === 0 && childId === openId && !regions.has(openId)) {
|
|
515
|
-
regions.set(openId, {
|
|
516
|
-
childId: openId,
|
|
517
|
-
start: openStart,
|
|
518
|
-
end: c,
|
|
519
|
-
frame: undefined,
|
|
520
|
-
adopt: true
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
477
|
}
|
|
527
478
|
#refArgsUnchanged(occurrence, record) {
|
|
528
479
|
const old = this.#slotArgs.get(occurrence);
|
|
@@ -566,15 +517,16 @@ class FrameImpl {
|
|
|
566
517
|
const regions = this.#slotRegions.get(slotKey);
|
|
567
518
|
if (!regions) return;
|
|
568
519
|
for (const entry of regions.values()) {
|
|
569
|
-
if (!entry.frame
|
|
570
|
-
entry.frame = new FrameImpl(
|
|
520
|
+
if (!entry.frame) {
|
|
521
|
+
entry.frame = new FrameImpl(entry.element, null, null, {
|
|
571
522
|
id: entry.childId,
|
|
572
523
|
host: this.#options.host,
|
|
573
524
|
adopt: entry.adopt,
|
|
574
525
|
claimScope: this.#options.claimScope ?? this.#options.id,
|
|
575
526
|
ownerScope: this.#options.ownerScope,
|
|
576
527
|
resolveSlot: prop => this.#resolveSlot(prop),
|
|
577
|
-
resolveSlotRecord: occurrence => this.#resolveSlotRecord(occurrence)
|
|
528
|
+
resolveSlotRecord: occurrence => this.#resolveSlotRecord(occurrence),
|
|
529
|
+
removeSlotRecord: occurrence => this.#removeSlotRecord(occurrence)
|
|
578
530
|
});
|
|
579
531
|
}
|
|
580
532
|
}
|
|
@@ -589,12 +541,7 @@ class FrameImpl {
|
|
|
589
541
|
n = afterRange(n, id);
|
|
590
542
|
continue;
|
|
591
543
|
}
|
|
592
|
-
|
|
593
|
-
if (regionId !== null) {
|
|
594
|
-
n = afterFrameRegion(n, regionId);
|
|
595
|
-
continue;
|
|
596
|
-
}
|
|
597
|
-
if (n.nodeType === ELEMENT_NODE) collectSlots(n, found);
|
|
544
|
+
if (n.nodeType === ELEMENT_NODE && !isFrameElement(n)) collectSlots(n, found);
|
|
598
545
|
n = n.nextSibling;
|
|
599
546
|
}
|
|
600
547
|
}
|
|
@@ -616,6 +563,7 @@ class FrameImpl {
|
|
|
616
563
|
if (this.#disposed) return;
|
|
617
564
|
this.#disposed = true;
|
|
618
565
|
for (const key of [...this.#slotCleanups.keys()]) this.#runSlotCleanups(key);
|
|
566
|
+
for (const key of this.#mountedSlots) this.#removeSlotRecord(key);
|
|
619
567
|
for (const regions of this.#slotRegions.values()) {
|
|
620
568
|
for (const {
|
|
621
569
|
frame
|
|
@@ -661,13 +609,7 @@ class FrameImpl {
|
|
|
661
609
|
}
|
|
662
610
|
#segmentReady(name) {
|
|
663
611
|
const content = this.#store[`seg:${name}`];
|
|
664
|
-
if (!content) return false;
|
|
665
|
-
if (content.kind === "block") {
|
|
666
|
-
const template = this.#store[content.template];
|
|
667
|
-
if (!template || template.kind !== "template") return false;
|
|
668
|
-
} else if (content.kind !== "html") {
|
|
669
|
-
return false;
|
|
670
|
-
}
|
|
612
|
+
if (!content || content.kind !== "html") return false;
|
|
671
613
|
if (!this.#store[`seg:${name}:reveal`]) return false;
|
|
672
614
|
const assets = this.#store[`seg:${name}:assets`];
|
|
673
615
|
if (assets && assets.styles) {
|
|
@@ -694,6 +636,23 @@ class FrameImpl {
|
|
|
694
636
|
parent.removeChild(n);
|
|
695
637
|
n = next;
|
|
696
638
|
}
|
|
639
|
+
if (this.#options.reveal) {
|
|
640
|
+
const fallbackFrag = tpl.content.cloneNode(true);
|
|
641
|
+
this.#claimTree(fallbackFrag);
|
|
642
|
+
this.#options.reveal({
|
|
643
|
+
before: closing,
|
|
644
|
+
fallback: [...fallbackFrag.childNodes],
|
|
645
|
+
content: () => {
|
|
646
|
+
const materialized = this.#materialize(content);
|
|
647
|
+
this.#syncSlots(materialized);
|
|
648
|
+
this.#claimTree(materialized);
|
|
649
|
+
return materialized;
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
tpl.remove();
|
|
653
|
+
this.#revealed.add(name);
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
697
656
|
const materialized = this.#materialize(content);
|
|
698
657
|
this.#claimTree(materialized);
|
|
699
658
|
parent.insertBefore(materialized, closing);
|
|
@@ -712,70 +671,37 @@ class FrameImpl {
|
|
|
712
671
|
return true;
|
|
713
672
|
}
|
|
714
673
|
#materialize(record) {
|
|
715
|
-
|
|
716
|
-
if (record.kind === "block") {
|
|
717
|
-
const template = this.#store[record.template];
|
|
718
|
-
if (!template || template.kind !== "template") return parseFragment("");
|
|
719
|
-
return materializeBlock(template, record.values);
|
|
720
|
-
}
|
|
721
|
-
return parseFragment("");
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
function materializeBlock(template, values) {
|
|
725
|
-
const fragment = parseFragment(template.html);
|
|
726
|
-
for (let i = 0; i < template.fields.length; i++) {
|
|
727
|
-
const marker = `field:${template.fields[i]}`;
|
|
728
|
-
const value = values[i] == null ? "" : String(values[i]);
|
|
729
|
-
let hole = findComment(fragment, marker);
|
|
730
|
-
while (hole) {
|
|
731
|
-
hole.replaceWith(document.createTextNode(value));
|
|
732
|
-
hole = findComment(fragment, marker);
|
|
733
|
-
}
|
|
674
|
+
return record.kind === "html" ? parseFragment(record.value) : parseFragment("");
|
|
734
675
|
}
|
|
735
|
-
return fragment;
|
|
736
676
|
}
|
|
737
677
|
function createFrame(boundary, options) {
|
|
738
678
|
return new FrameImpl(boundary, null, null, options);
|
|
739
679
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
}
|
|
746
|
-
const FRAME = Symbol.for("dom-expressions.frame");
|
|
747
|
-
function createFrameInsertable(options) {
|
|
748
|
-
let frame = null;
|
|
749
|
-
let start = null;
|
|
750
|
-
let end = null;
|
|
680
|
+
const FRAME_TAG = "dx-frame";
|
|
681
|
+
const FRAME_ID_ATTR = "data-fid";
|
|
682
|
+
function createFrameElement(options) {
|
|
683
|
+
const el = makeFrameElement(options.id);
|
|
684
|
+
const frame = new FrameImpl(el, null, null, options);
|
|
751
685
|
return {
|
|
686
|
+
element: el,
|
|
752
687
|
get frame() {
|
|
753
688
|
return frame;
|
|
754
689
|
},
|
|
755
690
|
dispose() {
|
|
756
|
-
if (!frame) return;
|
|
757
691
|
frame.dispose();
|
|
758
|
-
|
|
759
|
-
const parent = start.parentNode;
|
|
760
|
-
if (!parent) return;
|
|
761
|
-
let n = start;
|
|
762
|
-
while (n) {
|
|
763
|
-
const next = n.nextSibling;
|
|
764
|
-
parent.removeChild(n);
|
|
765
|
-
if (n === end) break;
|
|
766
|
-
n = next;
|
|
767
|
-
}
|
|
768
|
-
},
|
|
769
|
-
[FRAME](parent, marker) {
|
|
770
|
-
if (frame) return;
|
|
771
|
-
start = document.createComment("frame:start");
|
|
772
|
-
end = document.createComment("frame:end");
|
|
773
|
-
parent.insertBefore(start, marker);
|
|
774
|
-
parent.insertBefore(end, marker);
|
|
775
|
-
frame = new FrameImpl(null, start, end, options);
|
|
692
|
+
el.remove();
|
|
776
693
|
}
|
|
777
694
|
};
|
|
778
695
|
}
|
|
696
|
+
function makeFrameElement(id) {
|
|
697
|
+
const el = document.createElement(FRAME_TAG);
|
|
698
|
+
el.style.display = "contents";
|
|
699
|
+
if (id !== undefined) el.setAttribute(FRAME_ID_ATTR, id);
|
|
700
|
+
return el;
|
|
701
|
+
}
|
|
702
|
+
function isFrameElement(node) {
|
|
703
|
+
return node.nodeType === ELEMENT_NODE && node.hasAttribute(FRAME_ID_ATTR);
|
|
704
|
+
}
|
|
779
705
|
function segmentName(key) {
|
|
780
706
|
const m = /^seg:([^:]+)$/.exec(key);
|
|
781
707
|
return m ? m[1] : null;
|
|
@@ -874,29 +800,25 @@ function collectSlots(root, out) {
|
|
|
874
800
|
n = afterRange(n, id);
|
|
875
801
|
continue;
|
|
876
802
|
}
|
|
877
|
-
|
|
878
|
-
if (regionId !== null) {
|
|
879
|
-
n = afterFrameRegion(n, regionId);
|
|
880
|
-
continue;
|
|
881
|
-
}
|
|
882
|
-
if (n.nodeType === ELEMENT_NODE) collectSlots(n, out);
|
|
803
|
+
if (n.nodeType === ELEMENT_NODE && !isFrameElement(n)) collectSlots(n, out);
|
|
883
804
|
n = n.nextSibling;
|
|
884
805
|
}
|
|
885
806
|
}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
if (node
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
807
|
+
function collectRegionElements(node, regions) {
|
|
808
|
+
if (node.nodeType !== ELEMENT_NODE) return;
|
|
809
|
+
if (isFrameElement(node)) {
|
|
810
|
+
const childId = node.getAttribute(FRAME_ID_ATTR);
|
|
811
|
+
if (childId && !regions.has(childId)) {
|
|
812
|
+
regions.set(childId, {
|
|
813
|
+
childId,
|
|
814
|
+
element: node,
|
|
815
|
+
frame: undefined,
|
|
816
|
+
adopt: true
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
return;
|
|
898
820
|
}
|
|
899
|
-
|
|
821
|
+
for (let c = node.firstChild; c; c = c.nextSibling) collectRegionElements(c, regions);
|
|
900
822
|
}
|
|
901
823
|
function argsEquivalent(a, b) {
|
|
902
824
|
if (a === b) return true;
|
|
@@ -924,18 +846,6 @@ function rangeInterior(start, endData) {
|
|
|
924
846
|
}
|
|
925
847
|
return nodes;
|
|
926
848
|
}
|
|
927
|
-
function findComment(root, data) {
|
|
928
|
-
const children = root.childNodes;
|
|
929
|
-
for (let i = 0; i < children.length; i++) {
|
|
930
|
-
const node = children[i];
|
|
931
|
-
if (node.nodeType === COMMENT_NODE && node.data === data) return node;
|
|
932
|
-
if (node.nodeType === ELEMENT_NODE) {
|
|
933
|
-
const found = findComment(node, data);
|
|
934
|
-
if (found) return found;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
return null;
|
|
938
|
-
}
|
|
939
849
|
function slotStartId(node) {
|
|
940
850
|
if (node.nodeType !== COMMENT_NODE) return null;
|
|
941
851
|
const m = SLOT_START.exec(node.data);
|
|
@@ -951,12 +861,18 @@ function compatible(a, b) {
|
|
|
951
861
|
if (a.nodeType === ELEMENT_NODE) return a.nodeName === b.nodeName;
|
|
952
862
|
return a.nodeType === TEXT_NODE || a.nodeType === COMMENT_NODE;
|
|
953
863
|
}
|
|
864
|
+
function preservesOpen(el) {
|
|
865
|
+
const t = el.tagName;
|
|
866
|
+
return t === "DETAILS" || t === "DIALOG";
|
|
867
|
+
}
|
|
954
868
|
function morphAttributes(oldEl, newEl, claim) {
|
|
955
869
|
let reclaim = false;
|
|
956
870
|
let changed = false;
|
|
871
|
+
const keepOpen = preservesOpen(oldEl);
|
|
957
872
|
const oldAttrs = oldEl.attributes;
|
|
958
873
|
for (let i = oldAttrs.length - 1; i >= 0; i--) {
|
|
959
874
|
const name = oldAttrs[i].name;
|
|
875
|
+
if (keepOpen && name === "open") continue;
|
|
960
876
|
if (!newEl.hasAttribute(name)) {
|
|
961
877
|
oldEl.removeAttribute(name);
|
|
962
878
|
changed = true;
|
|
@@ -966,6 +882,7 @@ function morphAttributes(oldEl, newEl, claim) {
|
|
|
966
882
|
const newAttrs = newEl.attributes;
|
|
967
883
|
for (let i = 0; i < newAttrs.length; i++) {
|
|
968
884
|
const attr = newAttrs[i];
|
|
885
|
+
if (keepOpen && attr.name === "open") continue;
|
|
969
886
|
if (oldEl.getAttribute(attr.name) !== attr.value) {
|
|
970
887
|
oldEl.setAttribute(attr.name, attr.value);
|
|
971
888
|
changed = true;
|
|
@@ -976,6 +893,7 @@ function morphAttributes(oldEl, newEl, claim) {
|
|
|
976
893
|
}
|
|
977
894
|
function morphNode(oldNode, newNode, claim) {
|
|
978
895
|
if (oldNode.nodeType === ELEMENT_NODE) {
|
|
896
|
+
if (oldNode.hasAttribute("data-preserve")) return;
|
|
979
897
|
morphAttributes(oldNode, newNode, claim);
|
|
980
898
|
reconcileChildren(oldNode, newNode, null, null, claim);
|
|
981
899
|
} else if (oldNode.data !== newNode.data) {
|
|
@@ -1160,15 +1078,15 @@ class ChunkReader {
|
|
|
1160
1078
|
}
|
|
1161
1079
|
}
|
|
1162
1080
|
async next() {
|
|
1163
|
-
|
|
1081
|
+
while (this.buffer.length < 12) {
|
|
1164
1082
|
if (this.done) {
|
|
1165
|
-
return {
|
|
1083
|
+
if (this.buffer.length === 0) return {
|
|
1166
1084
|
done: true,
|
|
1167
1085
|
value: undefined
|
|
1168
1086
|
};
|
|
1087
|
+
throw new Error("Malformed server function stream.");
|
|
1169
1088
|
}
|
|
1170
1089
|
await this.readChunk();
|
|
1171
|
-
return await this.next();
|
|
1172
1090
|
}
|
|
1173
1091
|
const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
|
|
1174
1092
|
const bytes = Number.parseInt(head, 16);
|
|
@@ -1281,6 +1199,9 @@ function tableFor(id) {
|
|
|
1281
1199
|
for (const [root, t] of tables) if (id.startsWith(root + ".")) return t;
|
|
1282
1200
|
return undefined;
|
|
1283
1201
|
}
|
|
1202
|
+
function beginStream(frameId) {
|
|
1203
|
+
tables.set(frameId, createJSONDataTable());
|
|
1204
|
+
}
|
|
1284
1205
|
function getFrameHost() {
|
|
1285
1206
|
if (!sharedHost) {
|
|
1286
1207
|
sharedHost = createFrameHost({
|
|
@@ -1353,50 +1274,44 @@ function slotsFor(props) {
|
|
|
1353
1274
|
}
|
|
1354
1275
|
});
|
|
1355
1276
|
}
|
|
1277
|
+
function revealSeam(owner) {
|
|
1278
|
+
return seam => runWithOwner(owner, () => insert(seam.before.parentNode, createLoadingBoundary(() => seam.content(), () => seam.fallback), seam.before));
|
|
1279
|
+
}
|
|
1356
1280
|
function boundaryComponent(host, id) {
|
|
1357
1281
|
return props => {
|
|
1358
1282
|
const owner = getOwner();
|
|
1359
|
-
const
|
|
1283
|
+
const {
|
|
1284
|
+
element,
|
|
1285
|
+
dispose
|
|
1286
|
+
} = createFrameElement({
|
|
1360
1287
|
host,
|
|
1361
1288
|
id,
|
|
1362
1289
|
slots: slotsFor(props),
|
|
1363
|
-
ownerScope: fn => runWithOwner(owner, fn)
|
|
1290
|
+
ownerScope: fn => runWithOwner(owner, fn),
|
|
1291
|
+
reveal: revealSeam(owner)
|
|
1364
1292
|
});
|
|
1365
|
-
onCleanup(
|
|
1366
|
-
return
|
|
1293
|
+
onCleanup(dispose);
|
|
1294
|
+
return element;
|
|
1367
1295
|
};
|
|
1368
1296
|
}
|
|
1369
1297
|
const claimedBoundaries = new Set();
|
|
1370
1298
|
let boundaryIndex = null;
|
|
1371
|
-
function
|
|
1299
|
+
function findBoundaryElement(id) {
|
|
1372
1300
|
if (!boundaryIndex) {
|
|
1373
1301
|
boundaryIndex = new Map();
|
|
1374
1302
|
if (typeof document !== "undefined" && document.body) {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
const d = c.data;
|
|
1380
|
-
if (!d.startsWith("frame:")) continue;
|
|
1381
|
-
if (d.endsWith(":start")) {
|
|
1382
|
-
const key = d.slice(6, -6);
|
|
1383
|
-
if (key && !(key in opens)) opens[key] = c;
|
|
1384
|
-
} else if (d.endsWith(":end")) {
|
|
1385
|
-
const key = d.slice(6, -4);
|
|
1386
|
-
if (key && opens[key] && !boundaryIndex.has(key)) {
|
|
1387
|
-
boundaryIndex.set(key, [opens[key], c]);
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1303
|
+
document.body.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1304
|
+
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1305
|
+
if (key && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1306
|
+
});
|
|
1391
1307
|
}
|
|
1392
1308
|
}
|
|
1393
1309
|
return boundaryIndex.get(id);
|
|
1394
1310
|
}
|
|
1395
1311
|
function documentBoundary(host, id, props) {
|
|
1396
|
-
const
|
|
1397
|
-
if (!
|
|
1312
|
+
const el = !claimedBoundaries.has(id) ? findBoundaryElement(id) : undefined;
|
|
1313
|
+
if (!el) return boundaryComponent(host, id)(props);
|
|
1398
1314
|
claimedBoundaries.add(id);
|
|
1399
|
-
const [start, end] = range;
|
|
1400
1315
|
const hy = globalThis._$HY;
|
|
1401
1316
|
if (hy && hy.r) {
|
|
1402
1317
|
const slotPrefix = `sc:slot:${id}:`;
|
|
@@ -1425,19 +1340,16 @@ function documentBoundary(host, id, props) {
|
|
|
1425
1340
|
}
|
|
1426
1341
|
}
|
|
1427
1342
|
const owner = getOwner();
|
|
1428
|
-
const frame =
|
|
1343
|
+
const frame = createFrame(el, {
|
|
1344
|
+
adopt: true,
|
|
1429
1345
|
host,
|
|
1430
1346
|
id,
|
|
1431
1347
|
slots: slotsFor(props),
|
|
1432
|
-
ownerScope: fn => runWithOwner(owner, fn)
|
|
1348
|
+
ownerScope: fn => runWithOwner(owner, fn),
|
|
1349
|
+
reveal: revealSeam(owner)
|
|
1433
1350
|
});
|
|
1434
1351
|
onCleanup(() => frame.dispose());
|
|
1435
|
-
|
|
1436
|
-
for (let n = start; n; n = n.nextSibling) {
|
|
1437
|
-
nodes.push(n);
|
|
1438
|
-
if (n === end) break;
|
|
1439
|
-
}
|
|
1440
|
-
return nodes;
|
|
1352
|
+
return el;
|
|
1441
1353
|
}
|
|
1442
1354
|
function installServerComponents(host = getFrameHost()) {
|
|
1443
1355
|
const g = globalThis;
|
|
@@ -1450,6 +1362,21 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1450
1362
|
};
|
|
1451
1363
|
}
|
|
1452
1364
|
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1365
|
+
configureServerFunctionsClient({
|
|
1366
|
+
responseHandler: createServerComponentHandler({
|
|
1367
|
+
host,
|
|
1368
|
+
capture: () => getOwner() ?? undefined,
|
|
1369
|
+
component: frameId => boundaryComponent(host, frameId),
|
|
1370
|
+
onStream: frameId => beginStream(frameId),
|
|
1371
|
+
documentComponent: functionId => g._$SC.c[functionId],
|
|
1372
|
+
intercept: ({
|
|
1373
|
+
id
|
|
1374
|
+
}) => {
|
|
1375
|
+
if (claimedBoundaries.has(id) || !findBoundaryElement(id)) return undefined;
|
|
1376
|
+
return g._$SC.r(id);
|
|
1377
|
+
}
|
|
1378
|
+
})
|
|
1379
|
+
});
|
|
1453
1380
|
}
|
|
1454
1381
|
|
|
1455
|
-
export { FRAME_APPLIED_EVENT, FRAME_STREAM_HEADER, applyFrameResponse, createFrame,
|
|
1382
|
+
export { FRAME_APPLIED_EVENT, FRAME_STREAM_HEADER, applyFrameResponse, createFrame, createFrameElement, createFrameHost, createJSONDataTable, createServerComponentHandler, getFrameHost, installServerComponents, isFrameStreamResponse };
|