@solidjs/web 2.0.0-beta.31 → 2.0.0-beta.33
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 +285 -60
- package/dist/dev.js +267 -57
- package/dist/server.cjs +1148 -176
- package/dist/server.js +1133 -175
- package/dist/web.cjs +285 -60
- package/dist/web.js +267 -57
- package/frames/dist/client.cjs +397 -175
- package/frames/dist/client.dev.cjs +401 -175
- package/frames/dist/client.dev.js +399 -173
- package/frames/dist/client.js +395 -173
- package/frames/dist/server.cjs +1424 -277
- package/frames/dist/server.js +1426 -280
- package/package.json +69 -7
- package/serialization/decode/package.json +20 -0
- package/serialization/dist/decode.cjs +110 -0
- package/serialization/dist/decode.js +104 -0
- package/serialization/dist/serialization.cjs +106 -43
- package/serialization/dist/serialization.js +100 -44
- package/serialization/types/index.d.ts +85 -60
- package/serialization/types/serializer-decode.d.ts +182 -0
- package/serialization/types-cjs/index.d.cts +85 -60
- package/serialization/types-cjs/serializer-decode.d.cts +182 -0
- package/server-functions/dist/client.cjs +131 -98
- package/server-functions/dist/client.js +131 -99
- package/server-functions/dist/rich-args.cjs +11 -0
- package/server-functions/dist/rich-args.js +9 -0
- package/server-functions/dist/server.cjs +367 -194
- package/server-functions/dist/server.dev.cjs +1077 -0
- package/server-functions/dist/server.dev.js +1045 -0
- package/server-functions/dist/server.js +365 -195
- 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 +149 -6
- package/types/cookies.d.ts +93 -0
- package/types/core.d.ts +4 -2
- package/types/frames/client.d.ts +15 -1
- package/types/frames/frame-client.d.ts +63 -7
- package/types/frames/frame-sink.d.ts +26 -3
- package/types/frames/frame-transport.d.ts +40 -8
- package/types/frames/serializer.d.ts +85 -60
- package/types/frames/server.d.ts +22 -0
- package/types/index.d.ts +2 -3
- package/types/response.d.ts +45 -0
- package/types/serializer-decode.d.ts +182 -0
- package/types/serializer.d.ts +85 -60
- package/types/server-functions/client.d.ts +2 -1
- package/types/server-functions/rich-args.d.ts +10 -0
- package/types/server-functions/server.d.ts +99 -1
- package/types/server-functions/shared.d.ts +79 -1
- package/types/server-mock.d.ts +171 -59
- package/types/server.d.ts +209 -37
- package/types-cjs/client.d.cts +149 -6
- package/types-cjs/cookies.d.cts +93 -0
- package/types-cjs/core.d.cts +4 -2
- package/types-cjs/frames/client.d.cts +15 -1
- package/types-cjs/frames/frame-client.d.cts +63 -7
- package/types-cjs/frames/frame-sink.d.cts +26 -3
- package/types-cjs/frames/frame-transport.d.cts +40 -8
- package/types-cjs/frames/serializer.d.cts +85 -60
- package/types-cjs/frames/server.d.cts +22 -0
- package/types-cjs/index.d.cts +2 -3
- package/types-cjs/response.d.cts +45 -0
- package/types-cjs/serializer-decode.d.cts +182 -0
- package/types-cjs/serializer.d.cts +85 -60
- package/types-cjs/server-functions/client.d.cts +2 -1
- package/types-cjs/server-functions/rich-args.d.cts +10 -0
- package/types-cjs/server-functions/server.d.cts +99 -1
- package/types-cjs/server-functions/shared.d.cts +79 -1
- package/types-cjs/server-mock.d.cts +171 -59
- package/types-cjs/server.d.cts +209 -37
package/frames/dist/server.cjs
CHANGED
|
@@ -4,19 +4,129 @@ var solidJs = require('solid-js');
|
|
|
4
4
|
var seroval = require('seroval');
|
|
5
5
|
var web = require('seroval-plugins/web');
|
|
6
6
|
|
|
7
|
+
const STATE = Symbol.for("dom-expressions.container-trace-state");
|
|
8
|
+
const state = globalThis[STATE] || (globalThis[STATE] = {
|
|
9
|
+
materialized: new WeakMap(),
|
|
10
|
+
materializedValues: new WeakSet()
|
|
11
|
+
});
|
|
12
|
+
function setContainerTraceResolver(fn) {
|
|
13
|
+
state.resolveTrace = fn;
|
|
14
|
+
}
|
|
15
|
+
function isContainerTraced(value) {
|
|
16
|
+
const resolve = state.resolveTrace;
|
|
17
|
+
return !!(resolve && value && typeof value === "object" && resolve(value));
|
|
18
|
+
}
|
|
19
|
+
const TRACE = Symbol.for("dom-expressions.container-trace");
|
|
20
|
+
function envelopeContainerTraces(value) {
|
|
21
|
+
if (!state.resolveTrace || value == null || typeof value !== "object") return value;
|
|
22
|
+
const trace = state.resolveTrace(value);
|
|
23
|
+
if (trace) return {
|
|
24
|
+
[TRACE]: trace
|
|
25
|
+
};
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
let out = value;
|
|
28
|
+
for (let i = 0; i < value.length; i++) {
|
|
29
|
+
const next = envelopeContainerTraces(value[i]);
|
|
30
|
+
if (next !== value[i]) {
|
|
31
|
+
if (out === value) out = value.slice();
|
|
32
|
+
out[i] = next;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
if (Object.getPrototypeOf(value) === Object.prototype) {
|
|
38
|
+
let out = value;
|
|
39
|
+
for (const key of Object.keys(value)) {
|
|
40
|
+
const next = envelopeContainerTraces(value[key]);
|
|
41
|
+
if (next !== value[key]) {
|
|
42
|
+
if (out === value) out = {
|
|
43
|
+
...value
|
|
44
|
+
};
|
|
45
|
+
out[key] = next;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
function materialize(marker) {
|
|
53
|
+
let value = state.materialized.get(marker.$tr);
|
|
54
|
+
if (value === undefined) {
|
|
55
|
+
value = state.materializeTrace(marker);
|
|
56
|
+
state.materialized.set(marker.$tr, value);
|
|
57
|
+
if (value !== null && typeof value === "object") state.materializedValues.add(value);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
function parseTrace(value, ctx) {
|
|
62
|
+
const trace = value[TRACE];
|
|
63
|
+
return {
|
|
64
|
+
a: trace.array ? 1 : 0,
|
|
65
|
+
i: ctx.parse(trace.subscribe())
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const ContainerTracePlugin = {
|
|
69
|
+
tag: "dom-expressions/container-trace",
|
|
70
|
+
test(value) {
|
|
71
|
+
return value != null && typeof value === "object" && TRACE in value;
|
|
72
|
+
},
|
|
73
|
+
parse: {
|
|
74
|
+
sync() {
|
|
75
|
+
throw new Error("A reactive container can only be serialized by a streaming serializer.");
|
|
76
|
+
},
|
|
77
|
+
async async(value, ctx) {
|
|
78
|
+
const trace = value[TRACE];
|
|
79
|
+
return {
|
|
80
|
+
a: trace.array ? 1 : 0,
|
|
81
|
+
i: await ctx.parse(trace.subscribe())
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
stream: parseTrace
|
|
85
|
+
},
|
|
86
|
+
serialize(node, ctx) {
|
|
87
|
+
return "{$tr:" + ctx.serialize(node.i) + ",$ta:" + node.a + "}";
|
|
88
|
+
},
|
|
89
|
+
deserialize(node, ctx) {
|
|
90
|
+
const iterable = ctx.deserialize(node.i);
|
|
91
|
+
const marker = {
|
|
92
|
+
$tr: iterable,
|
|
93
|
+
$ta: node.a
|
|
94
|
+
};
|
|
95
|
+
return state.materializeTrace ? materialize(marker) : marker;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
7
99
|
const runWithHydrationScope = (id, fn) => solidJs.runWithOwner(solidJs.createOwner({
|
|
8
100
|
id
|
|
9
101
|
}), fn);
|
|
102
|
+
const ssrAsyncValue = value => solidJs.createMemo(() => value, {
|
|
103
|
+
serialize: false
|
|
104
|
+
});
|
|
10
105
|
|
|
11
|
-
const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
|
|
12
|
-
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : seroval.Feature.ErrorPrototypeStack;
|
|
13
|
-
const HYDRATION_GLOBAL = "_$HY.r";
|
|
14
106
|
const DEFAULT_WEB_PLUGINS = Object.freeze([web.AbortSignalPlugin,
|
|
15
107
|
web.CustomEventPlugin, web.DOMExceptionPlugin, web.EventPlugin,
|
|
16
|
-
web.FormDataPlugin, web.HeadersPlugin, web.ReadableStreamPlugin, web.RequestPlugin, web.ResponsePlugin, web.URLSearchParamsPlugin, web.URLPlugin
|
|
108
|
+
web.FormDataPlugin, web.HeadersPlugin, web.ReadableStreamPlugin, web.RequestPlugin, web.ResponsePlugin, web.URLSearchParamsPlugin, web.URLPlugin,
|
|
109
|
+
ContainerTracePlugin]);
|
|
17
110
|
function resolveSerializerPlugins(customPlugins) {
|
|
18
111
|
return customPlugins ? [...customPlugins, ...DEFAULT_WEB_PLUGINS] : [...DEFAULT_WEB_PLUGINS];
|
|
19
112
|
}
|
|
113
|
+
const JSON_CODEC_DISABLED_FEATURES = seroval.Feature.RegExp;
|
|
114
|
+
const JSON_CODEC_DEPTH_LIMIT = 64;
|
|
115
|
+
function resolveCodecOptions({
|
|
116
|
+
plugins,
|
|
117
|
+
disabledFeatures,
|
|
118
|
+
depthLimit
|
|
119
|
+
} = {}) {
|
|
120
|
+
return {
|
|
121
|
+
plugins: resolveSerializerPlugins(plugins),
|
|
122
|
+
disabledFeatures: disabledFeatures === undefined ? JSON_CODEC_DISABLED_FEATURES : disabledFeatures,
|
|
123
|
+
depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
|
|
128
|
+
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : seroval.Feature.ErrorPrototypeStack;
|
|
129
|
+
const HYDRATION_GLOBAL = "_$HY.r";
|
|
20
130
|
function createSerializer(options) {
|
|
21
131
|
return new seroval.Serializer({
|
|
22
132
|
...options,
|
|
@@ -43,34 +153,6 @@ function createHydrationSerializer({
|
|
|
43
153
|
function getLocalHeaderScript(id) {
|
|
44
154
|
return seroval.getCrossReferenceHeader(id) + ";";
|
|
45
155
|
}
|
|
46
|
-
const JSON_CODEC_DISABLED_FEATURES = seroval.Feature.RegExp;
|
|
47
|
-
const JSON_CODEC_DEPTH_LIMIT = 64;
|
|
48
|
-
function resolveCodecOptions({
|
|
49
|
-
plugins,
|
|
50
|
-
disabledFeatures,
|
|
51
|
-
depthLimit
|
|
52
|
-
} = {}) {
|
|
53
|
-
return {
|
|
54
|
-
plugins: resolveSerializerPlugins(plugins),
|
|
55
|
-
disabledFeatures: disabledFeatures === undefined ? JSON_CODEC_DISABLED_FEATURES : disabledFeatures,
|
|
56
|
-
depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
function serializeJSON(value, {
|
|
60
|
-
onParse,
|
|
61
|
-
onDone,
|
|
62
|
-
onError,
|
|
63
|
-
...codecOptions
|
|
64
|
-
}) {
|
|
65
|
-
const resolved = resolveCodecOptions(codecOptions);
|
|
66
|
-
return seroval.toCrossJSONStream(value, {
|
|
67
|
-
onParse,
|
|
68
|
-
onDone,
|
|
69
|
-
onError,
|
|
70
|
-
...resolved,
|
|
71
|
-
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures()
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
156
|
function createJSONSerializer({
|
|
75
157
|
onData,
|
|
76
158
|
onDone,
|
|
@@ -137,6 +219,146 @@ function createJSONSerializer({
|
|
|
137
219
|
};
|
|
138
220
|
}
|
|
139
221
|
|
|
222
|
+
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
223
|
+
function isResponseEnvelope(value) {
|
|
224
|
+
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
225
|
+
}
|
|
226
|
+
const REVALIDATE_HEADER = "X-Revalidate";
|
|
227
|
+
|
|
228
|
+
function frameAddress(id, args) {
|
|
229
|
+
return args && args.length ? id + ":" + hashArguments(args) : id;
|
|
230
|
+
}
|
|
231
|
+
function hashArguments(args) {
|
|
232
|
+
let hash = 0;
|
|
233
|
+
const text = stableString(args);
|
|
234
|
+
for (let i = 0; i < text.length; i++) {
|
|
235
|
+
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
236
|
+
hash |= 0;
|
|
237
|
+
}
|
|
238
|
+
return (hash >>> 0).toString(36);
|
|
239
|
+
}
|
|
240
|
+
function stableString(value, seen) {
|
|
241
|
+
if (value === null || typeof value !== "object") {
|
|
242
|
+
return typeof value === "bigint" ? value + "n" : String(value);
|
|
243
|
+
}
|
|
244
|
+
if (value instanceof Date) return "Date:" + value.getTime();
|
|
245
|
+
seen || (seen = new Set());
|
|
246
|
+
if (seen.has(value)) return "~";
|
|
247
|
+
seen.add(value);
|
|
248
|
+
if (value instanceof Map) {
|
|
249
|
+
const entries = [];
|
|
250
|
+
for (const [k, v] of value) {
|
|
251
|
+
entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
|
|
252
|
+
}
|
|
253
|
+
return "Map{" + entries.sort().join(",") + "}";
|
|
254
|
+
}
|
|
255
|
+
if (value instanceof Set) {
|
|
256
|
+
const members = [];
|
|
257
|
+
for (const v of value) members.push(stableString(v, seen));
|
|
258
|
+
return "Set{" + members.sort().join(",") + "}";
|
|
259
|
+
}
|
|
260
|
+
if (Array.isArray(value)) {
|
|
261
|
+
let out = "[";
|
|
262
|
+
for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
|
|
263
|
+
return out + "]";
|
|
264
|
+
}
|
|
265
|
+
const keys = Object.keys(value).sort();
|
|
266
|
+
let out = "{";
|
|
267
|
+
for (let i = 0; i < keys.length; i++) {
|
|
268
|
+
out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
|
|
269
|
+
}
|
|
270
|
+
return out + "}";
|
|
271
|
+
}
|
|
272
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
273
|
+
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
274
|
+
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
275
|
+
function createChunk(data) {
|
|
276
|
+
const encoder = new TextEncoder();
|
|
277
|
+
const encodeData = encoder.encode(data);
|
|
278
|
+
const bytes = encodeData.length;
|
|
279
|
+
const chunk = new Uint8Array(12 + bytes);
|
|
280
|
+
chunk.set(encoder.encode(`;0x${bytes.toString(16).padStart(8, "0")};`));
|
|
281
|
+
chunk.set(encodeData, 12);
|
|
282
|
+
return chunk;
|
|
283
|
+
}
|
|
284
|
+
class ChunkReader {
|
|
285
|
+
constructor(stream) {
|
|
286
|
+
this.reader = stream.getReader();
|
|
287
|
+
this.buffer = new Uint8Array(0);
|
|
288
|
+
this.done = false;
|
|
289
|
+
}
|
|
290
|
+
async readChunk() {
|
|
291
|
+
const chunk = await this.reader.read();
|
|
292
|
+
if (!chunk.done) {
|
|
293
|
+
const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
|
|
294
|
+
newBuffer.set(this.buffer);
|
|
295
|
+
newBuffer.set(chunk.value, this.buffer.length);
|
|
296
|
+
this.buffer = newBuffer;
|
|
297
|
+
} else {
|
|
298
|
+
this.done = true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
async next() {
|
|
302
|
+
while (this.buffer.length < 12) {
|
|
303
|
+
if (this.done) {
|
|
304
|
+
if (this.buffer.length === 0) return {
|
|
305
|
+
done: true,
|
|
306
|
+
value: undefined
|
|
307
|
+
};
|
|
308
|
+
throw new Error("Malformed server function stream.");
|
|
309
|
+
}
|
|
310
|
+
await this.readChunk();
|
|
311
|
+
}
|
|
312
|
+
const decoder = new TextDecoder();
|
|
313
|
+
const bytes = Number.parseInt(decoder.decode(this.buffer.subarray(1, 11)), 16);
|
|
314
|
+
if (Number.isNaN(bytes)) {
|
|
315
|
+
throw new Error("Malformed server function stream.");
|
|
316
|
+
}
|
|
317
|
+
while (bytes > this.buffer.length - 12) {
|
|
318
|
+
if (this.done) {
|
|
319
|
+
throw new Error("Malformed server function stream.");
|
|
320
|
+
}
|
|
321
|
+
await this.readChunk();
|
|
322
|
+
}
|
|
323
|
+
const partial = decoder.decode(this.buffer.subarray(12, 12 + bytes));
|
|
324
|
+
this.buffer = this.buffer.subarray(12 + bytes);
|
|
325
|
+
return {
|
|
326
|
+
done: false,
|
|
327
|
+
value: partial
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
async drain(interpret) {
|
|
331
|
+
while (true) {
|
|
332
|
+
const result = await this.next();
|
|
333
|
+
if (result.done) {
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
interpret(result.value);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function serializeStream(value, codecOptions) {
|
|
341
|
+
return new ReadableStream({
|
|
342
|
+
async start(controller) {
|
|
343
|
+
const {
|
|
344
|
+
serializeJSON
|
|
345
|
+
} = await import('@solidjs/web/serialization');
|
|
346
|
+
serializeJSON(value, {
|
|
347
|
+
...codecOptions,
|
|
348
|
+
onParse(node) {
|
|
349
|
+
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
350
|
+
},
|
|
351
|
+
onDone() {
|
|
352
|
+
controller.close();
|
|
353
|
+
},
|
|
354
|
+
onError(error) {
|
|
355
|
+
controller.error(error);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
140
362
|
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
141
363
|
const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
|
|
142
364
|
const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "stylesheet"]);
|
|
@@ -207,7 +429,6 @@ function resolveHead(groups) {
|
|
|
207
429
|
}
|
|
208
430
|
for (const [identity, tags] of byIdentity) {
|
|
209
431
|
if (identity === "title") {
|
|
210
|
-
if (tags.length > 1) console.warn("Multiple <title> tags in one head group; the last one wins.");
|
|
211
432
|
winners.set(identity, {
|
|
212
433
|
seq: group.seq,
|
|
213
434
|
tags: [tags[tags.length - 1]]
|
|
@@ -377,7 +598,8 @@ function createHeadRegistry() {
|
|
|
377
598
|
resources: new Set(),
|
|
378
599
|
eagerHtml: "",
|
|
379
600
|
flushed: null,
|
|
380
|
-
shellFlushed: false
|
|
601
|
+
shellFlushed: false,
|
|
602
|
+
parkedResources: []
|
|
381
603
|
};
|
|
382
604
|
}
|
|
383
605
|
function registerHeadTags(registry, context, tracking, emitResource, nonce, tags) {
|
|
@@ -391,14 +613,24 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
391
613
|
return;
|
|
392
614
|
}
|
|
393
615
|
if (!Array.isArray(tags)) tags = [tags];
|
|
616
|
+
const probe = solidJs.sharedConfig.context && solidJs.sharedConfig.context._loadingPhase;
|
|
394
617
|
let replaceable = null;
|
|
395
618
|
for (let i = 0; i < tags.length; i++) {
|
|
396
619
|
const desc = tags[i];
|
|
397
620
|
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
398
|
-
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
399
621
|
continue;
|
|
400
622
|
}
|
|
401
623
|
const cls = classifyHeadTag(desc);
|
|
624
|
+
if (probe && !cls.resource) {
|
|
625
|
+
try {
|
|
626
|
+
evalHeadProps(desc.props || {}, cls.rel !== undefined ? {
|
|
627
|
+
rel: cls.rel
|
|
628
|
+
} : undefined);
|
|
629
|
+
evalHeadValue(desc.key);
|
|
630
|
+
} catch (err) {
|
|
631
|
+
if (solidJs.ssrHandleError(err)) throw err;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
402
634
|
if (cls.resource) {
|
|
403
635
|
emitHeadResource(registry, context, tracking, emitResource, nonce, desc, cls.rel);
|
|
404
636
|
} else {
|
|
@@ -415,6 +647,51 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
415
647
|
tags: replaceable
|
|
416
648
|
});
|
|
417
649
|
}
|
|
650
|
+
function headShellReady(registry, block) {
|
|
651
|
+
let ready = true;
|
|
652
|
+
const pends = err => {
|
|
653
|
+
const source = solidJs.ssrHandleError(err, true);
|
|
654
|
+
if (!source) return false;
|
|
655
|
+
block(source);
|
|
656
|
+
ready = false;
|
|
657
|
+
return true;
|
|
658
|
+
};
|
|
659
|
+
const parked = registry.parkedResources;
|
|
660
|
+
for (let i = parked.length - 1; i >= 0; i--) {
|
|
661
|
+
const {
|
|
662
|
+
desc,
|
|
663
|
+
rel,
|
|
664
|
+
emit
|
|
665
|
+
} = parked[i];
|
|
666
|
+
try {
|
|
667
|
+
evalHeadProps(desc.props || {}, rel !== undefined ? {
|
|
668
|
+
rel
|
|
669
|
+
} : undefined);
|
|
670
|
+
} catch (err) {
|
|
671
|
+
if (pends(err)) continue;
|
|
672
|
+
parked.splice(i, 1);
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
parked.splice(i, 1);
|
|
676
|
+
emit();
|
|
677
|
+
}
|
|
678
|
+
for (let i = 0; i < registry.pending.length; i++) {
|
|
679
|
+
const reg = registry.pending[i];
|
|
680
|
+
if (reg.boundary !== "" || reg.list) continue;
|
|
681
|
+
for (let j = 0; j < reg.tags.length; j++) {
|
|
682
|
+
const desc = reg.tags[j];
|
|
683
|
+
try {
|
|
684
|
+
evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
|
|
685
|
+
rel: desc.rel
|
|
686
|
+
} : undefined);
|
|
687
|
+
evalHeadValue(desc.key);
|
|
688
|
+
} catch (err) {
|
|
689
|
+
pends(err);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return ready;
|
|
694
|
+
}
|
|
418
695
|
function emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel) {
|
|
419
696
|
let props;
|
|
420
697
|
try {
|
|
@@ -422,7 +699,16 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
|
|
|
422
699
|
rel
|
|
423
700
|
} : undefined);
|
|
424
701
|
} catch (err) {
|
|
425
|
-
|
|
702
|
+
const loadingPhase = solidJs.sharedConfig.context && solidJs.sharedConfig.context._loadingPhase;
|
|
703
|
+
if (loadingPhase && solidJs.ssrHandleError(err)) throw err;
|
|
704
|
+
if (!loadingPhase && !context._currentBoundaryId && !registry.shellFlushed && typeof context.block === "function" && solidJs.ssrHandleError(err, true)) {
|
|
705
|
+
registry.parkedResources.push({
|
|
706
|
+
desc,
|
|
707
|
+
rel,
|
|
708
|
+
emit: () => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
|
|
709
|
+
});
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
426
712
|
return;
|
|
427
713
|
}
|
|
428
714
|
const identity = resourceIdentity(desc.tag, props);
|
|
@@ -484,7 +770,6 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
484
770
|
try {
|
|
485
771
|
resolved = reg.list();
|
|
486
772
|
} catch (err) {
|
|
487
|
-
console.warn(`useHead: error evaluating head group membership`, err);
|
|
488
773
|
continue;
|
|
489
774
|
}
|
|
490
775
|
if (!Array.isArray(resolved)) resolved = [resolved];
|
|
@@ -492,7 +777,6 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
492
777
|
for (let j = 0; j < resolved.length; j++) {
|
|
493
778
|
const desc = resolved[j];
|
|
494
779
|
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
495
|
-
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
496
780
|
continue;
|
|
497
781
|
}
|
|
498
782
|
const cls = classifyHeadTag(desc);
|
|
@@ -518,12 +802,10 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
518
802
|
} : undefined);
|
|
519
803
|
key = evalHeadValue(desc.key);
|
|
520
804
|
} catch (err) {
|
|
521
|
-
console.warn(`useHead: error evaluating tag props`, err);
|
|
522
805
|
continue;
|
|
523
806
|
}
|
|
524
807
|
const identity = replaceableIdentity(desc.tag, props, key, "u:" + registry.uniq++);
|
|
525
808
|
if ((identity === "base" || identity === "charset") && registry.shellFlushed) {
|
|
526
|
-
console.warn(`useHead: <${desc.tag}> (${identity}) registered after shell flush is ignored`);
|
|
527
809
|
continue;
|
|
528
810
|
}
|
|
529
811
|
tags.push({
|
|
@@ -605,7 +887,6 @@ function flushHeadFragment(registry, boundary) {
|
|
|
605
887
|
for (const name in t.props) {
|
|
606
888
|
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
607
889
|
if (!HEAD_ATTR_NAME.test(name)) {
|
|
608
|
-
console.warn(`useHead: ignoring invalid attribute name "${name}"`);
|
|
609
890
|
continue;
|
|
610
891
|
}
|
|
611
892
|
const v = t.props[name];
|
|
@@ -623,7 +904,6 @@ function renderHeadAttrHtml(props) {
|
|
|
623
904
|
for (const name in props) {
|
|
624
905
|
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
625
906
|
if (!HEAD_ATTR_NAME.test(name)) {
|
|
626
|
-
console.warn(`useHead: ignoring invalid attribute name "${name}"`);
|
|
627
907
|
continue;
|
|
628
908
|
}
|
|
629
909
|
const v = props[name];
|
|
@@ -683,6 +963,12 @@ function renderToStream(code, options = {}) {
|
|
|
683
963
|
d();
|
|
684
964
|
}
|
|
685
965
|
};
|
|
966
|
+
const failRender = err => {
|
|
967
|
+
try {
|
|
968
|
+
options.onError ? options.onError(err) : console.error(err);
|
|
969
|
+
} catch (_) {}
|
|
970
|
+
abandon();
|
|
971
|
+
};
|
|
686
972
|
const guardSink = w => ({
|
|
687
973
|
write(payload) {
|
|
688
974
|
if (dead) return;
|
|
@@ -764,7 +1050,7 @@ function renderToStream(code, options = {}) {
|
|
|
764
1050
|
}
|
|
765
1051
|
},
|
|
766
1052
|
shell(shellHtml, meta) {
|
|
767
|
-
buffer.write(assembleDocument(shellHtml, meta.
|
|
1053
|
+
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
768
1054
|
},
|
|
769
1055
|
...options.sink
|
|
770
1056
|
};
|
|
@@ -781,10 +1067,18 @@ function renderToStream(code, options = {}) {
|
|
|
781
1067
|
rootAssetsSerialized = true;
|
|
782
1068
|
serializeFragmentAssets("", tracking.boundaryModules, context);
|
|
783
1069
|
};
|
|
1070
|
+
let holds = 0;
|
|
784
1071
|
const flushEnd = () => {
|
|
785
|
-
if (!registry.size) {
|
|
1072
|
+
if (!registry.size && !holds) {
|
|
786
1073
|
serializeRootAssets();
|
|
787
|
-
queue(() => queue(() =>
|
|
1074
|
+
queue(() => queue(() => {
|
|
1075
|
+
if (context.live.end) {
|
|
1076
|
+
const end = context.live.end;
|
|
1077
|
+
context.live.end = null;
|
|
1078
|
+
end();
|
|
1079
|
+
}
|
|
1080
|
+
serializer.flush();
|
|
1081
|
+
}));
|
|
788
1082
|
}
|
|
789
1083
|
};
|
|
790
1084
|
const registry = new Map();
|
|
@@ -844,8 +1138,8 @@ function renderToStream(code, options = {}) {
|
|
|
844
1138
|
};
|
|
845
1139
|
solidJs.sharedConfig.context = context = {
|
|
846
1140
|
async: true,
|
|
847
|
-
assets: [],
|
|
848
1141
|
nonce,
|
|
1142
|
+
live: {},
|
|
849
1143
|
registerHeadTags(tags) {
|
|
850
1144
|
registerHeadTags(headRegistry, context, tracking,
|
|
851
1145
|
(markup, gateEntry) => {
|
|
@@ -882,6 +1176,16 @@ function renderToStream(code, options = {}) {
|
|
|
882
1176
|
block(p) {
|
|
883
1177
|
if (!firstFlushed) blockingPromises.add(p);
|
|
884
1178
|
},
|
|
1179
|
+
hold() {
|
|
1180
|
+
holds++;
|
|
1181
|
+
let released = false;
|
|
1182
|
+
return () => {
|
|
1183
|
+
if (released) return;
|
|
1184
|
+
released = true;
|
|
1185
|
+
holds--;
|
|
1186
|
+
if (!holds) queue(flushEnd);
|
|
1187
|
+
};
|
|
1188
|
+
},
|
|
885
1189
|
replace(id, payloadFn) {
|
|
886
1190
|
if (firstFlushed) return;
|
|
887
1191
|
const placeholder = `<!--!$${id}-->`;
|
|
@@ -990,6 +1294,7 @@ function renderToStream(code, options = {}) {
|
|
|
990
1294
|
}
|
|
991
1295
|
};
|
|
992
1296
|
applyAssetTracking(context, tracking, manifest, noScripts);
|
|
1297
|
+
context.failRender = failRender;
|
|
993
1298
|
registerEntryAssets(manifest);
|
|
994
1299
|
let html = solidJs.createRoot(d => {
|
|
995
1300
|
dispose = d;
|
|
@@ -1046,7 +1351,7 @@ function renderToStream(code, options = {}) {
|
|
|
1046
1351
|
if (shellCompleted) return;
|
|
1047
1352
|
solidJs.sharedConfig.context = context;
|
|
1048
1353
|
if (!resolveRootHoles()) return;
|
|
1049
|
-
|
|
1354
|
+
if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
|
|
1050
1355
|
headStyles = new Set();
|
|
1051
1356
|
for (const url of tracking.emittedAssets) {
|
|
1052
1357
|
if (isCssUrl(url)) headStyles.add(url);
|
|
@@ -1054,7 +1359,6 @@ function renderToStream(code, options = {}) {
|
|
|
1054
1359
|
serializeRootAssets();
|
|
1055
1360
|
const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
|
|
1056
1361
|
sink.shell(html, {
|
|
1057
|
-
assets: assetsHtml,
|
|
1058
1362
|
preloads: tracking.emittedAssets,
|
|
1059
1363
|
inlineStyles: tracking.inlineStyles,
|
|
1060
1364
|
tasks,
|
|
@@ -1103,7 +1407,12 @@ function renderToStream(code, options = {}) {
|
|
|
1103
1407
|
allSettled(blockingPromises).then(() => {
|
|
1104
1408
|
scheduleFlush(() => {
|
|
1105
1409
|
if (dead) return resolve();
|
|
1106
|
-
|
|
1410
|
+
try {
|
|
1411
|
+
doShell();
|
|
1412
|
+
} catch (err) {
|
|
1413
|
+
failRender(err);
|
|
1414
|
+
return resolve();
|
|
1415
|
+
}
|
|
1107
1416
|
if (!shellCompleted) return flush();
|
|
1108
1417
|
const encoder = new TextEncoder();
|
|
1109
1418
|
const writer = w.getWriter();
|
|
@@ -1144,27 +1453,35 @@ function renderToStream(code, options = {}) {
|
|
|
1144
1453
|
return p;
|
|
1145
1454
|
};
|
|
1146
1455
|
return {
|
|
1147
|
-
then(
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1456
|
+
then(onFulfilled, onRejected) {
|
|
1457
|
+
const p = new Promise(resolve => {
|
|
1458
|
+
function complete() {
|
|
1459
|
+
dispose();
|
|
1460
|
+
resolve(tmp);
|
|
1461
|
+
}
|
|
1462
|
+
if (onCompleteAll) {
|
|
1463
|
+
let ogComplete = onCompleteAll;
|
|
1464
|
+
onCompleteAll = options => {
|
|
1465
|
+
ogComplete(options);
|
|
1466
|
+
complete();
|
|
1467
|
+
};
|
|
1468
|
+
} else onCompleteAll = complete;
|
|
1469
|
+
function flush() {
|
|
1470
|
+
allSettled(blockingPromises).then(() => {
|
|
1471
|
+
scheduleFlush(() => {
|
|
1472
|
+
try {
|
|
1473
|
+
if (!resolveRootHoles() || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
|
|
1474
|
+
} catch (err) {
|
|
1475
|
+
failRender(err);
|
|
1476
|
+
return resolve(tmp);
|
|
1477
|
+
}
|
|
1478
|
+
queue(flushEnd);
|
|
1479
|
+
});
|
|
1164
1480
|
});
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1481
|
+
}
|
|
1482
|
+
flush();
|
|
1483
|
+
});
|
|
1484
|
+
return p.then(onFulfilled, onRejected);
|
|
1168
1485
|
},
|
|
1169
1486
|
pipe(w) {
|
|
1170
1487
|
claimConsumer("pipe");
|
|
@@ -1172,7 +1489,15 @@ function renderToStream(code, options = {}) {
|
|
|
1172
1489
|
allSettled(blockingPromises).then(() => {
|
|
1173
1490
|
scheduleFlush(() => {
|
|
1174
1491
|
if (dead) return;
|
|
1175
|
-
|
|
1492
|
+
try {
|
|
1493
|
+
doShell();
|
|
1494
|
+
} catch (err) {
|
|
1495
|
+
failRender(err);
|
|
1496
|
+
try {
|
|
1497
|
+
w.end();
|
|
1498
|
+
} catch (_) {}
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1176
1501
|
if (!shellCompleted) return flush();
|
|
1177
1502
|
buffer = writable = guardSink(w);
|
|
1178
1503
|
buffer.write(tmp);
|
|
@@ -1204,9 +1529,27 @@ function renderToStream(code, options = {}) {
|
|
|
1204
1529
|
function buildAsyncWrap(err, node) {
|
|
1205
1530
|
const p = solidJs.ssrHandleError(err);
|
|
1206
1531
|
if (!p) return null;
|
|
1532
|
+
if (node.$rw) return {
|
|
1533
|
+
fn: node,
|
|
1534
|
+
p
|
|
1535
|
+
};
|
|
1207
1536
|
const owner = solidJs.getOwner();
|
|
1537
|
+
const live = solidJs.sharedConfig.context && solidJs.sharedConfig.context.liveHoles;
|
|
1538
|
+
const suppress = node.$lhSuppress || live && (live.suppressed || live.sweeping);
|
|
1539
|
+
if (!owner) {
|
|
1540
|
+
if (suppress) node.$lhSuppress = true;
|
|
1541
|
+
return {
|
|
1542
|
+
fn: node,
|
|
1543
|
+
p
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
const fn = () => solidJs.runWithOwner(owner, node);
|
|
1547
|
+
fn.$rw = true;
|
|
1548
|
+
if (suppress) fn.$lhSuppress = true;
|
|
1549
|
+
if (node.$lhSkip) fn.$lhSkip = true;
|
|
1550
|
+
if (node.$lhBinding) fn.$lhBinding = node.$lhBinding;
|
|
1208
1551
|
return {
|
|
1209
|
-
fn
|
|
1552
|
+
fn,
|
|
1210
1553
|
p
|
|
1211
1554
|
};
|
|
1212
1555
|
}
|
|
@@ -1266,6 +1609,326 @@ function ssrGroupSlot(fn, idx) {
|
|
|
1266
1609
|
}
|
|
1267
1610
|
};
|
|
1268
1611
|
}
|
|
1612
|
+
const holePositionCache = new WeakMap();
|
|
1613
|
+
function holeContentPositions(t) {
|
|
1614
|
+
let cached = holePositionCache.get(t);
|
|
1615
|
+
if (cached) return cached;
|
|
1616
|
+
const pos = [];
|
|
1617
|
+
const openOff = [];
|
|
1618
|
+
const closeOff = [];
|
|
1619
|
+
let inTag = false;
|
|
1620
|
+
let quote = "";
|
|
1621
|
+
let curOpen = null;
|
|
1622
|
+
let scanningName = false;
|
|
1623
|
+
for (let i = 0; i < t.length; i++) {
|
|
1624
|
+
const seg = t[i];
|
|
1625
|
+
let close = -1;
|
|
1626
|
+
const openAtStart = inTag;
|
|
1627
|
+
let reopened = false;
|
|
1628
|
+
for (let j = 0; j < seg.length; j++) {
|
|
1629
|
+
const ch = seg[j];
|
|
1630
|
+
if (quote) {
|
|
1631
|
+
if (ch === quote) quote = "";
|
|
1632
|
+
} else if (inTag) {
|
|
1633
|
+
if (scanningName && (ch === " " || ch === "\t" || ch === "\n" || ch === ">" || ch === "/")) {
|
|
1634
|
+
scanningName = false;
|
|
1635
|
+
curOpen = {
|
|
1636
|
+
seg: i,
|
|
1637
|
+
off: j
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
if (ch === '"' || ch === "'") quote = ch;else if (ch === ">") {
|
|
1641
|
+
inTag = false;
|
|
1642
|
+
if (openAtStart && !reopened && close === -1) close = j;
|
|
1643
|
+
curOpen = null;
|
|
1644
|
+
}
|
|
1645
|
+
} else if (ch === "<") {
|
|
1646
|
+
inTag = true;
|
|
1647
|
+
scanningName = true;
|
|
1648
|
+
reopened = true;
|
|
1649
|
+
curOpen = null;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
if (inTag && scanningName) {
|
|
1653
|
+
scanningName = false;
|
|
1654
|
+
curOpen = {
|
|
1655
|
+
seg: i,
|
|
1656
|
+
off: seg.length
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
closeOff.push(close);
|
|
1660
|
+
openOff.push(inTag && curOpen && curOpen.seg === i ? curOpen.off : -1);
|
|
1661
|
+
if (i < t.length - 1) pos.push(!inTag);
|
|
1662
|
+
}
|
|
1663
|
+
cached = {
|
|
1664
|
+
pos,
|
|
1665
|
+
openOff,
|
|
1666
|
+
closeOff
|
|
1667
|
+
};
|
|
1668
|
+
holePositionCache.set(t, cached);
|
|
1669
|
+
return cached;
|
|
1670
|
+
}
|
|
1671
|
+
function createLiveHoles(sink, scoped) {
|
|
1672
|
+
let nextId = 0;
|
|
1673
|
+
const stamp = typeof solidJs.creationStamp === "function" ? solidJs.creationStamp : () => 0;
|
|
1674
|
+
const inScope = scoped && typeof solidJs.inServerComponentScope === "function" ? solidJs.inServerComponentScope : null;
|
|
1675
|
+
const stripMarkers = html => html.replace(/<!--lh:\/?\d+-->/g, "");
|
|
1676
|
+
function resolveHoleValue(hole) {
|
|
1677
|
+
const result = {
|
|
1678
|
+
t: [""],
|
|
1679
|
+
h: [],
|
|
1680
|
+
p: []
|
|
1681
|
+
};
|
|
1682
|
+
try {
|
|
1683
|
+
resolveSSRNode(hole(), result);
|
|
1684
|
+
} catch (err) {
|
|
1685
|
+
const wrap = buildAsyncWrap(err, hole);
|
|
1686
|
+
if (!wrap) throw err;
|
|
1687
|
+
result.h.push(wrap.fn);
|
|
1688
|
+
result.p.push(wrap.p);
|
|
1689
|
+
result.t.push("");
|
|
1690
|
+
}
|
|
1691
|
+
return result;
|
|
1692
|
+
}
|
|
1693
|
+
function closeChildren(b) {
|
|
1694
|
+
for (const c of b.children) {
|
|
1695
|
+
c.closed = true;
|
|
1696
|
+
if (c.key) sink.closeBinding(c.key);
|
|
1697
|
+
closeChildren(c);
|
|
1698
|
+
}
|
|
1699
|
+
b.children.length = 0;
|
|
1700
|
+
}
|
|
1701
|
+
const engine = {
|
|
1702
|
+
suppressed: 0,
|
|
1703
|
+
sweeping: false,
|
|
1704
|
+
parent: null,
|
|
1705
|
+
recordStamp: 0,
|
|
1706
|
+
gateHit: false,
|
|
1707
|
+
content(hole) {
|
|
1708
|
+
if (hole.$lhSuppress) {
|
|
1709
|
+
const r = {
|
|
1710
|
+
t: [""],
|
|
1711
|
+
h: [],
|
|
1712
|
+
p: []
|
|
1713
|
+
};
|
|
1714
|
+
engine.suppressed++;
|
|
1715
|
+
try {
|
|
1716
|
+
try {
|
|
1717
|
+
resolveSSRNode(hole(), r);
|
|
1718
|
+
} catch (err) {
|
|
1719
|
+
const wrap = buildAsyncWrap(err, hole);
|
|
1720
|
+
if (wrap) {
|
|
1721
|
+
r.h.push(wrap.fn);
|
|
1722
|
+
r.p.push(wrap.p);
|
|
1723
|
+
r.t.push("");
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
} finally {
|
|
1727
|
+
engine.suppressed--;
|
|
1728
|
+
}
|
|
1729
|
+
const b = hole.$lhBinding;
|
|
1730
|
+
if (b && !b.closed && !r.h.length && !engine.sweeping) {
|
|
1731
|
+
b.last = stripMarkers(r.t[0]);
|
|
1732
|
+
}
|
|
1733
|
+
return r.h.length ? r : r.t[0];
|
|
1734
|
+
}
|
|
1735
|
+
if (engine.suppressed || engine.sweeping) return null;
|
|
1736
|
+
if (hole.$lhSkip) return null;
|
|
1737
|
+
if (inScope && !inScope()) return null;
|
|
1738
|
+
const recordsBefore = engine.recordStamp;
|
|
1739
|
+
const ownersBefore = stamp();
|
|
1740
|
+
const owner = solidJs.getOwner();
|
|
1741
|
+
const b = {
|
|
1742
|
+
key: null,
|
|
1743
|
+
children: [],
|
|
1744
|
+
last: null,
|
|
1745
|
+
closed: false,
|
|
1746
|
+
sweep() {
|
|
1747
|
+
if (b.closed) return;
|
|
1748
|
+
const prevSweeping = engine.sweeping;
|
|
1749
|
+
engine.sweeping = true;
|
|
1750
|
+
engine.gateHit = false;
|
|
1751
|
+
const sweepOwnersBefore = stamp();
|
|
1752
|
+
let res;
|
|
1753
|
+
try {
|
|
1754
|
+
res = owner ? solidJs.runWithOwner(owner, () => resolveHoleValue(hole)) : resolveHoleValue(hole);
|
|
1755
|
+
} catch (err) {
|
|
1756
|
+
b.closed = true;
|
|
1757
|
+
sink.closeBinding(b.key);
|
|
1758
|
+
sink.error(b.key, String(err && err.message || err));
|
|
1759
|
+
return;
|
|
1760
|
+
} finally {
|
|
1761
|
+
engine.sweeping = prevSweeping;
|
|
1762
|
+
}
|
|
1763
|
+
if (engine.gateHit || stamp() !== sweepOwnersBefore) {
|
|
1764
|
+
b.closed = true;
|
|
1765
|
+
sink.closeBinding(b.key);
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
if (res.h.length) return;
|
|
1769
|
+
const html = res.t[0];
|
|
1770
|
+
if (b.last === null || html === b.last) return;
|
|
1771
|
+
b.last = html;
|
|
1772
|
+
closeChildren(b);
|
|
1773
|
+
sink.hole(b.key, html);
|
|
1774
|
+
}
|
|
1775
|
+
};
|
|
1776
|
+
if (engine.parent) engine.parent.children.push(b);
|
|
1777
|
+
const prevParent = engine.parent;
|
|
1778
|
+
engine.parent = b;
|
|
1779
|
+
let value;
|
|
1780
|
+
let escalated = null;
|
|
1781
|
+
try {
|
|
1782
|
+
value = hole();
|
|
1783
|
+
} catch (err) {
|
|
1784
|
+
const wrap = buildAsyncWrap(err, hole);
|
|
1785
|
+
if (!wrap) {
|
|
1786
|
+
engine.parent = prevParent;
|
|
1787
|
+
closeChildren(b);
|
|
1788
|
+
return "";
|
|
1789
|
+
}
|
|
1790
|
+
escalated = wrap;
|
|
1791
|
+
}
|
|
1792
|
+
if (!escalated && (typeof value === "function" && value.$lhSkip || value !== null && typeof value === "object" && value.$slot)) {
|
|
1793
|
+
engine.parent = prevParent;
|
|
1794
|
+
const r = {
|
|
1795
|
+
t: [""],
|
|
1796
|
+
h: [],
|
|
1797
|
+
p: []
|
|
1798
|
+
};
|
|
1799
|
+
engine.suppressed++;
|
|
1800
|
+
try {
|
|
1801
|
+
resolveSSRNode(value, r);
|
|
1802
|
+
} finally {
|
|
1803
|
+
engine.suppressed--;
|
|
1804
|
+
}
|
|
1805
|
+
return r.h.length ? r : r.t[0];
|
|
1806
|
+
}
|
|
1807
|
+
let res;
|
|
1808
|
+
if (escalated) {
|
|
1809
|
+
closeChildren(b);
|
|
1810
|
+
escalated.fn.$lhSuppress = true;
|
|
1811
|
+
escalated.fn.$lhBinding = b;
|
|
1812
|
+
res = {
|
|
1813
|
+
t: ["", ""],
|
|
1814
|
+
h: [escalated.fn],
|
|
1815
|
+
p: [escalated.p]
|
|
1816
|
+
};
|
|
1817
|
+
} else {
|
|
1818
|
+
res = {
|
|
1819
|
+
t: [""],
|
|
1820
|
+
h: [],
|
|
1821
|
+
p: []
|
|
1822
|
+
};
|
|
1823
|
+
try {
|
|
1824
|
+
resolveSSRNode(value, res);
|
|
1825
|
+
} catch (_) {
|
|
1826
|
+
engine.parent = prevParent;
|
|
1827
|
+
closeChildren(b);
|
|
1828
|
+
return "";
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
engine.parent = prevParent;
|
|
1832
|
+
if (engine.recordStamp !== recordsBefore || stamp() !== ownersBefore) {
|
|
1833
|
+
return res.h.length ? res : res.t[0];
|
|
1834
|
+
}
|
|
1835
|
+
const id = nextId++;
|
|
1836
|
+
const key = b.key = "lh:" + id;
|
|
1837
|
+
const open = `<!--lh:${id}-->`;
|
|
1838
|
+
const close = `<!--lh:/${id}-->`;
|
|
1839
|
+
if (!res.h.length) {
|
|
1840
|
+
b.last = stripMarkers(res.t[0]);
|
|
1841
|
+
sink.openBinding(key, b);
|
|
1842
|
+
return open + res.t[0] + close;
|
|
1843
|
+
}
|
|
1844
|
+
const t = res.t.slice();
|
|
1845
|
+
t[0] = open + t[0];
|
|
1846
|
+
t[t.length - 1] += close;
|
|
1847
|
+
sink.openBinding(key, b);
|
|
1848
|
+
return {
|
|
1849
|
+
t,
|
|
1850
|
+
h: res.h,
|
|
1851
|
+
p: res.p
|
|
1852
|
+
};
|
|
1853
|
+
},
|
|
1854
|
+
mint() {
|
|
1855
|
+
return nextId++;
|
|
1856
|
+
},
|
|
1857
|
+
active() {
|
|
1858
|
+
return !inScope || inScope();
|
|
1859
|
+
},
|
|
1860
|
+
attr(cap) {
|
|
1861
|
+
const owner = solidJs.getOwner();
|
|
1862
|
+
const b = {
|
|
1863
|
+
key: "lha:" + cap.id,
|
|
1864
|
+
children: [],
|
|
1865
|
+
last: cap.base,
|
|
1866
|
+
closed: false,
|
|
1867
|
+
sweep() {
|
|
1868
|
+
if (b.closed) return;
|
|
1869
|
+
const prevSweeping = engine.sweeping;
|
|
1870
|
+
engine.sweeping = true;
|
|
1871
|
+
engine.gateHit = false;
|
|
1872
|
+
const sweepOwnersBefore = stamp();
|
|
1873
|
+
let html = "";
|
|
1874
|
+
try {
|
|
1875
|
+
let group = null;
|
|
1876
|
+
let groupVal = null;
|
|
1877
|
+
const run = () => {
|
|
1878
|
+
for (const part of cap.parts) {
|
|
1879
|
+
if (typeof part === "string") {
|
|
1880
|
+
html += part;
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
let v;
|
|
1884
|
+
if (part.g) {
|
|
1885
|
+
if (group !== part.g) {
|
|
1886
|
+
group = part.g;
|
|
1887
|
+
groupVal = part.g();
|
|
1888
|
+
}
|
|
1889
|
+
v = groupVal[part.i];
|
|
1890
|
+
} else {
|
|
1891
|
+
v = part.f();
|
|
1892
|
+
}
|
|
1893
|
+
const vt = typeof v;
|
|
1894
|
+
if (vt === "string" || vt === "number") html += v;
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
owner ? solidJs.runWithOwner(owner, run) : run();
|
|
1898
|
+
} catch (err) {
|
|
1899
|
+
if (solidJs.ssrHandleError(err, true)) return;
|
|
1900
|
+
b.closed = true;
|
|
1901
|
+
sink.closeBinding(b.key);
|
|
1902
|
+
sink.error("lha:" + cap.id, String(err && err.message || err));
|
|
1903
|
+
return;
|
|
1904
|
+
} finally {
|
|
1905
|
+
engine.sweeping = prevSweeping;
|
|
1906
|
+
}
|
|
1907
|
+
if (engine.gateHit || stamp() !== sweepOwnersBefore) {
|
|
1908
|
+
b.closed = true;
|
|
1909
|
+
sink.closeBinding(b.key);
|
|
1910
|
+
return;
|
|
1911
|
+
}
|
|
1912
|
+
if (html === b.last) return;
|
|
1913
|
+
const before = attrNames(b.last);
|
|
1914
|
+
const after = attrNames(html);
|
|
1915
|
+
const removed = before.filter(n => !after.includes(n));
|
|
1916
|
+
b.last = html;
|
|
1917
|
+
sink.attr(String(cap.id), html, removed);
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
sink.openBinding(b.key, b);
|
|
1921
|
+
}
|
|
1922
|
+
};
|
|
1923
|
+
return engine;
|
|
1924
|
+
}
|
|
1925
|
+
function attrNames(text) {
|
|
1926
|
+
const names = [];
|
|
1927
|
+
const re = /(?:^|\s)([^\s=/>"']+)(?:="[^"]*")?/g;
|
|
1928
|
+
let m;
|
|
1929
|
+
while (m = re.exec(text)) names.push(m[1]);
|
|
1930
|
+
return names;
|
|
1931
|
+
}
|
|
1269
1932
|
function ssr(t) {
|
|
1270
1933
|
const len = arguments.length;
|
|
1271
1934
|
if (len === 1) return {
|
|
@@ -1276,13 +1939,54 @@ function ssr(t) {
|
|
|
1276
1939
|
let lastGroup = null;
|
|
1277
1940
|
let lastGroupVal = null;
|
|
1278
1941
|
let lastGroupIdx = 0;
|
|
1942
|
+
const live = solidJs.sharedConfig.context && solidJs.sharedConfig.context.liveHoles;
|
|
1943
|
+
const hp = live ? holeContentPositions(t) : null;
|
|
1944
|
+
let lastOpen = null;
|
|
1945
|
+
let cap = null;
|
|
1946
|
+
if (live && hp.openOff[0] >= 0) lastOpen = {
|
|
1947
|
+
r: null,
|
|
1948
|
+
seg: -1,
|
|
1949
|
+
off: hp.openOff[0]
|
|
1950
|
+
};
|
|
1951
|
+
const captureStart = () => {
|
|
1952
|
+
if (cap) return true;
|
|
1953
|
+
if (!lastOpen || live.suppressed || live.sweeping || !live.active()) return false;
|
|
1954
|
+
if (lastOpen.r !== result || result !== null && lastOpen.seg !== result.t.length - 1) {
|
|
1955
|
+
return false;
|
|
1956
|
+
}
|
|
1957
|
+
const id = live.mint();
|
|
1958
|
+
const inject = ` data-lha="${id}"`;
|
|
1959
|
+
let prefix;
|
|
1960
|
+
if (result === null) {
|
|
1961
|
+
s = s.slice(0, lastOpen.off) + inject + s.slice(lastOpen.off);
|
|
1962
|
+
prefix = s.slice(lastOpen.off + inject.length);
|
|
1963
|
+
} else {
|
|
1964
|
+
const seg = result.t[lastOpen.seg];
|
|
1965
|
+
result.t[lastOpen.seg] = seg.slice(0, lastOpen.off) + inject + seg.slice(lastOpen.off);
|
|
1966
|
+
prefix = result.t[lastOpen.seg].slice(lastOpen.off + inject.length);
|
|
1967
|
+
}
|
|
1968
|
+
cap = {
|
|
1969
|
+
id,
|
|
1970
|
+
parts: [prefix],
|
|
1971
|
+
base: prefix
|
|
1972
|
+
};
|
|
1973
|
+
return true;
|
|
1974
|
+
};
|
|
1279
1975
|
for (let i = 1; i < len; i++) {
|
|
1280
1976
|
const hole = arguments[i];
|
|
1281
1977
|
const ht = typeof hole;
|
|
1282
1978
|
if (ht === "string") {
|
|
1283
1979
|
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
1980
|
+
if (cap) {
|
|
1981
|
+
cap.parts.push(hole);
|
|
1982
|
+
cap.base += hole;
|
|
1983
|
+
}
|
|
1284
1984
|
} else if (ht === "number") {
|
|
1285
1985
|
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
1986
|
+
if (cap) {
|
|
1987
|
+
cap.parts.push("" + hole);
|
|
1988
|
+
cap.base += hole;
|
|
1989
|
+
}
|
|
1286
1990
|
} else if (hole == null || ht === "boolean") ; else if (ht === "function" && hole.$g) {
|
|
1287
1991
|
let value;
|
|
1288
1992
|
let hasValue = false;
|
|
@@ -1306,7 +2010,14 @@ function ssr(t) {
|
|
|
1306
2010
|
if (Array.isArray(lastGroupVal)) {
|
|
1307
2011
|
value = lastGroupVal[lastGroupIdx++];
|
|
1308
2012
|
hasValue = true;
|
|
2013
|
+
if (live && !hp.pos[i - 1] && captureStart()) {
|
|
2014
|
+
cap.parts.push({
|
|
2015
|
+
g: hole,
|
|
2016
|
+
i: lastGroupIdx - 1
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
1309
2019
|
} else {
|
|
2020
|
+
cap = null;
|
|
1310
2021
|
result.h.push(ssrGroupSlot(lastGroupVal.fn, lastGroupIdx++));
|
|
1311
2022
|
result.p.push(lastGroupVal.p);
|
|
1312
2023
|
result.t.push("");
|
|
@@ -1316,6 +2027,7 @@ function ssr(t) {
|
|
|
1316
2027
|
const vt = typeof value;
|
|
1317
2028
|
if (vt === "string" || vt === "number") {
|
|
1318
2029
|
if (result === null) s += value;else result.t[result.t.length - 1] += value;
|
|
2030
|
+
if (cap && !hp.pos[i - 1]) cap.base += value;
|
|
1319
2031
|
} else if (value == null || vt === "boolean") ; else if (result !== null) {
|
|
1320
2032
|
resolveSSRNode(value, result);
|
|
1321
2033
|
} else {
|
|
@@ -1333,19 +2045,67 @@ function ssr(t) {
|
|
|
1333
2045
|
}
|
|
1334
2046
|
}
|
|
1335
2047
|
}
|
|
1336
|
-
} else if (result !== null) {
|
|
1337
|
-
resolveSSRNode(hole, result);
|
|
1338
2048
|
} else if (ht === "function") {
|
|
1339
|
-
|
|
1340
|
-
if (
|
|
1341
|
-
|
|
1342
|
-
t
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
2049
|
+
let liveNode = null;
|
|
2050
|
+
if (live && hp.pos[i - 1] && (liveNode = live.content(hole)) !== null) {
|
|
2051
|
+
if (typeof liveNode === "string") {
|
|
2052
|
+
if (result === null) s += liveNode;else result.t[result.t.length - 1] += liveNode;
|
|
2053
|
+
} else {
|
|
2054
|
+
if (result === null) {
|
|
2055
|
+
result = {
|
|
2056
|
+
t: [s],
|
|
2057
|
+
h: [],
|
|
2058
|
+
p: []
|
|
2059
|
+
};
|
|
2060
|
+
s = "";
|
|
2061
|
+
}
|
|
2062
|
+
resolveSSRNode(liveNode, result);
|
|
2063
|
+
}
|
|
2064
|
+
} else if (result !== null) {
|
|
2065
|
+
const inTag = live && !hp.pos[i - 1];
|
|
2066
|
+
const capturing = inTag && captureStart();
|
|
2067
|
+
const li = capturing ? result.t.length - 1 : 0;
|
|
2068
|
+
const before = capturing ? result.t[li].length : 0;
|
|
2069
|
+
if (live) live.suppressed++;
|
|
2070
|
+
try {
|
|
2071
|
+
resolveSSRNode(hole, result);
|
|
2072
|
+
} finally {
|
|
2073
|
+
if (live) live.suppressed--;
|
|
2074
|
+
}
|
|
2075
|
+
if (capturing) {
|
|
2076
|
+
if (result.t.length - 1 === li) {
|
|
2077
|
+
cap.base += result.t[li].slice(before);
|
|
2078
|
+
cap.parts.push({
|
|
2079
|
+
f: hole
|
|
2080
|
+
});
|
|
2081
|
+
} else {
|
|
2082
|
+
cap = null;
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
} else {
|
|
2086
|
+
const capturing = live && !hp.pos[i - 1] && captureStart();
|
|
2087
|
+
const r = tryResolveFunctionHole(hole);
|
|
2088
|
+
if (typeof r === "string") {
|
|
2089
|
+
s += r;
|
|
2090
|
+
if (capturing) {
|
|
2091
|
+
cap.base += r;
|
|
2092
|
+
cap.parts.push({
|
|
2093
|
+
f: hole
|
|
2094
|
+
});
|
|
2095
|
+
}
|
|
2096
|
+
} else {
|
|
2097
|
+
if (capturing) cap = null;
|
|
2098
|
+
result = {
|
|
2099
|
+
t: [s],
|
|
2100
|
+
h: [],
|
|
2101
|
+
p: []
|
|
2102
|
+
};
|
|
2103
|
+
s = "";
|
|
2104
|
+
appendResolvedNode(result, r);
|
|
2105
|
+
}
|
|
1348
2106
|
}
|
|
2107
|
+
} else if (result !== null) {
|
|
2108
|
+
resolveSSRNode(hole, result);
|
|
1349
2109
|
} else {
|
|
1350
2110
|
const r = tryResolveString(hole);
|
|
1351
2111
|
if (typeof r === "string") {
|
|
@@ -1361,6 +2121,32 @@ function ssr(t) {
|
|
|
1361
2121
|
}
|
|
1362
2122
|
}
|
|
1363
2123
|
const next = t[i];
|
|
2124
|
+
if (live) {
|
|
2125
|
+
if (cap) {
|
|
2126
|
+
const co = hp.closeOff[i];
|
|
2127
|
+
if (co >= 0) {
|
|
2128
|
+
const tail = next.slice(0, co);
|
|
2129
|
+
cap.parts.push(tail);
|
|
2130
|
+
cap.base += tail;
|
|
2131
|
+
live.attr(cap);
|
|
2132
|
+
cap = null;
|
|
2133
|
+
} else {
|
|
2134
|
+
cap.parts.push(next);
|
|
2135
|
+
cap.base += next;
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
if (hp.openOff[i] >= 0) {
|
|
2139
|
+
lastOpen = result === null ? {
|
|
2140
|
+
r: null,
|
|
2141
|
+
seg: -1,
|
|
2142
|
+
off: s.length + hp.openOff[i]
|
|
2143
|
+
} : {
|
|
2144
|
+
r: result,
|
|
2145
|
+
seg: result.t.length - 1,
|
|
2146
|
+
off: result.t[result.t.length - 1].length + hp.openOff[i]
|
|
2147
|
+
};
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
1364
2150
|
if (result === null) s += next;else result.t[result.t.length - 1] += next;
|
|
1365
2151
|
}
|
|
1366
2152
|
if (result === null) return {
|
|
@@ -1449,17 +2235,11 @@ function allSettled(promises) {
|
|
|
1449
2235
|
return;
|
|
1450
2236
|
});
|
|
1451
2237
|
}
|
|
1452
|
-
function
|
|
1453
|
-
if (!assets || !assets.length) return "";
|
|
1454
|
-
let out = "";
|
|
1455
|
-
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
1456
|
-
return out;
|
|
1457
|
-
}
|
|
1458
|
-
function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2238
|
+
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1459
2239
|
const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
|
|
1460
2240
|
const headTagsHtml = headTags ? headTags.html : "";
|
|
1461
2241
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
1462
|
-
if (!onHead && !
|
|
2242
|
+
if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
1463
2243
|
if (!scriptTag) return html;
|
|
1464
2244
|
const xs = html.indexOf("<!--xs-->");
|
|
1465
2245
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -1474,13 +2254,13 @@ function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts
|
|
|
1474
2254
|
const headIdx = html.indexOf("</head>");
|
|
1475
2255
|
if (headIdx === -1) {
|
|
1476
2256
|
if (onHead) {
|
|
1477
|
-
onHead(headPrelude + headTagsHtml +
|
|
2257
|
+
onHead(headPrelude + headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
1478
2258
|
}
|
|
1479
2259
|
if (!scriptTag) return html;
|
|
1480
2260
|
const xs = html.indexOf("<!--xs-->");
|
|
1481
2261
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
1482
2262
|
}
|
|
1483
|
-
const head = headTagsHtml +
|
|
2263
|
+
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
1484
2264
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
1485
2265
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
1486
2266
|
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
@@ -1599,7 +2379,6 @@ function tryResolveString(node) {
|
|
|
1599
2379
|
merge: node
|
|
1600
2380
|
};
|
|
1601
2381
|
if (node.t === undefined) {
|
|
1602
|
-
console.warn(`Unrecognized value. Skipped inserting`, node);
|
|
1603
2382
|
return "";
|
|
1604
2383
|
}
|
|
1605
2384
|
return Array.isArray(node.t) ? node.t[0] : node.t;
|
|
@@ -1624,13 +2403,19 @@ function resolveSSRNode(node, result = {
|
|
|
1624
2403
|
if (t === "string" || t === "number") {
|
|
1625
2404
|
result.t[result.t.length - 1] += node;
|
|
1626
2405
|
} else if (node == null || t === "boolean") ; else if (Array.isArray(node)) {
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
2406
|
+
const slotLive = node.$slot && solidJs.sharedConfig.context && solidJs.sharedConfig.context.liveHoles;
|
|
2407
|
+
if (slotLive) slotLive.suppressed++;
|
|
2408
|
+
try {
|
|
2409
|
+
let prevNonObj = false;
|
|
2410
|
+
for (let i = 0, len = node.length; i < len; i++) {
|
|
2411
|
+
const item = node[i];
|
|
2412
|
+
const itemNonObj = item !== null && typeof item !== "object";
|
|
2413
|
+
if (!top && prevNonObj && itemNonObj) result.t[result.t.length - 1] += `<!--!$-->`;
|
|
2414
|
+
prevNonObj = itemNonObj;
|
|
2415
|
+
resolveSSRNode(item, result);
|
|
2416
|
+
}
|
|
2417
|
+
} finally {
|
|
2418
|
+
if (slotLive) slotLive.suppressed--;
|
|
1634
2419
|
}
|
|
1635
2420
|
} else if (t === "object") {
|
|
1636
2421
|
if (node.h) {
|
|
@@ -1642,16 +2427,22 @@ function resolveSSRNode(node, result = {
|
|
|
1642
2427
|
}
|
|
1643
2428
|
} else if (node.t !== undefined) {
|
|
1644
2429
|
result.t[result.t.length - 1] += node.t;
|
|
1645
|
-
} else
|
|
2430
|
+
} else ;
|
|
1646
2431
|
} else if (t === "function") {
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
2432
|
+
const live = solidJs.sharedConfig.context && solidJs.sharedConfig.context.liveHoles;
|
|
2433
|
+
let liveNode = null;
|
|
2434
|
+
if (live && (liveNode = live.content(node)) !== null) {
|
|
2435
|
+
if (typeof liveNode === "string") result.t[result.t.length - 1] += liveNode;else resolveSSRNode(liveNode, result);
|
|
2436
|
+
} else {
|
|
2437
|
+
try {
|
|
2438
|
+
resolveSSRNode(node(), result);
|
|
2439
|
+
} catch (err) {
|
|
2440
|
+
const wrap = buildAsyncWrap(err, node);
|
|
2441
|
+
if (wrap) {
|
|
2442
|
+
result.h.push(wrap.fn);
|
|
2443
|
+
result.p.push(wrap.p);
|
|
2444
|
+
result.t.push("");
|
|
2445
|
+
}
|
|
1655
2446
|
}
|
|
1656
2447
|
}
|
|
1657
2448
|
}
|
|
@@ -1662,142 +2453,7 @@ function resolveSSRSync(node) {
|
|
|
1662
2453
|
if (!res.h.length) return res.t[0];
|
|
1663
2454
|
throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
|
|
1664
2455
|
}
|
|
1665
|
-
|
|
1666
|
-
function frameAddress(id, args) {
|
|
1667
|
-
return args && args.length ? id + ":" + hashArguments(args) : id;
|
|
1668
|
-
}
|
|
1669
|
-
function hashArguments(args) {
|
|
1670
|
-
let hash = 0;
|
|
1671
|
-
const text = stableString(args);
|
|
1672
|
-
for (let i = 0; i < text.length; i++) {
|
|
1673
|
-
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
1674
|
-
hash |= 0;
|
|
1675
|
-
}
|
|
1676
|
-
return (hash >>> 0).toString(36);
|
|
1677
|
-
}
|
|
1678
|
-
function stableString(value, seen) {
|
|
1679
|
-
if (value === null || typeof value !== "object") {
|
|
1680
|
-
return typeof value === "bigint" ? value + "n" : String(value);
|
|
1681
|
-
}
|
|
1682
|
-
if (value instanceof Date) return "Date:" + value.getTime();
|
|
1683
|
-
seen || (seen = new Set());
|
|
1684
|
-
if (seen.has(value)) return "~";
|
|
1685
|
-
seen.add(value);
|
|
1686
|
-
if (value instanceof Map) {
|
|
1687
|
-
const entries = [];
|
|
1688
|
-
for (const [k, v] of value) {
|
|
1689
|
-
entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
|
|
1690
|
-
}
|
|
1691
|
-
return "Map{" + entries.sort().join(",") + "}";
|
|
1692
|
-
}
|
|
1693
|
-
if (value instanceof Set) {
|
|
1694
|
-
const members = [];
|
|
1695
|
-
for (const v of value) members.push(stableString(v, seen));
|
|
1696
|
-
return "Set{" + members.sort().join(",") + "}";
|
|
1697
|
-
}
|
|
1698
|
-
if (Array.isArray(value)) {
|
|
1699
|
-
let out = "[";
|
|
1700
|
-
for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
|
|
1701
|
-
return out + "]";
|
|
1702
|
-
}
|
|
1703
|
-
const keys = Object.keys(value).sort();
|
|
1704
|
-
let out = "{";
|
|
1705
|
-
for (let i = 0; i < keys.length; i++) {
|
|
1706
|
-
out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
|
|
1707
|
-
}
|
|
1708
|
-
return out + "}";
|
|
1709
|
-
}
|
|
1710
|
-
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
1711
|
-
function createChunk(data) {
|
|
1712
|
-
const encodeData = new TextEncoder().encode(data);
|
|
1713
|
-
const bytes = encodeData.length;
|
|
1714
|
-
const baseHex = bytes.toString(16);
|
|
1715
|
-
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex;
|
|
1716
|
-
const head = new TextEncoder().encode(`;0x${totalHex};`);
|
|
1717
|
-
const chunk = new Uint8Array(12 + bytes);
|
|
1718
|
-
chunk.set(head);
|
|
1719
|
-
chunk.set(encodeData, 12);
|
|
1720
|
-
return chunk;
|
|
1721
|
-
}
|
|
1722
|
-
class ChunkReader {
|
|
1723
|
-
constructor(stream) {
|
|
1724
|
-
this.reader = stream.getReader();
|
|
1725
|
-
this.buffer = new Uint8Array(0);
|
|
1726
|
-
this.done = false;
|
|
1727
|
-
}
|
|
1728
|
-
async readChunk() {
|
|
1729
|
-
const chunk = await this.reader.read();
|
|
1730
|
-
if (!chunk.done) {
|
|
1731
|
-
const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
|
|
1732
|
-
newBuffer.set(this.buffer);
|
|
1733
|
-
newBuffer.set(chunk.value, this.buffer.length);
|
|
1734
|
-
this.buffer = newBuffer;
|
|
1735
|
-
} else {
|
|
1736
|
-
this.done = true;
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
async next() {
|
|
1740
|
-
while (this.buffer.length < 12) {
|
|
1741
|
-
if (this.done) {
|
|
1742
|
-
if (this.buffer.length === 0) return {
|
|
1743
|
-
done: true,
|
|
1744
|
-
value: undefined
|
|
1745
|
-
};
|
|
1746
|
-
throw new Error("Malformed server function stream.");
|
|
1747
|
-
}
|
|
1748
|
-
await this.readChunk();
|
|
1749
|
-
}
|
|
1750
|
-
const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
|
|
1751
|
-
const bytes = Number.parseInt(head, 16);
|
|
1752
|
-
if (Number.isNaN(bytes)) {
|
|
1753
|
-
throw new Error("Malformed server function stream.");
|
|
1754
|
-
}
|
|
1755
|
-
while (bytes > this.buffer.length - 12) {
|
|
1756
|
-
if (this.done) {
|
|
1757
|
-
throw new Error("Malformed server function stream.");
|
|
1758
|
-
}
|
|
1759
|
-
await this.readChunk();
|
|
1760
|
-
}
|
|
1761
|
-
const partial = new TextDecoder().decode(this.buffer.subarray(12, 12 + bytes));
|
|
1762
|
-
this.buffer = this.buffer.subarray(12 + bytes);
|
|
1763
|
-
return {
|
|
1764
|
-
done: false,
|
|
1765
|
-
value: partial
|
|
1766
|
-
};
|
|
1767
|
-
}
|
|
1768
|
-
async drain(interpret) {
|
|
1769
|
-
while (true) {
|
|
1770
|
-
const result = await this.next();
|
|
1771
|
-
if (result.done) {
|
|
1772
|
-
break;
|
|
1773
|
-
}
|
|
1774
|
-
interpret(result.value);
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
function serializeStream(value, codecOptions) {
|
|
1779
|
-
return new ReadableStream({
|
|
1780
|
-
start(controller) {
|
|
1781
|
-
serializeJSON(value, {
|
|
1782
|
-
...codecOptions,
|
|
1783
|
-
onParse(node) {
|
|
1784
|
-
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
1785
|
-
},
|
|
1786
|
-
onDone() {
|
|
1787
|
-
controller.close();
|
|
1788
|
-
},
|
|
1789
|
-
onError(error) {
|
|
1790
|
-
controller.error(error);
|
|
1791
|
-
}
|
|
1792
|
-
});
|
|
1793
|
-
}
|
|
1794
|
-
});
|
|
1795
|
-
}
|
|
1796
|
-
|
|
1797
|
-
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
1798
|
-
function isResponseEnvelope(value) {
|
|
1799
|
-
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1800
|
-
}
|
|
2456
|
+
/*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
1801
2457
|
|
|
1802
2458
|
const INVOCATIONS = new WeakMap();
|
|
1803
2459
|
function getEventServerFunctionInvocation(event) {
|
|
@@ -1821,7 +2477,7 @@ function parseServerComponent(value, ctx) {
|
|
|
1821
2477
|
address: ctx.parse(value[SERVER_COMPONENT_ADDRESS])
|
|
1822
2478
|
};
|
|
1823
2479
|
}
|
|
1824
|
-
const ServerComponentPlugin =
|
|
2480
|
+
const ServerComponentPlugin = {
|
|
1825
2481
|
tag: "dom-expressions/server-component",
|
|
1826
2482
|
test(value) {
|
|
1827
2483
|
return typeof value === "function" && SERVER_COMPONENT in value;
|
|
@@ -1845,18 +2501,17 @@ const ServerComponentPlugin = /*#__PURE__*/seroval.createPlugin({
|
|
|
1845
2501
|
ctx.deserialize(node.address);
|
|
1846
2502
|
return globalThis._$SC.r(id);
|
|
1847
2503
|
}
|
|
1848
|
-
}
|
|
2504
|
+
};
|
|
1849
2505
|
function flightCodec(codec) {
|
|
1850
2506
|
const plugins = codec && codec.plugins || [];
|
|
1851
|
-
|
|
1852
|
-
if (plugin && plugin.tag === "dom-expressions/server-component") return codec;
|
|
1853
|
-
}
|
|
2507
|
+
if (plugins.some(plugin => plugin && plugin.tag === ServerComponentPlugin.tag)) return codec;
|
|
1854
2508
|
return {
|
|
1855
2509
|
...codec,
|
|
1856
2510
|
plugins: [...plugins, ServerComponentPlugin]
|
|
1857
2511
|
};
|
|
1858
2512
|
}
|
|
1859
2513
|
|
|
2514
|
+
const scopeStamp = typeof solidJs.creationStamp === "function" ? solidJs.creationStamp : () => 0;
|
|
1860
2515
|
function serverOwned(render) {
|
|
1861
2516
|
return solidJs.NoHydration ? solidJs.NoHydration({
|
|
1862
2517
|
get children() {
|
|
@@ -1881,6 +2536,29 @@ function createFrameSink(emit, frame) {
|
|
|
1881
2536
|
version
|
|
1882
2537
|
} = frame;
|
|
1883
2538
|
const styledKeys = new Set();
|
|
2539
|
+
const bindings = new Map();
|
|
2540
|
+
const sweepMinted = new Set();
|
|
2541
|
+
const argRefVersions = new Map();
|
|
2542
|
+
let sweepScheduled = false;
|
|
2543
|
+
let closed = false;
|
|
2544
|
+
let epoch = 0;
|
|
2545
|
+
const sweep = () => {
|
|
2546
|
+
epoch++;
|
|
2547
|
+
for (const b of [...bindings.values()]) {
|
|
2548
|
+
try {
|
|
2549
|
+
b.sweep();
|
|
2550
|
+
} catch (_) {
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
};
|
|
2554
|
+
const scheduleSweep = () => {
|
|
2555
|
+
if (closed || sweepScheduled || !bindings.size) return;
|
|
2556
|
+
sweepScheduled = true;
|
|
2557
|
+
queueMicrotask(() => {
|
|
2558
|
+
sweepScheduled = false;
|
|
2559
|
+
if (!closed) sweep();
|
|
2560
|
+
});
|
|
2561
|
+
};
|
|
1884
2562
|
const regionKeys = new Map();
|
|
1885
2563
|
const frameOf = key => regionKeys.get(key) || id;
|
|
1886
2564
|
return {
|
|
@@ -1922,6 +2600,7 @@ function createFrameSink(emit, frame) {
|
|
|
1922
2600
|
version,
|
|
1923
2601
|
payload: record
|
|
1924
2602
|
});
|
|
2603
|
+
scheduleSweep();
|
|
1925
2604
|
} else {
|
|
1926
2605
|
emit({
|
|
1927
2606
|
type: "data",
|
|
@@ -1931,6 +2610,7 @@ function createFrameSink(emit, frame) {
|
|
|
1931
2610
|
node: record.node,
|
|
1932
2611
|
initial: record.initial
|
|
1933
2612
|
});
|
|
2613
|
+
if (!sweepMinted.has(record.key)) scheduleSweep();
|
|
1934
2614
|
}
|
|
1935
2615
|
},
|
|
1936
2616
|
fragment(key, value, meta = {}) {
|
|
@@ -1967,6 +2647,7 @@ function createFrameSink(emit, frame) {
|
|
|
1967
2647
|
key,
|
|
1968
2648
|
html: value
|
|
1969
2649
|
});
|
|
2650
|
+
scheduleSweep();
|
|
1970
2651
|
if (meta.error) {
|
|
1971
2652
|
emit({
|
|
1972
2653
|
type: "error",
|
|
@@ -2021,6 +2702,8 @@ function createFrameSink(emit, frame) {
|
|
|
2021
2702
|
});
|
|
2022
2703
|
},
|
|
2023
2704
|
end() {
|
|
2705
|
+
if (bindings.size) sweep();
|
|
2706
|
+
closed = true;
|
|
2024
2707
|
emit({
|
|
2025
2708
|
type: "complete",
|
|
2026
2709
|
id,
|
|
@@ -2052,6 +2735,44 @@ function createFrameSink(emit, frame) {
|
|
|
2052
2735
|
version,
|
|
2053
2736
|
html
|
|
2054
2737
|
});
|
|
2738
|
+
},
|
|
2739
|
+
hole(key, html) {
|
|
2740
|
+
emit({
|
|
2741
|
+
type: "hole",
|
|
2742
|
+
id,
|
|
2743
|
+
version,
|
|
2744
|
+
key,
|
|
2745
|
+
html
|
|
2746
|
+
});
|
|
2747
|
+
},
|
|
2748
|
+
attr(key, attrs, removed) {
|
|
2749
|
+
const chunk = {
|
|
2750
|
+
type: "attr",
|
|
2751
|
+
id,
|
|
2752
|
+
version,
|
|
2753
|
+
key,
|
|
2754
|
+
attrs
|
|
2755
|
+
};
|
|
2756
|
+
if (removed && removed.length) chunk.removed = removed;
|
|
2757
|
+
emit(chunk);
|
|
2758
|
+
},
|
|
2759
|
+
openBinding(key, b) {
|
|
2760
|
+
bindings.set(key, b);
|
|
2761
|
+
},
|
|
2762
|
+
closeBinding(key) {
|
|
2763
|
+
bindings.delete(key);
|
|
2764
|
+
},
|
|
2765
|
+
mintRef(ref) {
|
|
2766
|
+
sweepMinted.add(ref);
|
|
2767
|
+
},
|
|
2768
|
+
nextArgRef(ledgerKey) {
|
|
2769
|
+
const n = (argRefVersions.get(ledgerKey) || 0) + 1;
|
|
2770
|
+
argRefVersions.set(ledgerKey, n);
|
|
2771
|
+
return n;
|
|
2772
|
+
},
|
|
2773
|
+
commit: scheduleSweep,
|
|
2774
|
+
get epoch() {
|
|
2775
|
+
return epoch;
|
|
2055
2776
|
}
|
|
2056
2777
|
};
|
|
2057
2778
|
}
|
|
@@ -2061,7 +2782,15 @@ function renderToFrameStream(code, options = {}) {
|
|
|
2061
2782
|
function renderServerComponent(component, options = {}) {
|
|
2062
2783
|
return frameStream((sink, frame) => {
|
|
2063
2784
|
const props = createSlotProps(sink, frame);
|
|
2064
|
-
return () =>
|
|
2785
|
+
return () => {
|
|
2786
|
+
const ctx = solidJs.sharedConfig.context;
|
|
2787
|
+
if (ctx) {
|
|
2788
|
+
ctx.commit = sink.commit;
|
|
2789
|
+
ctx.commitEpoch = () => sink.epoch;
|
|
2790
|
+
ctx.liveHoles = createLiveHoles(sink);
|
|
2791
|
+
}
|
|
2792
|
+
return serverComponentScope(() => component(props));
|
|
2793
|
+
};
|
|
2065
2794
|
}, options);
|
|
2066
2795
|
}
|
|
2067
2796
|
function frameStream(makeCode, options) {
|
|
@@ -2119,7 +2848,8 @@ function frameStream(makeCode, options) {
|
|
|
2119
2848
|
}
|
|
2120
2849
|
function slotRange(occurrence) {
|
|
2121
2850
|
return {
|
|
2122
|
-
t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end
|
|
2851
|
+
t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end-->`,
|
|
2852
|
+
$slot: true
|
|
2123
2853
|
};
|
|
2124
2854
|
}
|
|
2125
2855
|
const OCCURRENCE_UNSAFE = /[^A-Za-z0-9_.-]/g;
|
|
@@ -2138,14 +2868,57 @@ function occurrenceId(prop, raw, counts) {
|
|
|
2138
2868
|
counts[prop] = n + 1;
|
|
2139
2869
|
return `${prop}#${n}`;
|
|
2140
2870
|
}
|
|
2871
|
+
function isAsyncValue(v) {
|
|
2872
|
+
return !!v && typeof v === "object" && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
2873
|
+
}
|
|
2874
|
+
function tapFirstYield(iterable) {
|
|
2875
|
+
const iter = iterable[Symbol.asyncIterator]();
|
|
2876
|
+
const firstStep = Promise.resolve(iter.next());
|
|
2877
|
+
return {
|
|
2878
|
+
first: firstStep.then(r => r.done ? undefined : r.value),
|
|
2879
|
+
rest: {
|
|
2880
|
+
[Symbol.asyncIterator]() {
|
|
2881
|
+
let replayed = false;
|
|
2882
|
+
return {
|
|
2883
|
+
next: () => {
|
|
2884
|
+
if (!replayed) {
|
|
2885
|
+
replayed = true;
|
|
2886
|
+
return firstStep;
|
|
2887
|
+
}
|
|
2888
|
+
return iter.next();
|
|
2889
|
+
},
|
|
2890
|
+
return: v => iter.return ? iter.return(v) : Promise.resolve({
|
|
2891
|
+
done: true,
|
|
2892
|
+
value: v
|
|
2893
|
+
}),
|
|
2894
|
+
throw: e => iter.throw ? iter.throw(e) : Promise.reject(e)
|
|
2895
|
+
};
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
};
|
|
2899
|
+
}
|
|
2900
|
+
function suppressedFill(render) {
|
|
2901
|
+
const live = solidJs.sharedConfig.context && solidJs.sharedConfig.context.liveHoles;
|
|
2902
|
+
if (!live) return render();
|
|
2903
|
+
live.suppressed++;
|
|
2904
|
+
try {
|
|
2905
|
+
return render();
|
|
2906
|
+
} finally {
|
|
2907
|
+
live.suppressed--;
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2141
2910
|
function createDocumentSlotProps(clientProps, frameId) {
|
|
2142
2911
|
const counts = Object.create(null);
|
|
2143
2912
|
const getters = new Map();
|
|
2144
|
-
const range = (occurrence, content) =>
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2913
|
+
const range = (occurrence, content) => {
|
|
2914
|
+
const r = [{
|
|
2915
|
+
t: `<!--slot:${occurrence}:start-->`
|
|
2916
|
+
}, content, {
|
|
2917
|
+
t: `<!--slot:${occurrence}:end-->`
|
|
2918
|
+
}];
|
|
2919
|
+
r.$slot = true;
|
|
2920
|
+
return r;
|
|
2921
|
+
};
|
|
2149
2922
|
const zoneOwner = solidJs.getOwner ? solidJs.getOwner() : null;
|
|
2150
2923
|
const scoped = (occurrence, render) => {
|
|
2151
2924
|
const id = `sc-${frameId}-${occurrence}-`;
|
|
@@ -2168,27 +2941,68 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
2168
2941
|
if (!fn) {
|
|
2169
2942
|
fn = (...callArgs) => {
|
|
2170
2943
|
if (callArgs.length === 0 || callArgs[0] === undefined) {
|
|
2171
|
-
return scoped(prop, () => {
|
|
2944
|
+
return suppressedFill(() => scoped(prop, () => {
|
|
2172
2945
|
const value = clientProps[prop];
|
|
2173
2946
|
return range(prop, typeof value === "function" ? value() : value);
|
|
2174
|
-
});
|
|
2947
|
+
}));
|
|
2175
2948
|
}
|
|
2176
2949
|
const raw = callArgs[0];
|
|
2177
2950
|
const occurrence = occurrenceId(prop, raw, counts);
|
|
2178
2951
|
const slot = clientProps[prop];
|
|
2179
2952
|
if (typeof slot !== "function") return range(occurrence, undefined);
|
|
2180
2953
|
const resolved = {};
|
|
2954
|
+
const liveArgs = solidJs.sharedConfig.context && solidJs.sharedConfig.context.live && solidJs.sharedConfig.context.live.args;
|
|
2181
2955
|
const vals = {};
|
|
2956
|
+
const evals = {};
|
|
2957
|
+
const states = {};
|
|
2958
|
+
const minted = {};
|
|
2182
2959
|
for (const key of Object.keys(raw)) {
|
|
2183
2960
|
if (key === "$key") continue;
|
|
2184
|
-
|
|
2185
|
-
|
|
2961
|
+
const desc = Object.getOwnPropertyDescriptor(raw, key);
|
|
2962
|
+
let evaluate = null;
|
|
2963
|
+
let value;
|
|
2964
|
+
if (desc.get) {
|
|
2965
|
+
const get = desc.get;
|
|
2966
|
+
evaluate = () => unwrapThunks(get.call(raw));
|
|
2967
|
+
} else {
|
|
2968
|
+
value = desc.value;
|
|
2969
|
+
if (typeof value === "function") {
|
|
2970
|
+
const fn = value;
|
|
2971
|
+
evaluate = () => unwrapThunks(fn);
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
if (evaluate) {
|
|
2975
|
+
evals[key] = evaluate;
|
|
2976
|
+
const stampBefore = scopeStamp();
|
|
2977
|
+
try {
|
|
2978
|
+
value = evaluate();
|
|
2979
|
+
states[key] = {
|
|
2980
|
+
settled: true,
|
|
2981
|
+
last: value
|
|
2982
|
+
};
|
|
2983
|
+
} catch (err) {
|
|
2984
|
+
const blocked = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
|
|
2985
|
+
if (!blocked) throw err;
|
|
2986
|
+
const state = states[key] = {
|
|
2987
|
+
settled: false,
|
|
2988
|
+
last: undefined
|
|
2989
|
+
};
|
|
2990
|
+
value = retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
2991
|
+
state.settled = true;
|
|
2992
|
+
state.last = v;
|
|
2993
|
+
if (liveArgs) liveArgs.commit();
|
|
2994
|
+
});
|
|
2995
|
+
}
|
|
2996
|
+
if (scopeStamp() !== stampBefore) minted[key] = true;
|
|
2997
|
+
}
|
|
2186
2998
|
vals[key] = value;
|
|
2187
2999
|
}
|
|
2188
3000
|
const regions = [];
|
|
2189
3001
|
for (const key of Object.keys(vals)) {
|
|
2190
3002
|
const value = vals[key];
|
|
2191
|
-
if (
|
|
3003
|
+
if (isContainerTraced(value)) {
|
|
3004
|
+
resolved[key] = value;
|
|
3005
|
+
} else if (isServerContent(value)) {
|
|
2192
3006
|
const childId = `${frameId}.${occurrence}.${key}`;
|
|
2193
3007
|
const region = {
|
|
2194
3008
|
key,
|
|
@@ -2207,11 +3021,27 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
2207
3021
|
t: FRAME_ELEMENT_CLOSE
|
|
2208
3022
|
}];
|
|
2209
3023
|
};
|
|
3024
|
+
} else if (ssrAsyncValue && isAsyncValue(value)) {
|
|
3025
|
+
let readable = value;
|
|
3026
|
+
if (typeof value.then !== "function") {
|
|
3027
|
+
const {
|
|
3028
|
+
first,
|
|
3029
|
+
rest
|
|
3030
|
+
} = tapFirstYield(value);
|
|
3031
|
+
readable = first;
|
|
3032
|
+
vals[key] = rest;
|
|
3033
|
+
}
|
|
3034
|
+
const read = ssrAsyncValue(readable);
|
|
3035
|
+
Object.defineProperty(resolved, key, {
|
|
3036
|
+
get: read,
|
|
3037
|
+
enumerable: true,
|
|
3038
|
+
configurable: true
|
|
3039
|
+
});
|
|
2210
3040
|
} else {
|
|
2211
3041
|
resolved[key] = value;
|
|
2212
3042
|
}
|
|
2213
3043
|
}
|
|
2214
|
-
const out = scoped(occurrence, () => range(occurrence, slot(resolved)));
|
|
3044
|
+
const out = suppressedFill(() => scoped(occurrence, () => range(occurrence, slot(resolved))));
|
|
2215
3045
|
const unused = regions.filter(r => !r.used);
|
|
2216
3046
|
if (solidJs.sharedConfig.context) {
|
|
2217
3047
|
const args = {};
|
|
@@ -2224,17 +3054,33 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
2224
3054
|
};
|
|
2225
3055
|
continue;
|
|
2226
3056
|
}
|
|
2227
|
-
if (isServerContent(value)) continue;
|
|
2228
|
-
args[key] = value;
|
|
3057
|
+
if (!isContainerTraced(value) && isServerContent(value)) continue;
|
|
3058
|
+
args[key] = envelopeContainerTraces(value);
|
|
2229
3059
|
}
|
|
2230
|
-
solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`,
|
|
3060
|
+
solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, {
|
|
3061
|
+
...args
|
|
3062
|
+
});
|
|
2231
3063
|
for (const region of unused) {
|
|
2232
3064
|
region.locked = true;
|
|
2233
3065
|
solidJs.sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(solidJs.sharedConfig.context, region.value));
|
|
2234
3066
|
}
|
|
3067
|
+
if (liveArgs) {
|
|
3068
|
+
for (const key of Object.keys(evals)) {
|
|
3069
|
+
if (regions.some(r => r.key === key)) continue;
|
|
3070
|
+
if (minted[key]) continue;
|
|
3071
|
+
const ledgerKey = `${frameId}:${occurrence}:${key}`;
|
|
3072
|
+
openArgBinding(liveArgs, ledgerKey, occurrence, key, evals[key], states[key], value => {
|
|
3073
|
+
args[key] = envelopeContainerTraces(value);
|
|
3074
|
+
liveArgs.slot(frameId, occurrence, {
|
|
3075
|
+
...args
|
|
3076
|
+
});
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
2235
3080
|
}
|
|
2236
3081
|
return out;
|
|
2237
3082
|
};
|
|
3083
|
+
fn.$lhSkip = true;
|
|
2238
3084
|
getters.set(prop, fn);
|
|
2239
3085
|
}
|
|
2240
3086
|
return fn;
|
|
@@ -2248,6 +3094,113 @@ function frameElementOpen(id) {
|
|
|
2248
3094
|
return `<${FRAME_TAG} ${FRAME_ID_ATTR}="${escaped}" style="display:contents">`;
|
|
2249
3095
|
}
|
|
2250
3096
|
const FRAME_ELEMENT_CLOSE = `</${FRAME_TAG}>`;
|
|
3097
|
+
function armDocumentLiveHoles(ctx) {
|
|
3098
|
+
if (!ctx || ctx.liveHoles !== undefined) return;
|
|
3099
|
+
const live = ctx.live;
|
|
3100
|
+
if (live && live.holes !== undefined) {
|
|
3101
|
+
ctx.liveHoles = live.holes;
|
|
3102
|
+
if (live.holes) {
|
|
3103
|
+
ctx.commit = live.commit;
|
|
3104
|
+
ctx.commitEpoch = live.commitEpoch;
|
|
3105
|
+
}
|
|
3106
|
+
return;
|
|
3107
|
+
}
|
|
3108
|
+
if (!live || !ctx.async || ctx.noHydrate || !ctx.serialize || typeof ReadableStream !== "function") {
|
|
3109
|
+
ctx.liveHoles = null;
|
|
3110
|
+
if (live) live.holes = null;
|
|
3111
|
+
return;
|
|
3112
|
+
}
|
|
3113
|
+
const bindings = new Map();
|
|
3114
|
+
let epoch = 0;
|
|
3115
|
+
let sweepScheduled = false;
|
|
3116
|
+
let closed = false;
|
|
3117
|
+
const sweep = () => {
|
|
3118
|
+
epoch++;
|
|
3119
|
+
for (const b of [...bindings.values()]) {
|
|
3120
|
+
try {
|
|
3121
|
+
b.sweep();
|
|
3122
|
+
} catch (_) {
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
3125
|
+
};
|
|
3126
|
+
const scheduleSweep = () => {
|
|
3127
|
+
if (closed || sweepScheduled || !bindings.size) return;
|
|
3128
|
+
sweepScheduled = true;
|
|
3129
|
+
queueMicrotask(() => {
|
|
3130
|
+
sweepScheduled = false;
|
|
3131
|
+
if (!closed) sweep();
|
|
3132
|
+
});
|
|
3133
|
+
};
|
|
3134
|
+
let channel;
|
|
3135
|
+
ctx.serialize("sc:live", new ReadableStream({
|
|
3136
|
+
start(c) {
|
|
3137
|
+
channel = c;
|
|
3138
|
+
}
|
|
3139
|
+
}));
|
|
3140
|
+
const push = op => {
|
|
3141
|
+
if (!closed) channel.enqueue(op);
|
|
3142
|
+
};
|
|
3143
|
+
ctx.liveHoles = live.holes = createLiveHoles({
|
|
3144
|
+
openBinding(key, b) {
|
|
3145
|
+
bindings.set(key, b);
|
|
3146
|
+
},
|
|
3147
|
+
closeBinding(key) {
|
|
3148
|
+
bindings.delete(key);
|
|
3149
|
+
},
|
|
3150
|
+
hole(key, html) {
|
|
3151
|
+
push({
|
|
3152
|
+
type: "hole",
|
|
3153
|
+
key,
|
|
3154
|
+
html
|
|
3155
|
+
});
|
|
3156
|
+
},
|
|
3157
|
+
attr(key, attrs, removed) {
|
|
3158
|
+
const op = {
|
|
3159
|
+
type: "attr",
|
|
3160
|
+
key,
|
|
3161
|
+
attrs
|
|
3162
|
+
};
|
|
3163
|
+
if (removed && removed.length) op.removed = removed;
|
|
3164
|
+
push(op);
|
|
3165
|
+
},
|
|
3166
|
+
error(key, error) {
|
|
3167
|
+
push({
|
|
3168
|
+
type: "error",
|
|
3169
|
+
key,
|
|
3170
|
+
error
|
|
3171
|
+
});
|
|
3172
|
+
},
|
|
3173
|
+
commit: scheduleSweep,
|
|
3174
|
+
get epoch() {
|
|
3175
|
+
return epoch;
|
|
3176
|
+
}
|
|
3177
|
+
}, true);
|
|
3178
|
+
ctx.commit = live.commit = scheduleSweep;
|
|
3179
|
+
ctx.commitEpoch = live.commitEpoch = () => epoch;
|
|
3180
|
+
live.args = {
|
|
3181
|
+
openBinding(key, b) {
|
|
3182
|
+
bindings.set(key, b);
|
|
3183
|
+
},
|
|
3184
|
+
closeBinding(key) {
|
|
3185
|
+
bindings.delete(key);
|
|
3186
|
+
},
|
|
3187
|
+
slot(fid, occurrence, args) {
|
|
3188
|
+
push({
|
|
3189
|
+
type: "slot",
|
|
3190
|
+
fid,
|
|
3191
|
+
key: occurrence,
|
|
3192
|
+
args
|
|
3193
|
+
});
|
|
3194
|
+
},
|
|
3195
|
+
commit: scheduleSweep
|
|
3196
|
+
};
|
|
3197
|
+
live.end = () => {
|
|
3198
|
+
if (closed) return;
|
|
3199
|
+
if (bindings.size) sweep();
|
|
3200
|
+
closed = true;
|
|
3201
|
+
channel.close();
|
|
3202
|
+
};
|
|
3203
|
+
}
|
|
2251
3204
|
function frameTransformDirectResult(value, {
|
|
2252
3205
|
id,
|
|
2253
3206
|
args
|
|
@@ -2258,6 +3211,7 @@ function frameTransformDirectResult(value, {
|
|
|
2258
3211
|
t: frameElementOpen(id)
|
|
2259
3212
|
},
|
|
2260
3213
|
serverOwned(() => {
|
|
3214
|
+
armDocumentLiveHoles(solidJs.sharedConfig.context);
|
|
2261
3215
|
const slotProps = createDocumentSlotProps(props, id);
|
|
2262
3216
|
return serverComponentScope(() => component(slotProps));
|
|
2263
3217
|
}), {
|
|
@@ -2294,6 +3248,76 @@ function isServerContent(value) {
|
|
|
2294
3248
|
}
|
|
2295
3249
|
return false;
|
|
2296
3250
|
}
|
|
3251
|
+
function unwrapThunks(value) {
|
|
3252
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
3253
|
+
return value;
|
|
3254
|
+
}
|
|
3255
|
+
function contentArgError(key, occurrence) {
|
|
3256
|
+
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.");
|
|
3257
|
+
}
|
|
3258
|
+
function retryArgUntilSettled(evaluate, blocked, key, occurrence, onSettle) {
|
|
3259
|
+
const owner = solidJs.getOwner();
|
|
3260
|
+
return new Promise((resolve, reject) => {
|
|
3261
|
+
const retry = () => {
|
|
3262
|
+
try {
|
|
3263
|
+
const value = owner ? solidJs.runWithOwner(owner, evaluate) : evaluate();
|
|
3264
|
+
if (isServerContent(value)) {
|
|
3265
|
+
reject(contentArgError(key, occurrence));
|
|
3266
|
+
return;
|
|
3267
|
+
}
|
|
3268
|
+
if (onSettle) onSettle(value);
|
|
3269
|
+
resolve(value);
|
|
3270
|
+
} catch (err) {
|
|
3271
|
+
const next = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
|
|
3272
|
+
if (next) next.then(retry, retry);else reject(err);
|
|
3273
|
+
}
|
|
3274
|
+
};
|
|
3275
|
+
blocked.then(retry, retry);
|
|
3276
|
+
});
|
|
3277
|
+
}
|
|
3278
|
+
function openArgBinding(sink, ledgerKey, occurrence, key, evaluate, state, emit) {
|
|
3279
|
+
const owner = solidJs.getOwner();
|
|
3280
|
+
sink.openBinding(ledgerKey, {
|
|
3281
|
+
sweep() {
|
|
3282
|
+
if (!state.settled) return;
|
|
3283
|
+
let value;
|
|
3284
|
+
const stampBefore = scopeStamp();
|
|
3285
|
+
try {
|
|
3286
|
+
value = owner ? solidJs.runWithOwner(owner, evaluate) : evaluate();
|
|
3287
|
+
} catch (err) {
|
|
3288
|
+
const blocked = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
|
|
3289
|
+
if (!blocked) {
|
|
3290
|
+
sink.closeBinding(ledgerKey);
|
|
3291
|
+
emit(Promise.reject(err instanceof Error ? err : new Error(String(err))));
|
|
3292
|
+
return;
|
|
3293
|
+
}
|
|
3294
|
+
if (scopeStamp() !== stampBefore) {
|
|
3295
|
+
sink.closeBinding(ledgerKey);
|
|
3296
|
+
return;
|
|
3297
|
+
}
|
|
3298
|
+
state.settled = false;
|
|
3299
|
+
emit(retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
3300
|
+
state.settled = true;
|
|
3301
|
+
state.last = v;
|
|
3302
|
+
sink.commit();
|
|
3303
|
+
}));
|
|
3304
|
+
return;
|
|
3305
|
+
}
|
|
3306
|
+
if (scopeStamp() !== stampBefore) {
|
|
3307
|
+
sink.closeBinding(ledgerKey);
|
|
3308
|
+
return;
|
|
3309
|
+
}
|
|
3310
|
+
if (value === state.last) return;
|
|
3311
|
+
state.last = value;
|
|
3312
|
+
if (isServerContent(value)) {
|
|
3313
|
+
sink.closeBinding(ledgerKey);
|
|
3314
|
+
emit(Promise.reject(contentArgError(key, occurrence)));
|
|
3315
|
+
return;
|
|
3316
|
+
}
|
|
3317
|
+
emit(value);
|
|
3318
|
+
}
|
|
3319
|
+
});
|
|
3320
|
+
}
|
|
2297
3321
|
function createSlotProps(sink, frame) {
|
|
2298
3322
|
const counts = Object.create(null);
|
|
2299
3323
|
const getters = new Map();
|
|
@@ -2310,9 +3334,21 @@ function createSlotProps(sink, frame) {
|
|
|
2310
3334
|
if (callArgs.length === 0 || callArgs[0] === undefined) {
|
|
2311
3335
|
return slotRange(prop);
|
|
2312
3336
|
}
|
|
3337
|
+
const live = solidJs.sharedConfig.context && solidJs.sharedConfig.context.liveHoles;
|
|
3338
|
+
if (live) {
|
|
3339
|
+
if (live.sweeping) {
|
|
3340
|
+
live.gateHit = true;
|
|
3341
|
+
return {
|
|
3342
|
+
t: "",
|
|
3343
|
+
$slot: true
|
|
3344
|
+
};
|
|
3345
|
+
}
|
|
3346
|
+
live.recordStamp++;
|
|
3347
|
+
}
|
|
2313
3348
|
const raw = callArgs[0];
|
|
2314
3349
|
const occurrence = occurrenceId(prop, raw, counts);
|
|
2315
3350
|
const args = {};
|
|
3351
|
+
const opened = [];
|
|
2316
3352
|
for (const key of Object.keys(raw)) {
|
|
2317
3353
|
if (key === "$key") continue;
|
|
2318
3354
|
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
@@ -2323,12 +3359,47 @@ function createSlotProps(sink, frame) {
|
|
|
2323
3359
|
return origRegister.call(ctx, fragKey, fragOptions);
|
|
2324
3360
|
};
|
|
2325
3361
|
try {
|
|
2326
|
-
|
|
2327
|
-
|
|
3362
|
+
const desc = Object.getOwnPropertyDescriptor(raw, key);
|
|
3363
|
+
let evaluate = null;
|
|
3364
|
+
let value;
|
|
3365
|
+
let state = null;
|
|
3366
|
+
const stampBefore = scopeStamp();
|
|
3367
|
+
try {
|
|
3368
|
+
if (desc.get) {
|
|
3369
|
+
const get = desc.get;
|
|
3370
|
+
evaluate = () => unwrapThunks(get.call(raw));
|
|
3371
|
+
value = evaluate();
|
|
3372
|
+
} else {
|
|
3373
|
+
value = desc.value;
|
|
3374
|
+
if (typeof value === "function") {
|
|
3375
|
+
const fn = value;
|
|
3376
|
+
evaluate = () => unwrapThunks(fn);
|
|
3377
|
+
value = evaluate();
|
|
3378
|
+
}
|
|
3379
|
+
}
|
|
3380
|
+
} catch (err) {
|
|
3381
|
+
const blocked = solidJs.ssrHandleError && solidJs.ssrHandleError(err);
|
|
3382
|
+
if (!blocked) throw err;
|
|
3383
|
+
state = {
|
|
3384
|
+
settled: false,
|
|
3385
|
+
last: undefined
|
|
3386
|
+
};
|
|
3387
|
+
const pendingState = state;
|
|
3388
|
+
value = retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
3389
|
+
pendingState.settled = true;
|
|
3390
|
+
pendingState.last = v;
|
|
3391
|
+
sink.commit();
|
|
3392
|
+
});
|
|
3393
|
+
}
|
|
3394
|
+
const mintedEval = scopeStamp() !== stampBefore;
|
|
2328
3395
|
const t = typeof value;
|
|
2329
3396
|
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
2330
3397
|
args[key] = value;
|
|
2331
|
-
|
|
3398
|
+
if (evaluate) state = {
|
|
3399
|
+
settled: true,
|
|
3400
|
+
last: value
|
|
3401
|
+
};
|
|
3402
|
+
} else if (!isContainerTraced(value) && isServerContent(value)) {
|
|
2332
3403
|
const resolved = ctx.resolve(value);
|
|
2333
3404
|
if (resolved.h.length) {
|
|
2334
3405
|
throw new Error("Async server content in a slot arg needs a boundary (arg '" + key + "' of " + occurrence + "). Wrap the async read in a <Suspense>, or move it above the slot.");
|
|
@@ -2339,30 +3410,72 @@ function createSlotProps(sink, frame) {
|
|
|
2339
3410
|
};
|
|
2340
3411
|
} else {
|
|
2341
3412
|
const ref = `arg:${occurrence}:${key}`;
|
|
2342
|
-
ctx.serialize(ref, value);
|
|
3413
|
+
ctx.serialize(ref, envelopeContainerTraces(value));
|
|
2343
3414
|
args[key] = {
|
|
2344
3415
|
$ref: ref
|
|
2345
3416
|
};
|
|
3417
|
+
if (evaluate && !state) state = {
|
|
3418
|
+
settled: true,
|
|
3419
|
+
last: value
|
|
3420
|
+
};
|
|
2346
3421
|
}
|
|
3422
|
+
if (evaluate && state && !mintedEval) opened.push({
|
|
3423
|
+
key,
|
|
3424
|
+
evaluate,
|
|
3425
|
+
state
|
|
3426
|
+
});
|
|
2347
3427
|
} finally {
|
|
2348
3428
|
ctx.registerFragment = origRegister;
|
|
2349
3429
|
}
|
|
2350
3430
|
}
|
|
2351
|
-
sink.slot(occurrence,
|
|
3431
|
+
sink.slot(occurrence, {
|
|
3432
|
+
...args
|
|
3433
|
+
});
|
|
3434
|
+
const ctx = solidJs.sharedConfig.context;
|
|
3435
|
+
for (const b of opened) {
|
|
3436
|
+
const key = b.key;
|
|
3437
|
+
const ledgerKey = `${occurrence}:${key}`;
|
|
3438
|
+
openArgBinding(sink, ledgerKey, occurrence, key, b.evaluate, b.state, value => {
|
|
3439
|
+
const t = typeof value;
|
|
3440
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
3441
|
+
args[key] = value;
|
|
3442
|
+
} else {
|
|
3443
|
+
const ref = `arg:${occurrence}:${key}@${sink.nextArgRef(ledgerKey)}`;
|
|
3444
|
+
sink.mintRef(ref);
|
|
3445
|
+
ctx.serialize(ref, envelopeContainerTraces(value));
|
|
3446
|
+
args[key] = {
|
|
3447
|
+
$ref: ref
|
|
3448
|
+
};
|
|
3449
|
+
}
|
|
3450
|
+
sink.slot(occurrence, {
|
|
3451
|
+
...args
|
|
3452
|
+
});
|
|
3453
|
+
});
|
|
3454
|
+
}
|
|
2352
3455
|
return slotRange(occurrence);
|
|
2353
3456
|
};
|
|
3457
|
+
fn.$lhSkip = true;
|
|
2354
3458
|
getters.set(prop, fn);
|
|
2355
3459
|
}
|
|
2356
3460
|
return fn;
|
|
2357
3461
|
}
|
|
2358
3462
|
});
|
|
2359
3463
|
}
|
|
3464
|
+
function copyInitHeaders(init) {
|
|
3465
|
+
if (!init || !init.getSetCookie) return new Headers(init);
|
|
3466
|
+
const headers = new Headers();
|
|
3467
|
+
init.forEach((value, key) => {
|
|
3468
|
+
if (key !== "set-cookie") headers.append(key, value);
|
|
3469
|
+
});
|
|
3470
|
+
for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
|
|
3471
|
+
return headers;
|
|
3472
|
+
}
|
|
2360
3473
|
function serverComponentResponse(component, options = {}, init = {}) {
|
|
2361
3474
|
const {
|
|
2362
3475
|
id = "",
|
|
2363
3476
|
version = 1
|
|
2364
3477
|
} = options.frame || {};
|
|
2365
|
-
const headers =
|
|
3478
|
+
const headers = copyInitHeaders(init.headers);
|
|
2366
3479
|
headers.set("Content-Type", "application/x-frame-stream");
|
|
2367
3480
|
headers.set(FRAME_STREAM_HEADER, id);
|
|
2368
3481
|
headers.set("X-Content-Raw", "1");
|
|
@@ -2373,16 +3486,27 @@ function serverComponentResponse(component, options = {}, init = {}) {
|
|
|
2373
3486
|
version
|
|
2374
3487
|
}
|
|
2375
3488
|
});
|
|
3489
|
+
let closed = false;
|
|
2376
3490
|
const body = new ReadableStream({
|
|
2377
3491
|
start(controller) {
|
|
2378
3492
|
stream.pipe({
|
|
2379
3493
|
write(chunk) {
|
|
2380
|
-
|
|
3494
|
+
if (closed) return;
|
|
3495
|
+
try {
|
|
3496
|
+
controller.enqueue(createChunk(JSON.stringify(chunk)));
|
|
3497
|
+
} catch (_) {
|
|
3498
|
+
closed = true;
|
|
3499
|
+
}
|
|
2381
3500
|
},
|
|
2382
3501
|
end() {
|
|
3502
|
+
if (closed) return;
|
|
3503
|
+
closed = true;
|
|
2383
3504
|
controller.close();
|
|
2384
3505
|
}
|
|
2385
3506
|
});
|
|
3507
|
+
},
|
|
3508
|
+
cancel() {
|
|
3509
|
+
closed = true;
|
|
2386
3510
|
}
|
|
2387
3511
|
});
|
|
2388
3512
|
return new Response(body, {
|
|
@@ -2461,14 +3585,22 @@ function frameFlightResponse({
|
|
|
2461
3585
|
codec
|
|
2462
3586
|
}, init = {}) {
|
|
2463
3587
|
const frames = primary ? [primary, ...regions] : regions;
|
|
2464
|
-
const headers =
|
|
3588
|
+
const headers = copyInitHeaders(init.headers);
|
|
2465
3589
|
headers.set("Content-Type", "application/x-frame-stream");
|
|
2466
3590
|
headers.set(FRAME_STREAM_HEADER, primary ? primary.id : "");
|
|
2467
3591
|
headers.set("X-Content-Raw", "1");
|
|
2468
3592
|
headers.set(SINGLE_FLIGHT_HEADER, "true");
|
|
3593
|
+
let closed = false;
|
|
2469
3594
|
const body = new ReadableStream({
|
|
2470
3595
|
async start(controller) {
|
|
2471
|
-
const write = chunk =>
|
|
3596
|
+
const write = chunk => {
|
|
3597
|
+
if (closed) return;
|
|
3598
|
+
try {
|
|
3599
|
+
controller.enqueue(createChunk(JSON.stringify(chunk)));
|
|
3600
|
+
} catch (_) {
|
|
3601
|
+
closed = true;
|
|
3602
|
+
}
|
|
3603
|
+
};
|
|
2472
3604
|
try {
|
|
2473
3605
|
for (const {
|
|
2474
3606
|
id,
|
|
@@ -2495,10 +3627,19 @@ function frameFlightResponse({
|
|
|
2495
3627
|
});
|
|
2496
3628
|
}
|
|
2497
3629
|
}
|
|
2498
|
-
|
|
3630
|
+
if (!closed) {
|
|
3631
|
+
closed = true;
|
|
3632
|
+
controller.close();
|
|
3633
|
+
}
|
|
2499
3634
|
} catch (err) {
|
|
2500
|
-
|
|
3635
|
+
if (!closed) {
|
|
3636
|
+
closed = true;
|
|
3637
|
+
controller.error(err);
|
|
3638
|
+
}
|
|
2501
3639
|
}
|
|
3640
|
+
},
|
|
3641
|
+
cancel() {
|
|
3642
|
+
closed = true;
|
|
2502
3643
|
}
|
|
2503
3644
|
});
|
|
2504
3645
|
return new Response(body, {
|
|
@@ -2507,9 +3648,15 @@ function frameFlightResponse({
|
|
|
2507
3648
|
});
|
|
2508
3649
|
}
|
|
2509
3650
|
|
|
3651
|
+
setContainerTraceResolver(solidJs.getProjectionTrace);
|
|
3652
|
+
function asyncArg(value) {
|
|
3653
|
+
return value;
|
|
3654
|
+
}
|
|
3655
|
+
|
|
2510
3656
|
exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
|
|
2511
3657
|
exports.SERVER_COMPONENT_BOOTSTRAP = SERVER_COMPONENT_BOOTSTRAP;
|
|
2512
3658
|
exports.ServerComponentPlugin = ServerComponentPlugin;
|
|
3659
|
+
exports.asyncArg = asyncArg;
|
|
2513
3660
|
exports.createFrameSink = createFrameSink;
|
|
2514
3661
|
exports.frameTransformDirectResult = frameTransformDirectResult;
|
|
2515
3662
|
exports.frameTransformFlightResult = frameTransformFlightResult;
|