@solidjs/web 2.0.0-beta.31 → 2.0.0-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -6
- package/dist/dev.cjs +234 -45
- package/dist/dev.js +221 -42
- package/dist/server.cjs +456 -123
- package/dist/server.js +445 -120
- package/dist/web.cjs +234 -45
- package/dist/web.js +221 -42
- package/frames/dist/client.cjs +217 -112
- package/frames/dist/client.dev.cjs +217 -112
- package/frames/dist/client.dev.js +218 -113
- package/frames/dist/client.js +218 -113
- package/frames/dist/server.cjs +488 -177
- package/frames/dist/server.js +489 -179
- package/package.json +55 -4
- package/serialization/dist/serialization.cjs +8 -0
- package/serialization/dist/serialization.js +1 -0
- package/serialization/types/index.d.ts +173 -6
- package/serialization/types-cjs/index.d.cts +173 -6
- package/server-functions/dist/client.cjs +46 -9
- package/server-functions/dist/client.js +47 -11
- package/server-functions/dist/rich-args.cjs +11 -0
- package/server-functions/dist/rich-args.js +9 -0
- package/server-functions/dist/server.cjs +275 -126
- package/server-functions/dist/server.dev.cjs +1053 -0
- package/server-functions/dist/server.dev.js +1021 -0
- package/server-functions/dist/server.js +273 -127
- package/server-functions/package.json +10 -0
- package/server-functions/rich-args/package.json +20 -0
- package/storage/types/index.d.ts +1 -1
- package/storage/types-cjs/index.d.cts +1 -1
- package/types/client.d.ts +127 -6
- package/types/core.d.ts +3 -1
- package/types/frames/client.d.ts +15 -1
- package/types/frames/frame-client.d.ts +37 -7
- package/types/frames/frame-sink.d.ts +26 -3
- package/types/frames/frame-transport.d.ts +39 -7
- package/types/frames/serializer.d.ts +173 -6
- package/types/frames/server.d.ts +22 -0
- package/types/index.d.ts +2 -3
- package/types/response.d.ts +45 -0
- package/types/serializer.d.ts +173 -6
- package/types/server-functions/client.d.ts +1 -0
- package/types/server-functions/rich-args.d.ts +10 -0
- package/types/server-functions/server.d.ts +98 -0
- package/types/server-functions/shared.d.ts +22 -0
- package/types/server-mock.d.ts +171 -59
- package/types/server.d.ts +188 -36
- package/types-cjs/client.d.cts +127 -6
- package/types-cjs/core.d.cts +3 -1
- package/types-cjs/frames/client.d.cts +15 -1
- package/types-cjs/frames/frame-client.d.cts +37 -7
- package/types-cjs/frames/frame-sink.d.cts +26 -3
- package/types-cjs/frames/frame-transport.d.cts +39 -7
- package/types-cjs/frames/serializer.d.cts +173 -6
- package/types-cjs/frames/server.d.cts +22 -0
- package/types-cjs/index.d.cts +2 -3
- package/types-cjs/response.d.cts +45 -0
- package/types-cjs/serializer.d.cts +173 -6
- package/types-cjs/server-functions/client.d.cts +1 -0
- package/types-cjs/server-functions/rich-args.d.cts +10 -0
- package/types-cjs/server-functions/server.d.cts +98 -0
- package/types-cjs/server-functions/shared.d.cts +22 -0
- package/types-cjs/server-mock.d.cts +171 -59
- package/types-cjs/server.d.cts +188 -36
package/frames/dist/server.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, NoHydration, runInServerComponentScope, Hydration } from 'solid-js';
|
|
1
|
+
import { createMemo, runWithOwner, createOwner, sharedConfig, createRoot, ssrHandleError, getOwner, NoHydration, runInServerComponentScope, Hydration } from 'solid-js';
|
|
2
2
|
import { toCrossJSONStream, Feature, Serializer, getCrossReferenceHeader, createPlugin } from 'seroval';
|
|
3
3
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
4
4
|
|
|
5
5
|
const runWithHydrationScope = (id, fn) => runWithOwner(createOwner({
|
|
6
6
|
id
|
|
7
7
|
}), fn);
|
|
8
|
+
const ssrAsyncValue = value => createMemo(() => value, {
|
|
9
|
+
serialize: false
|
|
10
|
+
});
|
|
8
11
|
|
|
9
12
|
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
10
13
|
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
|
|
@@ -135,6 +138,143 @@ function createJSONSerializer({
|
|
|
135
138
|
};
|
|
136
139
|
}
|
|
137
140
|
|
|
141
|
+
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
142
|
+
function isResponseEnvelope(value) {
|
|
143
|
+
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
144
|
+
}
|
|
145
|
+
const REVALIDATE_HEADER = "X-Revalidate";
|
|
146
|
+
|
|
147
|
+
function frameAddress(id, args) {
|
|
148
|
+
return args && args.length ? id + ":" + hashArguments(args) : id;
|
|
149
|
+
}
|
|
150
|
+
function hashArguments(args) {
|
|
151
|
+
let hash = 0;
|
|
152
|
+
const text = stableString(args);
|
|
153
|
+
for (let i = 0; i < text.length; i++) {
|
|
154
|
+
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
155
|
+
hash |= 0;
|
|
156
|
+
}
|
|
157
|
+
return (hash >>> 0).toString(36);
|
|
158
|
+
}
|
|
159
|
+
function stableString(value, seen) {
|
|
160
|
+
if (value === null || typeof value !== "object") {
|
|
161
|
+
return typeof value === "bigint" ? value + "n" : String(value);
|
|
162
|
+
}
|
|
163
|
+
if (value instanceof Date) return "Date:" + value.getTime();
|
|
164
|
+
seen || (seen = new Set());
|
|
165
|
+
if (seen.has(value)) return "~";
|
|
166
|
+
seen.add(value);
|
|
167
|
+
if (value instanceof Map) {
|
|
168
|
+
const entries = [];
|
|
169
|
+
for (const [k, v] of value) {
|
|
170
|
+
entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
|
|
171
|
+
}
|
|
172
|
+
return "Map{" + entries.sort().join(",") + "}";
|
|
173
|
+
}
|
|
174
|
+
if (value instanceof Set) {
|
|
175
|
+
const members = [];
|
|
176
|
+
for (const v of value) members.push(stableString(v, seen));
|
|
177
|
+
return "Set{" + members.sort().join(",") + "}";
|
|
178
|
+
}
|
|
179
|
+
if (Array.isArray(value)) {
|
|
180
|
+
let out = "[";
|
|
181
|
+
for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
|
|
182
|
+
return out + "]";
|
|
183
|
+
}
|
|
184
|
+
const keys = Object.keys(value).sort();
|
|
185
|
+
let out = "{";
|
|
186
|
+
for (let i = 0; i < keys.length; i++) {
|
|
187
|
+
out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
|
|
188
|
+
}
|
|
189
|
+
return out + "}";
|
|
190
|
+
}
|
|
191
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
192
|
+
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
193
|
+
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
194
|
+
function createChunk(data) {
|
|
195
|
+
const encoder = new TextEncoder();
|
|
196
|
+
const encodeData = encoder.encode(data);
|
|
197
|
+
const bytes = encodeData.length;
|
|
198
|
+
const chunk = new Uint8Array(12 + bytes);
|
|
199
|
+
chunk.set(encoder.encode(`;0x${bytes.toString(16).padStart(8, "0")};`));
|
|
200
|
+
chunk.set(encodeData, 12);
|
|
201
|
+
return chunk;
|
|
202
|
+
}
|
|
203
|
+
class ChunkReader {
|
|
204
|
+
constructor(stream) {
|
|
205
|
+
this.reader = stream.getReader();
|
|
206
|
+
this.buffer = new Uint8Array(0);
|
|
207
|
+
this.done = false;
|
|
208
|
+
}
|
|
209
|
+
async readChunk() {
|
|
210
|
+
const chunk = await this.reader.read();
|
|
211
|
+
if (!chunk.done) {
|
|
212
|
+
const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
|
|
213
|
+
newBuffer.set(this.buffer);
|
|
214
|
+
newBuffer.set(chunk.value, this.buffer.length);
|
|
215
|
+
this.buffer = newBuffer;
|
|
216
|
+
} else {
|
|
217
|
+
this.done = true;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async next() {
|
|
221
|
+
while (this.buffer.length < 12) {
|
|
222
|
+
if (this.done) {
|
|
223
|
+
if (this.buffer.length === 0) return {
|
|
224
|
+
done: true,
|
|
225
|
+
value: undefined
|
|
226
|
+
};
|
|
227
|
+
throw new Error("Malformed server function stream.");
|
|
228
|
+
}
|
|
229
|
+
await this.readChunk();
|
|
230
|
+
}
|
|
231
|
+
const decoder = new TextDecoder();
|
|
232
|
+
const bytes = Number.parseInt(decoder.decode(this.buffer.subarray(1, 11)), 16);
|
|
233
|
+
if (Number.isNaN(bytes)) {
|
|
234
|
+
throw new Error("Malformed server function stream.");
|
|
235
|
+
}
|
|
236
|
+
while (bytes > this.buffer.length - 12) {
|
|
237
|
+
if (this.done) {
|
|
238
|
+
throw new Error("Malformed server function stream.");
|
|
239
|
+
}
|
|
240
|
+
await this.readChunk();
|
|
241
|
+
}
|
|
242
|
+
const partial = decoder.decode(this.buffer.subarray(12, 12 + bytes));
|
|
243
|
+
this.buffer = this.buffer.subarray(12 + bytes);
|
|
244
|
+
return {
|
|
245
|
+
done: false,
|
|
246
|
+
value: partial
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
async drain(interpret) {
|
|
250
|
+
while (true) {
|
|
251
|
+
const result = await this.next();
|
|
252
|
+
if (result.done) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
interpret(result.value);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function serializeStream(value, codecOptions) {
|
|
260
|
+
return new ReadableStream({
|
|
261
|
+
start(controller) {
|
|
262
|
+
serializeJSON(value, {
|
|
263
|
+
...codecOptions,
|
|
264
|
+
onParse(node) {
|
|
265
|
+
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
266
|
+
},
|
|
267
|
+
onDone() {
|
|
268
|
+
controller.close();
|
|
269
|
+
},
|
|
270
|
+
onError(error) {
|
|
271
|
+
controller.error(error);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
138
278
|
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
139
279
|
const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
|
|
140
280
|
const RESOURCE_LINK_RELS = new Set(["preload", "modulepreload", "prefetch", "preconnect", "dns-prefetch", "stylesheet"]);
|
|
@@ -375,7 +515,8 @@ function createHeadRegistry() {
|
|
|
375
515
|
resources: new Set(),
|
|
376
516
|
eagerHtml: "",
|
|
377
517
|
flushed: null,
|
|
378
|
-
shellFlushed: false
|
|
518
|
+
shellFlushed: false,
|
|
519
|
+
parkedResources: []
|
|
379
520
|
};
|
|
380
521
|
}
|
|
381
522
|
function registerHeadTags(registry, context, tracking, emitResource, nonce, tags) {
|
|
@@ -389,6 +530,7 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
389
530
|
return;
|
|
390
531
|
}
|
|
391
532
|
if (!Array.isArray(tags)) tags = [tags];
|
|
533
|
+
const probe = sharedConfig.context && sharedConfig.context._loadingPhase;
|
|
392
534
|
let replaceable = null;
|
|
393
535
|
for (let i = 0; i < tags.length; i++) {
|
|
394
536
|
const desc = tags[i];
|
|
@@ -397,6 +539,16 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
397
539
|
continue;
|
|
398
540
|
}
|
|
399
541
|
const cls = classifyHeadTag(desc);
|
|
542
|
+
if (probe && !cls.resource) {
|
|
543
|
+
try {
|
|
544
|
+
evalHeadProps(desc.props || {}, cls.rel !== undefined ? {
|
|
545
|
+
rel: cls.rel
|
|
546
|
+
} : undefined);
|
|
547
|
+
evalHeadValue(desc.key);
|
|
548
|
+
} catch (err) {
|
|
549
|
+
if (ssrHandleError(err)) throw err;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
400
552
|
if (cls.resource) {
|
|
401
553
|
emitHeadResource(registry, context, tracking, emitResource, nonce, desc, cls.rel);
|
|
402
554
|
} else {
|
|
@@ -413,6 +565,52 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
413
565
|
tags: replaceable
|
|
414
566
|
});
|
|
415
567
|
}
|
|
568
|
+
function headShellReady(registry, block) {
|
|
569
|
+
let ready = true;
|
|
570
|
+
const pends = err => {
|
|
571
|
+
const source = ssrHandleError(err, true);
|
|
572
|
+
if (!source) return false;
|
|
573
|
+
block(source);
|
|
574
|
+
ready = false;
|
|
575
|
+
return true;
|
|
576
|
+
};
|
|
577
|
+
const parked = registry.parkedResources;
|
|
578
|
+
for (let i = parked.length - 1; i >= 0; i--) {
|
|
579
|
+
const {
|
|
580
|
+
desc,
|
|
581
|
+
rel,
|
|
582
|
+
emit
|
|
583
|
+
} = parked[i];
|
|
584
|
+
try {
|
|
585
|
+
evalHeadProps(desc.props || {}, rel !== undefined ? {
|
|
586
|
+
rel
|
|
587
|
+
} : undefined);
|
|
588
|
+
} catch (err) {
|
|
589
|
+
if (pends(err)) continue;
|
|
590
|
+
console.warn(`useHead: error evaluating resource tag props`, err);
|
|
591
|
+
parked.splice(i, 1);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
parked.splice(i, 1);
|
|
595
|
+
emit();
|
|
596
|
+
}
|
|
597
|
+
for (let i = 0; i < registry.pending.length; i++) {
|
|
598
|
+
const reg = registry.pending[i];
|
|
599
|
+
if (reg.boundary !== "" || reg.list) continue;
|
|
600
|
+
for (let j = 0; j < reg.tags.length; j++) {
|
|
601
|
+
const desc = reg.tags[j];
|
|
602
|
+
try {
|
|
603
|
+
evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
|
|
604
|
+
rel: desc.rel
|
|
605
|
+
} : undefined);
|
|
606
|
+
evalHeadValue(desc.key);
|
|
607
|
+
} catch (err) {
|
|
608
|
+
pends(err);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return ready;
|
|
613
|
+
}
|
|
416
614
|
function emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel) {
|
|
417
615
|
let props;
|
|
418
616
|
try {
|
|
@@ -420,6 +618,16 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
|
|
|
420
618
|
rel
|
|
421
619
|
} : undefined);
|
|
422
620
|
} catch (err) {
|
|
621
|
+
const loadingPhase = sharedConfig.context && sharedConfig.context._loadingPhase;
|
|
622
|
+
if (loadingPhase && ssrHandleError(err)) throw err;
|
|
623
|
+
if (!loadingPhase && !context._currentBoundaryId && !registry.shellFlushed && typeof context.block === "function" && ssrHandleError(err, true)) {
|
|
624
|
+
registry.parkedResources.push({
|
|
625
|
+
desc,
|
|
626
|
+
rel,
|
|
627
|
+
emit: () => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
|
|
628
|
+
});
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
423
631
|
console.warn(`useHead: error evaluating resource tag props`, err);
|
|
424
632
|
return;
|
|
425
633
|
}
|
|
@@ -762,7 +970,7 @@ function renderToStream(code, options = {}) {
|
|
|
762
970
|
}
|
|
763
971
|
},
|
|
764
972
|
shell(shellHtml, meta) {
|
|
765
|
-
buffer.write(assembleDocument(shellHtml, meta.
|
|
973
|
+
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
766
974
|
},
|
|
767
975
|
...options.sink
|
|
768
976
|
};
|
|
@@ -842,7 +1050,6 @@ function renderToStream(code, options = {}) {
|
|
|
842
1050
|
};
|
|
843
1051
|
sharedConfig.context = context = {
|
|
844
1052
|
async: true,
|
|
845
|
-
assets: [],
|
|
846
1053
|
nonce,
|
|
847
1054
|
registerHeadTags(tags) {
|
|
848
1055
|
registerHeadTags(headRegistry, context, tracking,
|
|
@@ -1044,7 +1251,7 @@ function renderToStream(code, options = {}) {
|
|
|
1044
1251
|
if (shellCompleted) return;
|
|
1045
1252
|
sharedConfig.context = context;
|
|
1046
1253
|
if (!resolveRootHoles()) return;
|
|
1047
|
-
|
|
1254
|
+
if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
|
|
1048
1255
|
headStyles = new Set();
|
|
1049
1256
|
for (const url of tracking.emittedAssets) {
|
|
1050
1257
|
if (isCssUrl(url)) headStyles.add(url);
|
|
@@ -1052,7 +1259,6 @@ function renderToStream(code, options = {}) {
|
|
|
1052
1259
|
serializeRootAssets();
|
|
1053
1260
|
const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
|
|
1054
1261
|
sink.shell(html, {
|
|
1055
|
-
assets: assetsHtml,
|
|
1056
1262
|
preloads: tracking.emittedAssets,
|
|
1057
1263
|
inlineStyles: tracking.inlineStyles,
|
|
1058
1264
|
tasks,
|
|
@@ -1142,27 +1348,30 @@ function renderToStream(code, options = {}) {
|
|
|
1142
1348
|
return p;
|
|
1143
1349
|
};
|
|
1144
1350
|
return {
|
|
1145
|
-
then(
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1351
|
+
then(onFulfilled, onRejected) {
|
|
1352
|
+
const p = new Promise(resolve => {
|
|
1353
|
+
function complete() {
|
|
1354
|
+
dispose();
|
|
1355
|
+
resolve(tmp);
|
|
1356
|
+
}
|
|
1357
|
+
if (onCompleteAll) {
|
|
1358
|
+
let ogComplete = onCompleteAll;
|
|
1359
|
+
onCompleteAll = options => {
|
|
1360
|
+
ogComplete(options);
|
|
1361
|
+
complete();
|
|
1362
|
+
};
|
|
1363
|
+
} else onCompleteAll = complete;
|
|
1364
|
+
function flush() {
|
|
1365
|
+
allSettled(blockingPromises).then(() => {
|
|
1366
|
+
scheduleFlush(() => {
|
|
1367
|
+
if (!resolveRootHoles() || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
|
|
1368
|
+
queue(flushEnd);
|
|
1369
|
+
});
|
|
1162
1370
|
});
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1371
|
+
}
|
|
1372
|
+
flush();
|
|
1373
|
+
});
|
|
1374
|
+
return p.then(onFulfilled, onRejected);
|
|
1166
1375
|
},
|
|
1167
1376
|
pipe(w) {
|
|
1168
1377
|
claimConsumer("pipe");
|
|
@@ -1447,17 +1656,11 @@ function allSettled(promises) {
|
|
|
1447
1656
|
return;
|
|
1448
1657
|
});
|
|
1449
1658
|
}
|
|
1450
|
-
function
|
|
1451
|
-
if (!assets || !assets.length) return "";
|
|
1452
|
-
let out = "";
|
|
1453
|
-
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
1454
|
-
return out;
|
|
1455
|
-
}
|
|
1456
|
-
function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1659
|
+
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1457
1660
|
const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
|
|
1458
1661
|
const headTagsHtml = headTags ? headTags.html : "";
|
|
1459
1662
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
1460
|
-
if (!onHead && !
|
|
1663
|
+
if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
1461
1664
|
if (!scriptTag) return html;
|
|
1462
1665
|
const xs = html.indexOf("<!--xs-->");
|
|
1463
1666
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -1472,13 +1675,13 @@ function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts
|
|
|
1472
1675
|
const headIdx = html.indexOf("</head>");
|
|
1473
1676
|
if (headIdx === -1) {
|
|
1474
1677
|
if (onHead) {
|
|
1475
|
-
onHead(headPrelude + headTagsHtml +
|
|
1678
|
+
onHead(headPrelude + headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
1476
1679
|
}
|
|
1477
1680
|
if (!scriptTag) return html;
|
|
1478
1681
|
const xs = html.indexOf("<!--xs-->");
|
|
1479
1682
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
1480
1683
|
}
|
|
1481
|
-
const head = headTagsHtml +
|
|
1684
|
+
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
1482
1685
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
1483
1686
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
1484
1687
|
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
@@ -1660,142 +1863,7 @@ function resolveSSRSync(node) {
|
|
|
1660
1863
|
if (!res.h.length) return res.t[0];
|
|
1661
1864
|
throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
|
|
1662
1865
|
}
|
|
1663
|
-
|
|
1664
|
-
function frameAddress(id, args) {
|
|
1665
|
-
return args && args.length ? id + ":" + hashArguments(args) : id;
|
|
1666
|
-
}
|
|
1667
|
-
function hashArguments(args) {
|
|
1668
|
-
let hash = 0;
|
|
1669
|
-
const text = stableString(args);
|
|
1670
|
-
for (let i = 0; i < text.length; i++) {
|
|
1671
|
-
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
1672
|
-
hash |= 0;
|
|
1673
|
-
}
|
|
1674
|
-
return (hash >>> 0).toString(36);
|
|
1675
|
-
}
|
|
1676
|
-
function stableString(value, seen) {
|
|
1677
|
-
if (value === null || typeof value !== "object") {
|
|
1678
|
-
return typeof value === "bigint" ? value + "n" : String(value);
|
|
1679
|
-
}
|
|
1680
|
-
if (value instanceof Date) return "Date:" + value.getTime();
|
|
1681
|
-
seen || (seen = new Set());
|
|
1682
|
-
if (seen.has(value)) return "~";
|
|
1683
|
-
seen.add(value);
|
|
1684
|
-
if (value instanceof Map) {
|
|
1685
|
-
const entries = [];
|
|
1686
|
-
for (const [k, v] of value) {
|
|
1687
|
-
entries.push(stableString(k, seen) + "=>" + stableString(v, seen));
|
|
1688
|
-
}
|
|
1689
|
-
return "Map{" + entries.sort().join(",") + "}";
|
|
1690
|
-
}
|
|
1691
|
-
if (value instanceof Set) {
|
|
1692
|
-
const members = [];
|
|
1693
|
-
for (const v of value) members.push(stableString(v, seen));
|
|
1694
|
-
return "Set{" + members.sort().join(",") + "}";
|
|
1695
|
-
}
|
|
1696
|
-
if (Array.isArray(value)) {
|
|
1697
|
-
let out = "[";
|
|
1698
|
-
for (let i = 0; i < value.length; i++) out += (i ? "," : "") + stableString(value[i], seen);
|
|
1699
|
-
return out + "]";
|
|
1700
|
-
}
|
|
1701
|
-
const keys = Object.keys(value).sort();
|
|
1702
|
-
let out = "{";
|
|
1703
|
-
for (let i = 0; i < keys.length; i++) {
|
|
1704
|
-
out += (i ? "," : "") + keys[i] + ":" + stableString(value[keys[i]], seen);
|
|
1705
|
-
}
|
|
1706
|
-
return out + "}";
|
|
1707
|
-
}
|
|
1708
|
-
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
1709
|
-
function createChunk(data) {
|
|
1710
|
-
const encodeData = new TextEncoder().encode(data);
|
|
1711
|
-
const bytes = encodeData.length;
|
|
1712
|
-
const baseHex = bytes.toString(16);
|
|
1713
|
-
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex;
|
|
1714
|
-
const head = new TextEncoder().encode(`;0x${totalHex};`);
|
|
1715
|
-
const chunk = new Uint8Array(12 + bytes);
|
|
1716
|
-
chunk.set(head);
|
|
1717
|
-
chunk.set(encodeData, 12);
|
|
1718
|
-
return chunk;
|
|
1719
|
-
}
|
|
1720
|
-
class ChunkReader {
|
|
1721
|
-
constructor(stream) {
|
|
1722
|
-
this.reader = stream.getReader();
|
|
1723
|
-
this.buffer = new Uint8Array(0);
|
|
1724
|
-
this.done = false;
|
|
1725
|
-
}
|
|
1726
|
-
async readChunk() {
|
|
1727
|
-
const chunk = await this.reader.read();
|
|
1728
|
-
if (!chunk.done) {
|
|
1729
|
-
const newBuffer = new Uint8Array(this.buffer.length + chunk.value.length);
|
|
1730
|
-
newBuffer.set(this.buffer);
|
|
1731
|
-
newBuffer.set(chunk.value, this.buffer.length);
|
|
1732
|
-
this.buffer = newBuffer;
|
|
1733
|
-
} else {
|
|
1734
|
-
this.done = true;
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
async next() {
|
|
1738
|
-
while (this.buffer.length < 12) {
|
|
1739
|
-
if (this.done) {
|
|
1740
|
-
if (this.buffer.length === 0) return {
|
|
1741
|
-
done: true,
|
|
1742
|
-
value: undefined
|
|
1743
|
-
};
|
|
1744
|
-
throw new Error("Malformed server function stream.");
|
|
1745
|
-
}
|
|
1746
|
-
await this.readChunk();
|
|
1747
|
-
}
|
|
1748
|
-
const head = new TextDecoder().decode(this.buffer.subarray(1, 11));
|
|
1749
|
-
const bytes = Number.parseInt(head, 16);
|
|
1750
|
-
if (Number.isNaN(bytes)) {
|
|
1751
|
-
throw new Error("Malformed server function stream.");
|
|
1752
|
-
}
|
|
1753
|
-
while (bytes > this.buffer.length - 12) {
|
|
1754
|
-
if (this.done) {
|
|
1755
|
-
throw new Error("Malformed server function stream.");
|
|
1756
|
-
}
|
|
1757
|
-
await this.readChunk();
|
|
1758
|
-
}
|
|
1759
|
-
const partial = new TextDecoder().decode(this.buffer.subarray(12, 12 + bytes));
|
|
1760
|
-
this.buffer = this.buffer.subarray(12 + bytes);
|
|
1761
|
-
return {
|
|
1762
|
-
done: false,
|
|
1763
|
-
value: partial
|
|
1764
|
-
};
|
|
1765
|
-
}
|
|
1766
|
-
async drain(interpret) {
|
|
1767
|
-
while (true) {
|
|
1768
|
-
const result = await this.next();
|
|
1769
|
-
if (result.done) {
|
|
1770
|
-
break;
|
|
1771
|
-
}
|
|
1772
|
-
interpret(result.value);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
function serializeStream(value, codecOptions) {
|
|
1777
|
-
return new ReadableStream({
|
|
1778
|
-
start(controller) {
|
|
1779
|
-
serializeJSON(value, {
|
|
1780
|
-
...codecOptions,
|
|
1781
|
-
onParse(node) {
|
|
1782
|
-
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
1783
|
-
},
|
|
1784
|
-
onDone() {
|
|
1785
|
-
controller.close();
|
|
1786
|
-
},
|
|
1787
|
-
onError(error) {
|
|
1788
|
-
controller.error(error);
|
|
1789
|
-
}
|
|
1790
|
-
});
|
|
1791
|
-
}
|
|
1792
|
-
});
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
1796
|
-
function isResponseEnvelope(value) {
|
|
1797
|
-
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1798
|
-
}
|
|
1866
|
+
/*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
1799
1867
|
|
|
1800
1868
|
const INVOCATIONS = new WeakMap();
|
|
1801
1869
|
function getEventServerFunctionInvocation(event) {
|
|
@@ -1879,6 +1947,29 @@ function createFrameSink(emit, frame) {
|
|
|
1879
1947
|
version
|
|
1880
1948
|
} = frame;
|
|
1881
1949
|
const styledKeys = new Set();
|
|
1950
|
+
const bindings = new Map();
|
|
1951
|
+
const sweepMinted = new Set();
|
|
1952
|
+
const argRefVersions = new Map();
|
|
1953
|
+
let sweepScheduled = false;
|
|
1954
|
+
let closed = false;
|
|
1955
|
+
let epoch = 0;
|
|
1956
|
+
const sweep = () => {
|
|
1957
|
+
epoch++;
|
|
1958
|
+
for (const b of [...bindings.values()]) {
|
|
1959
|
+
try {
|
|
1960
|
+
b.sweep();
|
|
1961
|
+
} catch (_) {
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
const scheduleSweep = () => {
|
|
1966
|
+
if (closed || sweepScheduled || !bindings.size) return;
|
|
1967
|
+
sweepScheduled = true;
|
|
1968
|
+
queueMicrotask(() => {
|
|
1969
|
+
sweepScheduled = false;
|
|
1970
|
+
if (!closed) sweep();
|
|
1971
|
+
});
|
|
1972
|
+
};
|
|
1882
1973
|
const regionKeys = new Map();
|
|
1883
1974
|
const frameOf = key => regionKeys.get(key) || id;
|
|
1884
1975
|
return {
|
|
@@ -1920,6 +2011,7 @@ function createFrameSink(emit, frame) {
|
|
|
1920
2011
|
version,
|
|
1921
2012
|
payload: record
|
|
1922
2013
|
});
|
|
2014
|
+
scheduleSweep();
|
|
1923
2015
|
} else {
|
|
1924
2016
|
emit({
|
|
1925
2017
|
type: "data",
|
|
@@ -1929,6 +2021,7 @@ function createFrameSink(emit, frame) {
|
|
|
1929
2021
|
node: record.node,
|
|
1930
2022
|
initial: record.initial
|
|
1931
2023
|
});
|
|
2024
|
+
if (!sweepMinted.has(record.key)) scheduleSweep();
|
|
1932
2025
|
}
|
|
1933
2026
|
},
|
|
1934
2027
|
fragment(key, value, meta = {}) {
|
|
@@ -1965,6 +2058,7 @@ function createFrameSink(emit, frame) {
|
|
|
1965
2058
|
key,
|
|
1966
2059
|
html: value
|
|
1967
2060
|
});
|
|
2061
|
+
scheduleSweep();
|
|
1968
2062
|
if (meta.error) {
|
|
1969
2063
|
emit({
|
|
1970
2064
|
type: "error",
|
|
@@ -2019,6 +2113,8 @@ function createFrameSink(emit, frame) {
|
|
|
2019
2113
|
});
|
|
2020
2114
|
},
|
|
2021
2115
|
end() {
|
|
2116
|
+
if (bindings.size) sweep();
|
|
2117
|
+
closed = true;
|
|
2022
2118
|
emit({
|
|
2023
2119
|
type: "complete",
|
|
2024
2120
|
id,
|
|
@@ -2050,6 +2146,24 @@ function createFrameSink(emit, frame) {
|
|
|
2050
2146
|
version,
|
|
2051
2147
|
html
|
|
2052
2148
|
});
|
|
2149
|
+
},
|
|
2150
|
+
openBinding(key, b) {
|
|
2151
|
+
bindings.set(key, b);
|
|
2152
|
+
},
|
|
2153
|
+
closeBinding(key) {
|
|
2154
|
+
bindings.delete(key);
|
|
2155
|
+
},
|
|
2156
|
+
mintRef(ref) {
|
|
2157
|
+
sweepMinted.add(ref);
|
|
2158
|
+
},
|
|
2159
|
+
nextArgRef(ledgerKey) {
|
|
2160
|
+
const n = (argRefVersions.get(ledgerKey) || 0) + 1;
|
|
2161
|
+
argRefVersions.set(ledgerKey, n);
|
|
2162
|
+
return n;
|
|
2163
|
+
},
|
|
2164
|
+
commit: scheduleSweep,
|
|
2165
|
+
get epoch() {
|
|
2166
|
+
return epoch;
|
|
2053
2167
|
}
|
|
2054
2168
|
};
|
|
2055
2169
|
}
|
|
@@ -2059,7 +2173,14 @@ function renderToFrameStream(code, options = {}) {
|
|
|
2059
2173
|
function renderServerComponent(component, options = {}) {
|
|
2060
2174
|
return frameStream((sink, frame) => {
|
|
2061
2175
|
const props = createSlotProps(sink, frame);
|
|
2062
|
-
return () =>
|
|
2176
|
+
return () => {
|
|
2177
|
+
const ctx = sharedConfig.context;
|
|
2178
|
+
if (ctx) {
|
|
2179
|
+
ctx.commit = sink.commit;
|
|
2180
|
+
ctx.commitEpoch = () => sink.epoch;
|
|
2181
|
+
}
|
|
2182
|
+
return serverComponentScope(() => component(props));
|
|
2183
|
+
};
|
|
2063
2184
|
}, options);
|
|
2064
2185
|
}
|
|
2065
2186
|
function frameStream(makeCode, options) {
|
|
@@ -2136,6 +2257,35 @@ function occurrenceId(prop, raw, counts) {
|
|
|
2136
2257
|
counts[prop] = n + 1;
|
|
2137
2258
|
return `${prop}#${n}`;
|
|
2138
2259
|
}
|
|
2260
|
+
function isAsyncValue(v) {
|
|
2261
|
+
return !!v && typeof v === "object" && (typeof v.then === "function" || typeof v[Symbol.asyncIterator] === "function");
|
|
2262
|
+
}
|
|
2263
|
+
function tapFirstYield(iterable) {
|
|
2264
|
+
const iter = iterable[Symbol.asyncIterator]();
|
|
2265
|
+
const firstStep = Promise.resolve(iter.next());
|
|
2266
|
+
return {
|
|
2267
|
+
first: firstStep.then(r => r.done ? undefined : r.value),
|
|
2268
|
+
rest: {
|
|
2269
|
+
[Symbol.asyncIterator]() {
|
|
2270
|
+
let replayed = false;
|
|
2271
|
+
return {
|
|
2272
|
+
next: () => {
|
|
2273
|
+
if (!replayed) {
|
|
2274
|
+
replayed = true;
|
|
2275
|
+
return firstStep;
|
|
2276
|
+
}
|
|
2277
|
+
return iter.next();
|
|
2278
|
+
},
|
|
2279
|
+
return: v => iter.return ? iter.return(v) : Promise.resolve({
|
|
2280
|
+
done: true,
|
|
2281
|
+
value: v
|
|
2282
|
+
}),
|
|
2283
|
+
throw: e => iter.throw ? iter.throw(e) : Promise.reject(e)
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2139
2289
|
function createDocumentSlotProps(clientProps, frameId) {
|
|
2140
2290
|
const counts = Object.create(null);
|
|
2141
2291
|
const getters = new Map();
|
|
@@ -2205,6 +2355,22 @@ function createDocumentSlotProps(clientProps, frameId) {
|
|
|
2205
2355
|
t: FRAME_ELEMENT_CLOSE
|
|
2206
2356
|
}];
|
|
2207
2357
|
};
|
|
2358
|
+
} else if (ssrAsyncValue && isAsyncValue(value)) {
|
|
2359
|
+
let readable = value;
|
|
2360
|
+
if (typeof value.then !== "function") {
|
|
2361
|
+
const {
|
|
2362
|
+
first,
|
|
2363
|
+
rest
|
|
2364
|
+
} = tapFirstYield(value);
|
|
2365
|
+
readable = first;
|
|
2366
|
+
vals[key] = rest;
|
|
2367
|
+
}
|
|
2368
|
+
const read = ssrAsyncValue(readable);
|
|
2369
|
+
Object.defineProperty(resolved, key, {
|
|
2370
|
+
get: read,
|
|
2371
|
+
enumerable: true,
|
|
2372
|
+
configurable: true
|
|
2373
|
+
});
|
|
2208
2374
|
} else {
|
|
2209
2375
|
resolved[key] = value;
|
|
2210
2376
|
}
|
|
@@ -2292,6 +2458,88 @@ function isServerContent(value) {
|
|
|
2292
2458
|
}
|
|
2293
2459
|
return false;
|
|
2294
2460
|
}
|
|
2461
|
+
function unwrapThunks(value) {
|
|
2462
|
+
for (let d = 0; typeof value === "function" && d < 16; d++) value = value();
|
|
2463
|
+
return value;
|
|
2464
|
+
}
|
|
2465
|
+
function contentArgError(key, occurrence) {
|
|
2466
|
+
return new Error("Async slot arg resolved to JSX (arg '" + key + "' of " + occurrence + "). Async args must resolve to serializable values; render async content through a boundary instead.");
|
|
2467
|
+
}
|
|
2468
|
+
function retryArgUntilSettled(evaluate, blocked, key, occurrence, onSettle) {
|
|
2469
|
+
const owner = getOwner();
|
|
2470
|
+
return new Promise((resolve, reject) => {
|
|
2471
|
+
const retry = () => {
|
|
2472
|
+
try {
|
|
2473
|
+
const value = owner ? runWithOwner(owner, evaluate) : evaluate();
|
|
2474
|
+
if (isServerContent(value)) {
|
|
2475
|
+
reject(contentArgError(key, occurrence));
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
if (onSettle) onSettle(value);
|
|
2479
|
+
resolve(value);
|
|
2480
|
+
} catch (err) {
|
|
2481
|
+
const next = ssrHandleError && ssrHandleError(err);
|
|
2482
|
+
if (next) next.then(retry, retry);else reject(err);
|
|
2483
|
+
}
|
|
2484
|
+
};
|
|
2485
|
+
blocked.then(retry, retry);
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
function openArgBinding(sink, ctx, occurrence, key, evaluate, args, state) {
|
|
2489
|
+
const owner = getOwner();
|
|
2490
|
+
const ledgerKey = `${occurrence}:${key}`;
|
|
2491
|
+
const reEmit = value => {
|
|
2492
|
+
const ref = `arg:${occurrence}:${key}@${sink.nextArgRef(ledgerKey)}`;
|
|
2493
|
+
sink.mintRef(ref);
|
|
2494
|
+
ctx.serialize(ref, value);
|
|
2495
|
+
args[key] = {
|
|
2496
|
+
$ref: ref
|
|
2497
|
+
};
|
|
2498
|
+
sink.slot(occurrence, {
|
|
2499
|
+
...args
|
|
2500
|
+
});
|
|
2501
|
+
};
|
|
2502
|
+
const binding = {
|
|
2503
|
+
sweep() {
|
|
2504
|
+
if (!state.settled) return;
|
|
2505
|
+
let value;
|
|
2506
|
+
try {
|
|
2507
|
+
value = owner ? runWithOwner(owner, evaluate) : evaluate();
|
|
2508
|
+
} catch (err) {
|
|
2509
|
+
const blocked = ssrHandleError && ssrHandleError(err);
|
|
2510
|
+
if (!blocked) {
|
|
2511
|
+
sink.closeBinding(ledgerKey);
|
|
2512
|
+
reEmit(Promise.reject(err instanceof Error ? err : new Error(String(err))));
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
state.settled = false;
|
|
2516
|
+
reEmit(retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
2517
|
+
state.settled = true;
|
|
2518
|
+
state.last = v;
|
|
2519
|
+
sink.commit();
|
|
2520
|
+
}));
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
if (value === state.last) return;
|
|
2524
|
+
state.last = value;
|
|
2525
|
+
if (isServerContent(value)) {
|
|
2526
|
+
sink.closeBinding(ledgerKey);
|
|
2527
|
+
reEmit(Promise.reject(contentArgError(key, occurrence)));
|
|
2528
|
+
return;
|
|
2529
|
+
}
|
|
2530
|
+
const t = typeof value;
|
|
2531
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
2532
|
+
args[key] = value;
|
|
2533
|
+
sink.slot(occurrence, {
|
|
2534
|
+
...args
|
|
2535
|
+
});
|
|
2536
|
+
} else {
|
|
2537
|
+
reEmit(value);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
};
|
|
2541
|
+
sink.openBinding(ledgerKey, binding);
|
|
2542
|
+
}
|
|
2295
2543
|
function createSlotProps(sink, frame) {
|
|
2296
2544
|
const counts = Object.create(null);
|
|
2297
2545
|
const getters = new Map();
|
|
@@ -2311,6 +2559,7 @@ function createSlotProps(sink, frame) {
|
|
|
2311
2559
|
const raw = callArgs[0];
|
|
2312
2560
|
const occurrence = occurrenceId(prop, raw, counts);
|
|
2313
2561
|
const args = {};
|
|
2562
|
+
const opened = [];
|
|
2314
2563
|
for (const key of Object.keys(raw)) {
|
|
2315
2564
|
if (key === "$key") continue;
|
|
2316
2565
|
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
@@ -2321,11 +2570,44 @@ function createSlotProps(sink, frame) {
|
|
|
2321
2570
|
return origRegister.call(ctx, fragKey, fragOptions);
|
|
2322
2571
|
};
|
|
2323
2572
|
try {
|
|
2324
|
-
|
|
2325
|
-
|
|
2573
|
+
const desc = Object.getOwnPropertyDescriptor(raw, key);
|
|
2574
|
+
let evaluate = null;
|
|
2575
|
+
let value;
|
|
2576
|
+
let state = null;
|
|
2577
|
+
try {
|
|
2578
|
+
if (desc.get) {
|
|
2579
|
+
const get = desc.get;
|
|
2580
|
+
evaluate = () => unwrapThunks(get.call(raw));
|
|
2581
|
+
value = evaluate();
|
|
2582
|
+
} else {
|
|
2583
|
+
value = desc.value;
|
|
2584
|
+
if (typeof value === "function") {
|
|
2585
|
+
const fn = value;
|
|
2586
|
+
evaluate = () => unwrapThunks(fn);
|
|
2587
|
+
value = evaluate();
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
} catch (err) {
|
|
2591
|
+
const blocked = ssrHandleError && ssrHandleError(err);
|
|
2592
|
+
if (!blocked) throw err;
|
|
2593
|
+
state = {
|
|
2594
|
+
settled: false,
|
|
2595
|
+
last: undefined
|
|
2596
|
+
};
|
|
2597
|
+
const pendingState = state;
|
|
2598
|
+
value = retryArgUntilSettled(evaluate, blocked, key, occurrence, v => {
|
|
2599
|
+
pendingState.settled = true;
|
|
2600
|
+
pendingState.last = v;
|
|
2601
|
+
sink.commit();
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2326
2604
|
const t = typeof value;
|
|
2327
2605
|
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
2328
2606
|
args[key] = value;
|
|
2607
|
+
if (evaluate) state = {
|
|
2608
|
+
settled: true,
|
|
2609
|
+
last: value
|
|
2610
|
+
};
|
|
2329
2611
|
} else if (isServerContent(value)) {
|
|
2330
2612
|
const resolved = ctx.resolve(value);
|
|
2331
2613
|
if (resolved.h.length) {
|
|
@@ -2341,12 +2623,27 @@ function createSlotProps(sink, frame) {
|
|
|
2341
2623
|
args[key] = {
|
|
2342
2624
|
$ref: ref
|
|
2343
2625
|
};
|
|
2626
|
+
if (evaluate && !state) state = {
|
|
2627
|
+
settled: true,
|
|
2628
|
+
last: value
|
|
2629
|
+
};
|
|
2344
2630
|
}
|
|
2631
|
+
if (evaluate && state) opened.push({
|
|
2632
|
+
key,
|
|
2633
|
+
evaluate,
|
|
2634
|
+
state
|
|
2635
|
+
});
|
|
2345
2636
|
} finally {
|
|
2346
2637
|
ctx.registerFragment = origRegister;
|
|
2347
2638
|
}
|
|
2348
2639
|
}
|
|
2349
|
-
sink.slot(occurrence,
|
|
2640
|
+
sink.slot(occurrence, {
|
|
2641
|
+
...args
|
|
2642
|
+
});
|
|
2643
|
+
const ctx = sharedConfig.context;
|
|
2644
|
+
for (const b of opened) {
|
|
2645
|
+
openArgBinding(sink, ctx, occurrence, b.key, b.evaluate, args, b.state);
|
|
2646
|
+
}
|
|
2350
2647
|
return slotRange(occurrence);
|
|
2351
2648
|
};
|
|
2352
2649
|
getters.set(prop, fn);
|
|
@@ -2355,12 +2652,21 @@ function createSlotProps(sink, frame) {
|
|
|
2355
2652
|
}
|
|
2356
2653
|
});
|
|
2357
2654
|
}
|
|
2655
|
+
function copyInitHeaders(init) {
|
|
2656
|
+
if (!init || !init.getSetCookie) return new Headers(init);
|
|
2657
|
+
const headers = new Headers();
|
|
2658
|
+
init.forEach((value, key) => {
|
|
2659
|
+
if (key !== "set-cookie") headers.append(key, value);
|
|
2660
|
+
});
|
|
2661
|
+
for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
|
|
2662
|
+
return headers;
|
|
2663
|
+
}
|
|
2358
2664
|
function serverComponentResponse(component, options = {}, init = {}) {
|
|
2359
2665
|
const {
|
|
2360
2666
|
id = "",
|
|
2361
2667
|
version = 1
|
|
2362
2668
|
} = options.frame || {};
|
|
2363
|
-
const headers =
|
|
2669
|
+
const headers = copyInitHeaders(init.headers);
|
|
2364
2670
|
headers.set("Content-Type", "application/x-frame-stream");
|
|
2365
2671
|
headers.set(FRAME_STREAM_HEADER, id);
|
|
2366
2672
|
headers.set("X-Content-Raw", "1");
|
|
@@ -2459,7 +2765,7 @@ function frameFlightResponse({
|
|
|
2459
2765
|
codec
|
|
2460
2766
|
}, init = {}) {
|
|
2461
2767
|
const frames = primary ? [primary, ...regions] : regions;
|
|
2462
|
-
const headers =
|
|
2768
|
+
const headers = copyInitHeaders(init.headers);
|
|
2463
2769
|
headers.set("Content-Type", "application/x-frame-stream");
|
|
2464
2770
|
headers.set(FRAME_STREAM_HEADER, primary ? primary.id : "");
|
|
2465
2771
|
headers.set("X-Content-Raw", "1");
|
|
@@ -2505,4 +2811,8 @@ function frameFlightResponse({
|
|
|
2505
2811
|
});
|
|
2506
2812
|
}
|
|
2507
2813
|
|
|
2508
|
-
|
|
2814
|
+
function asyncArg(value) {
|
|
2815
|
+
return value;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
export { FRAME_STREAM_HEADER, SERVER_COMPONENT_BOOTSTRAP, ServerComponentPlugin, asyncArg, createFrameSink, frameTransformDirectResult, frameTransformFlightResult, frameTransformResult, isFrameStreamResponse, renderServerComponent, renderToFrameStream, serverComponentResponse };
|