@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/server.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, NoHydration, runInServerComponentScope, Hydration } from 'solid-js';
|
|
1
|
+
import { createMemo, runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, NoHydration, runInServerComponentScope, Hydration } from 'solid-js';
|
|
2
2
|
import { toCrossJSONStream, Feature, Serializer, getCrossReferenceHeader, createPlugin } from 'seroval';
|
|
3
3
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
4
4
|
|
|
5
5
|
const runWithHydrationScope = (id, fn) => runWithOwner(createOwner({
|
|
6
6
|
id
|
|
7
7
|
}), fn);
|
|
8
|
+
const ssrAsyncValue = value => createMemo(() => value, {
|
|
9
|
+
serialize: false
|
|
10
|
+
});
|
|
8
11
|
|
|
9
12
|
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
10
13
|
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
|
|
@@ -135,9 +138,146 @@ function createJSONSerializer({
|
|
|
135
138
|
};
|
|
136
139
|
}
|
|
137
140
|
|
|
141
|
+
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
142
|
+
function isResponseEnvelope(value) {
|
|
143
|
+
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
144
|
+
}
|
|
145
|
+
const REVALIDATE_HEADER = "X-Revalidate";
|
|
146
|
+
|
|
147
|
+
function frameAddress(id, args) {
|
|
148
|
+
return args && args.length ? id + ":" + hashArguments(args) : id;
|
|
149
|
+
}
|
|
150
|
+
function hashArguments(args) {
|
|
151
|
+
let hash = 0;
|
|
152
|
+
const text = stableString(args);
|
|
153
|
+
for (let i = 0; i < text.length; i++) {
|
|
154
|
+
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
155
|
+
hash |= 0;
|
|
156
|
+
}
|
|
157
|
+
return (hash >>> 0).toString(36);
|
|
158
|
+
}
|
|
159
|
+
function stableString(value, seen) {
|
|
160
|
+
if (value === null || typeof value !== "object") {
|
|
161
|
+
return typeof value === "bigint" ? value + "n" : String(value);
|
|
162
|
+
}
|
|
163
|
+
if (value instanceof Date) return "Date:" + value.getTime();
|
|
164
|
+
seen || (seen = new Set());
|
|
165
|
+
if (seen.has(value)) return "~";
|
|
166
|
+
seen.add(value);
|
|
167
|
+
if (value instanceof Map) {
|
|
168
|
+
const entries = [];
|
|
169
|
+
for (const [k, v] of value) {
|
|
170
|
+
entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
|
|
171
|
+
}
|
|
172
|
+
return "Map{" + entries.sort().join(",") + "}";
|
|
173
|
+
}
|
|
174
|
+
if (value instanceof Set) {
|
|
175
|
+
const members = [];
|
|
176
|
+
for (const v of value) members.push(stableString(v, seen));
|
|
177
|
+
return "Set{" + members.sort().join(",") + "}";
|
|
178
|
+
}
|
|
179
|
+
if (Array.isArray(value)) {
|
|
180
|
+
let out = "[";
|
|
181
|
+
for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
|
|
182
|
+
return out + "]";
|
|
183
|
+
}
|
|
184
|
+
const keys = Object.keys(value).sort();
|
|
185
|
+
let out = "{";
|
|
186
|
+
for (let i = 0; i < keys.length; i++) {
|
|
187
|
+
out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
|
|
188
|
+
}
|
|
189
|
+
return out + "}";
|
|
190
|
+
}
|
|
191
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
192
|
+
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
193
|
+
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
194
|
+
function createChunk(data) {
|
|
195
|
+
const encoder = new TextEncoder();
|
|
196
|
+
const encodeData = encoder.encode(data);
|
|
197
|
+
const bytes = encodeData.length;
|
|
198
|
+
const chunk = new Uint8Array(12 + bytes);
|
|
199
|
+
chunk.set(encoder.encode(`;0x${bytes.toString(16).padStart(8, "0")};`));
|
|
200
|
+
chunk.set(encodeData, 12);
|
|
201
|
+
return chunk;
|
|
202
|
+
}
|
|
203
|
+
class ChunkReader {
|
|
204
|
+
constructor(stream) {
|
|
205
|
+
this.reader = stream.getReader();
|
|
206
|
+
this.buffer = new Uint8Array(0);
|
|
207
|
+
this.done = false;
|
|
208
|
+
}
|
|
209
|
+
async readChunk() {
|
|
210
|
+
const chunk = await this.reader.read();
|
|
211
|
+
if (!chunk.done) {
|
|
212
|
+
const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
|
|
213
|
+
newBuffer.set(this.buffer);
|
|
214
|
+
newBuffer.set(chunk.value, this.buffer.length);
|
|
215
|
+
this.buffer = newBuffer;
|
|
216
|
+
} else {
|
|
217
|
+
this.done = true;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async next() {
|
|
221
|
+
while (this.buffer.length < 12) {
|
|
222
|
+
if (this.done) {
|
|
223
|
+
if (this.buffer.length === 0) return {
|
|
224
|
+
done: true,
|
|
225
|
+
value: undefined
|
|
226
|
+
};
|
|
227
|
+
throw new Error("Malformed server function stream.");
|
|
228
|
+
}
|
|
229
|
+
await this.readChunk();
|
|
230
|
+
}
|
|
231
|
+
const decoder = new TextDecoder();
|
|
232
|
+
const bytes = Number.parseInt(decoder.decode(this.buffer.subarray(1, 11)), 16);
|
|
233
|
+
if (Number.isNaN(bytes)) {
|
|
234
|
+
throw new Error("Malformed server function stream.");
|
|
235
|
+
}
|
|
236
|
+
while (bytes > this.buffer.length - 12) {
|
|
237
|
+
if (this.done) {
|
|
238
|
+
throw new Error("Malformed server function stream.");
|
|
239
|
+
}
|
|
240
|
+
await this.readChunk();
|
|
241
|
+
}
|
|
242
|
+
const partial = decoder.decode(this.buffer.subarray(12, 12 + bytes));
|
|
243
|
+
this.buffer = this.buffer.subarray(12 + bytes);
|
|
244
|
+
return {
|
|
245
|
+
done: false,
|
|
246
|
+
value: partial
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
async drain(interpret) {
|
|
250
|
+
while (true) {
|
|
251
|
+
const result = await this.next();
|
|
252
|
+
if (result.done) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
interpret(result.value);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function serializeStream(value, codecOptions) {
|
|
260
|
+
return new ReadableStream({
|
|
261
|
+
start(controller) {
|
|
262
|
+
serializeJSON(value, {
|
|
263
|
+
...codecOptions,
|
|
264
|
+
onParse(node) {
|
|
265
|
+
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
266
|
+
},
|
|
267
|
+
onDone() {
|
|
268
|
+
controller.close();
|
|
269
|
+
},
|
|
270
|
+
onError(error) {
|
|
271
|
+
controller.error(error);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
138
278
|
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
139
279
|
const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
|
|
140
|
-
const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "
|
|
280
|
+
const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "stylesheet"]);
|
|
141
281
|
const RESOURCE_QUALIFIERS = ["as", "crossorigin", "type", "media", "imagesrcset", "imagesizes"];
|
|
142
282
|
const STYLESHEET_FETCH_META = new Set(["crossorigin", "integrity", "referrerpolicy", "fetchpriority"]);
|
|
143
283
|
function evalHeadValue(v) {
|
|
@@ -181,12 +321,14 @@ function replaceableIdentity(tag, props, key, unique) {
|
|
|
181
321
|
if (tag === "meta" && props.charset != null) return "charset";
|
|
182
322
|
if (key != null) return tag + ":key:" + key;
|
|
183
323
|
if (tag === "meta") {
|
|
184
|
-
if (props
|
|
185
|
-
if (props.property != null) return "meta:property:" + props.property;
|
|
186
|
-
if (props["http-equiv"] != null) return "meta:http-equiv:" + props["http-equiv"];
|
|
324
|
+
for (const ns of ["name", "property", "http-equiv"]) if (props[ns] != null) return "meta:" + ns + ":" + props[ns] + (props.media != null ? ":media=" + props.media : "");
|
|
187
325
|
return unique;
|
|
188
326
|
}
|
|
189
|
-
if (tag === "link")
|
|
327
|
+
if (tag === "link") {
|
|
328
|
+
const rel = props.rel || "";
|
|
329
|
+
if (rel === "icon" || rel === "apple-touch-icon") return "link:" + rel + (props.sizes != null ? ":sizes=" + props.sizes : "") + (props.type != null ? ":type=" + props.type : "");
|
|
330
|
+
return "link:" + rel + ":" + (props.href || "");
|
|
331
|
+
}
|
|
190
332
|
return unique;
|
|
191
333
|
}
|
|
192
334
|
function resolveHead(groups) {
|
|
@@ -373,11 +515,22 @@ function createHeadRegistry() {
|
|
|
373
515
|
resources: new Set(),
|
|
374
516
|
eagerHtml: "",
|
|
375
517
|
flushed: null,
|
|
376
|
-
shellFlushed: false
|
|
518
|
+
shellFlushed: false,
|
|
519
|
+
parkedResources: []
|
|
377
520
|
};
|
|
378
521
|
}
|
|
379
522
|
function registerHeadTags(registry, context, tracking, emitResource, nonce, tags) {
|
|
380
523
|
const boundary = context._currentBoundaryId || "";
|
|
524
|
+
if (typeof tags === "function") {
|
|
525
|
+
registry.pending.push({
|
|
526
|
+
boundary,
|
|
527
|
+
list: tags,
|
|
528
|
+
resource: (desc, rel) => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
|
|
529
|
+
});
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (!Array.isArray(tags)) tags = [tags];
|
|
533
|
+
const probe = sharedConfig.context && sharedConfig.context._loadingPhase;
|
|
381
534
|
let replaceable = null;
|
|
382
535
|
for (let i = 0; i < tags.length; i++) {
|
|
383
536
|
const desc = tags[i];
|
|
@@ -386,6 +539,16 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
386
539
|
continue;
|
|
387
540
|
}
|
|
388
541
|
const cls = classifyHeadTag(desc);
|
|
542
|
+
if (probe && !cls.resource) {
|
|
543
|
+
try {
|
|
544
|
+
evalHeadProps(desc.props || {}, cls.rel !== undefined ? {
|
|
545
|
+
rel: cls.rel
|
|
546
|
+
} : undefined);
|
|
547
|
+
evalHeadValue(desc.key);
|
|
548
|
+
} catch (err) {
|
|
549
|
+
if (ssrHandleError(err)) throw err;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
389
552
|
if (cls.resource) {
|
|
390
553
|
emitHeadResource(registry, context, tracking, emitResource, nonce, desc, cls.rel);
|
|
391
554
|
} else {
|
|
@@ -402,6 +565,52 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
402
565
|
tags: replaceable
|
|
403
566
|
});
|
|
404
567
|
}
|
|
568
|
+
function headShellReady(registry, block) {
|
|
569
|
+
let ready = true;
|
|
570
|
+
const pends = err => {
|
|
571
|
+
const source = ssrHandleError(err, true);
|
|
572
|
+
if (!source) return false;
|
|
573
|
+
block(source);
|
|
574
|
+
ready = false;
|
|
575
|
+
return true;
|
|
576
|
+
};
|
|
577
|
+
const parked = registry.parkedResources;
|
|
578
|
+
for (let i = parked.length - 1; i >= 0; i--) {
|
|
579
|
+
const {
|
|
580
|
+
desc,
|
|
581
|
+
rel,
|
|
582
|
+
emit
|
|
583
|
+
} = parked[i];
|
|
584
|
+
try {
|
|
585
|
+
evalHeadProps(desc.props || {}, rel !== undefined ? {
|
|
586
|
+
rel
|
|
587
|
+
} : undefined);
|
|
588
|
+
} catch (err) {
|
|
589
|
+
if (pends(err)) continue;
|
|
590
|
+
console.warn(`useHead: error evaluating resource tag props`, err);
|
|
591
|
+
parked.splice(i, 1);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
parked.splice(i, 1);
|
|
595
|
+
emit();
|
|
596
|
+
}
|
|
597
|
+
for (let i = 0; i < registry.pending.length; i++) {
|
|
598
|
+
const reg = registry.pending[i];
|
|
599
|
+
if (reg.boundary !== "" || reg.list) continue;
|
|
600
|
+
for (let j = 0; j < reg.tags.length; j++) {
|
|
601
|
+
const desc = reg.tags[j];
|
|
602
|
+
try {
|
|
603
|
+
evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
|
|
604
|
+
rel: desc.rel
|
|
605
|
+
} : undefined);
|
|
606
|
+
evalHeadValue(desc.key);
|
|
607
|
+
} catch (err) {
|
|
608
|
+
pends(err);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return ready;
|
|
613
|
+
}
|
|
405
614
|
function emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel) {
|
|
406
615
|
let props;
|
|
407
616
|
try {
|
|
@@ -409,6 +618,16 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
|
|
|
409
618
|
rel
|
|
410
619
|
} : undefined);
|
|
411
620
|
} catch (err) {
|
|
621
|
+
const loadingPhase = sharedConfig.context && sharedConfig.context._loadingPhase;
|
|
622
|
+
if (loadingPhase && ssrHandleError(err)) throw err;
|
|
623
|
+
if (!loadingPhase && !context._currentBoundaryId && !registry.shellFlushed && typeof context.block === "function" && ssrHandleError(err, true)) {
|
|
624
|
+
registry.parkedResources.push({
|
|
625
|
+
desc,
|
|
626
|
+
rel,
|
|
627
|
+
emit: () => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
|
|
628
|
+
});
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
412
631
|
console.warn(`useHead: error evaluating resource tag props`, err);
|
|
413
632
|
return;
|
|
414
633
|
}
|
|
@@ -465,9 +684,39 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
465
684
|
keep.push(reg);
|
|
466
685
|
continue;
|
|
467
686
|
}
|
|
687
|
+
let descs = reg.tags;
|
|
688
|
+
if (reg.list) {
|
|
689
|
+
let resolved;
|
|
690
|
+
try {
|
|
691
|
+
resolved = reg.list();
|
|
692
|
+
} catch (err) {
|
|
693
|
+
console.warn(`useHead: error evaluating head group membership`, err);
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
if (!Array.isArray(resolved)) resolved = [resolved];
|
|
697
|
+
descs = [];
|
|
698
|
+
for (let j = 0; j < resolved.length; j++) {
|
|
699
|
+
const desc = resolved[j];
|
|
700
|
+
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
701
|
+
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
const cls = classifyHeadTag(desc);
|
|
705
|
+
if (cls.resource) {
|
|
706
|
+
reg.resource(desc, cls.rel);
|
|
707
|
+
} else {
|
|
708
|
+
descs.push(cls.rel !== undefined ? {
|
|
709
|
+
tag: desc.tag,
|
|
710
|
+
props: desc.props,
|
|
711
|
+
key: desc.key,
|
|
712
|
+
rel: cls.rel
|
|
713
|
+
} : desc);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
468
717
|
const tags = [];
|
|
469
|
-
for (let j = 0; j <
|
|
470
|
-
const desc =
|
|
718
|
+
for (let j = 0; j < descs.length; j++) {
|
|
719
|
+
const desc = descs[j];
|
|
471
720
|
let props, key;
|
|
472
721
|
try {
|
|
473
722
|
props = evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
|
|
@@ -610,7 +859,7 @@ function renderHeadTagMarkup(tag, props, identity, nonce) {
|
|
|
610
859
|
if (tag === "script") body = body.replace(/<\/(script)/gi, "<\\/$1");else if (tag === "style") body = escapeStyleContent(body);else body = escape(body);
|
|
611
860
|
return `<${tag}${attrs}>${body}</${tag}>`;
|
|
612
861
|
}
|
|
613
|
-
const REPLACE_SCRIPT = `function $df(e){return _$HY.f?_$HY.f(e):$dfr(e)}function $dfr(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;t=o.parentNode,o.replaceWith(n.content),n.remove(),_$HY.fe(e,t),_$HY.hp&&_$HY.hp[e]&&($dh(_$HY.hp[e]),delete _$HY.hp[e]),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
|
|
862
|
+
const REPLACE_SCRIPT = `function $df(e){return _$HY.f?_$HY.f(e):$dfr(e)}function $dfr(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;t=o.parentNode,o.replaceWith(n.content),n.remove(),(_$HY.v=_$HY.v||{})[e]=1,_$HY.fe(e,t),_$HY.hp&&_$HY.hp[e]&&($dh(_$HY.hp[e]),delete _$HY.hp[e]),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
|
|
614
863
|
const HEAD_SCRIPT = `function $dha(o,i,e,n){for(i=0;i<o.length;i++)e=o[i],"t"==e[0]?((n=document.querySelector("title"))||(n=document.createElement("title"),document.head.appendChild(n)),n.textContent=e[1],n.setAttribute("data-dh","title")):"r"==e[0]?$dhr(e[1]):(n=document.createElement(e[2]),Object.keys(e[3]).forEach(function(a){n.setAttribute(a,e[3][a])}),null!=e[4]&&(n.textContent=e[4]),n.setAttribute("data-dh",e[1]),document.head.appendChild(n))}function $dhr(v,l,i){for(l=document.head.querySelectorAll("[data-dh]"),i=0;i<l.length;i++)l[i].getAttribute("data-dh")==v&&l[i].remove()}function $dh(o){_$HY.h?_$HY.h(o):$dha(o)}`;
|
|
615
864
|
function renderToStream(code, options = {}) {
|
|
616
865
|
let {
|
|
@@ -623,6 +872,41 @@ function renderToStream(code, options = {}) {
|
|
|
623
872
|
onHead
|
|
624
873
|
} = options;
|
|
625
874
|
let dispose;
|
|
875
|
+
let dead = false;
|
|
876
|
+
const abandon = () => {
|
|
877
|
+
if (dead) return;
|
|
878
|
+
dead = true;
|
|
879
|
+
completed = true;
|
|
880
|
+
buffer = {
|
|
881
|
+
write() {}
|
|
882
|
+
};
|
|
883
|
+
writable = {
|
|
884
|
+
end() {}
|
|
885
|
+
};
|
|
886
|
+
if (dispose) {
|
|
887
|
+
const d = dispose;
|
|
888
|
+
dispose = () => {};
|
|
889
|
+
d();
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
const guardSink = w => ({
|
|
893
|
+
write(payload) {
|
|
894
|
+
if (dead) return;
|
|
895
|
+
try {
|
|
896
|
+
w.write(payload);
|
|
897
|
+
} catch (_) {
|
|
898
|
+
abandon();
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
end() {
|
|
902
|
+
if (dead) return;
|
|
903
|
+
try {
|
|
904
|
+
w.end();
|
|
905
|
+
} catch (_) {
|
|
906
|
+
abandon();
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
});
|
|
626
910
|
const blockingPromises = new Set();
|
|
627
911
|
let headerEmitted = false;
|
|
628
912
|
const pushTask = task => {
|
|
@@ -686,7 +970,7 @@ function renderToStream(code, options = {}) {
|
|
|
686
970
|
}
|
|
687
971
|
},
|
|
688
972
|
shell(shellHtml, meta) {
|
|
689
|
-
buffer.write(assembleDocument(shellHtml, meta.
|
|
973
|
+
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
690
974
|
},
|
|
691
975
|
...options.sink
|
|
692
976
|
};
|
|
@@ -766,7 +1050,6 @@ function renderToStream(code, options = {}) {
|
|
|
766
1050
|
};
|
|
767
1051
|
sharedConfig.context = context = {
|
|
768
1052
|
async: true,
|
|
769
|
-
assets: [],
|
|
770
1053
|
nonce,
|
|
771
1054
|
registerHeadTags(tags) {
|
|
772
1055
|
registerHeadTags(headRegistry, context, tracking,
|
|
@@ -966,9 +1249,9 @@ function renderToStream(code, options = {}) {
|
|
|
966
1249
|
}
|
|
967
1250
|
function doShell() {
|
|
968
1251
|
if (shellCompleted) return;
|
|
969
|
-
if (!resolveRootHoles()) return;
|
|
970
1252
|
sharedConfig.context = context;
|
|
971
|
-
|
|
1253
|
+
if (!resolveRootHoles()) return;
|
|
1254
|
+
if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
|
|
972
1255
|
headStyles = new Set();
|
|
973
1256
|
for (const url of tracking.emittedAssets) {
|
|
974
1257
|
if (isCssUrl(url)) headStyles.add(url);
|
|
@@ -976,7 +1259,6 @@ function renderToStream(code, options = {}) {
|
|
|
976
1259
|
serializeRootAssets();
|
|
977
1260
|
const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
|
|
978
1261
|
sink.shell(html, {
|
|
979
|
-
assets: assetsHtml,
|
|
980
1262
|
preloads: tracking.emittedAssets,
|
|
981
1263
|
inlineStyles: tracking.inlineStyles,
|
|
982
1264
|
tasks,
|
|
@@ -1024,14 +1306,24 @@ function renderToStream(code, options = {}) {
|
|
|
1024
1306
|
function flush() {
|
|
1025
1307
|
allSettled(blockingPromises).then(() => {
|
|
1026
1308
|
scheduleFlush(() => {
|
|
1309
|
+
if (dead) return resolve();
|
|
1027
1310
|
doShell();
|
|
1028
1311
|
if (!shellCompleted) return flush();
|
|
1029
1312
|
const encoder = new TextEncoder();
|
|
1030
1313
|
const writer = w.getWriter();
|
|
1031
1314
|
let pendingWrites = Promise.resolve();
|
|
1315
|
+
let ended = false;
|
|
1316
|
+
const failed = () => {
|
|
1317
|
+
if (!ended) {
|
|
1318
|
+
abandon();
|
|
1319
|
+
resolve();
|
|
1320
|
+
}
|
|
1321
|
+
};
|
|
1322
|
+
writer.closed && writer.closed.catch(failed);
|
|
1032
1323
|
writable = {
|
|
1033
1324
|
end() {
|
|
1034
1325
|
pendingWrites.then(() => {
|
|
1326
|
+
ended = true;
|
|
1035
1327
|
writer.releaseLock();
|
|
1036
1328
|
w.close().catch(() => {});
|
|
1037
1329
|
resolve();
|
|
@@ -1040,7 +1332,7 @@ function renderToStream(code, options = {}) {
|
|
|
1040
1332
|
};
|
|
1041
1333
|
buffer = {
|
|
1042
1334
|
write(payload) {
|
|
1043
|
-
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(
|
|
1335
|
+
pendingWrites = pendingWrites.then(() => writer.write(encoder.encode(payload))).catch(failed);
|
|
1044
1336
|
}
|
|
1045
1337
|
};
|
|
1046
1338
|
buffer.write(tmp);
|
|
@@ -1056,36 +1348,40 @@ function renderToStream(code, options = {}) {
|
|
|
1056
1348
|
return p;
|
|
1057
1349
|
};
|
|
1058
1350
|
return {
|
|
1059
|
-
then(
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1351
|
+
then(onFulfilled, onRejected) {
|
|
1352
|
+
const p = new Promise(resolve => {
|
|
1353
|
+
function complete() {
|
|
1354
|
+
dispose();
|
|
1355
|
+
resolve(tmp);
|
|
1356
|
+
}
|
|
1357
|
+
if (onCompleteAll) {
|
|
1358
|
+
let ogComplete = onCompleteAll;
|
|
1359
|
+
onCompleteAll = options => {
|
|
1360
|
+
ogComplete(options);
|
|
1361
|
+
complete();
|
|
1362
|
+
};
|
|
1363
|
+
} else onCompleteAll = complete;
|
|
1364
|
+
function flush() {
|
|
1365
|
+
allSettled(blockingPromises).then(() => {
|
|
1366
|
+
scheduleFlush(() => {
|
|
1367
|
+
if (!resolveRootHoles() || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
|
|
1368
|
+
queue(flushEnd);
|
|
1369
|
+
});
|
|
1076
1370
|
});
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1371
|
+
}
|
|
1372
|
+
flush();
|
|
1373
|
+
});
|
|
1374
|
+
return p.then(onFulfilled, onRejected);
|
|
1080
1375
|
},
|
|
1081
1376
|
pipe(w) {
|
|
1082
1377
|
claimConsumer("pipe");
|
|
1083
1378
|
function flush() {
|
|
1084
1379
|
allSettled(blockingPromises).then(() => {
|
|
1085
1380
|
scheduleFlush(() => {
|
|
1381
|
+
if (dead) return;
|
|
1086
1382
|
doShell();
|
|
1087
1383
|
if (!shellCompleted) return flush();
|
|
1088
|
-
buffer = writable = w;
|
|
1384
|
+
buffer = writable = guardSink(w);
|
|
1089
1385
|
buffer.write(tmp);
|
|
1090
1386
|
firstFlushed = true;
|
|
1091
1387
|
if (completed) {
|
|
@@ -1360,17 +1656,11 @@ function allSettled(promises) {
|
|
|
1360
1656
|
return;
|
|
1361
1657
|
});
|
|
1362
1658
|
}
|
|
1363
|
-
function
|
|
1364
|
-
if (!assets || !assets.length) return "";
|
|
1365
|
-
let out = "";
|
|
1366
|
-
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
1367
|
-
return out;
|
|
1368
|
-
}
|
|
1369
|
-
function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1659
|
+
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1370
1660
|
const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
|
|
1371
1661
|
const headTagsHtml = headTags ? headTags.html : "";
|
|
1372
1662
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
1373
|
-
if (!onHead && !
|
|
1663
|
+
if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
1374
1664
|
if (!scriptTag) return html;
|
|
1375
1665
|
const xs = html.indexOf("<!--xs-->");
|
|
1376
1666
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -1385,13 +1675,13 @@ function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts
|
|
|
1385
1675
|
const headIdx = html.indexOf("</head>");
|
|
1386
1676
|
if (headIdx === -1) {
|
|
1387
1677
|
if (onHead) {
|
|
1388
|
-
onHead(headPrelude + headTagsHtml +
|
|
1678
|
+
onHead(headPrelude + headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
1389
1679
|
}
|
|
1390
1680
|
if (!scriptTag) return html;
|
|
1391
1681
|
const xs = html.indexOf("<!--xs-->");
|
|
1392
1682
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
1393
1683
|
}
|
|
1394
|
-
const head = headTagsHtml +
|
|
1684
|
+
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
1395
1685
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
1396
1686
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
1397
1687
|
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
@@ -1573,142 +1863,7 @@ function resolveSSRSync(node) {
|
|
|
1573
1863
|
if (!res.h.length) return res.t[0];
|
|
1574
1864
|
throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
|
|
1575
1865
|
}
|
|
1576
|
-
|
|
1577
|
-
function frameAddress(id, args) {
|
|
1578
|
-
return args && args.length ? id + ":" + hashArguments(args) : id;
|
|
1579
|
-
}
|
|
1580
|
-
function hashArguments(args) {
|
|
1581
|
-
let hash = 0;
|
|
1582
|
-
const text = stableString(args);
|
|
1583
|
-
for (let i = 0; i < text.length; i++) {
|
|
1584
|
-
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
1585
|
-
hash |= 0;
|
|
1586
|
-
}
|
|
1587
|
-
return (hash >>> 0).toString(36);
|
|
1588
|
-
}
|
|
1589
|
-
function stableString(value, seen) {
|
|
1590
|
-
if (value === null || typeof value !== "object") {
|
|
1591
|
-
return typeof value === "bigint" ? value + "n" : String(value);
|
|
1592
|
-
}
|
|
1593
|
-
if (value instanceof Date) return "Date:" + value.getTime();
|
|
1594
|
-
seen || (seen = new Set());
|
|
1595
|
-
if (seen.has(value)) return "~";
|
|
1596
|
-
seen.add(value);
|
|
1597
|
-
if (value instanceof Map) {
|
|
1598
|
-
const entries = [];
|
|
1599
|
-
for (const [k, v] of value) {
|
|
1600
|
-
entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
|
|
1601
|
-
}
|
|
1602
|
-
return "Map{" + entries.sort().join(",") + "}";
|
|
1603
|
-
}
|
|
1604
|
-
if (value instanceof Set) {
|
|
1605
|
-
const members = [];
|
|
1606
|
-
for (const v of value) members.push(stableString(v, seen));
|
|
1607
|
-
return "Set{" + members.sort().join(",") + "}";
|
|
1608
|
-
}
|
|
1609
|
-
if (Array.isArray(value)) {
|
|
1610
|
-
let out = "[";
|
|
1611
|
-
for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
|
|
1612
|
-
return out + "]";
|
|
1613
|
-
}
|
|
1614
|
-
const keys = Object.keys(value).sort();
|
|
1615
|
-
let out = "{";
|
|
1616
|
-
for (let i = 0; i < keys.length; i++) {
|
|
1617
|
-
out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
|
|
1618
|
-
}
|
|
1619
|
-
return out + "}";
|
|
1620
|
-
}
|
|
1621
|
-
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
1622
|
-
function createChunk(data) {
|
|
1623
|
-
const encodeData = new TextEncoder().encode(data);
|
|
1624
|
-
const bytes = encodeData.length;
|
|
1625
|
-
const baseHex = bytes.toString(16);
|
|
1626
|
-
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex;
|
|
1627
|
-
const head = new TextEncoder().encode(`;0x${totalHex};`);
|
|
1628
|
-
const chunk = new Uint8Array(12 + bytes);
|
|
1629
|
-
chunk.set(head);
|
|
1630
|
-
chunk.set(encodeData, 12);
|
|
1631
|
-
return chunk;
|
|
1632
|
-
}
|
|
1633
|
-
class ChunkReader {
|
|
1634
|
-
constructor(stream) {
|
|
1635
|
-
this.reader = stream.getReader();
|
|
1636
|
-
this.buffer = new Uint8Array(0);
|
|
1637
|
-
this.done = false;
|
|
1638
|
-
}
|
|
1639
|
-
async readChunk() {
|
|
1640
|
-
const chunk = await this.reader.read();
|
|
1641
|
-
if (!chunk.done) {
|
|
1642
|
-
const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
|
|
1643
|
-
newBuffer.set(this.buffer);
|
|
1644
|
-
newBuffer.set(chunk.value, this.buffer.length);
|
|
1645
|
-
this.buffer = newBuffer;
|
|
1646
|
-
} else {
|
|
1647
|
-
this.done = true;
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
async next() {
|
|
1651
|
-
while (this.buffer.length < 12) {
|
|
1652
|
-
if (this.done) {
|
|
1653
|
-
if (this.buffer.length === 0) return {
|
|
1654
|
-
done: true,
|
|
1655
|
-
value: undefined
|
|
1656
|
-
};
|
|
1657
|
-
throw new Error("Malformed server function stream.");
|
|
1658
|
-
}
|
|
1659
|
-
await this.readChunk();
|
|
1660
|
-
}
|
|
1661
|
-
const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
|
|
1662
|
-
const bytes = Number.parseInt(head, 16);
|
|
1663
|
-
if (Number.isNaN(bytes)) {
|
|
1664
|
-
throw new Error("Malformed server function stream.");
|
|
1665
|
-
}
|
|
1666
|
-
while (bytes > this.buffer.length - 12) {
|
|
1667
|
-
if (this.done) {
|
|
1668
|
-
throw new Error("Malformed server function stream.");
|
|
1669
|
-
}
|
|
1670
|
-
await this.readChunk();
|
|
1671
|
-
}
|
|
1672
|
-
const partial = new TextDecoder().decode(this.buffer.subarray(12, 12 + bytes));
|
|
1673
|
-
this.buffer = this.buffer.subarray(12 + bytes);
|
|
1674
|
-
return {
|
|
1675
|
-
done: false,
|
|
1676
|
-
value: partial
|
|
1677
|
-
};
|
|
1678
|
-
}
|
|
1679
|
-
async drain(interpret) {
|
|
1680
|
-
while (true) {
|
|
1681
|
-
const result = await this.next();
|
|
1682
|
-
if (result.done) {
|
|
1683
|
-
break;
|
|
1684
|
-
}
|
|
1685
|
-
interpret(result.value);
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
function serializeStream(value, codecOptions) {
|
|
1690
|
-
return new ReadableStream({
|
|
1691
|
-
start(controller) {
|
|
1692
|
-
serializeJSON(value, {
|
|
1693
|
-
...codecOptions,
|
|
1694
|
-
onParse(node) {
|
|
1695
|
-
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
1696
|
-
},
|
|
1697
|
-
onDone() {
|
|
1698
|
-
controller.close();
|
|
1699
|
-
},
|
|
1700
|
-
onError(error) {
|
|
1701
|
-
controller.error(error);
|
|
1702
|
-
}
|
|
1703
|
-
});
|
|
1704
|
-
}
|
|
1705
|
-
});
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
1709
|
-
function isResponseEnvelope(value) {
|
|
1710
|
-
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1711
|
-
}
|
|
1866
|
+
/*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
1712
1867
|
|
|
1713
1868
|
const INVOCATIONS = new WeakMap();
|
|
1714
1869
|
function getEventServerFunctionInvocation(event) {
|
|
@@ -1722,6 +1877,10 @@ function isFrameStreamResponse(response) {
|
|
|
1722
1877
|
const SERVER_COMPONENT = /*#__PURE__*/Symbol.for("dom-expressions.server-component");
|
|
1723
1878
|
const SERVER_COMPONENT_SOURCE = /*#__PURE__*/Symbol.for("dom-expressions.server-component-source");
|
|
1724
1879
|
const SERVER_COMPONENT_ADDRESS = /*#__PURE__*/Symbol.for("dom-expressions.server-component-address");
|
|
1880
|
+
let serverComponentRegistryExpr;
|
|
1881
|
+
function setServerComponentBootstrap(resolve) {
|
|
1882
|
+
serverComponentRegistryExpr = resolve;
|
|
1883
|
+
}
|
|
1725
1884
|
function parseServerComponent(value, ctx) {
|
|
1726
1885
|
return {
|
|
1727
1886
|
id: ctx.parse(value[SERVER_COMPONENT]),
|
|
@@ -1744,7 +1903,8 @@ const ServerComponentPlugin = /*#__PURE__*/createPlugin({
|
|
|
1744
1903
|
stream: parseServerComponent
|
|
1745
1904
|
},
|
|
1746
1905
|
serialize(node, ctx) {
|
|
1747
|
-
|
|
1906
|
+
const registry = serverComponentRegistryExpr ? serverComponentRegistryExpr(ctx) : "self._$SC";
|
|
1907
|
+
return registry + ".r(" + ctx.serialize(node.id) + "," + ctx.serialize(node.address) + ")";
|
|
1748
1908
|
},
|
|
1749
1909
|
deserialize(node, ctx) {
|
|
1750
1910
|
const id = ctx.deserialize(node.id);
|
|
@@ -1773,12 +1933,43 @@ function serverOwned(render) {
|
|
|
1773
1933
|
function serverComponentScope(render) {
|
|
1774
1934
|
return runInServerComponentScope ? runInServerComponentScope(render) : render();
|
|
1775
1935
|
}
|
|
1936
|
+
const SERVER_COMPONENT_BOOTSTRAP_EXPR = "(self._$SC||(self._$SC={c:{},a:{},r(i,a){a&&(this.a[a]=i,this.reg&&this.reg(a,i));return this.c[i]||(this.c[i]=(p,b)=>self._$SC.impl(i,p,b))}}))";
|
|
1937
|
+
const bootstrappedScripts = new WeakSet();
|
|
1938
|
+
setServerComponentBootstrap(ctx => {
|
|
1939
|
+
if (bootstrappedScripts.has(ctx)) return "self._$SC";
|
|
1940
|
+
bootstrappedScripts.add(ctx);
|
|
1941
|
+
return SERVER_COMPONENT_BOOTSTRAP_EXPR;
|
|
1942
|
+
});
|
|
1943
|
+
const SERVER_COMPONENT_BOOTSTRAP = SERVER_COMPONENT_BOOTSTRAP_EXPR + ";";
|
|
1776
1944
|
function createFrameSink(emit, frame) {
|
|
1777
1945
|
const {
|
|
1778
1946
|
id,
|
|
1779
1947
|
version
|
|
1780
1948
|
} = frame;
|
|
1781
1949
|
const styledKeys = new Set();
|
|
1950
|
+
const bindings = new Map();
|
|
1951
|
+
const sweepMinted = new Set();
|
|
1952
|
+
const argRefVersions = new Map();
|
|
1953
|
+
let sweepScheduled = false;
|
|
1954
|
+
let closed = false;
|
|
1955
|
+
let epoch = 0;
|
|
1956
|
+
const sweep = () => {
|
|
1957
|
+
epoch++;
|
|
1958
|
+
for (const b of [...bindings.values()]) {
|
|
1959
|
+
try {
|
|
1960
|
+
b.sweep();
|
|
1961
|
+
} catch (_) {
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
const scheduleSweep = () => {
|
|
1966
|
+
if (closed || sweepScheduled || !bindings.size) return;
|
|
1967
|
+
sweepScheduled = true;
|
|
1968
|
+
queueMicrotask(() => {
|
|
1969
|
+
sweepScheduled = false;
|
|
1970
|
+
if (!closed) sweep();
|
|
1971
|
+
});
|
|
1972
|
+
};
|
|
1782
1973
|
const regionKeys = new Map();
|
|
1783
1974
|
const frameOf = key => regionKeys.get(key) || id;
|
|
1784
1975
|
return {
|
|
@@ -1820,6 +2011,7 @@ function createFrameSink(emit, frame) {
|
|
|
1820
2011
|
version,
|
|
1821
2012
|
payload: record
|
|
1822
2013
|
});
|
|
2014
|
+
scheduleSweep();
|
|
1823
2015
|
} else {
|
|
1824
2016
|
emit({
|
|
1825
2017
|
type: "data",
|
|
@@ -1829,6 +2021,7 @@ function createFrameSink(emit, frame) {
|
|
|
1829
2021
|
node: record.node,
|
|
1830
2022
|
initial: record.initial
|
|
1831
2023
|
});
|
|
2024
|
+
if (!sweepMinted.has(record.key)) scheduleSweep();
|
|
1832
2025
|
}
|
|
1833
2026
|
},
|
|
1834
2027
|
fragment(key, value, meta = {}) {
|
|
@@ -1865,6 +2058,7 @@ function createFrameSink(emit, frame) {
|
|
|
1865
2058
|
key,
|
|
1866
2059
|
html: value
|
|
1867
2060
|
});
|
|
2061
|
+
scheduleSweep();
|
|
1868
2062
|
if (meta.error) {
|
|
1869
2063
|
emit({
|
|
1870
2064
|
type: "error",
|
|
@@ -1919,6 +2113,8 @@ function createFrameSink(emit, frame) {
|
|
|
1919
2113
|
});
|
|
1920
2114
|
},
|
|
1921
2115
|
end() {
|
|
2116
|
+
if (bindings.size) sweep();
|
|
2117
|
+
closed = true;
|
|
1922
2118
|
emit({
|
|
1923
2119
|
type: "complete",
|
|
1924
2120
|
id,
|
|
@@ -1950,6 +2146,24 @@ function createFrameSink(emit, frame) {
|
|
|
1950
2146
|
version,
|
|
1951
2147
|
html
|
|
1952
2148
|
});
|
|
2149
|
+
},
|
|
2150
|
+
openBinding(key, b) {
|
|
2151
|
+
bindings.set(key, b);
|
|
2152
|
+
},
|
|
2153
|
+
closeBinding(key) {
|
|
2154
|
+
bindings.delete(key);
|
|
2155
|
+
},
|
|
2156
|
+
mintRef(ref) {
|
|
2157
|
+
sweepMinted.add(ref);
|
|
2158
|
+
},
|
|
2159
|
+
nextArgRef(ledgerKey) {
|
|
2160
|
+
const n = (argRefVersions.get(ledgerKey) || 0) + 1;
|
|
2161
|
+
argRefVersions.set(ledgerKey, n);
|
|
2162
|
+
return n;
|
|
2163
|
+
},
|
|
2164
|
+
commit: scheduleSweep,
|
|
2165
|
+
get epoch() {
|
|
2166
|
+
return epoch;
|
|
1953
2167
|
}
|
|
1954
2168
|
};
|
|
1955
2169
|
}
|
|
@@ -1959,7 +2173,14 @@ function renderToFrameStream(code, options = {}) {
|
|
|
1959
2173
|
function renderServerComponent(component, options = {}) {
|
|
1960
2174
|
return frameStream((sink, frame) => {
|
|
1961
2175
|
const props = createSlotProps(sink, frame);
|
|
1962
|
-
return () =>
|
|
2176
|
+
return () => {
|
|
2177
|
+
const ctx = sharedConfig.context;
|
|
2178
|
+
if (ctx) {
|
|
2179
|
+
ctx.commit = sink.commit;
|
|
2180
|
+
ctx.commitEpoch = () => sink.epoch;
|
|
2181
|
+
}
|
|
2182
|
+
return serverComponentScope(() => component(props));
|
|
2183
|
+
};
|
|
1963
2184
|
}, options);
|
|
1964
2185
|
}
|
|
1965
2186
|
function frameStream(makeCode, options) {
|
|
@@ -2036,6 +2257,35 @@ function occurrenceId(prop, raw, counts) {
|
|
|
2036
2257
|
counts[prop] = n + 1;
|
|
2037
2258
|
return `${prop}#${n}`;
|
|
2038
2259
|
}
|
|
2260
|
+
function isAsyncValue(v) {
|
|
2261
|
+
return !!v && typeof v === "object" && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
2262
|
+
}
|
|
2263
|
+
function tapFirstYield(iterable) {
|
|
2264
|
+
const iter = iterable[Symbol.asyncIterator]();
|
|
2265
|
+
const firstStep = Promise.resolve(iter.next());
|
|
2266
|
+
return {
|
|
2267
|
+
first: firstStep.then(r => r.done ? undefined : r.value),
|
|
2268
|
+
rest: {
|
|
2269
|
+
[Symbol.asyncIterator]() {
|
|
2270
|
+
let replayed = false;
|
|
2271
|
+
return {
|
|
2272
|
+
next: () => {
|
|
2273
|
+
if (!replayed) {
|
|
2274
|
+
replayed = true;
|
|
2275
|
+
return firstStep;
|
|
2276
|
+
}
|
|
2277
|
+
return iter.next();
|
|
2278
|
+
},
|
|
2279
|
+
return: v => iter.return ? iter.return(v) : Promise.resolve({
|
|
2280
|
+
done: true,
|
|
2281
|
+
value: v
|
|
2282
|
+
}),
|
|
2283
|
+
throw: e => iter.throw ? iter.throw(e) : Promise.reject(e)
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2039
2289
|
function createDocumentSlotProps(clientProps, frameId) {
|
|
2040
2290
|
const counts = Object.create(null);
|
|
2041
2291
|
const getters = new Map();
|
|
@@ -2105,6 +2355,22 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
2105
2355
|
t: FRAME_ELEMENT_CLOSE
|
|
2106
2356
|
}];
|
|
2107
2357
|
};
|
|
2358
|
+
} else if (ssrAsyncValue && isAsyncValue(value)) {
|
|
2359
|
+
let readable = value;
|
|
2360
|
+
if (typeof value.then !== "function") {
|
|
2361
|
+
const {
|
|
2362
|
+
first,
|
|
2363
|
+
rest
|
|
2364
|
+
} = tapFirstYield(value);
|
|
2365
|
+
readable = first;
|
|
2366
|
+
vals[key] = rest;
|
|
2367
|
+
}
|
|
2368
|
+
const read = ssrAsyncValue(readable);
|
|
2369
|
+
Object.defineProperty(resolved, key, {
|
|
2370
|
+
get: read,
|
|
2371
|
+
enumerable: true,
|
|
2372
|
+
configurable: true
|
|
2373
|
+
});
|
|
2108
2374
|
} else {
|
|
2109
2375
|
resolved[key] = value;
|
|
2110
2376
|
}
|
|
@@ -2113,24 +2379,19 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
2113
2379
|
const unused = regions.filter(r => !r.used);
|
|
2114
2380
|
if (sharedConfig.context) {
|
|
2115
2381
|
const args = {};
|
|
2116
|
-
let any = false;
|
|
2117
2382
|
for (const key of Object.keys(vals)) {
|
|
2118
2383
|
const value = vals[key];
|
|
2119
2384
|
const region = regions.find(r => r.key === key);
|
|
2120
2385
|
if (region) {
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
};
|
|
2125
|
-
any = true;
|
|
2126
|
-
}
|
|
2386
|
+
args[key] = {
|
|
2387
|
+
$frame: region.childId
|
|
2388
|
+
};
|
|
2127
2389
|
continue;
|
|
2128
2390
|
}
|
|
2129
2391
|
if (isServerContent(value)) continue;
|
|
2130
2392
|
args[key] = value;
|
|
2131
|
-
any = true;
|
|
2132
2393
|
}
|
|
2133
|
-
|
|
2394
|
+
sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
|
|
2134
2395
|
for (const region of unused) {
|
|
2135
2396
|
region.locked = true;
|
|
2136
2397
|
sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(sharedConfig.context, region.value));
|
|
@@ -2185,7 +2446,6 @@ function resolveRegionHtml(ctx, node) {
|
|
|
2185
2446
|
return out;
|
|
2186
2447
|
});
|
|
2187
2448
|
}
|
|
2188
|
-
const SERVER_COMPONENT_BOOTSTRAP = "self._$SC={c:{},a:{},r(i,a){a&&(this.a[a]=i,this.reg&&this.reg(a,i));return this.c[i]||(this.c[i]=(p)=>self._$SC.impl(i,p))}};";
|
|
2189
2449
|
function isServerContent(value) {
|
|
2190
2450
|
if (value && typeof value === "object") {
|
|
2191
2451
|
if ("t" in value) return true;
|
|
@@ -2198,6 +2458,88 @@ function isServerContent(value) {
|
|
|
2198
2458
|
}
|
|
2199
2459
|
return false;
|
|
2200
2460
|
}
|
|
2461
|
+
function unwrapThunks(value) {
|
|
2462
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
2463
|
+
return value;
|
|
2464
|
+
}
|
|
2465
|
+
function contentArgError(key, occurrence) {
|
|
2466
|
+
return new Error("Async slot arg resolved to JSX (arg '" + key + "' of " + occurrence + "). Async args must resolve to serializable values; render async content through a boundary instead.");
|
|
2467
|
+
}
|
|
2468
|
+
function retryArgUntilSettled(evaluate, blocked, key, occurrence, onSettle) {
|
|
2469
|
+
const owner = getOwner();
|
|
2470
|
+
return new Promise((resolve, reject) => {
|
|
2471
|
+
const retry = () => {
|
|
2472
|
+
try {
|
|
2473
|
+
const value = owner ? runWithOwner(owner, evaluate) : evaluate();
|
|
2474
|
+
if (isServerContent(value)) {
|
|
2475
|
+
reject(contentArgError(key, occurrence));
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
if (onSettle) onSettle(value);
|
|
2479
|
+
resolve(value);
|
|
2480
|
+
} catch (err) {
|
|
2481
|
+
const next = ssrHandleError && ssrHandleError(err);
|
|
2482
|
+
if (next) next.then(retry, retry);else reject(err);
|
|
2483
|
+
}
|
|
2484
|
+
};
|
|
2485
|
+
blocked.then(retry, retry);
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
function openArgBinding(sink, ctx, occurrence, key, evaluate, args, state) {
|
|
2489
|
+
const owner = getOwner();
|
|
2490
|
+
const ledgerKey = `${occurrence}:${key}`;
|
|
2491
|
+
const reEmit = value => {
|
|
2492
|
+
const ref = `arg:${occurrence}:${key}@${sink.nextArgRef(ledgerKey)}`;
|
|
2493
|
+
sink.mintRef(ref);
|
|
2494
|
+
ctx.serialize(ref, value);
|
|
2495
|
+
args[key] = {
|
|
2496
|
+
$ref: ref
|
|
2497
|
+
};
|
|
2498
|
+
sink.slot(occurrence, {
|
|
2499
|
+
...args
|
|
2500
|
+
});
|
|
2501
|
+
};
|
|
2502
|
+
const binding = {
|
|
2503
|
+
sweep() {
|
|
2504
|
+
if (!state.settled) return;
|
|
2505
|
+
let value;
|
|
2506
|
+
try {
|
|
2507
|
+
value = owner ? runWithOwner(owner, evaluate) : evaluate();
|
|
2508
|
+
} catch (err) {
|
|
2509
|
+
const blocked = ssrHandleError && ssrHandleError(err);
|
|
2510
|
+
if (!blocked) {
|
|
2511
|
+
sink.closeBinding(ledgerKey);
|
|
2512
|
+
reEmit(Promise.reject(err instanceof Error ? err : new Error(String(err))));
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
state.settled = false;
|
|
2516
|
+
reEmit(retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
2517
|
+
state.settled = true;
|
|
2518
|
+
state.last = v;
|
|
2519
|
+
sink.commit();
|
|
2520
|
+
}));
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
if (value === state.last) return;
|
|
2524
|
+
state.last = value;
|
|
2525
|
+
if (isServerContent(value)) {
|
|
2526
|
+
sink.closeBinding(ledgerKey);
|
|
2527
|
+
reEmit(Promise.reject(contentArgError(key, occurrence)));
|
|
2528
|
+
return;
|
|
2529
|
+
}
|
|
2530
|
+
const t = typeof value;
|
|
2531
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
2532
|
+
args[key] = value;
|
|
2533
|
+
sink.slot(occurrence, {
|
|
2534
|
+
...args
|
|
2535
|
+
});
|
|
2536
|
+
} else {
|
|
2537
|
+
reEmit(value);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
};
|
|
2541
|
+
sink.openBinding(ledgerKey, binding);
|
|
2542
|
+
}
|
|
2201
2543
|
function createSlotProps(sink, frame) {
|
|
2202
2544
|
const counts = Object.create(null);
|
|
2203
2545
|
const getters = new Map();
|
|
@@ -2217,6 +2559,7 @@ function createSlotProps(sink, frame) {
|
|
|
2217
2559
|
const raw = callArgs[0];
|
|
2218
2560
|
const occurrence = occurrenceId(prop, raw, counts);
|
|
2219
2561
|
const args = {};
|
|
2562
|
+
const opened = [];
|
|
2220
2563
|
for (const key of Object.keys(raw)) {
|
|
2221
2564
|
if (key === "$key") continue;
|
|
2222
2565
|
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
@@ -2227,11 +2570,44 @@ function createSlotProps(sink, frame) {
|
|
|
2227
2570
|
return origRegister.call(ctx, fragKey, fragOptions);
|
|
2228
2571
|
};
|
|
2229
2572
|
try {
|
|
2230
|
-
|
|
2231
|
-
|
|
2573
|
+
const desc = Object.getOwnPropertyDescriptor(raw, key);
|
|
2574
|
+
let evaluate = null;
|
|
2575
|
+
let value;
|
|
2576
|
+
let state = null;
|
|
2577
|
+
try {
|
|
2578
|
+
if (desc.get) {
|
|
2579
|
+
const get = desc.get;
|
|
2580
|
+
evaluate = () => unwrapThunks(get.call(raw));
|
|
2581
|
+
value = evaluate();
|
|
2582
|
+
} else {
|
|
2583
|
+
value = desc.value;
|
|
2584
|
+
if (typeof value === "function") {
|
|
2585
|
+
const fn = value;
|
|
2586
|
+
evaluate = () => unwrapThunks(fn);
|
|
2587
|
+
value = evaluate();
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
} catch (err) {
|
|
2591
|
+
const blocked = ssrHandleError && ssrHandleError(err);
|
|
2592
|
+
if (!blocked) throw err;
|
|
2593
|
+
state = {
|
|
2594
|
+
settled: false,
|
|
2595
|
+
last: undefined
|
|
2596
|
+
};
|
|
2597
|
+
const pendingState = state;
|
|
2598
|
+
value = retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
2599
|
+
pendingState.settled = true;
|
|
2600
|
+
pendingState.last = v;
|
|
2601
|
+
sink.commit();
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2232
2604
|
const t = typeof value;
|
|
2233
2605
|
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
2234
2606
|
args[key] = value;
|
|
2607
|
+
if (evaluate) state = {
|
|
2608
|
+
settled: true,
|
|
2609
|
+
last: value
|
|
2610
|
+
};
|
|
2235
2611
|
} else if (isServerContent(value)) {
|
|
2236
2612
|
const resolved = ctx.resolve(value);
|
|
2237
2613
|
if (resolved.h.length) {
|
|
@@ -2247,12 +2623,27 @@ function createSlotProps(sink, frame) {
|
|
|
2247
2623
|
args[key] = {
|
|
2248
2624
|
$ref: ref
|
|
2249
2625
|
};
|
|
2626
|
+
if (evaluate && !state) state = {
|
|
2627
|
+
settled: true,
|
|
2628
|
+
last: value
|
|
2629
|
+
};
|
|
2250
2630
|
}
|
|
2631
|
+
if (evaluate && state) opened.push({
|
|
2632
|
+
key,
|
|
2633
|
+
evaluate,
|
|
2634
|
+
state
|
|
2635
|
+
});
|
|
2251
2636
|
} finally {
|
|
2252
2637
|
ctx.registerFragment = origRegister;
|
|
2253
2638
|
}
|
|
2254
2639
|
}
|
|
2255
|
-
sink.slot(occurrence,
|
|
2640
|
+
sink.slot(occurrence, {
|
|
2641
|
+
...args
|
|
2642
|
+
});
|
|
2643
|
+
const ctx = sharedConfig.context;
|
|
2644
|
+
for (const b of opened) {
|
|
2645
|
+
openArgBinding(sink, ctx, occurrence, b.key, b.evaluate, args, b.state);
|
|
2646
|
+
}
|
|
2256
2647
|
return slotRange(occurrence);
|
|
2257
2648
|
};
|
|
2258
2649
|
getters.set(prop, fn);
|
|
@@ -2261,12 +2652,21 @@ function createSlotProps(sink, frame) {
|
|
|
2261
2652
|
}
|
|
2262
2653
|
});
|
|
2263
2654
|
}
|
|
2655
|
+
function copyInitHeaders(init) {
|
|
2656
|
+
if (!init || !init.getSetCookie) return new Headers(init);
|
|
2657
|
+
const headers = new Headers();
|
|
2658
|
+
init.forEach((value, key) => {
|
|
2659
|
+
if (key !== "set-cookie") headers.append(key, value);
|
|
2660
|
+
});
|
|
2661
|
+
for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
|
|
2662
|
+
return headers;
|
|
2663
|
+
}
|
|
2264
2664
|
function serverComponentResponse(component, options = {}, init = {}) {
|
|
2265
2665
|
const {
|
|
2266
2666
|
id = "",
|
|
2267
2667
|
version = 1
|
|
2268
2668
|
} = options.frame || {};
|
|
2269
|
-
const headers =
|
|
2669
|
+
const headers = copyInitHeaders(init.headers);
|
|
2270
2670
|
headers.set("Content-Type", "application/x-frame-stream");
|
|
2271
2671
|
headers.set(FRAME_STREAM_HEADER, id);
|
|
2272
2672
|
headers.set("X-Content-Raw", "1");
|
|
@@ -2365,7 +2765,7 @@ function frameFlightResponse({
|
|
|
2365
2765
|
codec
|
|
2366
2766
|
}, init = {}) {
|
|
2367
2767
|
const frames = primary ? [primary, ...regions] : regions;
|
|
2368
|
-
const headers =
|
|
2768
|
+
const headers = copyInitHeaders(init.headers);
|
|
2369
2769
|
headers.set("Content-Type", "application/x-frame-stream");
|
|
2370
2770
|
headers.set(FRAME_STREAM_HEADER, primary ? primary.id : "");
|
|
2371
2771
|
headers.set("X-Content-Raw", "1");
|
|
@@ -2411,4 +2811,8 @@ function frameFlightResponse({
|
|
|
2411
2811
|
});
|
|
2412
2812
|
}
|
|
2413
2813
|
|
|
2414
|
-
|
|
2814
|
+
function asyncArg(value) {
|
|
2815
|
+
return value;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
export { FRAME_STREAM_HEADER, SERVER_COMPONENT_BOOTSTRAP, ServerComponentPlugin, asyncArg, createFrameSink, frameTransformDirectResult, frameTransformFlightResult, frameTransformResult, isFrameStreamResponse, renderServerComponent, renderToFrameStream, serverComponentResponse };
|