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