@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/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createRenderEffect, createMemo, sharedConfig, createRoot,
|
|
1
|
+
import { createRenderEffect, createMemo, sharedConfig, createRoot, getOwner, ssrHandleError, runWithOwner, inServerComponentScope, creationStamp, createComponent, omit, getNextChildId, onCleanup, getProjectionTrace } from 'solid-js';
|
|
2
2
|
export { Errored, For, Hydration, Loading, Match, NoHydration, Repeat, Reveal, Show, Switch, createComponent, getOwner, merge as mergeProps, ssrScope as scope, untrack } from 'solid-js';
|
|
3
|
-
import { Serializer, getCrossReferenceHeader
|
|
3
|
+
import { Feature, Serializer, getCrossReferenceHeader } from 'seroval';
|
|
4
4
|
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
5
5
|
|
|
6
6
|
const DOMWithState = {
|
|
@@ -63,15 +63,74 @@ const effect = (fn, effectFn, options) => createRenderEffect(fn, effectFn, optio
|
|
|
63
63
|
} : transparentOptions);
|
|
64
64
|
const memo = fn => createMemo(() => fn(), syncOptions);
|
|
65
65
|
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
66
|
+
const STATE = Symbol.for("dom-expressions.container-trace-state");
|
|
67
|
+
const state = globalThis[STATE] || (globalThis[STATE] = {
|
|
68
|
+
materialized: new WeakMap(),
|
|
69
|
+
materializedValues: new WeakSet()
|
|
70
|
+
});
|
|
71
|
+
function setContainerTraceResolver(fn) {
|
|
72
|
+
state.resolveTrace = fn;
|
|
73
|
+
}
|
|
74
|
+
const TRACE = Symbol.for("dom-expressions.container-trace");
|
|
75
|
+
function materialize(marker) {
|
|
76
|
+
let value = state.materialized.get(marker.$tr);
|
|
77
|
+
if (value === undefined) {
|
|
78
|
+
value = state.materializeTrace(marker);
|
|
79
|
+
state.materialized.set(marker.$tr, value);
|
|
80
|
+
if (value !== null && typeof value === "object") state.materializedValues.add(value);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
function parseTrace(value, ctx) {
|
|
85
|
+
const trace = value[TRACE];
|
|
86
|
+
return {
|
|
87
|
+
a: trace.array ? 1 : 0,
|
|
88
|
+
i: ctx.parse(trace.subscribe())
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const ContainerTracePlugin = {
|
|
92
|
+
tag: "dom-expressions/container-trace",
|
|
93
|
+
test(value) {
|
|
94
|
+
return value != null && typeof value === "object" && TRACE in value;
|
|
95
|
+
},
|
|
96
|
+
parse: {
|
|
97
|
+
sync() {
|
|
98
|
+
throw new Error("A reactive container can only be serialized by a streaming serializer.");
|
|
99
|
+
},
|
|
100
|
+
async async(value, ctx) {
|
|
101
|
+
const trace = value[TRACE];
|
|
102
|
+
return {
|
|
103
|
+
a: trace.array ? 1 : 0,
|
|
104
|
+
i: await ctx.parse(trace.subscribe())
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
stream: parseTrace
|
|
108
|
+
},
|
|
109
|
+
serialize(node, ctx) {
|
|
110
|
+
return "{$tr:" + ctx.serialize(node.i) + ",$ta:" + node.a + "}";
|
|
111
|
+
},
|
|
112
|
+
deserialize(node, ctx) {
|
|
113
|
+
const iterable = ctx.deserialize(node.i);
|
|
114
|
+
const marker = {
|
|
115
|
+
$tr: iterable,
|
|
116
|
+
$ta: node.a
|
|
117
|
+
};
|
|
118
|
+
return state.materializeTrace ? materialize(marker) : marker;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
69
122
|
const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
|
|
70
123
|
CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
|
|
71
|
-
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin
|
|
124
|
+
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin,
|
|
125
|
+
ContainerTracePlugin]);
|
|
72
126
|
function resolveSerializerPlugins(customPlugins) {
|
|
73
127
|
return customPlugins ? [...customPlugins, ...DEFAULT_WEB_PLUGINS] : [...DEFAULT_WEB_PLUGINS];
|
|
74
128
|
}
|
|
129
|
+
Feature.RegExp;
|
|
130
|
+
|
|
131
|
+
const DEFAULT_DISABLED_FEATURES = Feature.AggregateError | Feature.BigIntTypedArray;
|
|
132
|
+
const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
|
|
133
|
+
const HYDRATION_GLOBAL = "_$HY.r";
|
|
75
134
|
function createSerializer(options) {
|
|
76
135
|
return new Serializer({
|
|
77
136
|
...options,
|
|
@@ -98,7 +157,166 @@ function createHydrationSerializer({
|
|
|
98
157
|
function getLocalHeaderScript(id) {
|
|
99
158
|
return getCrossReferenceHeader(id) + ";";
|
|
100
159
|
}
|
|
101
|
-
|
|
160
|
+
|
|
161
|
+
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
162
|
+
// PURE-annotated factory (same convention as solid's MockPromise): the brand
|
|
163
|
+
const ResponseEnvelope = /* @__PURE__ */(() => {
|
|
164
|
+
class ResponseEnvelope {
|
|
165
|
+
constructor(response, value) {
|
|
166
|
+
this.response = response;
|
|
167
|
+
this.value = value;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
171
|
+
return ResponseEnvelope;
|
|
172
|
+
})();
|
|
173
|
+
function isResponseEnvelope(value) {
|
|
174
|
+
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
175
|
+
}
|
|
176
|
+
const HREF = Symbol.for("solid.Href");
|
|
177
|
+
function isHref(value) {
|
|
178
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
179
|
+
}
|
|
180
|
+
const SAFE_ERROR = Symbol.for("solid.SafeError");
|
|
181
|
+
function markSafeError(error) {
|
|
182
|
+
if (error && (typeof error === "object" || typeof error === "function")) {
|
|
183
|
+
Object.defineProperty(error, SAFE_ERROR, {
|
|
184
|
+
value: true,
|
|
185
|
+
enumerable: false,
|
|
186
|
+
configurable: true
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return error;
|
|
190
|
+
}
|
|
191
|
+
function isSafeError(value) {
|
|
192
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[SAFE_ERROR]);
|
|
193
|
+
}
|
|
194
|
+
const REVALIDATE_HEADER = "X-Revalidate";
|
|
195
|
+
function initWithRevalidate(init) {
|
|
196
|
+
const {
|
|
197
|
+
revalidate,
|
|
198
|
+
...responseInit
|
|
199
|
+
} = init;
|
|
200
|
+
let headers;
|
|
201
|
+
if (responseInit.headers && responseInit.headers.getSetCookie) {
|
|
202
|
+
headers = new Headers();
|
|
203
|
+
responseInit.headers.forEach((value, key) => {
|
|
204
|
+
if (key !== "set-cookie") headers.append(key, value);
|
|
205
|
+
});
|
|
206
|
+
for (const cookie of responseInit.headers.getSetCookie()) {
|
|
207
|
+
headers.append("Set-Cookie", cookie);
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
headers = new Headers(responseInit.headers);
|
|
211
|
+
}
|
|
212
|
+
revalidate !== undefined && headers.set(REVALIDATE_HEADER, revalidate.toString());
|
|
213
|
+
return {
|
|
214
|
+
responseInit,
|
|
215
|
+
headers
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function redirect(url, init = 302) {
|
|
219
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
220
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
221
|
+
}
|
|
222
|
+
const {
|
|
223
|
+
responseInit,
|
|
224
|
+
headers
|
|
225
|
+
} = initWithRevalidate(typeof init === "number" ? {
|
|
226
|
+
status: init
|
|
227
|
+
} : init);
|
|
228
|
+
if (responseInit.status === undefined) {
|
|
229
|
+
responseInit.status = 302;
|
|
230
|
+
}
|
|
231
|
+
headers.set("Location", String(url));
|
|
232
|
+
return new Response(null, {
|
|
233
|
+
...responseInit,
|
|
234
|
+
headers
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function reload(init = {}) {
|
|
238
|
+
const {
|
|
239
|
+
responseInit,
|
|
240
|
+
headers
|
|
241
|
+
} = initWithRevalidate(init);
|
|
242
|
+
return new Response(null, {
|
|
243
|
+
...responseInit,
|
|
244
|
+
headers
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function respond(value, init = {}) {
|
|
248
|
+
const {
|
|
249
|
+
responseInit,
|
|
250
|
+
headers
|
|
251
|
+
} = initWithRevalidate(init);
|
|
252
|
+
headers.set("Content-Type", "application/json");
|
|
253
|
+
return new ResponseEnvelope(new Response(JSON.stringify(value), {
|
|
254
|
+
...responseInit,
|
|
255
|
+
headers
|
|
256
|
+
}), value);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const SERVER_FUNCTION_METADATA = Symbol.for("solid.ServerFunctionMetadata");
|
|
260
|
+
function getServerFunctionMetadata(fn) {
|
|
261
|
+
if (typeof fn !== "function") return undefined;
|
|
262
|
+
return fn[SERVER_FUNCTION_METADATA] || undefined;
|
|
263
|
+
}
|
|
264
|
+
function isServerFunction(fn) {
|
|
265
|
+
return typeof fn === "function" && !!fn[SERVER_FUNCTION_METADATA];
|
|
266
|
+
}
|
|
267
|
+
const SERVER_FUNCTION_RPC = Symbol.for("solid.ServerFunctionRPC");
|
|
268
|
+
function getServerFunctionRPC() {
|
|
269
|
+
return globalThis[SERVER_FUNCTION_RPC];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function parseCookieHeader(header) {
|
|
273
|
+
const cookies = {};
|
|
274
|
+
if (!header) return cookies;
|
|
275
|
+
for (const part of header.split(";")) {
|
|
276
|
+
const eq = part.indexOf("=");
|
|
277
|
+
if (eq < 0) continue;
|
|
278
|
+
const name = decodeSafe(part.slice(0, eq).trim());
|
|
279
|
+
let value = part.slice(eq + 1).trim();
|
|
280
|
+
if (value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
281
|
+
value = value.slice(1, -1);
|
|
282
|
+
}
|
|
283
|
+
cookies[name] = decodeSafe(value);
|
|
284
|
+
}
|
|
285
|
+
return cookies;
|
|
286
|
+
}
|
|
287
|
+
function decodeSafe(text) {
|
|
288
|
+
try {
|
|
289
|
+
return decodeURIComponent(text);
|
|
290
|
+
} catch {
|
|
291
|
+
return text;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function serializeCookie(name, value, options = {}) {
|
|
295
|
+
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
296
|
+
cookie += `; Path=${options.path === undefined ? "/" : options.path}`;
|
|
297
|
+
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
298
|
+
if (options.maxAge !== undefined) cookie += `; Max-Age=${Math.trunc(options.maxAge)}`;
|
|
299
|
+
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
300
|
+
if (options.httpOnly) cookie += "; HttpOnly";
|
|
301
|
+
if (options.secure) cookie += "; Secure";
|
|
302
|
+
if (options.sameSite) {
|
|
303
|
+
const sameSite = options.sameSite.toLowerCase();
|
|
304
|
+
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
305
|
+
}
|
|
306
|
+
return cookie;
|
|
307
|
+
}
|
|
308
|
+
const FLASH_COOKIE = "flash";
|
|
309
|
+
const FLASH_MATCHER = new RegExp(`(?:^|;\\s*)${FLASH_COOKIE}=([^;]+)`);
|
|
310
|
+
function hasFlashCookie(cookieHeader) {
|
|
311
|
+
return !!cookieHeader && FLASH_MATCHER.test(cookieHeader);
|
|
312
|
+
}
|
|
313
|
+
function clearFlashCookie() {
|
|
314
|
+
return `${FLASH_COOKIE}=; Max-Age=0; Path=/`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
318
|
+
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
319
|
+
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
102
320
|
|
|
103
321
|
const HEAD_ELIGIBLE_TAGS = new Set(["title", "meta", "link", "style", "script", "base"]);
|
|
104
322
|
const HEAD_ATTR_NAME = /^[a-zA-Z_][a-zA-Z0-9_:.-]*$/;
|
|
@@ -170,7 +388,6 @@ function resolveHead(groups) {
|
|
|
170
388
|
}
|
|
171
389
|
for (const [identity, tags] of byIdentity) {
|
|
172
390
|
if (identity === "title") {
|
|
173
|
-
if (tags.length > 1) console.warn("Multiple <title> tags in one head group; the last one wins.");
|
|
174
391
|
winners.set(identity, {
|
|
175
392
|
seq: group.seq,
|
|
176
393
|
tags: [tags[tags.length - 1]]
|
|
@@ -340,7 +557,8 @@ function createHeadRegistry() {
|
|
|
340
557
|
resources: new Set(),
|
|
341
558
|
eagerHtml: "",
|
|
342
559
|
flushed: null,
|
|
343
|
-
shellFlushed: false
|
|
560
|
+
shellFlushed: false,
|
|
561
|
+
parkedResources: []
|
|
344
562
|
};
|
|
345
563
|
}
|
|
346
564
|
function registerHeadTags(registry, context, tracking, emitResource, nonce, tags) {
|
|
@@ -354,14 +572,24 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
354
572
|
return;
|
|
355
573
|
}
|
|
356
574
|
if (!Array.isArray(tags)) tags = [tags];
|
|
575
|
+
const probe = sharedConfig.context && sharedConfig.context._loadingPhase;
|
|
357
576
|
let replaceable = null;
|
|
358
577
|
for (let i = 0; i < tags.length; i++) {
|
|
359
578
|
const desc = tags[i];
|
|
360
579
|
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
361
|
-
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
362
580
|
continue;
|
|
363
581
|
}
|
|
364
582
|
const cls = classifyHeadTag(desc);
|
|
583
|
+
if (probe && !cls.resource) {
|
|
584
|
+
try {
|
|
585
|
+
evalHeadProps(desc.props || {}, cls.rel !== undefined ? {
|
|
586
|
+
rel: cls.rel
|
|
587
|
+
} : undefined);
|
|
588
|
+
evalHeadValue(desc.key);
|
|
589
|
+
} catch (err) {
|
|
590
|
+
if (ssrHandleError(err)) throw err;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
365
593
|
if (cls.resource) {
|
|
366
594
|
emitHeadResource(registry, context, tracking, emitResource, nonce, desc, cls.rel);
|
|
367
595
|
} else {
|
|
@@ -378,6 +606,51 @@ function registerHeadTags(registry, context, tracking, emitResource, nonce, tags
|
|
|
378
606
|
tags: replaceable
|
|
379
607
|
});
|
|
380
608
|
}
|
|
609
|
+
function headShellReady(registry, block) {
|
|
610
|
+
let ready = true;
|
|
611
|
+
const pends = err => {
|
|
612
|
+
const source = ssrHandleError(err, true);
|
|
613
|
+
if (!source) return false;
|
|
614
|
+
block(source);
|
|
615
|
+
ready = false;
|
|
616
|
+
return true;
|
|
617
|
+
};
|
|
618
|
+
const parked = registry.parkedResources;
|
|
619
|
+
for (let i = parked.length - 1; i >= 0; i--) {
|
|
620
|
+
const {
|
|
621
|
+
desc,
|
|
622
|
+
rel,
|
|
623
|
+
emit
|
|
624
|
+
} = parked[i];
|
|
625
|
+
try {
|
|
626
|
+
evalHeadProps(desc.props || {}, rel !== undefined ? {
|
|
627
|
+
rel
|
|
628
|
+
} : undefined);
|
|
629
|
+
} catch (err) {
|
|
630
|
+
if (pends(err)) continue;
|
|
631
|
+
parked.splice(i, 1);
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
parked.splice(i, 1);
|
|
635
|
+
emit();
|
|
636
|
+
}
|
|
637
|
+
for (let i = 0; i < registry.pending.length; i++) {
|
|
638
|
+
const reg = registry.pending[i];
|
|
639
|
+
if (reg.boundary !== "" || reg.list) continue;
|
|
640
|
+
for (let j = 0; j < reg.tags.length; j++) {
|
|
641
|
+
const desc = reg.tags[j];
|
|
642
|
+
try {
|
|
643
|
+
evalHeadProps(desc.props || {}, desc.rel !== undefined ? {
|
|
644
|
+
rel: desc.rel
|
|
645
|
+
} : undefined);
|
|
646
|
+
evalHeadValue(desc.key);
|
|
647
|
+
} catch (err) {
|
|
648
|
+
pends(err);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return ready;
|
|
653
|
+
}
|
|
381
654
|
function emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel) {
|
|
382
655
|
let props;
|
|
383
656
|
try {
|
|
@@ -385,7 +658,16 @@ function emitHeadResource(registry, context, tracking, emitResource, nonce, desc
|
|
|
385
658
|
rel
|
|
386
659
|
} : undefined);
|
|
387
660
|
} catch (err) {
|
|
388
|
-
|
|
661
|
+
const loadingPhase = sharedConfig.context && sharedConfig.context._loadingPhase;
|
|
662
|
+
if (loadingPhase && ssrHandleError(err)) throw err;
|
|
663
|
+
if (!loadingPhase && !context._currentBoundaryId && !registry.shellFlushed && typeof context.block === "function" && ssrHandleError(err, true)) {
|
|
664
|
+
registry.parkedResources.push({
|
|
665
|
+
desc,
|
|
666
|
+
rel,
|
|
667
|
+
emit: () => emitHeadResource(registry, context, tracking, emitResource, nonce, desc, rel)
|
|
668
|
+
});
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
389
671
|
return;
|
|
390
672
|
}
|
|
391
673
|
const identity = resourceIdentity(desc.tag, props);
|
|
@@ -447,7 +729,6 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
447
729
|
try {
|
|
448
730
|
resolved = reg.list();
|
|
449
731
|
} catch (err) {
|
|
450
|
-
console.warn(`useHead: error evaluating head group membership`, err);
|
|
451
732
|
continue;
|
|
452
733
|
}
|
|
453
734
|
if (!Array.isArray(resolved)) resolved = [resolved];
|
|
@@ -455,7 +736,6 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
455
736
|
for (let j = 0; j < resolved.length; j++) {
|
|
456
737
|
const desc = resolved[j];
|
|
457
738
|
if (!desc || !HEAD_ELIGIBLE_TAGS.has(desc.tag)) {
|
|
458
|
-
console.warn(`useHead: ignoring non-head tag`, desc);
|
|
459
739
|
continue;
|
|
460
740
|
}
|
|
461
741
|
const cls = classifyHeadTag(desc);
|
|
@@ -481,12 +761,10 @@ function commitHeadBoundary(registry, boundary, isPendingFragment) {
|
|
|
481
761
|
} : undefined);
|
|
482
762
|
key = evalHeadValue(desc.key);
|
|
483
763
|
} catch (err) {
|
|
484
|
-
console.warn(`useHead: error evaluating tag props`, err);
|
|
485
764
|
continue;
|
|
486
765
|
}
|
|
487
766
|
const identity = replaceableIdentity(desc.tag, props, key, "u:" + registry.uniq++);
|
|
488
767
|
if ((identity === "base" || identity === "charset") && registry.shellFlushed) {
|
|
489
|
-
console.warn(`useHead: <${desc.tag}> (${identity}) registered after shell flush is ignored`);
|
|
490
768
|
continue;
|
|
491
769
|
}
|
|
492
770
|
tags.push({
|
|
@@ -568,7 +846,6 @@ function flushHeadFragment(registry, boundary) {
|
|
|
568
846
|
for (const name in t.props) {
|
|
569
847
|
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
570
848
|
if (!HEAD_ATTR_NAME.test(name)) {
|
|
571
|
-
console.warn(`useHead: ignoring invalid attribute name "${name}"`);
|
|
572
849
|
continue;
|
|
573
850
|
}
|
|
574
851
|
const v = t.props[name];
|
|
@@ -586,7 +863,6 @@ function renderHeadAttrHtml(props) {
|
|
|
586
863
|
for (const name in props) {
|
|
587
864
|
if (name === "children" || name === "ref" || name.slice(0, 2) === "on") continue;
|
|
588
865
|
if (!HEAD_ATTR_NAME.test(name)) {
|
|
589
|
-
console.warn(`useHead: ignoring invalid attribute name "${name}"`);
|
|
590
866
|
continue;
|
|
591
867
|
}
|
|
592
868
|
const v = props[name];
|
|
@@ -619,7 +895,6 @@ function renderHeadTagMarkup(tag, props, identity, nonce) {
|
|
|
619
895
|
function useHead(tags) {
|
|
620
896
|
const ctx = sharedConfig.context;
|
|
621
897
|
if (!ctx || !ctx.registerHeadTags) {
|
|
622
|
-
console.warn("useHead() called outside of a server render; registration ignored.");
|
|
623
898
|
return;
|
|
624
899
|
}
|
|
625
900
|
ctx.registerHeadTags(tags);
|
|
@@ -651,7 +926,6 @@ function renderToString(code, options = {}) {
|
|
|
651
926
|
const tracking = createAssetTracking();
|
|
652
927
|
const headRegistry = createHeadRegistry();
|
|
653
928
|
sharedConfig.context = {
|
|
654
|
-
assets: [],
|
|
655
929
|
nonce,
|
|
656
930
|
escape: escape,
|
|
657
931
|
resolve: resolveSSRNode,
|
|
@@ -693,9 +967,8 @@ function renderToString(code, options = {}) {
|
|
|
693
967
|
serializeFragmentAssets("", tracking.boundaryModules, sharedConfig.context);
|
|
694
968
|
sharedConfig.context.noHydrate = true;
|
|
695
969
|
serializer.close();
|
|
696
|
-
const assetsHtml = resolveAssetsHtml(sharedConfig.context.assets);
|
|
697
970
|
const head = renderShellHead(headRegistry, nonce, null);
|
|
698
|
-
return assembleDocument(html,
|
|
971
|
+
return assembleDocument(html, tracking.emittedAssets, tracking.inlineStyles, scripts.length ? scripts : "", nonce, head, onHead);
|
|
699
972
|
}
|
|
700
973
|
function renderToStream(code, options = {}) {
|
|
701
974
|
let {
|
|
@@ -725,6 +998,12 @@ function renderToStream(code, options = {}) {
|
|
|
725
998
|
d();
|
|
726
999
|
}
|
|
727
1000
|
};
|
|
1001
|
+
const failRender = err => {
|
|
1002
|
+
try {
|
|
1003
|
+
options.onError ? options.onError(err) : console.error(err);
|
|
1004
|
+
} catch (_) {}
|
|
1005
|
+
abandon();
|
|
1006
|
+
};
|
|
728
1007
|
const guardSink = w => ({
|
|
729
1008
|
write(payload) {
|
|
730
1009
|
if (dead) return;
|
|
@@ -806,7 +1085,7 @@ function renderToStream(code, options = {}) {
|
|
|
806
1085
|
}
|
|
807
1086
|
},
|
|
808
1087
|
shell(shellHtml, meta) {
|
|
809
|
-
buffer.write(assembleDocument(shellHtml, meta.
|
|
1088
|
+
buffer.write(assembleDocument(shellHtml, meta.preloads, meta.inlineStyles, meta.tasks.length ? meta.tasks : "", nonce, meta.head, onHead));
|
|
810
1089
|
},
|
|
811
1090
|
...options.sink
|
|
812
1091
|
};
|
|
@@ -823,10 +1102,18 @@ function renderToStream(code, options = {}) {
|
|
|
823
1102
|
rootAssetsSerialized = true;
|
|
824
1103
|
serializeFragmentAssets("", tracking.boundaryModules, context);
|
|
825
1104
|
};
|
|
1105
|
+
let holds = 0;
|
|
826
1106
|
const flushEnd = () => {
|
|
827
|
-
if (!registry.size) {
|
|
1107
|
+
if (!registry.size && !holds) {
|
|
828
1108
|
serializeRootAssets();
|
|
829
|
-
queue(() => queue(() =>
|
|
1109
|
+
queue(() => queue(() => {
|
|
1110
|
+
if (context.live.end) {
|
|
1111
|
+
const end = context.live.end;
|
|
1112
|
+
context.live.end = null;
|
|
1113
|
+
end();
|
|
1114
|
+
}
|
|
1115
|
+
serializer.flush();
|
|
1116
|
+
}));
|
|
830
1117
|
}
|
|
831
1118
|
};
|
|
832
1119
|
const registry = new Map();
|
|
@@ -886,8 +1173,8 @@ function renderToStream(code, options = {}) {
|
|
|
886
1173
|
};
|
|
887
1174
|
sharedConfig.context = context = {
|
|
888
1175
|
async: true,
|
|
889
|
-
assets: [],
|
|
890
1176
|
nonce,
|
|
1177
|
+
live: {},
|
|
891
1178
|
registerHeadTags(tags) {
|
|
892
1179
|
registerHeadTags(headRegistry, context, tracking,
|
|
893
1180
|
(markup, gateEntry) => {
|
|
@@ -924,6 +1211,16 @@ function renderToStream(code, options = {}) {
|
|
|
924
1211
|
block(p) {
|
|
925
1212
|
if (!firstFlushed) blockingPromises.add(p);
|
|
926
1213
|
},
|
|
1214
|
+
hold() {
|
|
1215
|
+
holds++;
|
|
1216
|
+
let released = false;
|
|
1217
|
+
return () => {
|
|
1218
|
+
if (released) return;
|
|
1219
|
+
released = true;
|
|
1220
|
+
holds--;
|
|
1221
|
+
if (!holds) queue(flushEnd);
|
|
1222
|
+
};
|
|
1223
|
+
},
|
|
927
1224
|
replace(id, payloadFn) {
|
|
928
1225
|
if (firstFlushed) return;
|
|
929
1226
|
const placeholder = `<!--!$${id}-->`;
|
|
@@ -1032,6 +1329,7 @@ function renderToStream(code, options = {}) {
|
|
|
1032
1329
|
}
|
|
1033
1330
|
};
|
|
1034
1331
|
applyAssetTracking(context, tracking, manifest, noScripts);
|
|
1332
|
+
context.failRender = failRender;
|
|
1035
1333
|
registerEntryAssets(manifest);
|
|
1036
1334
|
let html = createRoot(d => {
|
|
1037
1335
|
dispose = d;
|
|
@@ -1088,7 +1386,7 @@ function renderToStream(code, options = {}) {
|
|
|
1088
1386
|
if (shellCompleted) return;
|
|
1089
1387
|
sharedConfig.context = context;
|
|
1090
1388
|
if (!resolveRootHoles()) return;
|
|
1091
|
-
|
|
1389
|
+
if (!headShellReady(headRegistry, p => blockingPromises.add(p))) return;
|
|
1092
1390
|
headStyles = new Set();
|
|
1093
1391
|
for (const url of tracking.emittedAssets) {
|
|
1094
1392
|
if (isCssUrl(url)) headStyles.add(url);
|
|
@@ -1096,7 +1394,6 @@ function renderToStream(code, options = {}) {
|
|
|
1096
1394
|
serializeRootAssets();
|
|
1097
1395
|
const head = renderShellHead(headRegistry, nonce, k => registry.has(k));
|
|
1098
1396
|
sink.shell(html, {
|
|
1099
|
-
assets: assetsHtml,
|
|
1100
1397
|
preloads: tracking.emittedAssets,
|
|
1101
1398
|
inlineStyles: tracking.inlineStyles,
|
|
1102
1399
|
tasks,
|
|
@@ -1145,7 +1442,12 @@ function renderToStream(code, options = {}) {
|
|
|
1145
1442
|
allSettled(blockingPromises).then(() => {
|
|
1146
1443
|
scheduleFlush(() => {
|
|
1147
1444
|
if (dead) return resolve();
|
|
1148
|
-
|
|
1445
|
+
try {
|
|
1446
|
+
doShell();
|
|
1447
|
+
} catch (err) {
|
|
1448
|
+
failRender(err);
|
|
1449
|
+
return resolve();
|
|
1450
|
+
}
|
|
1149
1451
|
if (!shellCompleted) return flush();
|
|
1150
1452
|
const encoder = new TextEncoder();
|
|
1151
1453
|
const writer = w.getWriter();
|
|
@@ -1186,27 +1488,35 @@ function renderToStream(code, options = {}) {
|
|
|
1186
1488
|
return p;
|
|
1187
1489
|
};
|
|
1188
1490
|
return {
|
|
1189
|
-
then(
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1491
|
+
then(onFulfilled, onRejected) {
|
|
1492
|
+
const p = new Promise(resolve => {
|
|
1493
|
+
function complete() {
|
|
1494
|
+
dispose();
|
|
1495
|
+
resolve(tmp);
|
|
1496
|
+
}
|
|
1497
|
+
if (onCompleteAll) {
|
|
1498
|
+
let ogComplete = onCompleteAll;
|
|
1499
|
+
onCompleteAll = options => {
|
|
1500
|
+
ogComplete(options);
|
|
1501
|
+
complete();
|
|
1502
|
+
};
|
|
1503
|
+
} else onCompleteAll = complete;
|
|
1504
|
+
function flush() {
|
|
1505
|
+
allSettled(blockingPromises).then(() => {
|
|
1506
|
+
scheduleFlush(() => {
|
|
1507
|
+
try {
|
|
1508
|
+
if (!resolveRootHoles() || !headShellReady(headRegistry, p => blockingPromises.add(p))) return flush();
|
|
1509
|
+
} catch (err) {
|
|
1510
|
+
failRender(err);
|
|
1511
|
+
return resolve(tmp);
|
|
1512
|
+
}
|
|
1513
|
+
queue(flushEnd);
|
|
1514
|
+
});
|
|
1206
1515
|
});
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1516
|
+
}
|
|
1517
|
+
flush();
|
|
1518
|
+
});
|
|
1519
|
+
return p.then(onFulfilled, onRejected);
|
|
1210
1520
|
},
|
|
1211
1521
|
pipe(w) {
|
|
1212
1522
|
claimConsumer("pipe");
|
|
@@ -1214,7 +1524,15 @@ function renderToStream(code, options = {}) {
|
|
|
1214
1524
|
allSettled(blockingPromises).then(() => {
|
|
1215
1525
|
scheduleFlush(() => {
|
|
1216
1526
|
if (dead) return;
|
|
1217
|
-
|
|
1527
|
+
try {
|
|
1528
|
+
doShell();
|
|
1529
|
+
} catch (err) {
|
|
1530
|
+
failRender(err);
|
|
1531
|
+
try {
|
|
1532
|
+
w.end();
|
|
1533
|
+
} catch (_) {}
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1218
1536
|
if (!shellCompleted) return flush();
|
|
1219
1537
|
buffer = writable = guardSink(w);
|
|
1220
1538
|
buffer.write(tmp);
|
|
@@ -1259,9 +1577,27 @@ function ssrGroup(fn, n) {
|
|
|
1259
1577
|
function buildAsyncWrap(err, node) {
|
|
1260
1578
|
const p = ssrHandleError(err);
|
|
1261
1579
|
if (!p) return null;
|
|
1580
|
+
if (node.$rw) return {
|
|
1581
|
+
fn: node,
|
|
1582
|
+
p
|
|
1583
|
+
};
|
|
1262
1584
|
const owner = getOwner();
|
|
1585
|
+
const live = sharedConfig.context && sharedConfig.context.liveHoles;
|
|
1586
|
+
const suppress = node.$lhSuppress || live && (live.suppressed || live.sweeping);
|
|
1587
|
+
if (!owner) {
|
|
1588
|
+
if (suppress) node.$lhSuppress = true;
|
|
1589
|
+
return {
|
|
1590
|
+
fn: node,
|
|
1591
|
+
p
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
const fn = () => runWithOwner(owner, node);
|
|
1595
|
+
fn.$rw = true;
|
|
1596
|
+
if (suppress) fn.$lhSuppress = true;
|
|
1597
|
+
if (node.$lhSkip) fn.$lhSkip = true;
|
|
1598
|
+
if (node.$lhBinding) fn.$lhBinding = node.$lhBinding;
|
|
1263
1599
|
return {
|
|
1264
|
-
fn
|
|
1600
|
+
fn,
|
|
1265
1601
|
p
|
|
1266
1602
|
};
|
|
1267
1603
|
}
|
|
@@ -1321,6 +1657,326 @@ function ssrGroupSlot(fn, idx) {
|
|
|
1321
1657
|
}
|
|
1322
1658
|
};
|
|
1323
1659
|
}
|
|
1660
|
+
const holePositionCache = new WeakMap();
|
|
1661
|
+
function holeContentPositions(t) {
|
|
1662
|
+
let cached = holePositionCache.get(t);
|
|
1663
|
+
if (cached) return cached;
|
|
1664
|
+
const pos = [];
|
|
1665
|
+
const openOff = [];
|
|
1666
|
+
const closeOff = [];
|
|
1667
|
+
let inTag = false;
|
|
1668
|
+
let quote = "";
|
|
1669
|
+
let curOpen = null;
|
|
1670
|
+
let scanningName = false;
|
|
1671
|
+
for (let i = 0; i < t.length; i++) {
|
|
1672
|
+
const seg = t[i];
|
|
1673
|
+
let close = -1;
|
|
1674
|
+
const openAtStart = inTag;
|
|
1675
|
+
let reopened = false;
|
|
1676
|
+
for (let j = 0; j < seg.length; j++) {
|
|
1677
|
+
const ch = seg[j];
|
|
1678
|
+
if (quote) {
|
|
1679
|
+
if (ch === quote) quote = "";
|
|
1680
|
+
} else if (inTag) {
|
|
1681
|
+
if (scanningName && (ch === " " || ch === "\t" || ch === "\n" || ch === ">" || ch === "/")) {
|
|
1682
|
+
scanningName = false;
|
|
1683
|
+
curOpen = {
|
|
1684
|
+
seg: i,
|
|
1685
|
+
off: j
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
if (ch === '"' || ch === "'") quote = ch;else if (ch === ">") {
|
|
1689
|
+
inTag = false;
|
|
1690
|
+
if (openAtStart && !reopened && close === -1) close = j;
|
|
1691
|
+
curOpen = null;
|
|
1692
|
+
}
|
|
1693
|
+
} else if (ch === "<") {
|
|
1694
|
+
inTag = true;
|
|
1695
|
+
scanningName = true;
|
|
1696
|
+
reopened = true;
|
|
1697
|
+
curOpen = null;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
if (inTag && scanningName) {
|
|
1701
|
+
scanningName = false;
|
|
1702
|
+
curOpen = {
|
|
1703
|
+
seg: i,
|
|
1704
|
+
off: seg.length
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
closeOff.push(close);
|
|
1708
|
+
openOff.push(inTag && curOpen && curOpen.seg === i ? curOpen.off : -1);
|
|
1709
|
+
if (i < t.length - 1) pos.push(!inTag);
|
|
1710
|
+
}
|
|
1711
|
+
cached = {
|
|
1712
|
+
pos,
|
|
1713
|
+
openOff,
|
|
1714
|
+
closeOff
|
|
1715
|
+
};
|
|
1716
|
+
holePositionCache.set(t, cached);
|
|
1717
|
+
return cached;
|
|
1718
|
+
}
|
|
1719
|
+
function createLiveHoles(sink, scoped) {
|
|
1720
|
+
let nextId = 0;
|
|
1721
|
+
const stamp = typeof creationStamp === "function" ? creationStamp : () => 0;
|
|
1722
|
+
const inScope = scoped && typeof inServerComponentScope === "function" ? inServerComponentScope : null;
|
|
1723
|
+
const stripMarkers = html => html.replace(/<!--lh:\/?\d+-->/g, "");
|
|
1724
|
+
function resolveHoleValue(hole) {
|
|
1725
|
+
const result = {
|
|
1726
|
+
t: [""],
|
|
1727
|
+
h: [],
|
|
1728
|
+
p: []
|
|
1729
|
+
};
|
|
1730
|
+
try {
|
|
1731
|
+
resolveSSRNode(hole(), result);
|
|
1732
|
+
} catch (err) {
|
|
1733
|
+
const wrap = buildAsyncWrap(err, hole);
|
|
1734
|
+
if (!wrap) throw err;
|
|
1735
|
+
result.h.push(wrap.fn);
|
|
1736
|
+
result.p.push(wrap.p);
|
|
1737
|
+
result.t.push("");
|
|
1738
|
+
}
|
|
1739
|
+
return result;
|
|
1740
|
+
}
|
|
1741
|
+
function closeChildren(b) {
|
|
1742
|
+
for (const c of b.children) {
|
|
1743
|
+
c.closed = true;
|
|
1744
|
+
if (c.key) sink.closeBinding(c.key);
|
|
1745
|
+
closeChildren(c);
|
|
1746
|
+
}
|
|
1747
|
+
b.children.length = 0;
|
|
1748
|
+
}
|
|
1749
|
+
const engine = {
|
|
1750
|
+
suppressed: 0,
|
|
1751
|
+
sweeping: false,
|
|
1752
|
+
parent: null,
|
|
1753
|
+
recordStamp: 0,
|
|
1754
|
+
gateHit: false,
|
|
1755
|
+
content(hole) {
|
|
1756
|
+
if (hole.$lhSuppress) {
|
|
1757
|
+
const r = {
|
|
1758
|
+
t: [""],
|
|
1759
|
+
h: [],
|
|
1760
|
+
p: []
|
|
1761
|
+
};
|
|
1762
|
+
engine.suppressed++;
|
|
1763
|
+
try {
|
|
1764
|
+
try {
|
|
1765
|
+
resolveSSRNode(hole(), r);
|
|
1766
|
+
} catch (err) {
|
|
1767
|
+
const wrap = buildAsyncWrap(err, hole);
|
|
1768
|
+
if (wrap) {
|
|
1769
|
+
r.h.push(wrap.fn);
|
|
1770
|
+
r.p.push(wrap.p);
|
|
1771
|
+
r.t.push("");
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
} finally {
|
|
1775
|
+
engine.suppressed--;
|
|
1776
|
+
}
|
|
1777
|
+
const b = hole.$lhBinding;
|
|
1778
|
+
if (b && !b.closed && !r.h.length && !engine.sweeping) {
|
|
1779
|
+
b.last = stripMarkers(r.t[0]);
|
|
1780
|
+
}
|
|
1781
|
+
return r.h.length ? r : r.t[0];
|
|
1782
|
+
}
|
|
1783
|
+
if (engine.suppressed || engine.sweeping) return null;
|
|
1784
|
+
if (hole.$lhSkip) return null;
|
|
1785
|
+
if (inScope && !inScope()) return null;
|
|
1786
|
+
const recordsBefore = engine.recordStamp;
|
|
1787
|
+
const ownersBefore = stamp();
|
|
1788
|
+
const owner = getOwner();
|
|
1789
|
+
const b = {
|
|
1790
|
+
key: null,
|
|
1791
|
+
children: [],
|
|
1792
|
+
last: null,
|
|
1793
|
+
closed: false,
|
|
1794
|
+
sweep() {
|
|
1795
|
+
if (b.closed) return;
|
|
1796
|
+
const prevSweeping = engine.sweeping;
|
|
1797
|
+
engine.sweeping = true;
|
|
1798
|
+
engine.gateHit = false;
|
|
1799
|
+
const sweepOwnersBefore = stamp();
|
|
1800
|
+
let res;
|
|
1801
|
+
try {
|
|
1802
|
+
res = owner ? runWithOwner(owner, () => resolveHoleValue(hole)) : resolveHoleValue(hole);
|
|
1803
|
+
} catch (err) {
|
|
1804
|
+
b.closed = true;
|
|
1805
|
+
sink.closeBinding(b.key);
|
|
1806
|
+
sink.error(b.key, String(err && err.message || err));
|
|
1807
|
+
return;
|
|
1808
|
+
} finally {
|
|
1809
|
+
engine.sweeping = prevSweeping;
|
|
1810
|
+
}
|
|
1811
|
+
if (engine.gateHit || stamp() !== sweepOwnersBefore) {
|
|
1812
|
+
b.closed = true;
|
|
1813
|
+
sink.closeBinding(b.key);
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
if (res.h.length) return;
|
|
1817
|
+
const html = res.t[0];
|
|
1818
|
+
if (b.last === null || html === b.last) return;
|
|
1819
|
+
b.last = html;
|
|
1820
|
+
closeChildren(b);
|
|
1821
|
+
sink.hole(b.key, html);
|
|
1822
|
+
}
|
|
1823
|
+
};
|
|
1824
|
+
if (engine.parent) engine.parent.children.push(b);
|
|
1825
|
+
const prevParent = engine.parent;
|
|
1826
|
+
engine.parent = b;
|
|
1827
|
+
let value;
|
|
1828
|
+
let escalated = null;
|
|
1829
|
+
try {
|
|
1830
|
+
value = hole();
|
|
1831
|
+
} catch (err) {
|
|
1832
|
+
const wrap = buildAsyncWrap(err, hole);
|
|
1833
|
+
if (!wrap) {
|
|
1834
|
+
engine.parent = prevParent;
|
|
1835
|
+
closeChildren(b);
|
|
1836
|
+
return "";
|
|
1837
|
+
}
|
|
1838
|
+
escalated = wrap;
|
|
1839
|
+
}
|
|
1840
|
+
if (!escalated && (typeof value === "function" && value.$lhSkip || value !== null && typeof value === "object" && value.$slot)) {
|
|
1841
|
+
engine.parent = prevParent;
|
|
1842
|
+
const r = {
|
|
1843
|
+
t: [""],
|
|
1844
|
+
h: [],
|
|
1845
|
+
p: []
|
|
1846
|
+
};
|
|
1847
|
+
engine.suppressed++;
|
|
1848
|
+
try {
|
|
1849
|
+
resolveSSRNode(value, r);
|
|
1850
|
+
} finally {
|
|
1851
|
+
engine.suppressed--;
|
|
1852
|
+
}
|
|
1853
|
+
return r.h.length ? r : r.t[0];
|
|
1854
|
+
}
|
|
1855
|
+
let res;
|
|
1856
|
+
if (escalated) {
|
|
1857
|
+
closeChildren(b);
|
|
1858
|
+
escalated.fn.$lhSuppress = true;
|
|
1859
|
+
escalated.fn.$lhBinding = b;
|
|
1860
|
+
res = {
|
|
1861
|
+
t: ["", ""],
|
|
1862
|
+
h: [escalated.fn],
|
|
1863
|
+
p: [escalated.p]
|
|
1864
|
+
};
|
|
1865
|
+
} else {
|
|
1866
|
+
res = {
|
|
1867
|
+
t: [""],
|
|
1868
|
+
h: [],
|
|
1869
|
+
p: []
|
|
1870
|
+
};
|
|
1871
|
+
try {
|
|
1872
|
+
resolveSSRNode(value, res);
|
|
1873
|
+
} catch (_) {
|
|
1874
|
+
engine.parent = prevParent;
|
|
1875
|
+
closeChildren(b);
|
|
1876
|
+
return "";
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
engine.parent = prevParent;
|
|
1880
|
+
if (engine.recordStamp !== recordsBefore || stamp() !== ownersBefore) {
|
|
1881
|
+
return res.h.length ? res : res.t[0];
|
|
1882
|
+
}
|
|
1883
|
+
const id = nextId++;
|
|
1884
|
+
const key = b.key = "lh:" + id;
|
|
1885
|
+
const open = `<!--lh:${id}-->`;
|
|
1886
|
+
const close = `<!--lh:/${id}-->`;
|
|
1887
|
+
if (!res.h.length) {
|
|
1888
|
+
b.last = stripMarkers(res.t[0]);
|
|
1889
|
+
sink.openBinding(key, b);
|
|
1890
|
+
return open + res.t[0] + close;
|
|
1891
|
+
}
|
|
1892
|
+
const t = res.t.slice();
|
|
1893
|
+
t[0] = open + t[0];
|
|
1894
|
+
t[t.length - 1] += close;
|
|
1895
|
+
sink.openBinding(key, b);
|
|
1896
|
+
return {
|
|
1897
|
+
t,
|
|
1898
|
+
h: res.h,
|
|
1899
|
+
p: res.p
|
|
1900
|
+
};
|
|
1901
|
+
},
|
|
1902
|
+
mint() {
|
|
1903
|
+
return nextId++;
|
|
1904
|
+
},
|
|
1905
|
+
active() {
|
|
1906
|
+
return !inScope || inScope();
|
|
1907
|
+
},
|
|
1908
|
+
attr(cap) {
|
|
1909
|
+
const owner = getOwner();
|
|
1910
|
+
const b = {
|
|
1911
|
+
key: "lha:" + cap.id,
|
|
1912
|
+
children: [],
|
|
1913
|
+
last: cap.base,
|
|
1914
|
+
closed: false,
|
|
1915
|
+
sweep() {
|
|
1916
|
+
if (b.closed) return;
|
|
1917
|
+
const prevSweeping = engine.sweeping;
|
|
1918
|
+
engine.sweeping = true;
|
|
1919
|
+
engine.gateHit = false;
|
|
1920
|
+
const sweepOwnersBefore = stamp();
|
|
1921
|
+
let html = "";
|
|
1922
|
+
try {
|
|
1923
|
+
let group = null;
|
|
1924
|
+
let groupVal = null;
|
|
1925
|
+
const run = () => {
|
|
1926
|
+
for (const part of cap.parts) {
|
|
1927
|
+
if (typeof part === "string") {
|
|
1928
|
+
html += part;
|
|
1929
|
+
continue;
|
|
1930
|
+
}
|
|
1931
|
+
let v;
|
|
1932
|
+
if (part.g) {
|
|
1933
|
+
if (group !== part.g) {
|
|
1934
|
+
group = part.g;
|
|
1935
|
+
groupVal = part.g();
|
|
1936
|
+
}
|
|
1937
|
+
v = groupVal[part.i];
|
|
1938
|
+
} else {
|
|
1939
|
+
v = part.f();
|
|
1940
|
+
}
|
|
1941
|
+
const vt = typeof v;
|
|
1942
|
+
if (vt === "string" || vt === "number") html += v;
|
|
1943
|
+
}
|
|
1944
|
+
};
|
|
1945
|
+
owner ? runWithOwner(owner, run) : run();
|
|
1946
|
+
} catch (err) {
|
|
1947
|
+
if (ssrHandleError(err, true)) return;
|
|
1948
|
+
b.closed = true;
|
|
1949
|
+
sink.closeBinding(b.key);
|
|
1950
|
+
sink.error("lha:" + cap.id, String(err && err.message || err));
|
|
1951
|
+
return;
|
|
1952
|
+
} finally {
|
|
1953
|
+
engine.sweeping = prevSweeping;
|
|
1954
|
+
}
|
|
1955
|
+
if (engine.gateHit || stamp() !== sweepOwnersBefore) {
|
|
1956
|
+
b.closed = true;
|
|
1957
|
+
sink.closeBinding(b.key);
|
|
1958
|
+
return;
|
|
1959
|
+
}
|
|
1960
|
+
if (html === b.last) return;
|
|
1961
|
+
const before = attrNames(b.last);
|
|
1962
|
+
const after = attrNames(html);
|
|
1963
|
+
const removed = before.filter(n => !after.includes(n));
|
|
1964
|
+
b.last = html;
|
|
1965
|
+
sink.attr(String(cap.id), html, removed);
|
|
1966
|
+
}
|
|
1967
|
+
};
|
|
1968
|
+
sink.openBinding(b.key, b);
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
return engine;
|
|
1972
|
+
}
|
|
1973
|
+
function attrNames(text) {
|
|
1974
|
+
const names = [];
|
|
1975
|
+
const re = /(?:^|\s)([^\s=/>"']+)(?:="[^"]*")?/g;
|
|
1976
|
+
let m;
|
|
1977
|
+
while (m = re.exec(text)) names.push(m[1]);
|
|
1978
|
+
return names;
|
|
1979
|
+
}
|
|
1324
1980
|
function ssr(t) {
|
|
1325
1981
|
const len = arguments.length;
|
|
1326
1982
|
if (len === 1) return {
|
|
@@ -1331,13 +1987,54 @@ function ssr(t) {
|
|
|
1331
1987
|
let lastGroup = null;
|
|
1332
1988
|
let lastGroupVal = null;
|
|
1333
1989
|
let lastGroupIdx = 0;
|
|
1990
|
+
const live = sharedConfig.context && sharedConfig.context.liveHoles;
|
|
1991
|
+
const hp = live ? holeContentPositions(t) : null;
|
|
1992
|
+
let lastOpen = null;
|
|
1993
|
+
let cap = null;
|
|
1994
|
+
if (live && hp.openOff[0] >= 0) lastOpen = {
|
|
1995
|
+
r: null,
|
|
1996
|
+
seg: -1,
|
|
1997
|
+
off: hp.openOff[0]
|
|
1998
|
+
};
|
|
1999
|
+
const captureStart = () => {
|
|
2000
|
+
if (cap) return true;
|
|
2001
|
+
if (!lastOpen || live.suppressed || live.sweeping || !live.active()) return false;
|
|
2002
|
+
if (lastOpen.r !== result || result !== null && lastOpen.seg !== result.t.length - 1) {
|
|
2003
|
+
return false;
|
|
2004
|
+
}
|
|
2005
|
+
const id = live.mint();
|
|
2006
|
+
const inject = ` data-lha="${id}"`;
|
|
2007
|
+
let prefix;
|
|
2008
|
+
if (result === null) {
|
|
2009
|
+
s = s.slice(0, lastOpen.off) + inject + s.slice(lastOpen.off);
|
|
2010
|
+
prefix = s.slice(lastOpen.off + inject.length);
|
|
2011
|
+
} else {
|
|
2012
|
+
const seg = result.t[lastOpen.seg];
|
|
2013
|
+
result.t[lastOpen.seg] = seg.slice(0, lastOpen.off) + inject + seg.slice(lastOpen.off);
|
|
2014
|
+
prefix = result.t[lastOpen.seg].slice(lastOpen.off + inject.length);
|
|
2015
|
+
}
|
|
2016
|
+
cap = {
|
|
2017
|
+
id,
|
|
2018
|
+
parts: [prefix],
|
|
2019
|
+
base: prefix
|
|
2020
|
+
};
|
|
2021
|
+
return true;
|
|
2022
|
+
};
|
|
1334
2023
|
for (let i = 1; i < len; i++) {
|
|
1335
2024
|
const hole = arguments[i];
|
|
1336
2025
|
const ht = typeof hole;
|
|
1337
2026
|
if (ht === "string") {
|
|
1338
2027
|
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
2028
|
+
if (cap) {
|
|
2029
|
+
cap.parts.push(hole);
|
|
2030
|
+
cap.base += hole;
|
|
2031
|
+
}
|
|
1339
2032
|
} else if (ht === "number") {
|
|
1340
2033
|
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
2034
|
+
if (cap) {
|
|
2035
|
+
cap.parts.push("" + hole);
|
|
2036
|
+
cap.base += hole;
|
|
2037
|
+
}
|
|
1341
2038
|
} else if (hole == null || ht === "boolean") ; else if (ht === "function" && hole.$g) {
|
|
1342
2039
|
let value;
|
|
1343
2040
|
let hasValue = false;
|
|
@@ -1361,7 +2058,14 @@ function ssr(t) {
|
|
|
1361
2058
|
if (Array.isArray(lastGroupVal)) {
|
|
1362
2059
|
value = lastGroupVal[lastGroupIdx++];
|
|
1363
2060
|
hasValue = true;
|
|
2061
|
+
if (live && !hp.pos[i - 1] && captureStart()) {
|
|
2062
|
+
cap.parts.push({
|
|
2063
|
+
g: hole,
|
|
2064
|
+
i: lastGroupIdx - 1
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
1364
2067
|
} else {
|
|
2068
|
+
cap = null;
|
|
1365
2069
|
result.h.push(ssrGroupSlot(lastGroupVal.fn, lastGroupIdx++));
|
|
1366
2070
|
result.p.push(lastGroupVal.p);
|
|
1367
2071
|
result.t.push("");
|
|
@@ -1371,6 +2075,7 @@ function ssr(t) {
|
|
|
1371
2075
|
const vt = typeof value;
|
|
1372
2076
|
if (vt === "string" || vt === "number") {
|
|
1373
2077
|
if (result === null) s += value;else result.t[result.t.length - 1] += value;
|
|
2078
|
+
if (cap && !hp.pos[i - 1]) cap.base += value;
|
|
1374
2079
|
} else if (value == null || vt === "boolean") ; else if (result !== null) {
|
|
1375
2080
|
resolveSSRNode(value, result);
|
|
1376
2081
|
} else {
|
|
@@ -1388,19 +2093,67 @@ function ssr(t) {
|
|
|
1388
2093
|
}
|
|
1389
2094
|
}
|
|
1390
2095
|
}
|
|
1391
|
-
} else if (result !== null) {
|
|
1392
|
-
resolveSSRNode(hole, result);
|
|
1393
2096
|
} else if (ht === "function") {
|
|
1394
|
-
|
|
1395
|
-
if (
|
|
1396
|
-
|
|
1397
|
-
t
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
2097
|
+
let liveNode = null;
|
|
2098
|
+
if (live && hp.pos[i - 1] && (liveNode = live.content(hole)) !== null) {
|
|
2099
|
+
if (typeof liveNode === "string") {
|
|
2100
|
+
if (result === null) s += liveNode;else result.t[result.t.length - 1] += liveNode;
|
|
2101
|
+
} else {
|
|
2102
|
+
if (result === null) {
|
|
2103
|
+
result = {
|
|
2104
|
+
t: [s],
|
|
2105
|
+
h: [],
|
|
2106
|
+
p: []
|
|
2107
|
+
};
|
|
2108
|
+
s = "";
|
|
2109
|
+
}
|
|
2110
|
+
resolveSSRNode(liveNode, result);
|
|
2111
|
+
}
|
|
2112
|
+
} else if (result !== null) {
|
|
2113
|
+
const inTag = live && !hp.pos[i - 1];
|
|
2114
|
+
const capturing = inTag && captureStart();
|
|
2115
|
+
const li = capturing ? result.t.length - 1 : 0;
|
|
2116
|
+
const before = capturing ? result.t[li].length : 0;
|
|
2117
|
+
if (live) live.suppressed++;
|
|
2118
|
+
try {
|
|
2119
|
+
resolveSSRNode(hole, result);
|
|
2120
|
+
} finally {
|
|
2121
|
+
if (live) live.suppressed--;
|
|
2122
|
+
}
|
|
2123
|
+
if (capturing) {
|
|
2124
|
+
if (result.t.length - 1 === li) {
|
|
2125
|
+
cap.base += result.t[li].slice(before);
|
|
2126
|
+
cap.parts.push({
|
|
2127
|
+
f: hole
|
|
2128
|
+
});
|
|
2129
|
+
} else {
|
|
2130
|
+
cap = null;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
} else {
|
|
2134
|
+
const capturing = live && !hp.pos[i - 1] && captureStart();
|
|
2135
|
+
const r = tryResolveFunctionHole(hole);
|
|
2136
|
+
if (typeof r === "string") {
|
|
2137
|
+
s += r;
|
|
2138
|
+
if (capturing) {
|
|
2139
|
+
cap.base += r;
|
|
2140
|
+
cap.parts.push({
|
|
2141
|
+
f: hole
|
|
2142
|
+
});
|
|
2143
|
+
}
|
|
2144
|
+
} else {
|
|
2145
|
+
if (capturing) cap = null;
|
|
2146
|
+
result = {
|
|
2147
|
+
t: [s],
|
|
2148
|
+
h: [],
|
|
2149
|
+
p: []
|
|
2150
|
+
};
|
|
2151
|
+
s = "";
|
|
2152
|
+
appendResolvedNode(result, r);
|
|
2153
|
+
}
|
|
1403
2154
|
}
|
|
2155
|
+
} else if (result !== null) {
|
|
2156
|
+
resolveSSRNode(hole, result);
|
|
1404
2157
|
} else {
|
|
1405
2158
|
const r = tryResolveString(hole);
|
|
1406
2159
|
if (typeof r === "string") {
|
|
@@ -1416,6 +2169,32 @@ function ssr(t) {
|
|
|
1416
2169
|
}
|
|
1417
2170
|
}
|
|
1418
2171
|
const next = t[i];
|
|
2172
|
+
if (live) {
|
|
2173
|
+
if (cap) {
|
|
2174
|
+
const co = hp.closeOff[i];
|
|
2175
|
+
if (co >= 0) {
|
|
2176
|
+
const tail = next.slice(0, co);
|
|
2177
|
+
cap.parts.push(tail);
|
|
2178
|
+
cap.base += tail;
|
|
2179
|
+
live.attr(cap);
|
|
2180
|
+
cap = null;
|
|
2181
|
+
} else {
|
|
2182
|
+
cap.parts.push(next);
|
|
2183
|
+
cap.base += next;
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
if (hp.openOff[i] >= 0) {
|
|
2187
|
+
lastOpen = result === null ? {
|
|
2188
|
+
r: null,
|
|
2189
|
+
seg: -1,
|
|
2190
|
+
off: s.length + hp.openOff[i]
|
|
2191
|
+
} : {
|
|
2192
|
+
r: result,
|
|
2193
|
+
seg: result.t.length - 1,
|
|
2194
|
+
off: result.t[result.t.length - 1].length + hp.openOff[i]
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
1419
2198
|
if (result === null) s += next;else result.t[result.t.length - 1] += next;
|
|
1420
2199
|
}
|
|
1421
2200
|
if (result === null) return {
|
|
@@ -1577,18 +2356,6 @@ function getHydrationKey() {
|
|
|
1577
2356
|
function applyRef(r, element) {
|
|
1578
2357
|
Array.isArray(r) ? r.flat(Infinity).forEach(f => f && f(element)) : r(element);
|
|
1579
2358
|
}
|
|
1580
|
-
function useAssets(fn) {
|
|
1581
|
-
sharedConfig.context.assets.push(() => resolveSSRSync(escape(fn())));
|
|
1582
|
-
}
|
|
1583
|
-
function getAssets() {
|
|
1584
|
-
const assets = sharedConfig.context.assets;
|
|
1585
|
-
let out = "";
|
|
1586
|
-
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
1587
|
-
return out;
|
|
1588
|
-
}
|
|
1589
|
-
function Assets(props) {
|
|
1590
|
-
useAssets(() => props.children);
|
|
1591
|
-
}
|
|
1592
2359
|
function generateHydrationScript({
|
|
1593
2360
|
eventNames = ["click", "input"],
|
|
1594
2361
|
nonce
|
|
@@ -1605,17 +2372,11 @@ function allSettled(promises) {
|
|
|
1605
2372
|
return;
|
|
1606
2373
|
});
|
|
1607
2374
|
}
|
|
1608
|
-
function
|
|
1609
|
-
if (!assets || !assets.length) return "";
|
|
1610
|
-
let out = "";
|
|
1611
|
-
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
1612
|
-
return out;
|
|
1613
|
-
}
|
|
1614
|
-
function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
2375
|
+
function assembleDocument(html, emittedAssets, inlineStyles, scripts, nonce, headTags, onHead) {
|
|
1615
2376
|
const scriptTag = scripts ? `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>` : "";
|
|
1616
2377
|
const headTagsHtml = headTags ? headTags.html : "";
|
|
1617
2378
|
const headPrelude = headTags ? headTags.prelude : "";
|
|
1618
|
-
if (!onHead && !
|
|
2379
|
+
if (!onHead && !headTagsHtml && !headPrelude && !(emittedAssets && emittedAssets.size) && !(inlineStyles && inlineStyles.size)) {
|
|
1619
2380
|
if (!scriptTag) return html;
|
|
1620
2381
|
const xs = html.indexOf("<!--xs-->");
|
|
1621
2382
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
@@ -1630,13 +2391,13 @@ function assembleDocument(html, assetsHtml, emittedAssets, inlineStyles, scripts
|
|
|
1630
2391
|
const headIdx = html.indexOf("</head>");
|
|
1631
2392
|
if (headIdx === -1) {
|
|
1632
2393
|
if (onHead) {
|
|
1633
|
-
onHead(headPrelude + headTagsHtml +
|
|
2394
|
+
onHead(headPrelude + headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce));
|
|
1634
2395
|
}
|
|
1635
2396
|
if (!scriptTag) return html;
|
|
1636
2397
|
const xs = html.indexOf("<!--xs-->");
|
|
1637
2398
|
return xs === -1 ? html + scriptTag : html.slice(0, xs) + scriptTag + html.slice(xs);
|
|
1638
2399
|
}
|
|
1639
|
-
const head = headTagsHtml +
|
|
2400
|
+
const head = headTagsHtml + renderHeadAssets(emittedAssets, inlineStyles, nonce);
|
|
1640
2401
|
if (!scriptTag) return html.slice(0, headIdx) + head + html.slice(headIdx);
|
|
1641
2402
|
const xsIdx = html.indexOf("<!--xs-->");
|
|
1642
2403
|
if (xsIdx === -1) return html.slice(0, headIdx) + head + html.slice(headIdx) + scriptTag;
|
|
@@ -1769,7 +2530,6 @@ function tryResolveString(node) {
|
|
|
1769
2530
|
merge: node
|
|
1770
2531
|
};
|
|
1771
2532
|
if (node.t === undefined) {
|
|
1772
|
-
console.warn(`Unrecognized value. Skipped inserting`, node);
|
|
1773
2533
|
return "";
|
|
1774
2534
|
}
|
|
1775
2535
|
return Array.isArray(node.t) ? node.t[0] : node.t;
|
|
@@ -1794,13 +2554,19 @@ function resolveSSRNode(node, result = {
|
|
|
1794
2554
|
if (t === "string" || t === "number") {
|
|
1795
2555
|
result.t[result.t.length - 1] += node;
|
|
1796
2556
|
} else if (node == null || t === "boolean") ; else if (Array.isArray(node)) {
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
2557
|
+
const slotLive = node.$slot && sharedConfig.context && sharedConfig.context.liveHoles;
|
|
2558
|
+
if (slotLive) slotLive.suppressed++;
|
|
2559
|
+
try {
|
|
2560
|
+
let prevNonObj = false;
|
|
2561
|
+
for (let i = 0, len = node.length; i < len; i++) {
|
|
2562
|
+
const item = node[i];
|
|
2563
|
+
const itemNonObj = item !== null && typeof item !== "object";
|
|
2564
|
+
if (!top && prevNonObj && itemNonObj) result.t[result.t.length - 1] += `<!--!$-->`;
|
|
2565
|
+
prevNonObj = itemNonObj;
|
|
2566
|
+
resolveSSRNode(item, result);
|
|
2567
|
+
}
|
|
2568
|
+
} finally {
|
|
2569
|
+
if (slotLive) slotLive.suppressed--;
|
|
1804
2570
|
}
|
|
1805
2571
|
} else if (t === "object") {
|
|
1806
2572
|
if (node.h) {
|
|
@@ -1812,16 +2578,22 @@ function resolveSSRNode(node, result = {
|
|
|
1812
2578
|
}
|
|
1813
2579
|
} else if (node.t !== undefined) {
|
|
1814
2580
|
result.t[result.t.length - 1] += node.t;
|
|
1815
|
-
} else
|
|
2581
|
+
} else ;
|
|
1816
2582
|
} else if (t === "function") {
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
2583
|
+
const live = sharedConfig.context && sharedConfig.context.liveHoles;
|
|
2584
|
+
let liveNode = null;
|
|
2585
|
+
if (live && (liveNode = live.content(node)) !== null) {
|
|
2586
|
+
if (typeof liveNode === "string") result.t[result.t.length - 1] += liveNode;else resolveSSRNode(liveNode, result);
|
|
2587
|
+
} else {
|
|
2588
|
+
try {
|
|
2589
|
+
resolveSSRNode(node(), result);
|
|
2590
|
+
} catch (err) {
|
|
2591
|
+
const wrap = buildAsyncWrap(err, node);
|
|
2592
|
+
if (wrap) {
|
|
2593
|
+
result.h.push(wrap.fn);
|
|
2594
|
+
result.p.push(wrap.p);
|
|
2595
|
+
result.t.push("");
|
|
2596
|
+
}
|
|
1825
2597
|
}
|
|
1826
2598
|
}
|
|
1827
2599
|
}
|
|
@@ -1836,92 +2608,229 @@ const RequestContext = Symbol.for("solid.RequestContext");
|
|
|
1836
2608
|
function getRequestEvent() {
|
|
1837
2609
|
return globalThis[RequestContext] ? globalThis[RequestContext].getStore() || sharedConfig.context && sharedConfig.context.event || console.warn("RequestEvent is missing. This is most likely due to accessing `getRequestEvent` non-managed async scope in a partially polyfilled environment. Try moving it above all `await` calls.") : undefined;
|
|
1838
2610
|
}
|
|
1839
|
-
function
|
|
1840
|
-
return
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
function claimElement(node) {
|
|
1847
|
-
return node;
|
|
2611
|
+
function createResponseStub() {
|
|
2612
|
+
return {
|
|
2613
|
+
status: undefined,
|
|
2614
|
+
statusText: undefined,
|
|
2615
|
+
headers: new Headers(),
|
|
2616
|
+
committed: false
|
|
2617
|
+
};
|
|
1848
2618
|
}
|
|
1849
|
-
function
|
|
1850
|
-
return
|
|
2619
|
+
function createRequestEvent(request, init) {
|
|
2620
|
+
return {
|
|
2621
|
+
request,
|
|
2622
|
+
locals: {},
|
|
2623
|
+
response: createResponseStub(),
|
|
2624
|
+
...init
|
|
2625
|
+
};
|
|
1851
2626
|
}
|
|
1852
|
-
function
|
|
1853
|
-
|
|
2627
|
+
function reportLostHeaderWrite(method, name) {
|
|
2628
|
+
const message = `Response header write dropped: headers.${method}(${JSON.stringify(String(name))}) ` + "ran after the response head was sent. Write headers before the shell flushes " + "(or before the handler returns).";
|
|
2629
|
+
console.error(message);
|
|
1854
2630
|
}
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
2631
|
+
function commitResponseStub(stub, {
|
|
2632
|
+
allowLateLocation = false
|
|
2633
|
+
} = {}) {
|
|
2634
|
+
if (!stub || stub.committed) return stub;
|
|
2635
|
+
stub.committed = true;
|
|
2636
|
+
const headers = stub.headers;
|
|
2637
|
+
if (!headers || typeof headers.set !== "function") return stub;
|
|
2638
|
+
for (const method of ["set", "append", "delete"]) {
|
|
2639
|
+
const original = headers[method].bind(headers);
|
|
2640
|
+
headers[method] = function (name, ...rest) {
|
|
2641
|
+
if (allowLateLocation && method === "set" && String(name).toLowerCase() === "location") {
|
|
2642
|
+
return original(name, ...rest);
|
|
2643
|
+
}
|
|
2644
|
+
reportLostHeaderWrite(method, name);
|
|
2645
|
+
};
|
|
1861
2646
|
}
|
|
2647
|
+
return stub;
|
|
1862
2648
|
}
|
|
1863
|
-
|
|
1864
|
-
function
|
|
1865
|
-
|
|
2649
|
+
const validRedirectStatuses = /*#__PURE__*/new Set([301, 302, 303, 307, 308]);
|
|
2650
|
+
function getExpectedRedirectStatus(response) {
|
|
2651
|
+
if (response.status && validRedirectStatuses.has(response.status)) return response.status;
|
|
2652
|
+
return 302;
|
|
1866
2653
|
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
2654
|
+
function mergeStubHeaders(target, stub) {
|
|
2655
|
+
if (!stub) return target;
|
|
2656
|
+
stub.headers.forEach((value, key) => {
|
|
2657
|
+
if (key !== "set-cookie") target.set(key, value);
|
|
2658
|
+
});
|
|
2659
|
+
const setCookies = stub.headers.getSetCookie ? stub.headers.getSetCookie() : [];
|
|
2660
|
+
for (const cookie of setCookies) target.append("set-cookie", cookie);
|
|
2661
|
+
return target;
|
|
2662
|
+
}
|
|
2663
|
+
function copyInitHeaders(init) {
|
|
2664
|
+
if (!init || !init.getSetCookie) return new Headers(init);
|
|
2665
|
+
const headers = new Headers();
|
|
2666
|
+
init.forEach((value, key) => {
|
|
2667
|
+
if (key !== "set-cookie") headers.append(key, value);
|
|
2668
|
+
});
|
|
2669
|
+
for (const cookie of init.getSetCookie()) headers.append("Set-Cookie", cookie);
|
|
2670
|
+
return headers;
|
|
2671
|
+
}
|
|
2672
|
+
const STUB_GAP_FILL_EXCLUDED = /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, "Location"].map(header => header.toLowerCase()));
|
|
2673
|
+
function fillsStubGap(key, headers, response) {
|
|
2674
|
+
if (key === "set-cookie" || STUB_GAP_FILL_EXCLUDED.has(key)) return false;
|
|
2675
|
+
if (response.body === null && (key === "content-type" || key === "content-length")) return false;
|
|
2676
|
+
return !headers.has(key);
|
|
2677
|
+
}
|
|
2678
|
+
function commitEventResponse(response, event = getRequestEvent()) {
|
|
2679
|
+
const stub = event && event.response;
|
|
2680
|
+
if (!stub || !stub.headers || stub.committed) return response;
|
|
2681
|
+
const cookies = stub.headers.getSetCookie ? stub.headers.getSetCookie() : [];
|
|
2682
|
+
commitResponseStub(stub);
|
|
2683
|
+
let hasGaps = false;
|
|
2684
|
+
stub.headers.forEach((value, key) => {
|
|
2685
|
+
if (fillsStubGap(key, response.headers, response)) hasGaps = true;
|
|
2686
|
+
});
|
|
2687
|
+
if (!cookies.length && !hasGaps) return response;
|
|
2688
|
+
try {
|
|
2689
|
+
for (const cookie of cookies) response.headers.append("Set-Cookie", cookie);
|
|
2690
|
+
stub.headers.forEach((value, key) => {
|
|
2691
|
+
if (fillsStubGap(key, response.headers, response)) response.headers.set(key, value);
|
|
2692
|
+
});
|
|
2693
|
+
return response;
|
|
2694
|
+
} catch {
|
|
2695
|
+
const headers = copyInitHeaders(response.headers);
|
|
2696
|
+
for (const cookie of cookies) headers.append("Set-Cookie", cookie);
|
|
2697
|
+
stub.headers.forEach((value, key) => {
|
|
2698
|
+
if (fillsStubGap(key, headers, response)) headers.set(key, value);
|
|
2699
|
+
});
|
|
2700
|
+
return new Response(response.body, {
|
|
2701
|
+
status: response.status,
|
|
2702
|
+
statusText: response.statusText,
|
|
2703
|
+
headers
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
1870
2706
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
const
|
|
1874
|
-
|
|
1875
|
-
...responseInit
|
|
1876
|
-
} = init;
|
|
1877
|
-
const headers = new Headers(responseInit.headers);
|
|
1878
|
-
revalidate !== undefined && headers.set(REVALIDATE_HEADER, revalidate.toString());
|
|
2707
|
+
function deriveHead(stub, responseInit = {}) {
|
|
2708
|
+
const headers = mergeStubHeaders(copyInitHeaders(responseInit.headers), stub);
|
|
2709
|
+
const status = stub && stub.status || responseInit.status || 200;
|
|
2710
|
+
const statusText = stub && stub.statusText || responseInit.statusText || undefined;
|
|
1879
2711
|
return {
|
|
1880
|
-
|
|
2712
|
+
status,
|
|
2713
|
+
statusText,
|
|
1881
2714
|
headers
|
|
1882
2715
|
};
|
|
1883
2716
|
}
|
|
1884
|
-
function
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
2717
|
+
function escapeAttribute(value) {
|
|
2718
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
2719
|
+
}
|
|
2720
|
+
function createSSRResponse(result, event, options = {}) {
|
|
2721
|
+
const stub = event && event.response;
|
|
1888
2722
|
const {
|
|
1889
2723
|
responseInit,
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
2724
|
+
nonce,
|
|
2725
|
+
transformChunk
|
|
2726
|
+
} = options;
|
|
2727
|
+
if (typeof result === "string") {
|
|
2728
|
+
if (stub) commitResponseStub(stub);
|
|
2729
|
+
const head = deriveHead(stub, responseInit);
|
|
2730
|
+
if (stub && stub.headers.get("Location")) {
|
|
2731
|
+
return new Response(null, {
|
|
2732
|
+
status: getExpectedRedirectStatus(stub),
|
|
2733
|
+
headers: head.headers
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
if (!head.headers.has("content-type")) {
|
|
2737
|
+
head.headers.set("content-type", "text/html; charset=utf-8");
|
|
2738
|
+
}
|
|
2739
|
+
return new Response(transformChunk ? transformChunk(result) : result, {
|
|
2740
|
+
status: head.status,
|
|
2741
|
+
statusText: head.statusText,
|
|
2742
|
+
headers: head.headers
|
|
2743
|
+
});
|
|
1896
2744
|
}
|
|
1897
|
-
|
|
1898
|
-
return new
|
|
1899
|
-
|
|
1900
|
-
|
|
2745
|
+
const encoder = new TextEncoder();
|
|
2746
|
+
return new Promise(resolve => {
|
|
2747
|
+
let controller;
|
|
2748
|
+
let closed = false;
|
|
2749
|
+
let flushed = false;
|
|
2750
|
+
const enqueue = value => {
|
|
2751
|
+
if (closed || !controller) return;
|
|
2752
|
+
try {
|
|
2753
|
+
controller.enqueue(encoder.encode(value));
|
|
2754
|
+
} catch {
|
|
2755
|
+
closed = true;
|
|
2756
|
+
}
|
|
2757
|
+
};
|
|
2758
|
+
result.pipe({
|
|
2759
|
+
write(chunk) {
|
|
2760
|
+
if (!flushed) {
|
|
2761
|
+
flushed = true;
|
|
2762
|
+
if (stub) commitResponseStub(stub, {
|
|
2763
|
+
allowLateLocation: true
|
|
2764
|
+
});
|
|
2765
|
+
const head = deriveHead(stub, responseInit);
|
|
2766
|
+
if (stub && stub.headers.get("Location")) {
|
|
2767
|
+
closed = true;
|
|
2768
|
+
resolve(new Response(null, {
|
|
2769
|
+
status: getExpectedRedirectStatus(stub),
|
|
2770
|
+
headers: head.headers
|
|
2771
|
+
}));
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
if (!head.headers.has("content-type")) {
|
|
2775
|
+
head.headers.set("content-type", "text/html; charset=utf-8");
|
|
2776
|
+
}
|
|
2777
|
+
resolve(new Response(new ReadableStream({
|
|
2778
|
+
start(c) {
|
|
2779
|
+
controller = c;
|
|
2780
|
+
},
|
|
2781
|
+
cancel() {
|
|
2782
|
+
closed = true;
|
|
2783
|
+
}
|
|
2784
|
+
}), {
|
|
2785
|
+
status: head.status,
|
|
2786
|
+
statusText: head.statusText,
|
|
2787
|
+
headers: head.headers
|
|
2788
|
+
}));
|
|
2789
|
+
}
|
|
2790
|
+
enqueue(transformChunk ? transformChunk(chunk) : chunk);
|
|
2791
|
+
},
|
|
2792
|
+
end() {
|
|
2793
|
+
if (closed || !controller) return;
|
|
2794
|
+
const location = stub && stub.headers.get("Location");
|
|
2795
|
+
if (location) {
|
|
2796
|
+
const attr = nonce ? ` nonce="${escapeAttribute(nonce)}"` : "";
|
|
2797
|
+
enqueue(`<script${attr}>window.location=${JSON.stringify(location).replace(/</g, "\\u003c")}</script>`);
|
|
2798
|
+
}
|
|
2799
|
+
closed = true;
|
|
2800
|
+
try {
|
|
2801
|
+
controller.close();
|
|
2802
|
+
} catch {}
|
|
2803
|
+
}
|
|
2804
|
+
});
|
|
1901
2805
|
});
|
|
1902
2806
|
}
|
|
1903
|
-
function
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2807
|
+
function composeMiddleware(middlewares) {
|
|
2808
|
+
return function run(request, next) {
|
|
2809
|
+
let index = -1;
|
|
2810
|
+
function dispatch(i, req) {
|
|
2811
|
+
if (i <= index) return Promise.reject(new Error("next() called multiple times"));
|
|
2812
|
+
index = i;
|
|
2813
|
+
if (i === middlewares.length) return Promise.resolve(next(req));
|
|
2814
|
+
return Promise.resolve(middlewares[i](req, override => dispatch(i + 1, override || req)));
|
|
2815
|
+
}
|
|
2816
|
+
return dispatch(0, request);
|
|
2817
|
+
};
|
|
1912
2818
|
}
|
|
1913
|
-
function
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
2819
|
+
function registerElementClaim() {
|
|
2820
|
+
return noopCleanup;
|
|
2821
|
+
}
|
|
2822
|
+
function noopCleanup() {}
|
|
2823
|
+
function claimElement(node) {
|
|
2824
|
+
return node;
|
|
2825
|
+
}
|
|
2826
|
+
function claimElementTree(root) {
|
|
2827
|
+
return root;
|
|
2828
|
+
}
|
|
2829
|
+
function notSup() {
|
|
2830
|
+
throw new Error("Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.");
|
|
1923
2831
|
}
|
|
1924
2832
|
|
|
2833
|
+
setContainerTraceResolver(getProjectionTrace);
|
|
1925
2834
|
const isServer = true;
|
|
1926
2835
|
const isDev = false;
|
|
1927
2836
|
function dynamic(source) {
|
|
@@ -1987,18 +2896,39 @@ function clientOnly(_fn, _options = {}, moduleUrl) {
|
|
|
1987
2896
|
return createMemo(() => props.fallback);
|
|
1988
2897
|
};
|
|
1989
2898
|
}
|
|
2899
|
+
const statusLedgers = /* @__PURE__ */new WeakMap();
|
|
2900
|
+
const headerLedgers = /* @__PURE__ */new WeakMap();
|
|
1990
2901
|
function httpStatus(code, text) {
|
|
1991
2902
|
const event = getRequestEvent();
|
|
1992
2903
|
const response = event && event.response;
|
|
1993
2904
|
if (response && !response.committed) {
|
|
1994
|
-
|
|
1995
|
-
|
|
2905
|
+
let ledger = statusLedgers.get(response);
|
|
2906
|
+
if (!ledger) {
|
|
2907
|
+
ledger = {
|
|
2908
|
+
base: {
|
|
2909
|
+
status: response.status,
|
|
2910
|
+
statusText: response.statusText
|
|
2911
|
+
},
|
|
2912
|
+
live: []
|
|
2913
|
+
};
|
|
2914
|
+
statusLedgers.set(response, ledger);
|
|
2915
|
+
}
|
|
2916
|
+
const declaration = {
|
|
2917
|
+
status: code,
|
|
2918
|
+
statusText: text
|
|
2919
|
+
};
|
|
2920
|
+
ledger.live.push(declaration);
|
|
1996
2921
|
response.status = code;
|
|
1997
2922
|
response.statusText = text;
|
|
1998
2923
|
onCleanup(() => {
|
|
1999
2924
|
if (response.committed) return;
|
|
2000
|
-
|
|
2001
|
-
|
|
2925
|
+
const index = ledger.live.indexOf(declaration);
|
|
2926
|
+
if (index < 0) return;
|
|
2927
|
+
ledger.live.splice(index, 1);
|
|
2928
|
+
const effective = ledger.live.length ? ledger.live[ledger.live.length - 1] : ledger.base;
|
|
2929
|
+
response.status = effective.status;
|
|
2930
|
+
response.statusText = effective.statusText;
|
|
2931
|
+
if (!ledger.live.length) statusLedgers.delete(response);
|
|
2002
2932
|
});
|
|
2003
2933
|
}
|
|
2004
2934
|
}
|
|
@@ -2007,13 +2937,41 @@ function httpHeader(name, value, options) {
|
|
|
2007
2937
|
const response = event && event.response;
|
|
2008
2938
|
if (response && !response.committed) {
|
|
2009
2939
|
const headers = response.headers;
|
|
2010
|
-
const
|
|
2011
|
-
|
|
2940
|
+
const key = name.toLowerCase();
|
|
2941
|
+
const setCookie = key === "set-cookie";
|
|
2942
|
+
let ledgers = headerLedgers.get(response);
|
|
2943
|
+
if (!ledgers) headerLedgers.set(response, ledgers = new Map());
|
|
2944
|
+
let ledger = ledgers.get(key);
|
|
2945
|
+
if (!ledger) {
|
|
2946
|
+
ledger = {
|
|
2947
|
+
base: setCookie ? headers.getSetCookie() : headers.get(name),
|
|
2948
|
+
live: []
|
|
2949
|
+
};
|
|
2950
|
+
ledgers.set(key, ledger);
|
|
2951
|
+
}
|
|
2952
|
+
const declaration = {
|
|
2953
|
+
value,
|
|
2954
|
+
append: !!(options && options.append)
|
|
2955
|
+
};
|
|
2956
|
+
ledger.live.push(declaration);
|
|
2957
|
+
if (declaration.append) headers.append(name, value);else headers.set(name, value);
|
|
2012
2958
|
onCleanup(() => {
|
|
2013
2959
|
if (response.committed) return;
|
|
2014
|
-
|
|
2960
|
+
const index = ledger.live.indexOf(declaration);
|
|
2961
|
+
if (index < 0) return;
|
|
2962
|
+
ledger.live.splice(index, 1);
|
|
2963
|
+
headers.delete(name);
|
|
2964
|
+
if (setCookie) {
|
|
2965
|
+
for (const cookie of ledger.base) headers.append(name, cookie);
|
|
2966
|
+
} else if (ledger.base !== null) {
|
|
2967
|
+
headers.set(name, ledger.base);
|
|
2968
|
+
}
|
|
2969
|
+
for (const d of ledger.live) {
|
|
2970
|
+
if (d.append) headers.append(name, d.value);else headers.set(name, d.value);
|
|
2971
|
+
}
|
|
2972
|
+
if (!ledger.live.length) ledgers.delete(key);
|
|
2015
2973
|
});
|
|
2016
2974
|
}
|
|
2017
2975
|
}
|
|
2018
2976
|
|
|
2019
|
-
export {
|
|
2977
|
+
export { ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, REVALIDATE_HEADER, RawTextElements, RequestContext, ResponseEnvelope, SAFE_ERROR, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, claimElementTree, notSup as className, clearFlashCookie, clientOnly, commitEventResponse, commitResponseStub, composeMiddleware, createLiveHoles, createRequestEvent, createResponseStub, createSSRResponse, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, notSup as getDelegatedRoot, getExpectedRedirectStatus, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, getServerFunctionMetadata, getServerFunctionRPC, hasFlashCookie, httpHeader, httpStatus, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isSafeError, isServer, isServerFunction, markSafeError, memo, parseCookieHeader, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, respond, notSup as runHydrationEvents, serializeCookie, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useHead };
|