@solidjs/web 2.0.0-beta.25 → 2.0.0-beta.27
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 +14 -9
- package/dist/dev.js +14 -10
- package/dist/server.cjs +41 -78
- package/dist/server.js +42 -80
- package/dist/web.cjs +14 -9
- package/dist/web.js +14 -10
- package/frames/dist/client.cjs +180 -224
- package/frames/dist/client.dev.cjs +1456 -0
- package/frames/dist/client.dev.js +1444 -0
- package/frames/dist/client.js +181 -225
- package/frames/dist/server.cjs +139 -123
- package/frames/dist/server.js +139 -123
- package/package.json +24 -4
- package/serialization/dist/serialization.cjs +6 -3
- package/serialization/dist/serialization.js +6 -3
- package/serialization/types/index.d.ts +7 -1
- package/serialization/types-cjs/index.d.cts +7 -1
- package/server-functions/dist/client.cjs +18 -5
- package/server-functions/dist/client.js +16 -6
- package/server-functions/dist/server.cjs +164 -8
- package/server-functions/dist/server.js +158 -9
- package/types/client.d.ts +3 -3
- package/types/frames/client.d.ts +1 -1
- package/types/frames/frame-client.d.ts +34 -28
- package/types/frames/serializer.d.ts +7 -1
- package/types/jsx.d.ts +1 -1
- package/types/response.d.ts +10 -0
- package/types/serializer.d.ts +7 -1
- package/types/server-functions/client.d.ts +3 -0
- package/types/server-functions/flash.d.ts +38 -0
- package/types/server-functions/server.d.ts +79 -4
- package/types/server-functions/shared.d.ts +35 -0
- package/types-cjs/client.d.cts +3 -3
- package/types-cjs/frames/client.d.cts +1 -1
- package/types-cjs/frames/frame-client.d.cts +34 -28
- package/types-cjs/frames/serializer.d.cts +7 -1
- package/types-cjs/jsx.d.cts +1 -1
- package/types-cjs/response.d.cts +10 -0
- package/types-cjs/serializer.d.cts +7 -1
- package/types-cjs/server-functions/client.d.cts +3 -0
- package/types-cjs/server-functions/flash.d.cts +38 -0
- package/types-cjs/server-functions/server.d.cts +79 -4
- package/types-cjs/server-functions/shared.d.cts +35 -0
package/frames/dist/client.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var solidJs = require('solid-js');
|
|
4
|
+
var web$1 = require('@solidjs/web');
|
|
4
5
|
var client = require('@solidjs/web/server-functions/client');
|
|
5
6
|
var seroval = require('seroval');
|
|
6
7
|
var web = require('seroval-plugins/web');
|
|
@@ -66,22 +67,6 @@ function chunkToRecords(chunk) {
|
|
|
66
67
|
args: chunk.args
|
|
67
68
|
}
|
|
68
69
|
};
|
|
69
|
-
case "template":
|
|
70
|
-
return {
|
|
71
|
-
[`tpl:${chunk.key}`]: {
|
|
72
|
-
kind: "template",
|
|
73
|
-
html: chunk.html,
|
|
74
|
-
fields: chunk.fields
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
case "block":
|
|
78
|
-
return {
|
|
79
|
-
[`seg:${chunk.key}`]: {
|
|
80
|
-
kind: "block",
|
|
81
|
-
template: `tpl:${chunk.template}`,
|
|
82
|
-
values: chunk.values
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
70
|
case "complete":
|
|
86
71
|
return {
|
|
87
72
|
":complete": true
|
|
@@ -129,7 +114,7 @@ function createFrameHost(options = {}) {
|
|
|
129
114
|
pending.delete(id);
|
|
130
115
|
const records = {};
|
|
131
116
|
let version;
|
|
132
|
-
for (const chunk of buffered) {
|
|
117
|
+
for (const chunk of buffered.chunks) {
|
|
133
118
|
if (chunk.type === "data") {
|
|
134
119
|
options.applyData && options.applyData(chunk);
|
|
135
120
|
continue;
|
|
@@ -161,12 +146,20 @@ function createFrameHost(options = {}) {
|
|
|
161
146
|
for (const frame of set) deliver(frame, chunk);
|
|
162
147
|
return;
|
|
163
148
|
}
|
|
164
|
-
const buffered = pending.get(chunk.id)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
149
|
+
const buffered = pending.get(chunk.id);
|
|
150
|
+
if (!buffered) {
|
|
151
|
+
pending.set(chunk.id, {
|
|
152
|
+
version: chunk.version,
|
|
153
|
+
chunks: [chunk]
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (chunk.version < buffered.version) return;
|
|
158
|
+
if (chunk.version > buffered.version) {
|
|
159
|
+
buffered.version = chunk.version;
|
|
160
|
+
buffered.chunks.length = 0;
|
|
161
|
+
}
|
|
162
|
+
buffered.chunks.push(chunk);
|
|
170
163
|
},
|
|
171
164
|
get(id) {
|
|
172
165
|
const set = frames.get(id);
|
|
@@ -225,7 +218,7 @@ class FrameImpl {
|
|
|
225
218
|
if (options.host && options.id !== undefined) {
|
|
226
219
|
options.host.register(options.id, this);
|
|
227
220
|
}
|
|
228
|
-
if (options.adopt) this.#syncSlots();
|
|
221
|
+
if (options.adopt && this.#version === undefined) this.#syncSlots();
|
|
229
222
|
}
|
|
230
223
|
#parent() {
|
|
231
224
|
return this.#element ?? this.#start.parentNode;
|
|
@@ -275,7 +268,7 @@ class FrameImpl {
|
|
|
275
268
|
this.#revealed.clear();
|
|
276
269
|
this.#fallbackShown.clear();
|
|
277
270
|
for (const key of Object.keys(this.#store)) {
|
|
278
|
-
if (key.startsWith("seg:") || key
|
|
271
|
+
if (key.startsWith("seg:") || key === ":error") {
|
|
279
272
|
delete this.#store[key];
|
|
280
273
|
}
|
|
281
274
|
}
|
|
@@ -344,10 +337,14 @@ class FrameImpl {
|
|
|
344
337
|
if (record !== undefined) return record;
|
|
345
338
|
return this.#options.resolveSlotRecord?.(occurrence);
|
|
346
339
|
}
|
|
347
|
-
#
|
|
340
|
+
#removeSlotRecord(occurrence) {
|
|
341
|
+
const key = `slot:${occurrence}`;
|
|
342
|
+
if (key in this.#store) delete this.#store[key];else this.#options.removeSlotRecord?.(occurrence);
|
|
343
|
+
}
|
|
344
|
+
#syncSlots(root) {
|
|
348
345
|
if (!this.#slots && !this.#options.resolveSlot) return;
|
|
349
346
|
const found = new Map();
|
|
350
|
-
this.#collectSlots(found);
|
|
347
|
+
if (root) collectSlots(root, found);else this.#collectSlots(found);
|
|
351
348
|
for (const [occurrence, start] of found) {
|
|
352
349
|
const callback = this.#resolveSlot(propOf(occurrence));
|
|
353
350
|
if (!callback) continue;
|
|
@@ -360,11 +357,12 @@ class FrameImpl {
|
|
|
360
357
|
this.#runSlotCleanups(occurrence);
|
|
361
358
|
}
|
|
362
359
|
if (!this.#mountedSlots.has(occurrence)) {
|
|
360
|
+
if (this.#options.adopt) this.#discoverRegions(occurrence, start);
|
|
363
361
|
const nodes = this.#invokeSlot(occurrence, callback, record, start, this.#options.adopt);
|
|
364
362
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
365
363
|
this.#slotNodes.set(occurrence, nodes);
|
|
366
364
|
this.#mountedSlots.add(occurrence);
|
|
367
|
-
this.#discoverRegions(occurrence, start);
|
|
365
|
+
if (!this.#options.adopt || nodes) this.#discoverRegions(occurrence, start);
|
|
368
366
|
this.#bindRegions(occurrence);
|
|
369
367
|
} else if (record !== this.#slotArgs.get(occurrence)) {
|
|
370
368
|
if (this.#refArgsUnchanged(occurrence, record)) {
|
|
@@ -377,8 +375,10 @@ class FrameImpl {
|
|
|
377
375
|
this.#bindRegions(occurrence);
|
|
378
376
|
}
|
|
379
377
|
}
|
|
380
|
-
|
|
381
|
-
|
|
378
|
+
if (!root) {
|
|
379
|
+
for (const occurrence of [...this.#mountedSlots]) {
|
|
380
|
+
if (!found.has(occurrence)) this.#unmountSlot(occurrence);
|
|
381
|
+
}
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
#invokeSlot(occurrence, callback, record, start, adopted) {
|
|
@@ -391,6 +391,13 @@ class FrameImpl {
|
|
|
391
391
|
existing: start ? rangeInterior(start, slotEnd(occurrence)) : []
|
|
392
392
|
};
|
|
393
393
|
const props = record && record.kind === "slot" ? this.#resolveArgs(occurrence, record.args) : {};
|
|
394
|
+
const regions = this.#slotRegions.get(occurrence);
|
|
395
|
+
if (regions) {
|
|
396
|
+
for (const entry of regions.values()) {
|
|
397
|
+
const argKey = entry.childId.slice(entry.childId.lastIndexOf(".") + 1);
|
|
398
|
+
if (!(argKey in props)) props[argKey] = entry.element;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
394
401
|
const content = callback(props, ctx);
|
|
395
402
|
this.#slotArgs.set(occurrence, record);
|
|
396
403
|
if (cleanups.length) this.#slotCleanups.set(occurrence, cleanups);
|
|
@@ -413,7 +420,7 @@ class FrameImpl {
|
|
|
413
420
|
this.#slotNodes.delete(key);
|
|
414
421
|
this.#slotArgs.delete(key);
|
|
415
422
|
this.#slotResolvedRefs.delete(key);
|
|
416
|
-
|
|
423
|
+
this.#removeSlotRecord(key);
|
|
417
424
|
this.#runSlotCleanups(key);
|
|
418
425
|
const regions = this.#slotRegions.get(key);
|
|
419
426
|
if (regions) {
|
|
@@ -447,29 +454,17 @@ class FrameImpl {
|
|
|
447
454
|
cache[key] = resolved;
|
|
448
455
|
props[key] = resolved;
|
|
449
456
|
} else if (isFrameRef(value)) {
|
|
450
|
-
const fragment = document.createDocumentFragment();
|
|
451
457
|
let entry = regions.get(value.$frame);
|
|
452
458
|
if (!entry) {
|
|
453
|
-
const
|
|
454
|
-
const end = document.createComment(`frame:${value.$frame}:end`);
|
|
459
|
+
const element = makeFrameElement(value.$frame);
|
|
455
460
|
entry = {
|
|
456
461
|
childId: value.$frame,
|
|
457
|
-
|
|
458
|
-
end,
|
|
462
|
+
element,
|
|
459
463
|
frame: undefined
|
|
460
464
|
};
|
|
461
465
|
regions.set(value.$frame, entry);
|
|
462
|
-
fragment.append(start, end);
|
|
463
|
-
} else {
|
|
464
|
-
let n = entry.start;
|
|
465
|
-
while (n) {
|
|
466
|
-
const next = n.nextSibling;
|
|
467
|
-
fragment.append(n);
|
|
468
|
-
if (n === entry.end) break;
|
|
469
|
-
n = next;
|
|
470
|
-
}
|
|
471
466
|
}
|
|
472
|
-
props[key] =
|
|
467
|
+
props[key] = entry.element;
|
|
473
468
|
} else {
|
|
474
469
|
props[key] = value;
|
|
475
470
|
}
|
|
@@ -483,49 +478,12 @@ class FrameImpl {
|
|
|
483
478
|
regions = new Map();
|
|
484
479
|
this.#slotRegions.set(slotKey, regions);
|
|
485
480
|
}
|
|
486
|
-
const doc = start.ownerDocument;
|
|
487
481
|
const endData = slotEnd(slotKey);
|
|
488
|
-
const comments = [];
|
|
489
482
|
let n = start.nextSibling;
|
|
490
483
|
while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
|
|
491
|
-
|
|
492
|
-
const walker = doc.createTreeWalker(n, 128 );
|
|
493
|
-
let c;
|
|
494
|
-
while (c = walker.nextNode()) comments.push(c);
|
|
495
|
-
}
|
|
484
|
+
collectRegionElements(n, regions);
|
|
496
485
|
n = n.nextSibling;
|
|
497
486
|
}
|
|
498
|
-
let depth = 0;
|
|
499
|
-
let openId = null;
|
|
500
|
-
let openStart = null;
|
|
501
|
-
for (const c of comments) {
|
|
502
|
-
const data = c.data;
|
|
503
|
-
if (!data.startsWith("frame:")) continue;
|
|
504
|
-
if (data.endsWith(":start")) {
|
|
505
|
-
const childId = data.slice(6, -6);
|
|
506
|
-
if (!childId) continue;
|
|
507
|
-
if (depth === 0) {
|
|
508
|
-
openId = childId;
|
|
509
|
-
openStart = c;
|
|
510
|
-
}
|
|
511
|
-
depth++;
|
|
512
|
-
} else if (data.endsWith(":end")) {
|
|
513
|
-
const childId = data.slice(6, -4);
|
|
514
|
-
if (!childId) continue;
|
|
515
|
-
if (depth > 0) {
|
|
516
|
-
depth--;
|
|
517
|
-
if (depth === 0 && childId === openId && !regions.has(openId)) {
|
|
518
|
-
regions.set(openId, {
|
|
519
|
-
childId: openId,
|
|
520
|
-
start: openStart,
|
|
521
|
-
end: c,
|
|
522
|
-
frame: undefined,
|
|
523
|
-
adopt: true
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
487
|
}
|
|
530
488
|
#refArgsUnchanged(occurrence, record) {
|
|
531
489
|
const old = this.#slotArgs.get(occurrence);
|
|
@@ -569,15 +527,16 @@ class FrameImpl {
|
|
|
569
527
|
const regions = this.#slotRegions.get(slotKey);
|
|
570
528
|
if (!regions) return;
|
|
571
529
|
for (const entry of regions.values()) {
|
|
572
|
-
if (!entry.frame
|
|
573
|
-
entry.frame = new FrameImpl(
|
|
530
|
+
if (!entry.frame) {
|
|
531
|
+
entry.frame = new FrameImpl(entry.element, null, null, {
|
|
574
532
|
id: entry.childId,
|
|
575
533
|
host: this.#options.host,
|
|
576
534
|
adopt: entry.adopt,
|
|
577
535
|
claimScope: this.#options.claimScope ?? this.#options.id,
|
|
578
536
|
ownerScope: this.#options.ownerScope,
|
|
579
537
|
resolveSlot: prop => this.#resolveSlot(prop),
|
|
580
|
-
resolveSlotRecord: occurrence => this.#resolveSlotRecord(occurrence)
|
|
538
|
+
resolveSlotRecord: occurrence => this.#resolveSlotRecord(occurrence),
|
|
539
|
+
removeSlotRecord: occurrence => this.#removeSlotRecord(occurrence)
|
|
581
540
|
});
|
|
582
541
|
}
|
|
583
542
|
}
|
|
@@ -592,12 +551,7 @@ class FrameImpl {
|
|
|
592
551
|
n = afterRange(n, id);
|
|
593
552
|
continue;
|
|
594
553
|
}
|
|
595
|
-
|
|
596
|
-
if (regionId !== null) {
|
|
597
|
-
n = afterFrameRegion(n, regionId);
|
|
598
|
-
continue;
|
|
599
|
-
}
|
|
600
|
-
if (n.nodeType === ELEMENT_NODE) collectSlots(n, found);
|
|
554
|
+
if (n.nodeType === ELEMENT_NODE && !isFrameElement(n)) collectSlots(n, found);
|
|
601
555
|
n = n.nextSibling;
|
|
602
556
|
}
|
|
603
557
|
}
|
|
@@ -619,6 +573,7 @@ class FrameImpl {
|
|
|
619
573
|
if (this.#disposed) return;
|
|
620
574
|
this.#disposed = true;
|
|
621
575
|
for (const key of [...this.#slotCleanups.keys()]) this.#runSlotCleanups(key);
|
|
576
|
+
for (const key of this.#mountedSlots) this.#removeSlotRecord(key);
|
|
622
577
|
for (const regions of this.#slotRegions.values()) {
|
|
623
578
|
for (const {
|
|
624
579
|
frame
|
|
@@ -664,13 +619,7 @@ class FrameImpl {
|
|
|
664
619
|
}
|
|
665
620
|
#segmentReady(name) {
|
|
666
621
|
const content = this.#store[`seg:${name}`];
|
|
667
|
-
if (!content) return false;
|
|
668
|
-
if (content.kind === "block") {
|
|
669
|
-
const template = this.#store[content.template];
|
|
670
|
-
if (!template || template.kind !== "template") return false;
|
|
671
|
-
} else if (content.kind !== "html") {
|
|
672
|
-
return false;
|
|
673
|
-
}
|
|
622
|
+
if (!content || content.kind !== "html") return false;
|
|
674
623
|
if (!this.#store[`seg:${name}:reveal`]) return false;
|
|
675
624
|
const assets = this.#store[`seg:${name}:assets`];
|
|
676
625
|
if (assets && assets.styles) {
|
|
@@ -697,6 +646,23 @@ class FrameImpl {
|
|
|
697
646
|
parent.removeChild(n);
|
|
698
647
|
n = next;
|
|
699
648
|
}
|
|
649
|
+
if (this.#options.reveal) {
|
|
650
|
+
const fallbackFrag = tpl.content.cloneNode(true);
|
|
651
|
+
this.#claimTree(fallbackFrag);
|
|
652
|
+
this.#options.reveal({
|
|
653
|
+
before: closing,
|
|
654
|
+
fallback: [...fallbackFrag.childNodes],
|
|
655
|
+
content: () => {
|
|
656
|
+
const materialized = this.#materialize(content);
|
|
657
|
+
this.#syncSlots(materialized);
|
|
658
|
+
this.#claimTree(materialized);
|
|
659
|
+
return materialized;
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
tpl.remove();
|
|
663
|
+
this.#revealed.add(name);
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
700
666
|
const materialized = this.#materialize(content);
|
|
701
667
|
this.#claimTree(materialized);
|
|
702
668
|
parent.insertBefore(materialized, closing);
|
|
@@ -715,70 +681,37 @@ class FrameImpl {
|
|
|
715
681
|
return true;
|
|
716
682
|
}
|
|
717
683
|
#materialize(record) {
|
|
718
|
-
|
|
719
|
-
if (record.kind === "block") {
|
|
720
|
-
const template = this.#store[record.template];
|
|
721
|
-
if (!template || template.kind !== "template") return parseFragment("");
|
|
722
|
-
return materializeBlock(template, record.values);
|
|
723
|
-
}
|
|
724
|
-
return parseFragment("");
|
|
684
|
+
return record.kind === "html" ? parseFragment(record.value) : parseFragment("");
|
|
725
685
|
}
|
|
726
686
|
}
|
|
727
|
-
function materializeBlock(template, values) {
|
|
728
|
-
const fragment = parseFragment(template.html);
|
|
729
|
-
for (let i = 0; i < template.fields.length; i++) {
|
|
730
|
-
const marker = `field:${template.fields[i]}`;
|
|
731
|
-
const value = values[i] == null ? "" : String(values[i]);
|
|
732
|
-
let hole = findComment(fragment, marker);
|
|
733
|
-
while (hole) {
|
|
734
|
-
hole.replaceWith(document.createTextNode(value));
|
|
735
|
-
hole = findComment(fragment, marker);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
return fragment;
|
|
739
|
-
}
|
|
740
687
|
function createFrame(boundary, options) {
|
|
741
688
|
return new FrameImpl(boundary, null, null, options);
|
|
742
689
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
}
|
|
749
|
-
const FRAME = Symbol.for("dom-expressions.frame");
|
|
750
|
-
function createFrameInsertable(options) {
|
|
751
|
-
let frame = null;
|
|
752
|
-
let start = null;
|
|
753
|
-
let end = null;
|
|
690
|
+
const FRAME_TAG = "dx-frame";
|
|
691
|
+
const FRAME_ID_ATTR = "data-fid";
|
|
692
|
+
function createFrameElement(options) {
|
|
693
|
+
const el = makeFrameElement(options.id);
|
|
694
|
+
const frame = new FrameImpl(el, null, null, options);
|
|
754
695
|
return {
|
|
696
|
+
element: el,
|
|
755
697
|
get frame() {
|
|
756
698
|
return frame;
|
|
757
699
|
},
|
|
758
700
|
dispose() {
|
|
759
|
-
if (!frame) return;
|
|
760
701
|
frame.dispose();
|
|
761
|
-
|
|
762
|
-
const parent = start.parentNode;
|
|
763
|
-
if (!parent) return;
|
|
764
|
-
let n = start;
|
|
765
|
-
while (n) {
|
|
766
|
-
const next = n.nextSibling;
|
|
767
|
-
parent.removeChild(n);
|
|
768
|
-
if (n === end) break;
|
|
769
|
-
n = next;
|
|
770
|
-
}
|
|
771
|
-
},
|
|
772
|
-
[FRAME](parent, marker) {
|
|
773
|
-
if (frame) return;
|
|
774
|
-
start = document.createComment("frame:start");
|
|
775
|
-
end = document.createComment("frame:end");
|
|
776
|
-
parent.insertBefore(start, marker);
|
|
777
|
-
parent.insertBefore(end, marker);
|
|
778
|
-
frame = new FrameImpl(null, start, end, options);
|
|
702
|
+
el.remove();
|
|
779
703
|
}
|
|
780
704
|
};
|
|
781
705
|
}
|
|
706
|
+
function makeFrameElement(id) {
|
|
707
|
+
const el = document.createElement(FRAME_TAG);
|
|
708
|
+
el.style.display = "contents";
|
|
709
|
+
if (id !== undefined) el.setAttribute(FRAME_ID_ATTR, id);
|
|
710
|
+
return el;
|
|
711
|
+
}
|
|
712
|
+
function isFrameElement(node) {
|
|
713
|
+
return node.nodeType === ELEMENT_NODE && node.hasAttribute(FRAME_ID_ATTR);
|
|
714
|
+
}
|
|
782
715
|
function segmentName(key) {
|
|
783
716
|
const m = /^seg:([^:]+)$/.exec(key);
|
|
784
717
|
return m ? m[1] : null;
|
|
@@ -877,29 +810,25 @@ function collectSlots(root, out) {
|
|
|
877
810
|
n = afterRange(n, id);
|
|
878
811
|
continue;
|
|
879
812
|
}
|
|
880
|
-
|
|
881
|
-
if (regionId !== null) {
|
|
882
|
-
n = afterFrameRegion(n, regionId);
|
|
883
|
-
continue;
|
|
884
|
-
}
|
|
885
|
-
if (n.nodeType === ELEMENT_NODE) collectSlots(n, out);
|
|
813
|
+
if (n.nodeType === ELEMENT_NODE && !isFrameElement(n)) collectSlots(n, out);
|
|
886
814
|
n = n.nextSibling;
|
|
887
815
|
}
|
|
888
816
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
if (node
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
817
|
+
function collectRegionElements(node, regions) {
|
|
818
|
+
if (node.nodeType !== ELEMENT_NODE) return;
|
|
819
|
+
if (isFrameElement(node)) {
|
|
820
|
+
const childId = node.getAttribute(FRAME_ID_ATTR);
|
|
821
|
+
if (childId && !regions.has(childId)) {
|
|
822
|
+
regions.set(childId, {
|
|
823
|
+
childId,
|
|
824
|
+
element: node,
|
|
825
|
+
frame: undefined,
|
|
826
|
+
adopt: true
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
return;
|
|
901
830
|
}
|
|
902
|
-
|
|
831
|
+
for (let c = node.firstChild; c; c = c.nextSibling) collectRegionElements(c, regions);
|
|
903
832
|
}
|
|
904
833
|
function argsEquivalent(a, b) {
|
|
905
834
|
if (a === b) return true;
|
|
@@ -927,18 +856,6 @@ function rangeInterior(start, endData) {
|
|
|
927
856
|
}
|
|
928
857
|
return nodes;
|
|
929
858
|
}
|
|
930
|
-
function findComment(root, data) {
|
|
931
|
-
const children = root.childNodes;
|
|
932
|
-
for (let i = 0; i < children.length; i++) {
|
|
933
|
-
const node = children[i];
|
|
934
|
-
if (node.nodeType === COMMENT_NODE && node.data === data) return node;
|
|
935
|
-
if (node.nodeType === ELEMENT_NODE) {
|
|
936
|
-
const found = findComment(node, data);
|
|
937
|
-
if (found) return found;
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
return null;
|
|
941
|
-
}
|
|
942
859
|
function slotStartId(node) {
|
|
943
860
|
if (node.nodeType !== COMMENT_NODE) return null;
|
|
944
861
|
const m = SLOT_START.exec(node.data);
|
|
@@ -954,12 +871,18 @@ function compatible(a, b) {
|
|
|
954
871
|
if (a.nodeType === ELEMENT_NODE) return a.nodeName === b.nodeName;
|
|
955
872
|
return a.nodeType === TEXT_NODE || a.nodeType === COMMENT_NODE;
|
|
956
873
|
}
|
|
874
|
+
function preservesOpen(el) {
|
|
875
|
+
const t = el.tagName;
|
|
876
|
+
return t === "DETAILS" || t === "DIALOG";
|
|
877
|
+
}
|
|
957
878
|
function morphAttributes(oldEl, newEl, claim) {
|
|
958
879
|
let reclaim = false;
|
|
959
880
|
let changed = false;
|
|
881
|
+
const keepOpen = preservesOpen(oldEl);
|
|
960
882
|
const oldAttrs = oldEl.attributes;
|
|
961
883
|
for (let i = oldAttrs.length - 1; i >= 0; i--) {
|
|
962
884
|
const name = oldAttrs[i].name;
|
|
885
|
+
if (keepOpen && name === "open") continue;
|
|
963
886
|
if (!newEl.hasAttribute(name)) {
|
|
964
887
|
oldEl.removeAttribute(name);
|
|
965
888
|
changed = true;
|
|
@@ -969,6 +892,7 @@ function morphAttributes(oldEl, newEl, claim) {
|
|
|
969
892
|
const newAttrs = newEl.attributes;
|
|
970
893
|
for (let i = 0; i < newAttrs.length; i++) {
|
|
971
894
|
const attr = newAttrs[i];
|
|
895
|
+
if (keepOpen && attr.name === "open") continue;
|
|
972
896
|
if (oldEl.getAttribute(attr.name) !== attr.value) {
|
|
973
897
|
oldEl.setAttribute(attr.name, attr.value);
|
|
974
898
|
changed = true;
|
|
@@ -979,6 +903,7 @@ function morphAttributes(oldEl, newEl, claim) {
|
|
|
979
903
|
}
|
|
980
904
|
function morphNode(oldNode, newNode, claim) {
|
|
981
905
|
if (oldNode.nodeType === ELEMENT_NODE) {
|
|
906
|
+
if (oldNode.hasAttribute("data-preserve")) return;
|
|
982
907
|
morphAttributes(oldNode, newNode, claim);
|
|
983
908
|
reconcileChildren(oldNode, newNode, null, null, claim);
|
|
984
909
|
} else if (oldNode.data !== newNode.data) {
|
|
@@ -1163,15 +1088,15 @@ class ChunkReader {
|
|
|
1163
1088
|
}
|
|
1164
1089
|
}
|
|
1165
1090
|
async next() {
|
|
1166
|
-
|
|
1091
|
+
while (this.buffer.length < 12) {
|
|
1167
1092
|
if (this.done) {
|
|
1168
|
-
return {
|
|
1093
|
+
if (this.buffer.length === 0) return {
|
|
1169
1094
|
done: true,
|
|
1170
1095
|
value: undefined
|
|
1171
1096
|
};
|
|
1097
|
+
throw new Error("Malformed server function stream.");
|
|
1172
1098
|
}
|
|
1173
1099
|
await this.readChunk();
|
|
1174
|
-
return await this.next();
|
|
1175
1100
|
}
|
|
1176
1101
|
const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
|
|
1177
1102
|
const bytes = Number.parseInt(head, 16);
|
|
@@ -1309,15 +1234,18 @@ function normalizeSlotContent(value) {
|
|
|
1309
1234
|
if (value == null || typeof value === "boolean") return document.createTextNode("");
|
|
1310
1235
|
return value instanceof Node ? value : document.createTextNode(String(value));
|
|
1311
1236
|
}
|
|
1237
|
+
function gatherClaims(el, registry) {
|
|
1238
|
+
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1239
|
+
if (el.hasAttribute(FRAME_ID_ATTR)) return;
|
|
1240
|
+
for (let c = el.firstElementChild; c; c = c.nextElementSibling) gatherClaims(c, registry);
|
|
1241
|
+
}
|
|
1312
1242
|
function claimRender(prefix, existing, render) {
|
|
1313
1243
|
const sc = solidJs.sharedConfig;
|
|
1314
1244
|
if (!sc.getNextContextId) return render();
|
|
1315
1245
|
const registry = new Map();
|
|
1316
1246
|
for (const n of existing) {
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
if (el.hasAttribute("_hk")) registry.set(el.getAttribute("_hk"), el);
|
|
1320
|
-
el.querySelectorAll("*[_hk]").forEach(child => registry.set(child.getAttribute("_hk"), child));
|
|
1247
|
+
if (n.nodeType !== 1) continue;
|
|
1248
|
+
gatherClaims(n, registry);
|
|
1321
1249
|
}
|
|
1322
1250
|
if (!registry.size) return render();
|
|
1323
1251
|
const prevRegistry = sc.registry;
|
|
@@ -1359,50 +1287,80 @@ function slotsFor(props) {
|
|
|
1359
1287
|
}
|
|
1360
1288
|
});
|
|
1361
1289
|
}
|
|
1290
|
+
function revealSeam(owner) {
|
|
1291
|
+
return seam => solidJs.runWithOwner(owner, () => web$1.insert(seam.before.parentNode, solidJs.createLoadingBoundary(() => seam.content(), () => seam.fallback), seam.before));
|
|
1292
|
+
}
|
|
1362
1293
|
function boundaryComponent(host, id) {
|
|
1363
1294
|
return props => {
|
|
1364
1295
|
const owner = solidJs.getOwner();
|
|
1365
|
-
const
|
|
1296
|
+
const {
|
|
1297
|
+
element,
|
|
1298
|
+
dispose
|
|
1299
|
+
} = createFrameElement({
|
|
1366
1300
|
host,
|
|
1367
1301
|
id,
|
|
1368
1302
|
slots: slotsFor(props),
|
|
1369
|
-
ownerScope: fn => solidJs.runWithOwner(owner, fn)
|
|
1303
|
+
ownerScope: fn => solidJs.runWithOwner(owner, fn),
|
|
1304
|
+
reveal: revealSeam(owner)
|
|
1370
1305
|
});
|
|
1371
|
-
solidJs.onCleanup(
|
|
1372
|
-
return
|
|
1306
|
+
solidJs.onCleanup(dispose);
|
|
1307
|
+
return element;
|
|
1373
1308
|
};
|
|
1374
1309
|
}
|
|
1375
1310
|
const claimedBoundaries = new Set();
|
|
1376
1311
|
let boundaryIndex = null;
|
|
1377
|
-
|
|
1312
|
+
const isBoundaryId = id => !id.includes(".");
|
|
1313
|
+
function indexBoundaries(root) {
|
|
1314
|
+
root.querySelectorAll(`[${FRAME_ID_ATTR}]`).forEach(el => {
|
|
1315
|
+
const key = el.getAttribute(FRAME_ID_ATTR);
|
|
1316
|
+
if (key && isBoundaryId(key) && !boundaryIndex.has(key)) boundaryIndex.set(key, el);
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
function findBoundaryElement(id) {
|
|
1378
1320
|
if (!boundaryIndex) {
|
|
1379
1321
|
boundaryIndex = new Map();
|
|
1380
|
-
if (typeof document !== "undefined" && document.body)
|
|
1381
|
-
const walker = document.createTreeWalker(document.body, 128 );
|
|
1382
|
-
const opens = {};
|
|
1383
|
-
let c;
|
|
1384
|
-
while (c = walker.nextNode()) {
|
|
1385
|
-
const d = c.data;
|
|
1386
|
-
if (!d.startsWith("frame:")) continue;
|
|
1387
|
-
if (d.endsWith(":start")) {
|
|
1388
|
-
const key = d.slice(6, -6);
|
|
1389
|
-
if (key && !(key in opens)) opens[key] = c;
|
|
1390
|
-
} else if (d.endsWith(":end")) {
|
|
1391
|
-
const key = d.slice(6, -4);
|
|
1392
|
-
if (key && opens[key] && !boundaryIndex.has(key)) {
|
|
1393
|
-
boundaryIndex.set(key, [opens[key], c]);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1322
|
+
if (typeof document !== "undefined" && document.body) indexBoundaries(document.body);
|
|
1398
1323
|
}
|
|
1399
1324
|
return boundaryIndex.get(id);
|
|
1400
1325
|
}
|
|
1326
|
+
const boundaryWaiters = new Map();
|
|
1327
|
+
function documentStreaming() {
|
|
1328
|
+
const hy = globalThis._$HY;
|
|
1329
|
+
return !!hy && !hy.done;
|
|
1330
|
+
}
|
|
1331
|
+
function installRevealHook() {
|
|
1332
|
+
const hy = globalThis._$HY;
|
|
1333
|
+
if (!hy || hy.$sc) return;
|
|
1334
|
+
hy.$sc = true;
|
|
1335
|
+
const prev = hy.fe;
|
|
1336
|
+
hy.fe = (fragmentId, parent) => {
|
|
1337
|
+
if (prev) prev(fragmentId, parent);
|
|
1338
|
+
if (!boundaryIndex) return;
|
|
1339
|
+
const root = parent || (typeof document !== "undefined" ? document.body : null);
|
|
1340
|
+
if (!root) return;
|
|
1341
|
+
indexBoundaries(root);
|
|
1342
|
+
for (const [id, notify] of boundaryWaiters) {
|
|
1343
|
+
const el = boundaryIndex.get(id);
|
|
1344
|
+
if (!el) continue;
|
|
1345
|
+
boundaryWaiters.delete(id);
|
|
1346
|
+
notify(el);
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1401
1350
|
function documentBoundary(host, id, props) {
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1351
|
+
const claimed = claimedBoundaries.has(id);
|
|
1352
|
+
const el = !claimed ? findBoundaryElement(id) : undefined;
|
|
1353
|
+
if (el) return adoptBoundary(host, id, el, props);
|
|
1354
|
+
if (!claimed && !boundaryWaiters.has(id) && documentStreaming()) {
|
|
1355
|
+
const owner = solidJs.getOwner();
|
|
1356
|
+
const arrival = new Promise(resolve => boundaryWaiters.set(id, resolve));
|
|
1357
|
+
solidJs.onCleanup(() => boundaryWaiters.delete(id));
|
|
1358
|
+
return solidJs.createMemo(() => arrival.then(node => solidJs.runWithOwner(owner, () => adoptBoundary(host, id, node, props))));
|
|
1359
|
+
}
|
|
1360
|
+
return boundaryComponent(host, id)(props);
|
|
1361
|
+
}
|
|
1362
|
+
function adoptBoundary(host, id, el, props) {
|
|
1404
1363
|
claimedBoundaries.add(id);
|
|
1405
|
-
const [start, end] = range;
|
|
1406
1364
|
const hy = globalThis._$HY;
|
|
1407
1365
|
if (hy && hy.r) {
|
|
1408
1366
|
const slotPrefix = `sc:slot:${id}:`;
|
|
@@ -1431,19 +1389,16 @@ function documentBoundary(host, id, props) {
|
|
|
1431
1389
|
}
|
|
1432
1390
|
}
|
|
1433
1391
|
const owner = solidJs.getOwner();
|
|
1434
|
-
const frame =
|
|
1392
|
+
const frame = createFrame(el, {
|
|
1393
|
+
adopt: true,
|
|
1435
1394
|
host,
|
|
1436
1395
|
id,
|
|
1437
1396
|
slots: slotsFor(props),
|
|
1438
|
-
ownerScope: fn => solidJs.runWithOwner(owner, fn)
|
|
1397
|
+
ownerScope: fn => solidJs.runWithOwner(owner, fn),
|
|
1398
|
+
reveal: revealSeam(owner)
|
|
1439
1399
|
});
|
|
1440
1400
|
solidJs.onCleanup(() => frame.dispose());
|
|
1441
|
-
|
|
1442
|
-
for (let n = start; n; n = n.nextSibling) {
|
|
1443
|
-
nodes.push(n);
|
|
1444
|
-
if (n === end) break;
|
|
1445
|
-
}
|
|
1446
|
-
return nodes;
|
|
1401
|
+
return el;
|
|
1447
1402
|
}
|
|
1448
1403
|
function installServerComponents(host = getFrameHost()) {
|
|
1449
1404
|
const g = globalThis;
|
|
@@ -1456,6 +1411,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1456
1411
|
};
|
|
1457
1412
|
}
|
|
1458
1413
|
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1414
|
+
installRevealHook();
|
|
1459
1415
|
client.configureServerFunctionsClient({
|
|
1460
1416
|
responseHandler: createServerComponentHandler({
|
|
1461
1417
|
host,
|
|
@@ -1466,7 +1422,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1466
1422
|
intercept: ({
|
|
1467
1423
|
id
|
|
1468
1424
|
}) => {
|
|
1469
|
-
if (claimedBoundaries.has(id) || !
|
|
1425
|
+
if (claimedBoundaries.has(id) || !findBoundaryElement(id)) return undefined;
|
|
1470
1426
|
return g._$SC.r(id);
|
|
1471
1427
|
}
|
|
1472
1428
|
})
|
|
@@ -1477,8 +1433,8 @@ exports.FRAME_APPLIED_EVENT = FRAME_APPLIED_EVENT;
|
|
|
1477
1433
|
exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
|
|
1478
1434
|
exports.applyFrameResponse = applyFrameResponse;
|
|
1479
1435
|
exports.createFrame = createFrame;
|
|
1436
|
+
exports.createFrameElement = createFrameElement;
|
|
1480
1437
|
exports.createFrameHost = createFrameHost;
|
|
1481
|
-
exports.createFrameInsertable = createFrameInsertable;
|
|
1482
1438
|
exports.createJSONDataTable = createJSONDataTable;
|
|
1483
1439
|
exports.createServerComponentHandler = createServerComponentHandler;
|
|
1484
1440
|
exports.getFrameHost = getFrameHost;
|