@solidjs/web 2.0.0-beta.30 → 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 +284 -82
- package/dist/dev.js +271 -79
- package/dist/server.cjs +555 -135
- package/dist/server.js +544 -132
- package/dist/web.cjs +281 -79
- package/dist/web.js +268 -76
- package/frames/dist/client.cjs +413 -360
- package/frames/dist/client.dev.cjs +413 -360
- package/frames/dist/client.dev.js +414 -361
- package/frames/dist/client.js +414 -361
- package/frames/dist/server.cjs +604 -199
- package/frames/dist/server.js +605 -201
- package/package.json +56 -6
- 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 +134 -11
- package/types/core.d.ts +3 -1
- package/types/frames/client.d.ts +24 -8
- package/types/frames/frame-client.d.ts +49 -7
- package/types/frames/frame-sink.d.ts +32 -6
- package/types/frames/frame-transport.d.ts +88 -62
- 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/jsx.d.ts +3 -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 +196 -42
- package/types-cjs/client.d.cts +134 -11
- package/types-cjs/core.d.cts +3 -1
- package/types-cjs/frames/client.d.cts +24 -8
- package/types-cjs/frames/frame-client.d.cts +49 -7
- package/types-cjs/frames/frame-sink.d.cts +32 -6
- package/types-cjs/frames/frame-transport.d.cts +88 -62
- 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/jsx.d.cts +3 -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 +196 -42
package/frames/dist/client.cjs
CHANGED
|
@@ -83,98 +83,73 @@ function chunkToRecords(chunk) {
|
|
|
83
83
|
}
|
|
84
84
|
function createFrameHost(options = {}) {
|
|
85
85
|
const frames = new Map();
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
frame.apply({
|
|
94
|
-
version: chunk.version,
|
|
95
|
-
r: chunkToRecords(chunk)
|
|
86
|
+
const stores = new Map();
|
|
87
|
+
const storeFor = id => {
|
|
88
|
+
let store = stores.get(id);
|
|
89
|
+
if (!store) stores.set(id, store = {
|
|
90
|
+
version: undefined,
|
|
91
|
+
records: {}
|
|
96
92
|
});
|
|
93
|
+
return store;
|
|
94
|
+
};
|
|
95
|
+
const write = (store, version, records) => {
|
|
96
|
+
if (store.version !== undefined && version < store.version) return false;
|
|
97
|
+
if (store.version === undefined || version > store.version) {
|
|
98
|
+
store.version = version;
|
|
99
|
+
clearStreamRecords(store.records);
|
|
100
|
+
}
|
|
101
|
+
Object.assign(store.records, records);
|
|
102
|
+
return true;
|
|
97
103
|
};
|
|
98
104
|
return {
|
|
99
105
|
register(id, frame) {
|
|
100
106
|
let set = frames.get(id);
|
|
101
107
|
if (!set) frames.set(id, set = new Set());
|
|
102
|
-
const sibling = set.size ? set.values().next().value : undefined;
|
|
103
108
|
set.add(frame);
|
|
104
|
-
|
|
109
|
+
const store = stores.get(id);
|
|
110
|
+
if (store && store.version !== undefined) {
|
|
105
111
|
frame.apply({
|
|
106
|
-
version:
|
|
107
|
-
r:
|
|
108
|
-
});
|
|
109
|
-
if (sibling.version === undefined) frame.rebase && frame.rebase();
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const kept = retained.get(id);
|
|
113
|
-
if (kept) {
|
|
114
|
-
retained.delete(id);
|
|
115
|
-
frame.apply({
|
|
116
|
-
version: kept.version,
|
|
117
|
-
r: kept.records
|
|
112
|
+
version: store.version,
|
|
113
|
+
r: store.records
|
|
118
114
|
});
|
|
119
115
|
frame.rebase && frame.rebase();
|
|
120
116
|
}
|
|
121
|
-
const buffered = pending.get(id);
|
|
122
|
-
if (buffered) {
|
|
123
|
-
pending.delete(id);
|
|
124
|
-
const records = {};
|
|
125
|
-
let version;
|
|
126
|
-
for (const chunk of buffered.chunks) {
|
|
127
|
-
if (chunk.type === "data") {
|
|
128
|
-
options.applyData && options.applyData(chunk);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
version = chunk.version;
|
|
132
|
-
Object.assign(records, chunkToRecords(chunk));
|
|
133
|
-
}
|
|
134
|
-
if (version !== undefined) frame.apply({
|
|
135
|
-
version,
|
|
136
|
-
r: records
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
117
|
},
|
|
140
118
|
unregister(id, frame) {
|
|
141
119
|
const set = frames.get(id);
|
|
142
120
|
if (set && frame) set.delete(frame);
|
|
143
121
|
if (!set || !frame || !set.size) {
|
|
144
|
-
if (frame) {
|
|
145
|
-
const kept = frame.snapshot && frame.snapshot();
|
|
146
|
-
if (kept) retained.set(id, kept);
|
|
147
|
-
} else {
|
|
148
|
-
retained.delete(id);
|
|
149
|
-
}
|
|
150
122
|
frames.delete(id);
|
|
151
|
-
|
|
123
|
+
if (frame && frame.contentHTML) {
|
|
124
|
+
const store = storeFor(id);
|
|
125
|
+
if (!store.records[""]) {
|
|
126
|
+
const html = frame.contentHTML();
|
|
127
|
+
if (html != null) {
|
|
128
|
+
store.records[""] = {
|
|
129
|
+
kind: "html",
|
|
130
|
+
value: html
|
|
131
|
+
};
|
|
132
|
+
if (store.version === undefined) store.version = 0;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
152
136
|
}
|
|
137
|
+
if (!frame) stores.delete(id);
|
|
153
138
|
},
|
|
154
139
|
apply(chunk) {
|
|
155
140
|
if (chunk.type === "data") {
|
|
156
141
|
options.applyData && options.applyData(chunk);
|
|
157
142
|
return;
|
|
158
143
|
}
|
|
144
|
+
const records = chunkToRecords(chunk);
|
|
145
|
+
if (!write(storeFor(chunk.id), chunk.version, records)) return;
|
|
159
146
|
const set = frames.get(chunk.id);
|
|
160
|
-
if (set
|
|
161
|
-
for (const frame of set)
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
const buffered = pending.get(chunk.id);
|
|
165
|
-
if (!buffered) {
|
|
166
|
-
pending.set(chunk.id, {
|
|
147
|
+
if (set) {
|
|
148
|
+
for (const frame of set) frame.apply({
|
|
167
149
|
version: chunk.version,
|
|
168
|
-
|
|
150
|
+
r: records
|
|
169
151
|
});
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
if (chunk.version < buffered.version) return;
|
|
173
|
-
if (chunk.version > buffered.version) {
|
|
174
|
-
buffered.version = chunk.version;
|
|
175
|
-
buffered.chunks.length = 0;
|
|
176
152
|
}
|
|
177
|
-
buffered.chunks.push(chunk);
|
|
178
153
|
},
|
|
179
154
|
get(id) {
|
|
180
155
|
const set = frames.get(id);
|
|
@@ -199,6 +174,7 @@ class FrameImpl {
|
|
|
199
174
|
#store = Object.create(null);
|
|
200
175
|
#appliedRootValue;
|
|
201
176
|
#hasContent = false;
|
|
177
|
+
#errorNotified = false;
|
|
202
178
|
#revealed = new Set();
|
|
203
179
|
#fallbackShown = new Set();
|
|
204
180
|
#slots;
|
|
@@ -210,6 +186,7 @@ class FrameImpl {
|
|
|
210
186
|
#slotResolvedRefs = new Map();
|
|
211
187
|
#slotNodes = new Map();
|
|
212
188
|
#processedAssets = new Set();
|
|
189
|
+
#recordRefresh = null;
|
|
213
190
|
#disposed = false;
|
|
214
191
|
#styleFlush = () => {
|
|
215
192
|
if (!this.#disposed) this.#flush();
|
|
@@ -217,10 +194,12 @@ class FrameImpl {
|
|
|
217
194
|
#claimTree = (node, direct) => {
|
|
218
195
|
const handlers = claimHandlers();
|
|
219
196
|
if (!handlers) return;
|
|
220
|
-
|
|
221
|
-
const scope = this.#options.ownerScope;
|
|
222
|
-
scope ? scope(run) : run();
|
|
197
|
+
this.#scoped(() => direct ? claimNode(handlers, node) : claimTree(handlers, node));
|
|
223
198
|
};
|
|
199
|
+
#scoped(fn) {
|
|
200
|
+
const scope = this.#options.ownerScope;
|
|
201
|
+
return scope ? scope(fn) : fn();
|
|
202
|
+
}
|
|
224
203
|
constructor(element, start, end, options = {}) {
|
|
225
204
|
this.#element = element;
|
|
226
205
|
this.#start = start;
|
|
@@ -281,15 +260,9 @@ class FrameImpl {
|
|
|
281
260
|
return;
|
|
282
261
|
} else if (v > this.#version) {
|
|
283
262
|
this.#version = v;
|
|
284
|
-
this.#
|
|
285
|
-
this.#fallbackShown.clear();
|
|
286
|
-
for (const key of Object.keys(this.#store)) {
|
|
287
|
-
if (key.startsWith("seg:") || key === ":error") {
|
|
288
|
-
delete this.#store[key];
|
|
289
|
-
}
|
|
290
|
-
}
|
|
263
|
+
this.#resetStreamState();
|
|
291
264
|
}
|
|
292
|
-
for (const key
|
|
265
|
+
for (const key in write.r) {
|
|
293
266
|
const incoming = write.r[key];
|
|
294
267
|
if (incoming && incoming.kind === "slot" && key.charCodeAt(0) === 115 && key.startsWith("slot:")) {
|
|
295
268
|
const existing = this.#store[key];
|
|
@@ -301,6 +274,12 @@ class FrameImpl {
|
|
|
301
274
|
}
|
|
302
275
|
this.#flush();
|
|
303
276
|
}
|
|
277
|
+
#resetStreamState(root) {
|
|
278
|
+
this.#revealed.clear();
|
|
279
|
+
this.#fallbackShown.clear();
|
|
280
|
+
this.#errorNotified = false;
|
|
281
|
+
clearStreamRecords(this.#store, root);
|
|
282
|
+
}
|
|
304
283
|
#flush() {
|
|
305
284
|
if (this.#disposed) return;
|
|
306
285
|
const version = this.#version;
|
|
@@ -311,10 +290,14 @@ class FrameImpl {
|
|
|
311
290
|
this.#appliedRootValue = root.value;
|
|
312
291
|
this.#applied(version, reason);
|
|
313
292
|
}
|
|
293
|
+
if (this.#store[":error"] && !this.#errorNotified) {
|
|
294
|
+
this.#errorNotified = true;
|
|
295
|
+
this.#applied(version, "error");
|
|
296
|
+
}
|
|
314
297
|
let progressed = true;
|
|
315
298
|
while (progressed) {
|
|
316
299
|
progressed = false;
|
|
317
|
-
for (const key
|
|
300
|
+
for (const key in this.#store) {
|
|
318
301
|
const name = segmentName(key);
|
|
319
302
|
if (name === null || this.#revealed.has(name)) continue;
|
|
320
303
|
if (this.#segmentReady(name)) {
|
|
@@ -323,7 +306,7 @@ class FrameImpl {
|
|
|
323
306
|
progressed = true;
|
|
324
307
|
}
|
|
325
308
|
}
|
|
326
|
-
for (const key
|
|
309
|
+
for (const key in this.#store) {
|
|
327
310
|
const m = /^seg:([^:]+):fallback$/.exec(key);
|
|
328
311
|
if (!m) continue;
|
|
329
312
|
const name = m[1];
|
|
@@ -335,7 +318,7 @@ class FrameImpl {
|
|
|
335
318
|
}
|
|
336
319
|
}
|
|
337
320
|
}
|
|
338
|
-
for (const key
|
|
321
|
+
for (const key in this.#store) {
|
|
339
322
|
if (this.#processedAssets.has(key) || !key.endsWith(":assets")) continue;
|
|
340
323
|
this.#processedAssets.add(key);
|
|
341
324
|
const record = this.#store[key];
|
|
@@ -355,7 +338,9 @@ class FrameImpl {
|
|
|
355
338
|
}
|
|
356
339
|
#removeSlotRecord(occurrence) {
|
|
357
340
|
const key = `slot:${occurrence}`;
|
|
358
|
-
if (key in this.#store)
|
|
341
|
+
if (key in this.#store) {
|
|
342
|
+
if (!this.#mountedSlots.has(occurrence)) delete this.#store[key];
|
|
343
|
+
} else this.#options.removeSlotRecord?.(occurrence);
|
|
359
344
|
}
|
|
360
345
|
#syncSlots(root) {
|
|
361
346
|
if (!this.#slots && !this.#options.resolveSlot) return;
|
|
@@ -365,6 +350,7 @@ class FrameImpl {
|
|
|
365
350
|
const callback = this.#resolveSlot(propOf(occurrence));
|
|
366
351
|
if (!callback) continue;
|
|
367
352
|
const record = this.#resolveSlotRecord(occurrence);
|
|
353
|
+
if (record && record.kind === "slot" && this.#refsUnresolved(record.args)) continue;
|
|
368
354
|
const prev = this.#slotNodes.get(occurrence);
|
|
369
355
|
const prevFirst = Array.isArray(prev) ? prev[0] : prev;
|
|
370
356
|
const zombie = this.#mountedSlots.has(occurrence) && prevFirst && !prevFirst.parentNode;
|
|
@@ -373,6 +359,15 @@ class FrameImpl {
|
|
|
373
359
|
this.#runSlotCleanups(occurrence);
|
|
374
360
|
}
|
|
375
361
|
if (!this.#mountedSlots.has(occurrence)) {
|
|
362
|
+
if (record === undefined && !root && this.#options.adopt && this.#options.recordsPending?.()) {
|
|
363
|
+
this.#recordRefresh ??= setTimeout(() => {
|
|
364
|
+
this.#recordRefresh = null;
|
|
365
|
+
if (this.#disposed) return;
|
|
366
|
+
this.#options.drainRecords?.();
|
|
367
|
+
this.#syncSlots();
|
|
368
|
+
});
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
376
371
|
if (this.#options.adopt) this.#discoverRegions(occurrence, start);
|
|
377
372
|
const nodes = this.#invokeSlot(occurrence, callback, record, start, this.#options.adopt);
|
|
378
373
|
if (nodes) this.#replaceRange(occurrence, start, nodes);
|
|
@@ -389,12 +384,6 @@ class FrameImpl {
|
|
|
389
384
|
const update = this.#slotUpdaters.get(occurrence);
|
|
390
385
|
if (update) {
|
|
391
386
|
const props = this.#resolveArgs(occurrence, record.args);
|
|
392
|
-
const regions = this.#slotRegions.get(occurrence);
|
|
393
|
-
if (regions) {
|
|
394
|
-
for (const [argKey, entry] of regions) {
|
|
395
|
-
if (!(argKey in props)) props[argKey] = entry.element;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
387
|
this.#slotArgs.set(occurrence, record);
|
|
399
388
|
update(props);
|
|
400
389
|
this.#bindRegions(occurrence);
|
|
@@ -417,15 +406,7 @@ class FrameImpl {
|
|
|
417
406
|
const cleanups = this.#slotCleanups.get(occurrence) ?? [];
|
|
418
407
|
let existing = [];
|
|
419
408
|
let end = null;
|
|
420
|
-
if (start)
|
|
421
|
-
const endData = slotEnd(occurrence);
|
|
422
|
-
let n = start.nextSibling;
|
|
423
|
-
while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
|
|
424
|
-
existing.push(n);
|
|
425
|
-
n = n.nextSibling;
|
|
426
|
-
}
|
|
427
|
-
end = n;
|
|
428
|
-
}
|
|
409
|
+
if (start) end = eachInRange(start, occurrence, n => existing.push(n));
|
|
429
410
|
const ctx = {
|
|
430
411
|
frame: this.#options.claimScope ?? this.#options.id,
|
|
431
412
|
key: occurrence,
|
|
@@ -440,29 +421,16 @@ class FrameImpl {
|
|
|
440
421
|
} : undefined
|
|
441
422
|
};
|
|
442
423
|
const props = record && record.kind === "slot" ? this.#resolveArgs(occurrence, record.args) : {};
|
|
443
|
-
const
|
|
444
|
-
if (regions) {
|
|
445
|
-
for (const [argKey, entry] of regions) {
|
|
446
|
-
if (!(argKey in props)) props[argKey] = entry.element;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
const scope = this.#options.ownerScope;
|
|
450
|
-
const content = scope ? scope(() => callback(props, ctx)) : callback(props, ctx);
|
|
424
|
+
const content = this.#scoped(() => callback(props, ctx));
|
|
451
425
|
this.#slotArgs.set(occurrence, record);
|
|
452
426
|
if (cleanups.length) this.#slotCleanups.set(occurrence, cleanups);
|
|
453
427
|
if (content == null) return null;
|
|
454
428
|
return Array.isArray(content) ? content : [content];
|
|
455
429
|
}
|
|
456
430
|
#replaceRange(key, start, nodes) {
|
|
457
|
-
const end = slotEnd(key);
|
|
458
431
|
const parent = start.parentNode;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const next = n.nextSibling;
|
|
462
|
-
parent.removeChild(n);
|
|
463
|
-
n = next;
|
|
464
|
-
}
|
|
465
|
-
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);
|
|
466
434
|
}
|
|
467
435
|
#unmountSlot(key) {
|
|
468
436
|
this.#mountedSlots.delete(key);
|
|
@@ -474,9 +442,7 @@ class FrameImpl {
|
|
|
474
442
|
this.#runSlotCleanups(key);
|
|
475
443
|
const regions = this.#slotRegions.get(key);
|
|
476
444
|
if (regions) {
|
|
477
|
-
|
|
478
|
-
frame
|
|
479
|
-
} of regions.values()) frame?.dispose();
|
|
445
|
+
disposeRegions(regions);
|
|
480
446
|
this.#slotRegions.delete(key);
|
|
481
447
|
}
|
|
482
448
|
}
|
|
@@ -486,15 +452,26 @@ class FrameImpl {
|
|
|
486
452
|
this.#slotCleanups.delete(key);
|
|
487
453
|
for (const fn of cleanups) fn();
|
|
488
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
|
+
}
|
|
489
470
|
#resolveArgs(slotKey, args) {
|
|
490
471
|
const host = this.#options.host;
|
|
491
|
-
|
|
492
|
-
if (!regions) {
|
|
493
|
-
regions = new Map();
|
|
494
|
-
this.#slotRegions.set(slotKey, regions);
|
|
495
|
-
}
|
|
472
|
+
const regions = this.#regionsFor(slotKey);
|
|
496
473
|
const props = {};
|
|
497
|
-
for (const key
|
|
474
|
+
for (const key in args) {
|
|
498
475
|
const value = args[key];
|
|
499
476
|
if (isDataRef(value)) {
|
|
500
477
|
const resolved = host ? host.resolve(value, this.#options.id) : undefined;
|
|
@@ -524,18 +501,8 @@ class FrameImpl {
|
|
|
524
501
|
}
|
|
525
502
|
#discoverRegions(slotKey, start) {
|
|
526
503
|
if (!start) return;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
regions = new Map();
|
|
530
|
-
this.#slotRegions.set(slotKey, regions);
|
|
531
|
-
}
|
|
532
|
-
const endData = slotEnd(slotKey);
|
|
533
|
-
const prefix = `${this.#options.id}.`;
|
|
534
|
-
let n = start.nextSibling;
|
|
535
|
-
while (n && !(n.nodeType === COMMENT_NODE && n.data === endData)) {
|
|
536
|
-
collectRegionElements(n, regions, prefix);
|
|
537
|
-
n = n.nextSibling;
|
|
538
|
-
}
|
|
504
|
+
const regions = this.#regionsFor(slotKey);
|
|
505
|
+
eachInRange(start, slotKey, n => collectRegionElements(n, regions));
|
|
539
506
|
}
|
|
540
507
|
#refArgsUnchanged(occurrence, record) {
|
|
541
508
|
const old = this.#slotArgs.get(occurrence);
|
|
@@ -545,26 +512,17 @@ class FrameImpl {
|
|
|
545
512
|
const b = record.args || {};
|
|
546
513
|
const ka = Object.keys(a);
|
|
547
514
|
const kb = Object.keys(b);
|
|
548
|
-
if (kb.length
|
|
549
|
-
if (kb.length !== ka.length) {
|
|
550
|
-
const regions = this.#slotRegions.get(occurrence);
|
|
551
|
-
for (const key of kb) {
|
|
552
|
-
if (key in a) continue;
|
|
553
|
-
const vb = b[key];
|
|
554
|
-
if (!vb || typeof vb !== "object" || typeof vb.$frame !== "string") return false;
|
|
555
|
-
if (!regions || !regions.has(key)) return false;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
515
|
+
if (kb.length !== ka.length) return false;
|
|
558
516
|
const cache = this.#slotResolvedRefs.get(occurrence);
|
|
559
517
|
for (const key of ka) {
|
|
560
518
|
const va = a[key];
|
|
561
519
|
const vb = b[key];
|
|
562
520
|
if (va === vb) continue;
|
|
563
|
-
if (
|
|
564
|
-
if (
|
|
565
|
-
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) {
|
|
566
523
|
const host = this.#options.host;
|
|
567
524
|
const next = host ? host.resolve(vb, this.#options.id) : undefined;
|
|
525
|
+
if (isAsyncLike(next) || isAsyncLike(cache[key])) return false;
|
|
568
526
|
try {
|
|
569
527
|
if (JSON.stringify(next) === JSON.stringify(cache[key])) continue;
|
|
570
528
|
} catch (e) {
|
|
@@ -580,7 +538,7 @@ class FrameImpl {
|
|
|
580
538
|
if (!args) return;
|
|
581
539
|
const regions = this.#slotRegions.get(occurrence);
|
|
582
540
|
if (!regions) return;
|
|
583
|
-
for (const key
|
|
541
|
+
for (const key in args) {
|
|
584
542
|
const value = args[key];
|
|
585
543
|
if (!isFrameRef(value)) continue;
|
|
586
544
|
const entry = regions.get(key);
|
|
@@ -611,22 +569,9 @@ class FrameImpl {
|
|
|
611
569
|
#findPlaceholder(name) {
|
|
612
570
|
return findPlaceholder(this.#firstContent(), this.#end, placeholderId(name));
|
|
613
571
|
}
|
|
614
|
-
|
|
615
|
-
if (this.#disposed) return null;
|
|
616
|
-
|
|
617
|
-
...this.#store
|
|
618
|
-
};
|
|
619
|
-
if (!records[""] && this.#element && this.#hasContent) {
|
|
620
|
-
records[""] = {
|
|
621
|
-
kind: "html",
|
|
622
|
-
value: this.#element.innerHTML
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
if (!records[""] && this.#version === undefined) return null;
|
|
626
|
-
return {
|
|
627
|
-
version: this.#version ?? 0,
|
|
628
|
-
records
|
|
629
|
-
};
|
|
572
|
+
contentHTML() {
|
|
573
|
+
if (this.#disposed || !this.#element || !this.#hasContent) return null;
|
|
574
|
+
return this.#element.innerHTML;
|
|
630
575
|
}
|
|
631
576
|
rebind(id) {
|
|
632
577
|
if (this.#disposed || id === this.#options.id) return;
|
|
@@ -643,11 +588,8 @@ class FrameImpl {
|
|
|
643
588
|
this.#element.setAttribute(FRAME_ID_ATTR, id);
|
|
644
589
|
}
|
|
645
590
|
this.#version = undefined;
|
|
646
|
-
this.#
|
|
647
|
-
this.#
|
|
648
|
-
for (const key of Object.keys(this.#store)) {
|
|
649
|
-
if (key.startsWith("seg:") || key === ":error") delete this.#store[key];
|
|
650
|
-
}
|
|
591
|
+
this.#appliedRootValue = undefined;
|
|
592
|
+
this.#resetStreamState(true);
|
|
651
593
|
if (host) host.register(id, this);
|
|
652
594
|
}
|
|
653
595
|
rebase() {
|
|
@@ -661,13 +603,13 @@ class FrameImpl {
|
|
|
661
603
|
} = this.#options;
|
|
662
604
|
if (host && id !== undefined) host.unregister(id, this);
|
|
663
605
|
this.#disposed = true;
|
|
606
|
+
if (this.#recordRefresh) {
|
|
607
|
+
clearTimeout(this.#recordRefresh);
|
|
608
|
+
this.#recordRefresh = null;
|
|
609
|
+
}
|
|
664
610
|
for (const key of [...this.#slotCleanups.keys()]) this.#runSlotCleanups(key);
|
|
665
611
|
for (const key of this.#mountedSlots) this.#removeSlotRecord(key);
|
|
666
|
-
for (const regions of this.#slotRegions.values())
|
|
667
|
-
for (const {
|
|
668
|
-
frame
|
|
669
|
-
} of regions.values()) frame?.dispose();
|
|
670
|
-
}
|
|
612
|
+
for (const regions of this.#slotRegions.values()) disposeRegions(regions);
|
|
671
613
|
this.#slotRegions.clear();
|
|
672
614
|
this.#mountedSlots.clear();
|
|
673
615
|
}
|
|
@@ -683,18 +625,13 @@ class FrameImpl {
|
|
|
683
625
|
const claim = claimHandlers() ? this.#claimTree : null;
|
|
684
626
|
const ranges = new Map();
|
|
685
627
|
this.#collectSlots(ranges);
|
|
686
|
-
|
|
687
|
-
|
|
628
|
+
const grafts = [];
|
|
629
|
+
reconcileChildren(parent, fragment, this.#start, this.#end, claim, ranges, grafts);
|
|
630
|
+
if (ranges.size) for (const root of grafts) flushGrafts(root, ranges);
|
|
688
631
|
}
|
|
689
632
|
}
|
|
690
633
|
#clearContent() {
|
|
691
|
-
|
|
692
|
-
let n = this.#firstContent();
|
|
693
|
-
while (n && n !== this.#end) {
|
|
694
|
-
const next = n.nextSibling;
|
|
695
|
-
parent.removeChild(n);
|
|
696
|
-
n = next;
|
|
697
|
-
}
|
|
634
|
+
removeUntil(this.#parent(), this.#firstContent(), this.#end);
|
|
698
635
|
}
|
|
699
636
|
#claimContent() {
|
|
700
637
|
if (!claimHandlers()) return;
|
|
@@ -711,9 +648,7 @@ class FrameImpl {
|
|
|
711
648
|
const assets = this.#store[`seg:${name}:assets`];
|
|
712
649
|
if (assets && assets.styles) {
|
|
713
650
|
let ready = true;
|
|
714
|
-
for (const entry of assets.styles)
|
|
715
|
-
if (!ensureStylesheet(entry, this.#styleFlush)) ready = false;
|
|
716
|
-
}
|
|
651
|
+
for (const entry of assets.styles) ready = ensureStylesheet(entry, this.#styleFlush) && ready;
|
|
717
652
|
if (!ready) return false;
|
|
718
653
|
}
|
|
719
654
|
if (!this.#findPlaceholder(name)) return false;
|
|
@@ -727,12 +662,7 @@ class FrameImpl {
|
|
|
727
662
|
const content = this.#store[`seg:${name}`];
|
|
728
663
|
const closing = rangeClose(tpl, placeholderId(name));
|
|
729
664
|
const parent = tpl.parentNode;
|
|
730
|
-
|
|
731
|
-
while (n && n !== closing) {
|
|
732
|
-
const next = n.nextSibling;
|
|
733
|
-
parent.removeChild(n);
|
|
734
|
-
n = next;
|
|
735
|
-
}
|
|
665
|
+
removeUntil(parent, tpl.nextSibling, closing);
|
|
736
666
|
if (this.#options.reveal) {
|
|
737
667
|
const fallbackFrag = tpl.content.cloneNode(true);
|
|
738
668
|
this.#claimTree(fallbackFrag);
|
|
@@ -781,9 +711,7 @@ function createFrameElement(options) {
|
|
|
781
711
|
const frame = new FrameImpl(el, null, null, options);
|
|
782
712
|
return {
|
|
783
713
|
element: el,
|
|
784
|
-
|
|
785
|
-
return frame;
|
|
786
|
-
},
|
|
714
|
+
frame,
|
|
787
715
|
dispose() {
|
|
788
716
|
frame.dispose();
|
|
789
717
|
el.remove();
|
|
@@ -803,15 +731,30 @@ function segmentName(key) {
|
|
|
803
731
|
const m = /^seg:([^:]+)$/.exec(key);
|
|
804
732
|
return m ? m[1] : null;
|
|
805
733
|
}
|
|
734
|
+
function isAsyncLike(v) {
|
|
735
|
+
return !!v && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
736
|
+
}
|
|
806
737
|
function propOf(occurrence) {
|
|
807
738
|
const hash = occurrence.indexOf("#");
|
|
808
739
|
return hash === -1 ? occurrence : occurrence.slice(0, hash);
|
|
809
740
|
}
|
|
810
741
|
function isDataRef(value) {
|
|
811
|
-
return
|
|
742
|
+
return !!value && typeof value.$ref === "string";
|
|
812
743
|
}
|
|
813
744
|
function isFrameRef(value) {
|
|
814
|
-
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
|
+
}
|
|
815
758
|
}
|
|
816
759
|
function parseFragment(html) {
|
|
817
760
|
const template = document.createElement("template");
|
|
@@ -819,9 +762,8 @@ function parseFragment(html) {
|
|
|
819
762
|
return template.content;
|
|
820
763
|
}
|
|
821
764
|
function findHeadElement(selector, attr, value) {
|
|
822
|
-
const
|
|
823
|
-
|
|
824
|
-
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;
|
|
825
767
|
}
|
|
826
768
|
return null;
|
|
827
769
|
}
|
|
@@ -870,7 +812,7 @@ function applyInlineStyles(inlineStyles) {
|
|
|
870
812
|
}
|
|
871
813
|
}
|
|
872
814
|
function isPlaceholderStart(node, id) {
|
|
873
|
-
return node.
|
|
815
|
+
return node.tagName === "TEMPLATE" && node.id === id;
|
|
874
816
|
}
|
|
875
817
|
function rangeClose(start, id) {
|
|
876
818
|
let n = start.nextSibling;
|
|
@@ -903,11 +845,11 @@ function collectSlots(n, end, out) {
|
|
|
903
845
|
n = n.nextSibling;
|
|
904
846
|
}
|
|
905
847
|
}
|
|
906
|
-
function collectRegionElements(node, regions
|
|
848
|
+
function collectRegionElements(node, regions) {
|
|
907
849
|
if (node.nodeType !== ELEMENT_NODE) return;
|
|
908
850
|
if (isFrameElement(node)) {
|
|
909
851
|
const childId = node.getAttribute(FRAME_ID_ATTR);
|
|
910
|
-
if (childId && childId.
|
|
852
|
+
if (childId && childId.includes(".")) {
|
|
911
853
|
const argKey = childId.slice(childId.lastIndexOf(".") + 1);
|
|
912
854
|
if (!regions.has(argKey)) {
|
|
913
855
|
regions.set(argKey, {
|
|
@@ -920,12 +862,27 @@ function collectRegionElements(node, regions, prefix) {
|
|
|
920
862
|
}
|
|
921
863
|
return;
|
|
922
864
|
}
|
|
923
|
-
for (let c = node.firstChild; c; c = c.nextSibling) collectRegionElements(c, regions
|
|
865
|
+
for (let c = node.firstChild; c; c = c.nextSibling) collectRegionElements(c, regions);
|
|
924
866
|
}
|
|
925
867
|
function renameRegion(entry, childId) {
|
|
926
868
|
entry.childId = childId;
|
|
927
869
|
if (entry.frame) entry.frame.rebind(childId);else entry.element.setAttribute(FRAME_ID_ATTR, childId);
|
|
928
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
|
+
}
|
|
929
886
|
function argsEquivalent(a, b) {
|
|
930
887
|
if (a === b) return true;
|
|
931
888
|
if (!a || !b) return false;
|
|
@@ -936,9 +893,7 @@ function argsEquivalent(a, b) {
|
|
|
936
893
|
const va = a[key];
|
|
937
894
|
const vb = b[key];
|
|
938
895
|
if (va === vb) continue;
|
|
939
|
-
if (va &&
|
|
940
|
-
continue;
|
|
941
|
-
}
|
|
896
|
+
if (isFrameRef(va) && va.$frame === vb?.$frame) continue;
|
|
942
897
|
return false;
|
|
943
898
|
}
|
|
944
899
|
return true;
|
|
@@ -988,11 +943,11 @@ function morphAttributes(oldEl, newEl, claim) {
|
|
|
988
943
|
}
|
|
989
944
|
if (claim && (reclaim || changed && oldEl.matches(CLAIMED_ELEMENTS))) claim(oldEl, true);
|
|
990
945
|
}
|
|
991
|
-
function morphNode(oldNode, newNode, claim, ranges) {
|
|
946
|
+
function morphNode(oldNode, newNode, claim, ranges, grafts) {
|
|
992
947
|
if (oldNode.nodeType === ELEMENT_NODE) {
|
|
993
948
|
if (oldNode.hasAttribute("data-preserve")) return;
|
|
994
949
|
morphAttributes(oldNode, newNode, claim);
|
|
995
|
-
reconcileChildren(oldNode, newNode, null, null, claim, ranges);
|
|
950
|
+
reconcileChildren(oldNode, newNode, null, null, claim, ranges, grafts);
|
|
996
951
|
} else if (oldNode.data !== newNode.data) {
|
|
997
952
|
oldNode.data = newNode.data;
|
|
998
953
|
}
|
|
@@ -1026,6 +981,13 @@ function moveRangeBefore(parent, start, id, ref) {
|
|
|
1026
981
|
n = next;
|
|
1027
982
|
}
|
|
1028
983
|
}
|
|
984
|
+
function placeRange(parent, range, id, ref) {
|
|
985
|
+
if (range.nodeType === 11 ) {
|
|
986
|
+
parent.insertBefore(range, ref);
|
|
987
|
+
} else {
|
|
988
|
+
moveRangeBefore(parent, range, id, ref);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
1029
991
|
function adoptRange(parent, start, id, ref, claim) {
|
|
1030
992
|
const end = slotEnd(id);
|
|
1031
993
|
let n = start;
|
|
@@ -1043,7 +1005,7 @@ function adoptRange(parent, start, id, ref, claim) {
|
|
|
1043
1005
|
}
|
|
1044
1006
|
return after;
|
|
1045
1007
|
}
|
|
1046
|
-
function reconcileChildren(parent, source, boundStart = null, boundEnd = null, claim = null, ranges = null) {
|
|
1008
|
+
function reconcileChildren(parent, source, boundStart = null, boundEnd = null, claim = null, ranges = null, grafts = null) {
|
|
1047
1009
|
let oldChild = boundStart ? boundStart.nextSibling : parent.firstChild;
|
|
1048
1010
|
let newChild = source.firstChild;
|
|
1049
1011
|
while (newChild) {
|
|
@@ -1059,11 +1021,7 @@ function reconcileChildren(parent, source, boundStart = null, boundEnd = null, c
|
|
|
1059
1021
|
const existing = displaced || findRangeStart(old, pid, boundEnd);
|
|
1060
1022
|
if (existing) {
|
|
1061
1023
|
if (ranges) ranges.delete(pid);
|
|
1062
|
-
|
|
1063
|
-
parent.insertBefore(existing, old ?? boundEnd);
|
|
1064
|
-
} else {
|
|
1065
|
-
moveRangeBefore(parent, existing, pid, old ?? boundEnd);
|
|
1066
|
-
}
|
|
1024
|
+
placeRange(parent, existing, pid, old ?? boundEnd);
|
|
1067
1025
|
newChild = afterRange(newChild, pid);
|
|
1068
1026
|
} else {
|
|
1069
1027
|
newChild = adoptRange(parent, newChild, pid, old ?? boundEnd, claim);
|
|
@@ -1074,17 +1032,19 @@ function reconcileChildren(parent, source, boundStart = null, boundEnd = null, c
|
|
|
1074
1032
|
if (!old) {
|
|
1075
1033
|
parent.insertBefore(newChild, boundEnd);
|
|
1076
1034
|
if (claim) claim(newChild);
|
|
1035
|
+
if (grafts) grafts.push(newChild);
|
|
1077
1036
|
newChild = nextNew;
|
|
1078
1037
|
continue;
|
|
1079
1038
|
}
|
|
1080
1039
|
if (isSlotMarker(old)) {
|
|
1081
1040
|
parent.insertBefore(newChild, old);
|
|
1082
1041
|
if (claim) claim(newChild);
|
|
1042
|
+
if (grafts) grafts.push(newChild);
|
|
1083
1043
|
newChild = nextNew;
|
|
1084
1044
|
continue;
|
|
1085
1045
|
}
|
|
1086
1046
|
if (compatible(old, newChild)) {
|
|
1087
|
-
morphNode(old, newChild, claim, ranges);
|
|
1047
|
+
morphNode(old, newChild, claim, ranges, grafts);
|
|
1088
1048
|
oldChild = old.nextSibling;
|
|
1089
1049
|
newChild = nextNew;
|
|
1090
1050
|
continue;
|
|
@@ -1097,13 +1057,14 @@ function reconcileChildren(parent, source, boundStart = null, boundEnd = null, c
|
|
|
1097
1057
|
}
|
|
1098
1058
|
if (ahead && ahead !== boundEnd) {
|
|
1099
1059
|
parent.insertBefore(ahead, old);
|
|
1100
|
-
morphNode(ahead, newChild, claim, ranges);
|
|
1060
|
+
morphNode(ahead, newChild, claim, ranges, grafts);
|
|
1101
1061
|
newChild = nextNew;
|
|
1102
1062
|
continue;
|
|
1103
1063
|
}
|
|
1104
1064
|
}
|
|
1105
1065
|
parent.insertBefore(newChild, old);
|
|
1106
1066
|
if (claim) claim(newChild);
|
|
1067
|
+
if (grafts) grafts.push(newChild);
|
|
1107
1068
|
newChild = nextNew;
|
|
1108
1069
|
}
|
|
1109
1070
|
while (oldChild && oldChild !== boundEnd) {
|
|
@@ -1120,20 +1081,24 @@ function reconcileChildren(parent, source, boundStart = null, boundEnd = null, c
|
|
|
1120
1081
|
oldChild = next;
|
|
1121
1082
|
}
|
|
1122
1083
|
}
|
|
1123
|
-
function
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
const
|
|
1128
|
-
if (
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1084
|
+
function flushGrafts(node, ranges) {
|
|
1085
|
+
if (node.nodeType !== ELEMENT_NODE || isFrameElement(node)) return;
|
|
1086
|
+
let n = node.firstChild;
|
|
1087
|
+
while (n) {
|
|
1088
|
+
const id = slotStartId(n);
|
|
1089
|
+
if (id !== null) {
|
|
1090
|
+
const next = afterRange(n, id);
|
|
1091
|
+
const displaced = ranges.get(id);
|
|
1092
|
+
if (displaced) {
|
|
1093
|
+
ranges.delete(id);
|
|
1094
|
+
placeRange(node, displaced, id, n);
|
|
1095
|
+
stashRange(document.createDocumentFragment(), n, id);
|
|
1096
|
+
}
|
|
1097
|
+
n = next;
|
|
1098
|
+
continue;
|
|
1135
1099
|
}
|
|
1136
|
-
|
|
1100
|
+
flushGrafts(n, ranges);
|
|
1101
|
+
n = n.nextSibling;
|
|
1137
1102
|
}
|
|
1138
1103
|
}
|
|
1139
1104
|
function stashRange(frag, start, id) {
|
|
@@ -1165,7 +1130,7 @@ async function applyFrameResponse(response, host, options = {}) {
|
|
|
1165
1130
|
if (chunk.type === "outcome") {
|
|
1166
1131
|
if (options.onOutcome) options.onOutcome(chunk.payload);
|
|
1167
1132
|
} else {
|
|
1168
|
-
if (as !== undefined && chunk.id === rootId) chunk.id = as;
|
|
1133
|
+
if (as !== undefined && chunk.id === rootId) chunk.id = as;
|
|
1169
1134
|
if (perFrame) {
|
|
1170
1135
|
let v = perFrame.get(chunk.id);
|
|
1171
1136
|
if (v === undefined) perFrame.set(chunk.id, v = version(chunk.id));
|
|
@@ -1179,7 +1144,7 @@ async function applyFrameResponse(response, host, options = {}) {
|
|
|
1179
1144
|
}
|
|
1180
1145
|
const SERVER_COMPONENT = /*#__PURE__*/Symbol.for("dom-expressions.server-component");
|
|
1181
1146
|
const SERVER_COMPONENT_ADDRESS = /*#__PURE__*/Symbol.for("dom-expressions.server-component-address");
|
|
1182
|
-
const
|
|
1147
|
+
const COMPONENT_BINDING = /*#__PURE__*/Symbol.for("dom-expressions.component-binding");
|
|
1183
1148
|
let resolveServerComponent;
|
|
1184
1149
|
function parseServerComponent(value, ctx) {
|
|
1185
1150
|
return {
|
|
@@ -1203,7 +1168,8 @@ const ServerComponentPlugin = /*#__PURE__*/seroval.createPlugin({
|
|
|
1203
1168
|
stream: parseServerComponent
|
|
1204
1169
|
},
|
|
1205
1170
|
serialize(node, ctx) {
|
|
1206
|
-
|
|
1171
|
+
const registry = "self._$SC";
|
|
1172
|
+
return registry + ".r(" + ctx.serialize(node.id) + "," + ctx.serialize(node.address) + ")";
|
|
1207
1173
|
},
|
|
1208
1174
|
deserialize(node, ctx) {
|
|
1209
1175
|
const id = ctx.deserialize(node.id);
|
|
@@ -1228,120 +1194,79 @@ function createServerComponentHandler({
|
|
|
1228
1194
|
host,
|
|
1229
1195
|
component,
|
|
1230
1196
|
onStream,
|
|
1231
|
-
documentComponent,
|
|
1232
1197
|
intercept,
|
|
1233
1198
|
consumer = client.getFlightDataConsumer,
|
|
1234
1199
|
codec = client.getServerFunctionsCodec
|
|
1235
1200
|
}) {
|
|
1236
|
-
const
|
|
1237
|
-
const
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
if (brandable && !comp[COMPONENT_HANDOFF]) {
|
|
1241
|
-
comp[COMPONENT_HANDOFF] = {
|
|
1242
|
-
fnId,
|
|
1243
|
-
frameId,
|
|
1244
|
-
take(prev) {
|
|
1245
|
-
const meta = prev !== null && (typeof prev === "function" || typeof prev === "object") && prev[COMPONENT_HANDOFF];
|
|
1246
|
-
if (!meta || meta.fnId !== fnId) return false;
|
|
1247
|
-
const root = meta.frameId;
|
|
1248
|
-
let cur = forwards.get(root) ?? root;
|
|
1249
|
-
if (cur !== root && !host.get(cur)) {
|
|
1250
|
-
forwards.delete(root);
|
|
1251
|
-
cur = root;
|
|
1252
|
-
}
|
|
1253
|
-
if (cur === frameId) return true;
|
|
1254
|
-
let frame = host.get(cur);
|
|
1255
|
-
if (!frame) return false;
|
|
1256
|
-
while (frame) {
|
|
1257
|
-
frame.rebind(frameId);
|
|
1258
|
-
frame = host.get(cur);
|
|
1259
|
-
}
|
|
1260
|
-
if (frameId === root) forwards.delete(root);else forwards.set(root, frameId);
|
|
1261
|
-
return true;
|
|
1262
|
-
}
|
|
1263
|
-
};
|
|
1264
|
-
}
|
|
1201
|
+
const byFn = new Map();
|
|
1202
|
+
const componentFor = fnId => {
|
|
1203
|
+
let comp = byFn.get(fnId);
|
|
1204
|
+
if (comp === undefined) byFn.set(fnId, comp = component(fnId));
|
|
1265
1205
|
return comp;
|
|
1266
1206
|
};
|
|
1267
|
-
const
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1207
|
+
const byAddress = new Map();
|
|
1208
|
+
const bindingFor = (address, fnId) => {
|
|
1209
|
+
let binding = byAddress.get(address);
|
|
1210
|
+
if (!binding) {
|
|
1211
|
+
const comp = componentFor(fnId);
|
|
1212
|
+
binding = props => comp(props, () => address);
|
|
1213
|
+
binding[COMPONENT_BINDING] = {
|
|
1214
|
+
component: comp,
|
|
1215
|
+
address
|
|
1273
1216
|
};
|
|
1274
|
-
byAddress.set(address,
|
|
1217
|
+
byAddress.set(address, binding);
|
|
1275
1218
|
}
|
|
1276
|
-
return
|
|
1219
|
+
return binding;
|
|
1277
1220
|
};
|
|
1278
|
-
|
|
1279
|
-
resolveServerComponent = resolveAddress;
|
|
1221
|
+
resolveServerComponent = (id, address) => bindingFor(address, id);
|
|
1280
1222
|
const versions = new Map();
|
|
1281
|
-
const bump =
|
|
1282
|
-
const version = (versions.get(
|
|
1283
|
-
versions.set(
|
|
1223
|
+
const bump = address => {
|
|
1224
|
+
const version = (versions.get(address) || 0) + 1;
|
|
1225
|
+
versions.set(address, version);
|
|
1284
1226
|
return version;
|
|
1285
1227
|
};
|
|
1286
1228
|
return {
|
|
1287
1229
|
intercept: intercept && (info => {
|
|
1288
1230
|
const hit = intercept(info);
|
|
1289
|
-
if (hit
|
|
1290
|
-
|
|
1291
|
-
byAddress.set(address, {
|
|
1292
|
-
frameId: info.id,
|
|
1293
|
-
component: brand(hit, info.id, info.id)
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
|
-
return hit;
|
|
1231
|
+
if (hit === undefined) return undefined;
|
|
1232
|
+
return bindingFor(client.frameAddress(info.id, info.args), info.id);
|
|
1297
1233
|
}),
|
|
1298
1234
|
handle(response, ctx) {
|
|
1299
1235
|
if (!isFrameStreamResponse(response)) return undefined;
|
|
1300
1236
|
const address = client.frameAddress(ctx.id, ctx.args);
|
|
1301
|
-
|
|
1302
|
-
if (!entry) {
|
|
1303
|
-
const adopted = documentComponent && documentComponent(ctx.id);
|
|
1304
|
-
if (adopted) {
|
|
1305
|
-
entry = {
|
|
1306
|
-
frameId: ctx.id,
|
|
1307
|
-
component: brand(adopted, ctx.id, ctx.id)
|
|
1308
|
-
};
|
|
1309
|
-
byAddress.set(address, entry);
|
|
1310
|
-
} else {
|
|
1311
|
-
entry = boundaryFor(address, ctx.id);
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1237
|
+
const binding = bindingFor(address, ctx.id);
|
|
1314
1238
|
if (response.headers.has(client.SINGLE_FLIGHT_HEADER)) {
|
|
1315
|
-
return applyFlightResponse(response,
|
|
1239
|
+
return applyFlightResponse(response, address, binding);
|
|
1316
1240
|
}
|
|
1317
|
-
const version = bump(
|
|
1318
|
-
if (onStream) onStream(
|
|
1241
|
+
const version = bump(address);
|
|
1242
|
+
if (onStream) onStream(address, version, response);
|
|
1319
1243
|
applyFrameResponse(response, host, {
|
|
1320
|
-
as:
|
|
1244
|
+
as: address,
|
|
1321
1245
|
version
|
|
1322
1246
|
}).catch(err => host.apply({
|
|
1323
1247
|
type: "error",
|
|
1324
|
-
id:
|
|
1248
|
+
id: address,
|
|
1325
1249
|
version,
|
|
1326
1250
|
error: {
|
|
1327
1251
|
message: String(err && err.message)
|
|
1328
1252
|
}
|
|
1329
1253
|
}));
|
|
1330
|
-
return
|
|
1254
|
+
return binding;
|
|
1331
1255
|
},
|
|
1332
|
-
showing(address, functionId
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1256
|
+
showing(address, functionId) {
|
|
1257
|
+
bindingFor(address, functionId);
|
|
1258
|
+
const comp = componentFor(functionId);
|
|
1259
|
+
if (comp && (typeof comp === "function" || typeof comp === "object") && !comp[COMPONENT_BINDING]) {
|
|
1260
|
+
comp[COMPONENT_BINDING] = {
|
|
1261
|
+
component: comp,
|
|
1337
1262
|
address
|
|
1338
|
-
}
|
|
1263
|
+
};
|
|
1339
1264
|
}
|
|
1340
1265
|
}
|
|
1341
1266
|
};
|
|
1342
|
-
async function applyFlightResponse(response,
|
|
1267
|
+
async function applyFlightResponse(response, address, binding) {
|
|
1343
1268
|
const rootId = response.headers.get(FRAME_STREAM_HEADER) ?? "";
|
|
1344
|
-
const as = rootId ?
|
|
1269
|
+
const as = rootId ? address : undefined;
|
|
1345
1270
|
let feed;
|
|
1346
1271
|
const source = new ReadableStream({
|
|
1347
1272
|
start(controller) {
|
|
@@ -1352,10 +1277,6 @@ function createServerComponentHandler({
|
|
|
1352
1277
|
let carried = false;
|
|
1353
1278
|
await applyFrameResponse(response, host, {
|
|
1354
1279
|
as,
|
|
1355
|
-
route: id => {
|
|
1356
|
-
const local = byAddress.get(id);
|
|
1357
|
-
return local ? local.frameId : id;
|
|
1358
|
-
},
|
|
1359
1280
|
version: frameId => {
|
|
1360
1281
|
const version = bump(frameId);
|
|
1361
1282
|
if (onStream) onStream(frameId, version, response);
|
|
@@ -1376,7 +1297,7 @@ function createServerComponentHandler({
|
|
|
1376
1297
|
if (response.headers.has(client.ERROR_HEADER) && !response.headers.has("Location") && !response.headers.has(client.REVALIDATE_HEADER)) {
|
|
1377
1298
|
throw envelope.value;
|
|
1378
1299
|
}
|
|
1379
|
-
return rootId ?
|
|
1300
|
+
return rootId ? binding : envelope.value;
|
|
1380
1301
|
}
|
|
1381
1302
|
}
|
|
1382
1303
|
|
|
@@ -1427,6 +1348,9 @@ function createJSONDataTable(options) {
|
|
|
1427
1348
|
};
|
|
1428
1349
|
}
|
|
1429
1350
|
|
|
1351
|
+
function asyncArg(value) {
|
|
1352
|
+
return value;
|
|
1353
|
+
}
|
|
1430
1354
|
let sharedHost;
|
|
1431
1355
|
const tables = new Map();
|
|
1432
1356
|
function tableFor(id) {
|
|
@@ -1503,8 +1427,26 @@ function claimRender(prefix, existing, render) {
|
|
|
1503
1427
|
function liveSlotProps(initial, ctx) {
|
|
1504
1428
|
const [args, setArgs] = solidJs.createSignal(initial);
|
|
1505
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();
|
|
1506
1438
|
return new Proxy({}, {
|
|
1507
|
-
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
|
+
},
|
|
1508
1450
|
has: (_, key) => key in args(),
|
|
1509
1451
|
ownKeys: () => Reflect.ownKeys(args()),
|
|
1510
1452
|
getOwnPropertyDescriptor: (_, key) => key in args() ? {
|
|
@@ -1522,6 +1464,7 @@ function isReactiveContent(value) {
|
|
|
1522
1464
|
}
|
|
1523
1465
|
function slotsFor(props) {
|
|
1524
1466
|
const bindings = new Map();
|
|
1467
|
+
const fillScopes = new Map();
|
|
1525
1468
|
return new Proxy({}, {
|
|
1526
1469
|
get(_, prop) {
|
|
1527
1470
|
if (typeof prop !== "string" || !(prop in props)) return undefined;
|
|
@@ -1532,6 +1475,19 @@ function slotsFor(props) {
|
|
|
1532
1475
|
bindings.delete(key);
|
|
1533
1476
|
prev.dispose();
|
|
1534
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
|
+
}
|
|
1535
1491
|
const settle = out => {
|
|
1536
1492
|
const existing = ctx && ctx.existing || [];
|
|
1537
1493
|
if (existing.length) {
|
|
@@ -1544,26 +1500,18 @@ function slotsFor(props) {
|
|
|
1544
1500
|
const evaluate = () => {
|
|
1545
1501
|
const v = props[prop];
|
|
1546
1502
|
if (typeof v === "function" && ctx && ctx.invoked) {
|
|
1547
|
-
return v(ctx.onUpdate ? liveSlotProps(slotProps, ctx) : slotProps);
|
|
1503
|
+
return v(ctx.onUpdate ? liveSlotProps(slotProps, ctx) : slotArgsProxy(() => slotProps));
|
|
1548
1504
|
}
|
|
1549
1505
|
return v;
|
|
1550
1506
|
};
|
|
1551
1507
|
const adopted = !!(ctx && ctx.frame && ctx.adopted && ctx.existing && ctx.existing.length);
|
|
1552
1508
|
const prefix = ctx && ctx.frame ? `sc-${ctx.frame}-${ctx.key}-` : "";
|
|
1553
|
-
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();
|
|
1554
1510
|
if (!isReactiveContent(value)) {
|
|
1555
1511
|
return settle(normalizeSlotContent(value));
|
|
1556
1512
|
}
|
|
1557
1513
|
if (ctx && ctx.range) {
|
|
1558
|
-
let claim = adopted;
|
|
1559
1514
|
const source = value;
|
|
1560
|
-
const accessor = () => {
|
|
1561
|
-
if (claim) {
|
|
1562
|
-
claim = false;
|
|
1563
|
-
return claimRender(prefix, ctx.existing, () => typeof source === "function" ? source() : source);
|
|
1564
|
-
}
|
|
1565
|
-
return typeof source === "function" ? source() : source;
|
|
1566
|
-
};
|
|
1567
1515
|
const owner = solidJs.createOwner();
|
|
1568
1516
|
bindings.set(key, owner);
|
|
1569
1517
|
ctx.onCleanup(() => {
|
|
@@ -1571,7 +1519,8 @@ function slotsFor(props) {
|
|
|
1571
1519
|
owner.dispose();
|
|
1572
1520
|
});
|
|
1573
1521
|
const end = ctx.range.end;
|
|
1574
|
-
|
|
1522
|
+
const bind = () => web$1.insert(end.parentNode, () => typeof source === "function" ? source() : source, end, [...ctx.existing]);
|
|
1523
|
+
solidJs.runWithOwner(owner, () => adopted ? claimRender(prefix, ctx.existing, bind) : bind());
|
|
1575
1524
|
return undefined;
|
|
1576
1525
|
}
|
|
1577
1526
|
return settle(normalizeSlotContent(value));
|
|
@@ -1582,24 +1531,61 @@ function slotsFor(props) {
|
|
|
1582
1531
|
function revealSeam(owner) {
|
|
1583
1532
|
return seam => solidJs.runWithOwner(owner, () => web$1.insert(seam.before.parentNode, solidJs.createLoadingBoundary(() => seam.content(), () => seam.fallback), seam.before));
|
|
1584
1533
|
}
|
|
1534
|
+
let streamInvoke = false;
|
|
1585
1535
|
function boundaryScope(owner) {
|
|
1586
|
-
return fn =>
|
|
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
|
+
};
|
|
1587
1545
|
}
|
|
1588
|
-
function boundaryComponent(host,
|
|
1589
|
-
return props => {
|
|
1546
|
+
function boundaryComponent(host, fnId) {
|
|
1547
|
+
return (props, binding) => {
|
|
1590
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;
|
|
1591
1555
|
const {
|
|
1592
1556
|
element,
|
|
1557
|
+
frame,
|
|
1593
1558
|
dispose
|
|
1594
1559
|
} = createFrameElement({
|
|
1595
1560
|
host,
|
|
1596
1561
|
id,
|
|
1597
1562
|
slots: slotsFor(props),
|
|
1598
1563
|
ownerScope: boundaryScope(owner),
|
|
1599
|
-
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
|
+
}
|
|
1600
1573
|
});
|
|
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
|
+
}
|
|
1601
1585
|
solidJs.onCleanup(dispose);
|
|
1602
|
-
return element;
|
|
1586
|
+
if (applied && !binding) return element;
|
|
1587
|
+
const gate = solidJs.createMemo(() => gatePromise());
|
|
1588
|
+
return solidJs.createMemo(() => (gate(), element));
|
|
1603
1589
|
};
|
|
1604
1590
|
}
|
|
1605
1591
|
const claimedBoundaries = new Set();
|
|
@@ -1619,51 +1605,76 @@ function findBoundaryElement(id) {
|
|
|
1619
1605
|
return boundaryIndex.get(id);
|
|
1620
1606
|
}
|
|
1621
1607
|
const boundaryWaiters = new Map();
|
|
1622
|
-
function
|
|
1608
|
+
function boundaryMayArrive() {
|
|
1623
1609
|
const hy = globalThis._$HY;
|
|
1624
|
-
|
|
1610
|
+
if (!hy) return false;
|
|
1611
|
+
return !hy.done || !!(hy.fr && hy.fr.pending());
|
|
1625
1612
|
}
|
|
1626
1613
|
function installRevealHook() {
|
|
1627
1614
|
const hy = globalThis._$HY;
|
|
1628
|
-
if (!hy || hy.$sc) return;
|
|
1615
|
+
if (!hy || hy.$sc || !hy.fr) return;
|
|
1629
1616
|
hy.$sc = true;
|
|
1630
|
-
|
|
1631
|
-
hy.fe = (fragmentId, parent) => {
|
|
1632
|
-
if (prev) prev(fragmentId, parent);
|
|
1617
|
+
hy.fr.subscribe((_id, parent) => {
|
|
1633
1618
|
if (!boundaryIndex) return;
|
|
1634
1619
|
const root = parent || (typeof document !== "undefined" ? document.body : null);
|
|
1635
|
-
if (
|
|
1636
|
-
|
|
1620
|
+
if (root) indexBoundaries(root);
|
|
1621
|
+
if (!boundaryWaiters.size) return;
|
|
1622
|
+
const exhausted = hy.done && !hy.fr.pending();
|
|
1637
1623
|
for (const [id, notify] of boundaryWaiters) {
|
|
1638
|
-
const el = boundaryIndex.get(id);
|
|
1639
|
-
if (!el) continue;
|
|
1624
|
+
const el = boundaryIndex && boundaryIndex.get(id);
|
|
1625
|
+
if (!el && !exhausted) continue;
|
|
1640
1626
|
boundaryWaiters.delete(id);
|
|
1641
1627
|
notify(el);
|
|
1642
1628
|
}
|
|
1643
|
-
};
|
|
1629
|
+
});
|
|
1644
1630
|
}
|
|
1645
|
-
function documentBoundary(host, id, props) {
|
|
1631
|
+
function documentBoundary(host, id, props, binding) {
|
|
1632
|
+
installRevealHook();
|
|
1646
1633
|
const claimed = claimedBoundaries.has(id);
|
|
1647
1634
|
const el = !claimed ? findBoundaryElement(id) : undefined;
|
|
1648
|
-
if (el) return adoptBoundary(host, id, el, props);
|
|
1649
|
-
if (!claimed && !boundaryWaiters.has(id) &&
|
|
1635
|
+
if (el) return adoptBoundary(host, id, el, props, binding);
|
|
1636
|
+
if (!claimed && !boundaryWaiters.has(id) && boundaryMayArrive()) {
|
|
1650
1637
|
const owner = solidJs.getOwner();
|
|
1651
1638
|
const arrival = new Promise(resolve => boundaryWaiters.set(id, resolve));
|
|
1652
1639
|
solidJs.onCleanup(() => boundaryWaiters.delete(id));
|
|
1653
|
-
return solidJs.createMemo(() => arrival.then(node => solidJs.runWithOwner(owner, () =>
|
|
1640
|
+
return solidJs.createMemo(() => arrival.then(node => solidJs.runWithOwner(owner, () =>
|
|
1641
|
+
node ? adoptBoundary(host, id, node, props, binding) : boundaryComponent(host, id)(props, binding))));
|
|
1654
1642
|
}
|
|
1655
|
-
return boundaryComponent(host, id)(props);
|
|
1643
|
+
return boundaryComponent(host, id)(props, binding);
|
|
1656
1644
|
}
|
|
1657
|
-
function
|
|
1645
|
+
function documentAddress(id) {
|
|
1646
|
+
const records = globalThis._$SC?.a;
|
|
1647
|
+
if (records) {
|
|
1648
|
+
for (const address in records) if (records[address] === id) return address;
|
|
1649
|
+
}
|
|
1650
|
+
return id;
|
|
1651
|
+
}
|
|
1652
|
+
function adoptBoundary(host, id, el, props, binding) {
|
|
1658
1653
|
claimedBoundaries.add(id);
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1654
|
+
const address = binding ? binding() : documentAddress(id);
|
|
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
|
+
};
|
|
1667
|
+
const drainRecords = () => {
|
|
1668
|
+
const hy = globalThis._$HY;
|
|
1669
|
+
if (!hy || !hy.r) return;
|
|
1661
1670
|
const slotPrefix = `sc:slot:${id}:`;
|
|
1662
1671
|
for (const key of Object.keys(hy.r)) {
|
|
1672
|
+
if (appliedRecords.has(key)) continue;
|
|
1663
1673
|
if (key.startsWith(slotPrefix)) {
|
|
1674
|
+
appliedRecords.add(key);
|
|
1664
1675
|
host.apply({
|
|
1665
1676
|
type: "slot",
|
|
1666
|
-
id,
|
|
1677
|
+
id: address,
|
|
1667
1678
|
version: 0,
|
|
1668
1679
|
key: key.slice(slotPrefix.length),
|
|
1669
1680
|
args: hy.r[key]
|
|
@@ -1671,6 +1682,7 @@ function adoptBoundary(host, id, el, props) {
|
|
|
1671
1682
|
} else if (key.startsWith("sc:region:")) {
|
|
1672
1683
|
const childId = key.slice("sc:region:".length);
|
|
1673
1684
|
if (childId.startsWith(id + ".")) {
|
|
1685
|
+
appliedRecords.add(key);
|
|
1674
1686
|
const val = hy.r[key];
|
|
1675
1687
|
const apply = html => host.apply({
|
|
1676
1688
|
type: "html",
|
|
@@ -1682,16 +1694,58 @@ function adoptBoundary(host, id, el, props) {
|
|
|
1682
1694
|
}
|
|
1683
1695
|
}
|
|
1684
1696
|
}
|
|
1685
|
-
}
|
|
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
|
+
});
|
|
1708
|
+
drainRecords();
|
|
1686
1709
|
const owner = solidJs.getOwner();
|
|
1710
|
+
let release;
|
|
1711
|
+
let setGate;
|
|
1687
1712
|
const frame = createFrame(el, {
|
|
1688
1713
|
adopt: true,
|
|
1689
1714
|
host,
|
|
1690
|
-
id,
|
|
1715
|
+
id: address,
|
|
1691
1716
|
slots: slotsFor(props),
|
|
1692
1717
|
ownerScope: boundaryScope(owner),
|
|
1693
|
-
reveal: revealSeam(owner)
|
|
1718
|
+
reveal: revealSeam(owner),
|
|
1719
|
+
onApply: () => {
|
|
1720
|
+
if (release) {
|
|
1721
|
+
release();
|
|
1722
|
+
release = undefined;
|
|
1723
|
+
}
|
|
1724
|
+
setGate && setGate(undefined);
|
|
1725
|
+
},
|
|
1726
|
+
...{
|
|
1727
|
+
recordsPending: () => {
|
|
1728
|
+
if (document.readyState === "loading") return true;
|
|
1729
|
+
const hy = globalThis._$HY;
|
|
1730
|
+
return !!(hy && hy.fr && hy.fr.pending());
|
|
1731
|
+
},
|
|
1732
|
+
drainRecords,
|
|
1733
|
+
claimScope: id
|
|
1734
|
+
}
|
|
1694
1735
|
});
|
|
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
|
+
}
|
|
1695
1749
|
solidJs.onCleanup(() => frame.dispose());
|
|
1696
1750
|
return el;
|
|
1697
1751
|
}
|
|
@@ -1706,17 +1760,16 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1706
1760
|
g._$SC.a[a] = i;
|
|
1707
1761
|
g._$SC.reg && g._$SC.reg(a, i);
|
|
1708
1762
|
}
|
|
1709
|
-
return g._$SC.c[i] || (g._$SC.c[i] = p => g._$SC.impl(i, p));
|
|
1763
|
+
return g._$SC.c[i] || (g._$SC.c[i] = (p, b) => g._$SC.impl(i, p, b));
|
|
1710
1764
|
}
|
|
1711
1765
|
};
|
|
1712
1766
|
}
|
|
1713
|
-
g._$SC.impl = (id, props) => documentBoundary(host, id, props);
|
|
1767
|
+
g._$SC.impl = (id, props, binding) => documentBoundary(host, id, props, binding);
|
|
1714
1768
|
installRevealHook();
|
|
1715
1769
|
const handler = createServerComponentHandler({
|
|
1716
1770
|
host,
|
|
1717
|
-
component:
|
|
1718
|
-
onStream:
|
|
1719
|
-
documentComponent: functionId => claimedBoundaries.has(functionId) ? undefined : g._$SC.c[functionId],
|
|
1771
|
+
component: fnId => g._$SC.r(fnId),
|
|
1772
|
+
onStream: address => beginStream(address),
|
|
1720
1773
|
intercept: ({
|
|
1721
1774
|
id
|
|
1722
1775
|
}) => {
|
|
@@ -1724,7 +1777,7 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1724
1777
|
return g._$SC.r(id);
|
|
1725
1778
|
}
|
|
1726
1779
|
});
|
|
1727
|
-
const showing = (address, id) => handler.showing(address, id
|
|
1780
|
+
const showing = (address, id) => handler.showing(address, id);
|
|
1728
1781
|
const records = g._$SC.a || (g._$SC.a = {});
|
|
1729
1782
|
for (const address in records) showing(address, records[address]);
|
|
1730
1783
|
g._$SC.reg = showing;
|
|
@@ -1736,10 +1789,10 @@ function installServerComponents(host = getFrameHost()) {
|
|
|
1736
1789
|
exports.FRAME_APPLIED_EVENT = FRAME_APPLIED_EVENT;
|
|
1737
1790
|
exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
|
|
1738
1791
|
exports.applyFrameResponse = applyFrameResponse;
|
|
1792
|
+
exports.asyncArg = asyncArg;
|
|
1739
1793
|
exports.createFrame = createFrame;
|
|
1740
1794
|
exports.createFrameElement = createFrameElement;
|
|
1741
1795
|
exports.createFrameHost = createFrameHost;
|
|
1742
|
-
exports.createJSONDataTable = createJSONDataTable;
|
|
1743
1796
|
exports.createServerComponentHandler = createServerComponentHandler;
|
|
1744
1797
|
exports.getFrameHost = getFrameHost;
|
|
1745
1798
|
exports.installServerComponents = installServerComponents;
|