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