@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
package/frames/dist/client.cjs
CHANGED
|
@@ -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;
|
|
@@ -686,12 +662,7 @@ class FrameImpl {
|
|
|
686
662
|
const content = this.#store[`seg:${name}`];
|
|
687
663
|
const closing = rangeClose(tpl, placeholderId(name));
|
|
688
664
|
const parent = tpl.parentNode;
|
|
689
|
-
|
|
690
|
-
while (n && n !== closing) {
|
|
691
|
-
const next = n.nextSibling;
|
|
692
|
-
parent.removeChild(n);
|
|
693
|
-
n = next;
|
|
694
|
-
}
|
|
665
|
+
removeUntil(parent, tpl.nextSibling, closing);
|
|
695
666
|
if (this.#options.reveal) {
|
|
696
667
|
const fallbackFrag = tpl.content.cloneNode(true);
|
|
697
668
|
this.#claimTree(fallbackFrag);
|
|
@@ -740,9 +711,7 @@ function createFrameElement(options) {
|
|
|
740
711
|
const frame = new FrameImpl(el, null, null, options);
|
|
741
712
|
return {
|
|
742
713
|
element: el,
|
|
743
|
-
|
|
744
|
-
return frame;
|
|
745
|
-
},
|
|
714
|
+
frame,
|
|
746
715
|
dispose() {
|
|
747
716
|
frame.dispose();
|
|
748
717
|
el.remove();
|
|
@@ -762,15 +731,30 @@ function segmentName(key) {
|
|
|
762
731
|
const m = /^seg:([^:]+)$/.exec(key);
|
|
763
732
|
return m ? m[1] : null;
|
|
764
733
|
}
|
|
734
|
+
function isAsyncLike(v) {
|
|
735
|
+
return !!v && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
736
|
+
}
|
|
765
737
|
function propOf(occurrence) {
|
|
766
738
|
const hash = occurrence.indexOf("#");
|
|
767
739
|
return hash === -1 ? occurrence : occurrence.slice(0, hash);
|
|
768
740
|
}
|
|
769
741
|
function isDataRef(value) {
|
|
770
|
-
return
|
|
742
|
+
return !!value && typeof value.$ref === "string";
|
|
771
743
|
}
|
|
772
744
|
function isFrameRef(value) {
|
|
773
|
-
return
|
|
745
|
+
return !!value && typeof value.$frame === "string";
|
|
746
|
+
}
|
|
747
|
+
function disposeRegions(regions) {
|
|
748
|
+
for (const {
|
|
749
|
+
frame
|
|
750
|
+
} of regions.values()) frame?.dispose();
|
|
751
|
+
}
|
|
752
|
+
function removeUntil(parent, n, stop) {
|
|
753
|
+
while (n && n !== stop) {
|
|
754
|
+
const next = n.nextSibling;
|
|
755
|
+
parent.removeChild(n);
|
|
756
|
+
n = next;
|
|
757
|
+
}
|
|
774
758
|
}
|
|
775
759
|
function parseFragment(html) {
|
|
776
760
|
const template = document.createElement("template");
|
|
@@ -778,9 +762,8 @@ function parseFragment(html) {
|
|
|
778
762
|
return template.content;
|
|
779
763
|
}
|
|
780
764
|
function findHeadElement(selector, attr, value) {
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
if (nodes[i].getAttribute(attr) === value) return nodes[i];
|
|
765
|
+
for (const node of document.head.querySelectorAll(selector)) {
|
|
766
|
+
if (node.getAttribute(attr) === value) return node;
|
|
784
767
|
}
|
|
785
768
|
return null;
|
|
786
769
|
}
|
|
@@ -829,7 +812,7 @@ function applyInlineStyles(inlineStyles) {
|
|
|
829
812
|
}
|
|
830
813
|
}
|
|
831
814
|
function isPlaceholderStart(node, id) {
|
|
832
|
-
return node.
|
|
815
|
+
return node.tagName === "TEMPLATE" && node.id === id;
|
|
833
816
|
}
|
|
834
817
|
function rangeClose(start, id) {
|
|
835
818
|
let n = start.nextSibling;
|
|
@@ -885,6 +868,21 @@ function renameRegion(entry, childId) {
|
|
|
885
868
|
entry.childId = childId;
|
|
886
869
|
if (entry.frame) entry.frame.rebind(childId);else entry.element.setAttribute(FRAME_ID_ATTR, childId);
|
|
887
870
|
}
|
|
871
|
+
function eachInRange(start, key, cb) {
|
|
872
|
+
const end = slotEnd(key);
|
|
873
|
+
let n = start.nextSibling;
|
|
874
|
+
while (n && !(n.nodeType === COMMENT_NODE && n.data === end)) {
|
|
875
|
+
const next = n.nextSibling;
|
|
876
|
+
cb(n);
|
|
877
|
+
n = next;
|
|
878
|
+
}
|
|
879
|
+
return n;
|
|
880
|
+
}
|
|
881
|
+
function clearStreamRecords(records, root) {
|
|
882
|
+
for (const key in records) {
|
|
883
|
+
if (key.startsWith("seg:") || key === ":error" || root && key === "") delete records[key];
|
|
884
|
+
}
|
|
885
|
+
}
|
|
888
886
|
function argsEquivalent(a, b) {
|
|
889
887
|
if (a === b) return true;
|
|
890
888
|
if (!a || !b) return false;
|
|
@@ -895,9 +893,7 @@ function argsEquivalent(a, b) {
|
|
|
895
893
|
const va = a[key];
|
|
896
894
|
const vb = b[key];
|
|
897
895
|
if (va === vb) continue;
|
|
898
|
-
if (va &&
|
|
899
|
-
continue;
|
|
900
|
-
}
|
|
896
|
+
if (isFrameRef(va) && va.$frame === vb?.$frame) continue;
|
|
901
897
|
return false;
|
|
902
898
|
}
|
|
903
899
|
return true;
|
|
@@ -1260,7 +1256,7 @@ function createServerComponentHandler({
|
|
|
1260
1256
|
showing(address, functionId) {
|
|
1261
1257
|
bindingFor(address, functionId);
|
|
1262
1258
|
const comp = componentFor(functionId);
|
|
1263
|
-
if ((typeof comp === "function" || typeof comp === "object"
|
|
1259
|
+
if (comp && (typeof comp === "function" || typeof comp === "object") && !comp[COMPONENT_BINDING]) {
|
|
1264
1260
|
comp[COMPONENT_BINDING] = {
|
|
1265
1261
|
component: comp,
|
|
1266
1262
|
address
|
|
@@ -1352,6 +1348,9 @@ function createJSONDataTable(options) {
|
|
|
1352
1348
|
};
|
|
1353
1349
|
}
|
|
1354
1350
|
|
|
1351
|
+
function asyncArg(value) {
|
|
1352
|
+
return value;
|
|
1353
|
+
}
|
|
1355
1354
|
let sharedHost;
|
|
1356
1355
|
const tables = new Map();
|
|
1357
1356
|
function tableFor(id) {
|
|
@@ -1428,8 +1427,26 @@ function claimRender(prefix, existing, render) {
|
|
|
1428
1427
|
function liveSlotProps(initial, ctx) {
|
|
1429
1428
|
const [args, setArgs] = solidJs.createSignal(initial);
|
|
1430
1429
|
ctx.onUpdate(next => setArgs(() => next));
|
|
1430
|
+
return slotArgsProxy(args);
|
|
1431
|
+
}
|
|
1432
|
+
function isAsyncValue(v) {
|
|
1433
|
+
return v !== null && typeof v === "object" && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
1434
|
+
}
|
|
1435
|
+
function slotArgsProxy(args) {
|
|
1436
|
+
const owner = solidJs.getOwner();
|
|
1437
|
+
const asyncReads = new Map();
|
|
1431
1438
|
return new Proxy({}, {
|
|
1432
|
-
get: (_, key) =>
|
|
1439
|
+
get: (_, key) => {
|
|
1440
|
+
const v = args()[key];
|
|
1441
|
+
if (!isAsyncValue(v)) return v;
|
|
1442
|
+
let read = asyncReads.get(key);
|
|
1443
|
+
if (!read) {
|
|
1444
|
+
const make = () => solidJs.createMemo(() => args()[key]);
|
|
1445
|
+
read = owner ? solidJs.runWithOwner(owner, make) : make();
|
|
1446
|
+
asyncReads.set(key, read);
|
|
1447
|
+
}
|
|
1448
|
+
return read();
|
|
1449
|
+
},
|
|
1433
1450
|
has: (_, key) => key in args(),
|
|
1434
1451
|
ownKeys: () => Reflect.ownKeys(args()),
|
|
1435
1452
|
getOwnPropertyDescriptor: (_, key) => key in args() ? {
|
|
@@ -1447,6 +1464,7 @@ function isReactiveContent(value) {
|
|
|
1447
1464
|
}
|
|
1448
1465
|
function slotsFor(props) {
|
|
1449
1466
|
const bindings = new Map();
|
|
1467
|
+
const fillScopes = new Map();
|
|
1450
1468
|
return new Proxy({}, {
|
|
1451
1469
|
get(_, prop) {
|
|
1452
1470
|
if (typeof prop !== "string" || !(prop in props)) return undefined;
|
|
@@ -1457,6 +1475,19 @@ function slotsFor(props) {
|
|
|
1457
1475
|
bindings.delete(key);
|
|
1458
1476
|
prev.dispose();
|
|
1459
1477
|
}
|
|
1478
|
+
const prevFill = key !== undefined && fillScopes.get(key);
|
|
1479
|
+
if (prevFill) {
|
|
1480
|
+
fillScopes.delete(key);
|
|
1481
|
+
prevFill.dispose();
|
|
1482
|
+
}
|
|
1483
|
+
const fillOwner = streamInvoke ? solidJs.createOwner() : null;
|
|
1484
|
+
if (fillOwner && key !== undefined && ctx) {
|
|
1485
|
+
fillScopes.set(key, fillOwner);
|
|
1486
|
+
ctx.onCleanup(() => {
|
|
1487
|
+
if (fillScopes.get(key) === fillOwner) fillScopes.delete(key);
|
|
1488
|
+
fillOwner.dispose();
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1460
1491
|
const settle = out => {
|
|
1461
1492
|
const existing = ctx && ctx.existing || [];
|
|
1462
1493
|
if (existing.length) {
|
|
@@ -1469,13 +1500,13 @@ function slotsFor(props) {
|
|
|
1469
1500
|
const evaluate = () => {
|
|
1470
1501
|
const v = props[prop];
|
|
1471
1502
|
if (typeof v === "function" && ctx && ctx.invoked) {
|
|
1472
|
-
return v(ctx.onUpdate ? liveSlotProps(slotProps, ctx) : slotProps);
|
|
1503
|
+
return v(ctx.onUpdate ? liveSlotProps(slotProps, ctx) : slotArgsProxy(() => slotProps));
|
|
1473
1504
|
}
|
|
1474
1505
|
return v;
|
|
1475
1506
|
};
|
|
1476
1507
|
const adopted = !!(ctx && ctx.frame && ctx.adopted && ctx.existing && ctx.existing.length);
|
|
1477
1508
|
const prefix = ctx && ctx.frame ? `sc-${ctx.frame}-${ctx.key}-` : "";
|
|
1478
|
-
const value = adopted ? claimRender(prefix, ctx.existing, evaluate) : evaluate();
|
|
1509
|
+
const value = fillOwner ? solidJs.runWithOwner(fillOwner, () => adopted ? claimRender(prefix, ctx.existing, evaluate) : evaluate()) : adopted ? claimRender(prefix, ctx.existing, evaluate) : evaluate();
|
|
1479
1510
|
if (!isReactiveContent(value)) {
|
|
1480
1511
|
return settle(normalizeSlotContent(value));
|
|
1481
1512
|
}
|
|
@@ -1500,29 +1531,61 @@ function slotsFor(props) {
|
|
|
1500
1531
|
function revealSeam(owner) {
|
|
1501
1532
|
return seam => solidJs.runWithOwner(owner, () => web$1.insert(seam.before.parentNode, solidJs.createLoadingBoundary(() => seam.content(), () => seam.fallback), seam.before));
|
|
1502
1533
|
}
|
|
1534
|
+
let streamInvoke = false;
|
|
1503
1535
|
function boundaryScope(owner) {
|
|
1504
|
-
return fn =>
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1536
|
+
return fn => {
|
|
1537
|
+
if (solidJs.getOwner()) return fn();
|
|
1538
|
+
streamInvoke = true;
|
|
1539
|
+
try {
|
|
1540
|
+
return solidJs.runWithOwner(owner, fn);
|
|
1541
|
+
} finally {
|
|
1542
|
+
streamInvoke = false;
|
|
1543
|
+
}
|
|
1544
|
+
};
|
|
1508
1545
|
}
|
|
1509
1546
|
function boundaryComponent(host, fnId) {
|
|
1510
1547
|
return (props, binding) => {
|
|
1511
1548
|
const owner = solidJs.getOwner();
|
|
1549
|
+
const id = binding ? binding() : fnId;
|
|
1550
|
+
let applied = !tables.has(id);
|
|
1551
|
+
let release;
|
|
1552
|
+
const arm = () => new Promise(r => release = r);
|
|
1553
|
+
const mountGate = applied ? undefined : arm();
|
|
1554
|
+
let setGate;
|
|
1512
1555
|
const {
|
|
1513
1556
|
element,
|
|
1514
1557
|
frame,
|
|
1515
1558
|
dispose
|
|
1516
1559
|
} = createFrameElement({
|
|
1517
1560
|
host,
|
|
1518
|
-
id
|
|
1561
|
+
id,
|
|
1519
1562
|
slots: slotsFor(props),
|
|
1520
1563
|
ownerScope: boundaryScope(owner),
|
|
1521
|
-
reveal: revealSeam(owner)
|
|
1564
|
+
reveal: revealSeam(owner),
|
|
1565
|
+
onApply: () => {
|
|
1566
|
+
applied = true;
|
|
1567
|
+
if (release) {
|
|
1568
|
+
release();
|
|
1569
|
+
release = undefined;
|
|
1570
|
+
}
|
|
1571
|
+
setGate && setGate(undefined);
|
|
1572
|
+
}
|
|
1522
1573
|
});
|
|
1523
|
-
|
|
1574
|
+
const [gatePromise, setGatePromise] = solidJs.createSignal(applied ? undefined : mountGate);
|
|
1575
|
+
setGate = setGatePromise;
|
|
1576
|
+
if (binding) {
|
|
1577
|
+
solidJs.createRenderEffect(binding, (address, prev) => {
|
|
1578
|
+
if (prev !== undefined && address !== prev && tables.has(address)) {
|
|
1579
|
+
applied = false;
|
|
1580
|
+
setGatePromise(arm());
|
|
1581
|
+
}
|
|
1582
|
+
frame.rebind(address);
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1524
1585
|
solidJs.onCleanup(dispose);
|
|
1525
|
-
return element;
|
|
1586
|
+
if (applied && !binding) return element;
|
|
1587
|
+
const gate = solidJs.createMemo(() => gatePromise());
|
|
1588
|
+
return solidJs.createMemo(() => (gate(), element));
|
|
1526
1589
|
};
|
|
1527
1590
|
}
|
|
1528
1591
|
const claimedBoundaries = new Set();
|
|
@@ -1590,6 +1653,17 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1590
1653
|
claimedBoundaries.add(id);
|
|
1591
1654
|
const address = binding ? binding() : documentAddress(id);
|
|
1592
1655
|
const appliedRecords = new Set();
|
|
1656
|
+
const claimedFragments = new Set();
|
|
1657
|
+
const claimRegionFragments = root => {
|
|
1658
|
+
const fr = globalThis._$HY?.fr;
|
|
1659
|
+
if (!fr || !fr.claim) return;
|
|
1660
|
+
root.querySelectorAll('template[id^="pl-"]').forEach(tpl => {
|
|
1661
|
+
const fragId = tpl.id.slice(3);
|
|
1662
|
+
if (claimedFragments.has(fragId)) return;
|
|
1663
|
+
claimedFragments.add(fragId);
|
|
1664
|
+
fr.claim(fragId);
|
|
1665
|
+
});
|
|
1666
|
+
};
|
|
1593
1667
|
const drainRecords = () => {
|
|
1594
1668
|
const hy = globalThis._$HY;
|
|
1595
1669
|
if (!hy || !hy.r) return;
|
|
@@ -1621,8 +1695,20 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1621
1695
|
}
|
|
1622
1696
|
}
|
|
1623
1697
|
};
|
|
1698
|
+
claimRegionFragments(el);
|
|
1699
|
+
const fr = globalThis._$HY?.fr;
|
|
1700
|
+
const unsubscribe = fr ? fr.subscribe((_fragId, parent) => {
|
|
1701
|
+
if (fr.claim && parent && el.contains(parent)) claimRegionFragments(parent);
|
|
1702
|
+
drainRecords();
|
|
1703
|
+
}) : undefined;
|
|
1704
|
+
solidJs.onCleanup(() => {
|
|
1705
|
+
unsubscribe && unsubscribe();
|
|
1706
|
+
if (fr && fr.release) for (const fragId of claimedFragments) fr.release(fragId);
|
|
1707
|
+
});
|
|
1624
1708
|
drainRecords();
|
|
1625
1709
|
const owner = solidJs.getOwner();
|
|
1710
|
+
let release;
|
|
1711
|
+
let setGate;
|
|
1626
1712
|
const frame = createFrame(el, {
|
|
1627
1713
|
adopt: true,
|
|
1628
1714
|
host,
|
|
@@ -1630,6 +1716,13 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1630
1716
|
slots: slotsFor(props),
|
|
1631
1717
|
ownerScope: boundaryScope(owner),
|
|
1632
1718
|
reveal: revealSeam(owner),
|
|
1719
|
+
onApply: () => {
|
|
1720
|
+
if (release) {
|
|
1721
|
+
release();
|
|
1722
|
+
release = undefined;
|
|
1723
|
+
}
|
|
1724
|
+
setGate && setGate(undefined);
|
|
1725
|
+
},
|
|
1633
1726
|
...{
|
|
1634
1727
|
recordsPending: () => {
|
|
1635
1728
|
if (document.readyState === "loading") return true;
|
|
@@ -1640,7 +1733,19 @@ function adoptBoundary(host, id, el, props, binding) {
|
|
|
1640
1733
|
claimScope: id
|
|
1641
1734
|
}
|
|
1642
1735
|
});
|
|
1643
|
-
if (binding)
|
|
1736
|
+
if (binding) {
|
|
1737
|
+
const arm = () => new Promise(r => release = r);
|
|
1738
|
+
const [gatePromise, setGatePromise] = solidJs.createSignal(undefined);
|
|
1739
|
+
setGate = setGatePromise;
|
|
1740
|
+
const gate = solidJs.createMemo(() => gatePromise());
|
|
1741
|
+
solidJs.createRenderEffect(binding, (address, prev) => {
|
|
1742
|
+
if (prev !== undefined && address !== prev && tables.has(address)) {
|
|
1743
|
+
setGatePromise(arm());
|
|
1744
|
+
}
|
|
1745
|
+
frame.rebind(address);
|
|
1746
|
+
});
|
|
1747
|
+
solidJs.createRenderEffect(() => (gate(), undefined), () => {});
|
|
1748
|
+
}
|
|
1644
1749
|
solidJs.onCleanup(() => frame.dispose());
|
|
1645
1750
|
return el;
|
|
1646
1751
|
}
|
|
@@ -1684,10 +1789,10 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1684
1789
|
exports.FRAME_APPLIED_EVENT = FRAME_APPLIED_EVENT;
|
|
1685
1790
|
exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
|
|
1686
1791
|
exports.applyFrameResponse = applyFrameResponse;
|
|
1792
|
+
exports.asyncArg = asyncArg;
|
|
1687
1793
|
exports.createFrame = createFrame;
|
|
1688
1794
|
exports.createFrameElement = createFrameElement;
|
|
1689
1795
|
exports.createFrameHost = createFrameHost;
|
|
1690
|
-
exports.createJSONDataTable = createJSONDataTable;
|
|
1691
1796
|
exports.createServerComponentHandler = createServerComponentHandler;
|
|
1692
1797
|
exports.getFrameHost = getFrameHost;
|
|
1693
1798
|
exports.installServerComponents = installServerComponents;
|