@solidjs/web 2.0.0-beta.21 → 2.0.0-beta.23
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/dist/dev.cjs +51 -1
- package/dist/dev.js +47 -2
- package/dist/server.cjs +98 -34
- package/dist/server.js +94 -35
- package/dist/web.cjs +51 -1
- package/dist/web.js +47 -2
- package/frames/dist/client.cjs +1442 -0
- package/frames/dist/client.js +1430 -0
- package/frames/dist/server.cjs +1705 -0
- package/frames/dist/server.js +1694 -0
- package/frames/package.json +30 -0
- package/package.json +78 -5
- package/serialization/dist/serialization.cjs +83 -0
- package/serialization/dist/serialization.js +82 -1
- package/serialization/types/index.d.ts +12 -0
- package/serialization/types-cjs/index.d.cts +12 -0
- package/server-functions/dist/client.cjs +114 -59
- package/server-functions/dist/client.js +113 -61
- package/server-functions/dist/server.cjs +54 -10
- package/server-functions/dist/server.js +52 -11
- package/types/client.d.ts +26 -0
- package/types/core.d.ts +2 -1
- package/types/frames/client.d.ts +53 -0
- package/types/frames/frame-client.d.ts +205 -0
- package/types/frames/frame-sink.d.ts +145 -0
- package/types/frames/frame-transport.d.ts +105 -0
- package/types/frames/serializer.d.ts +151 -0
- package/types/frames/server.d.ts +21 -0
- package/types/jsx.d.ts +17 -2
- package/types/response.d.ts +27 -1
- package/types/serializer.d.ts +12 -0
- package/types/server-functions/client.d.ts +40 -5
- package/types/server-functions/server.d.ts +9 -5
- package/types/server-functions/shared.d.ts +29 -0
- package/types/server.d.ts +10 -0
- package/types-cjs/client.d.cts +26 -0
- package/types-cjs/core.d.cts +2 -1
- package/types-cjs/frames/client.d.cts +53 -0
- package/types-cjs/frames/frame-client.d.cts +205 -0
- package/types-cjs/frames/frame-sink.d.cts +145 -0
- package/types-cjs/frames/frame-transport.d.cts +105 -0
- package/types-cjs/frames/serializer.d.cts +151 -0
- package/types-cjs/frames/server.d.cts +21 -0
- package/types-cjs/jsx.d.cts +17 -2
- package/types-cjs/response.d.cts +27 -1
- package/types-cjs/serializer.d.cts +12 -0
- package/types-cjs/server-functions/client.d.cts +40 -5
- package/types-cjs/server-functions/server.d.cts +9 -5
- package/types-cjs/server-functions/shared.d.cts +29 -0
- package/types-cjs/server.d.cts +10 -0
|
@@ -0,0 +1,1705 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var seroval = require('seroval');
|
|
4
|
+
var solidJs = require('solid-js');
|
|
5
|
+
var web = require('seroval-plugins/web');
|
|
6
|
+
|
|
7
|
+
const runWithHydrationScope = (id, fn) => solidJs.runWithOwner(solidJs.createOwner({
|
|
8
|
+
id
|
|
9
|
+
}), fn);
|
|
10
|
+
|
|
11
|
+
const DEFAULT_DISABLED_FEATURES = seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
|
|
12
|
+
const HYDRATION_GLOBAL = "_$HY.r";
|
|
13
|
+
const DEFAULT_WEB_PLUGINS = Object.freeze([web.AbortSignalPlugin,
|
|
14
|
+
web.CustomEventPlugin, web.DOMExceptionPlugin, web.EventPlugin,
|
|
15
|
+
web.FormDataPlugin, web.HeadersPlugin, web.ReadableStreamPlugin, web.RequestPlugin, web.ResponsePlugin, web.URLSearchParamsPlugin, web.URLPlugin]);
|
|
16
|
+
function resolveSerializerPlugins(customPlugins) {
|
|
17
|
+
return customPlugins ? [...customPlugins, ...DEFAULT_WEB_PLUGINS] : [...DEFAULT_WEB_PLUGINS];
|
|
18
|
+
}
|
|
19
|
+
function createSerializer(options) {
|
|
20
|
+
return new seroval.Serializer({
|
|
21
|
+
...options,
|
|
22
|
+
plugins: resolveSerializerPlugins(options.plugins),
|
|
23
|
+
disabledFeatures: options.disabledFeatures === undefined ? DEFAULT_DISABLED_FEATURES : options.disabledFeatures
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function createHydrationSerializer({
|
|
27
|
+
onData,
|
|
28
|
+
onDone,
|
|
29
|
+
scopeId,
|
|
30
|
+
onError,
|
|
31
|
+
plugins
|
|
32
|
+
}) {
|
|
33
|
+
return createSerializer({
|
|
34
|
+
scopeId,
|
|
35
|
+
plugins,
|
|
36
|
+
globalIdentifier: HYDRATION_GLOBAL,
|
|
37
|
+
onData,
|
|
38
|
+
onDone,
|
|
39
|
+
onError
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function getLocalHeaderScript(id) {
|
|
43
|
+
return seroval.getCrossReferenceHeader(id) + ";";
|
|
44
|
+
}
|
|
45
|
+
const JSON_CODEC_DISABLED_FEATURES = seroval.Feature.RegExp;
|
|
46
|
+
const JSON_CODEC_DEPTH_LIMIT = 64;
|
|
47
|
+
function resolveCodecOptions({
|
|
48
|
+
plugins,
|
|
49
|
+
disabledFeatures,
|
|
50
|
+
depthLimit
|
|
51
|
+
} = {}) {
|
|
52
|
+
return {
|
|
53
|
+
plugins: resolveSerializerPlugins(plugins),
|
|
54
|
+
disabledFeatures: disabledFeatures === undefined ? JSON_CODEC_DISABLED_FEATURES : disabledFeatures,
|
|
55
|
+
depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function createJSONSerializer({
|
|
59
|
+
onData,
|
|
60
|
+
onDone,
|
|
61
|
+
onError,
|
|
62
|
+
plugins,
|
|
63
|
+
disabledFeatures,
|
|
64
|
+
depthLimit
|
|
65
|
+
}) {
|
|
66
|
+
const resolved = resolveCodecOptions({
|
|
67
|
+
plugins,
|
|
68
|
+
disabledFeatures,
|
|
69
|
+
depthLimit
|
|
70
|
+
});
|
|
71
|
+
const refs = new Map();
|
|
72
|
+
const cancels = new Set();
|
|
73
|
+
let pendingWrites = 0;
|
|
74
|
+
let flushed = false;
|
|
75
|
+
let done = false;
|
|
76
|
+
const maybeDone = () => {
|
|
77
|
+
if (flushed && pendingWrites === 0 && !done) {
|
|
78
|
+
done = true;
|
|
79
|
+
onDone && onDone();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
write(key, value) {
|
|
84
|
+
if (flushed) return;
|
|
85
|
+
pendingWrites++;
|
|
86
|
+
let settled = false;
|
|
87
|
+
let cancel = null;
|
|
88
|
+
const stream = seroval.toCrossJSONStream(value, {
|
|
89
|
+
refs,
|
|
90
|
+
plugins: resolved.plugins,
|
|
91
|
+
disabledFeatures: resolved.disabledFeatures,
|
|
92
|
+
onParse(node, initial) {
|
|
93
|
+
onData({
|
|
94
|
+
key,
|
|
95
|
+
node,
|
|
96
|
+
initial
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
onError,
|
|
100
|
+
onDone() {
|
|
101
|
+
settled = true;
|
|
102
|
+
if (cancel) cancels.delete(cancel);
|
|
103
|
+
pendingWrites--;
|
|
104
|
+
maybeDone();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
if (!settled) {
|
|
108
|
+
cancel = stream;
|
|
109
|
+
cancels.add(cancel);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
flush() {
|
|
113
|
+
flushed = true;
|
|
114
|
+
maybeDone();
|
|
115
|
+
},
|
|
116
|
+
close() {
|
|
117
|
+
flushed = true;
|
|
118
|
+
for (const cancel of cancels) cancel();
|
|
119
|
+
cancels.clear();
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function joinAssetPath(base, file) {
|
|
125
|
+
if (/^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(file)) return file;
|
|
126
|
+
if (typeof base !== "string" || !base) base = "/";
|
|
127
|
+
if (base[base.length - 1] !== "/") base += "/";
|
|
128
|
+
return base + (file[0] === "/" ? file.slice(1) : file);
|
|
129
|
+
}
|
|
130
|
+
function resolveAssets(moduleUrl, manifest) {
|
|
131
|
+
if (!manifest) return null;
|
|
132
|
+
const base = manifest._base;
|
|
133
|
+
const entry = manifest[moduleUrl];
|
|
134
|
+
if (!entry) return null;
|
|
135
|
+
const css = [];
|
|
136
|
+
const js = [];
|
|
137
|
+
const visited = new Set();
|
|
138
|
+
const walk = key => {
|
|
139
|
+
if (visited.has(key)) return;
|
|
140
|
+
visited.add(key);
|
|
141
|
+
const e = manifest[key];
|
|
142
|
+
if (!e) return;
|
|
143
|
+
js.push(joinAssetPath(base, e.file));
|
|
144
|
+
if (e.css) for (let i = 0; i < e.css.length; i++) css.push(joinAssetPath(base, e.css[i]));
|
|
145
|
+
if (e.imports) for (let i = 0; i < e.imports.length; i++) walk(e.imports[i]);
|
|
146
|
+
};
|
|
147
|
+
walk(moduleUrl);
|
|
148
|
+
return {
|
|
149
|
+
js,
|
|
150
|
+
css
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function registerEntryAssets(manifest) {
|
|
154
|
+
if (!manifest || typeof manifest === "function" || typeof manifest.resolve === "function") return;
|
|
155
|
+
const ctx = solidJs.sharedConfig.context;
|
|
156
|
+
if (!ctx?.registerAsset) return;
|
|
157
|
+
for (const key in manifest) {
|
|
158
|
+
if (manifest[key].isEntry) {
|
|
159
|
+
const assets = resolveAssets(key, manifest);
|
|
160
|
+
if (assets) {
|
|
161
|
+
for (let i = 0; i < assets.css.length; i++) ctx.registerAsset("style", assets.css[i]);
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function createAssetTracking() {
|
|
168
|
+
const boundaryModules = new Map();
|
|
169
|
+
const boundaryStyles = new Map();
|
|
170
|
+
const emittedAssets = new Set();
|
|
171
|
+
const inlineStyles = new Map();
|
|
172
|
+
let currentBoundaryId = null;
|
|
173
|
+
return {
|
|
174
|
+
boundaryModules,
|
|
175
|
+
boundaryStyles,
|
|
176
|
+
emittedAssets,
|
|
177
|
+
inlineStyles,
|
|
178
|
+
registerInlineStyle(desc) {
|
|
179
|
+
let entry = inlineStyles.get(desc.id);
|
|
180
|
+
if (!entry) {
|
|
181
|
+
entry = {
|
|
182
|
+
id: desc.id,
|
|
183
|
+
content: desc.content || "",
|
|
184
|
+
attrs: desc.attrs,
|
|
185
|
+
emitted: false
|
|
186
|
+
};
|
|
187
|
+
inlineStyles.set(desc.id, entry);
|
|
188
|
+
}
|
|
189
|
+
if (currentBoundaryId) {
|
|
190
|
+
let styles = boundaryStyles.get(currentBoundaryId);
|
|
191
|
+
if (!styles) {
|
|
192
|
+
styles = new Set();
|
|
193
|
+
boundaryStyles.set(currentBoundaryId, styles);
|
|
194
|
+
}
|
|
195
|
+
styles.add(entry);
|
|
196
|
+
}
|
|
197
|
+
return entry;
|
|
198
|
+
},
|
|
199
|
+
get currentBoundaryId() {
|
|
200
|
+
return currentBoundaryId;
|
|
201
|
+
},
|
|
202
|
+
set currentBoundaryId(v) {
|
|
203
|
+
currentBoundaryId = v;
|
|
204
|
+
},
|
|
205
|
+
registerModule(key, entryUrl) {
|
|
206
|
+
const id = currentBoundaryId || "";
|
|
207
|
+
let map = boundaryModules.get(id);
|
|
208
|
+
if (!map) {
|
|
209
|
+
map = {};
|
|
210
|
+
boundaryModules.set(id, map);
|
|
211
|
+
}
|
|
212
|
+
map[key] = entryUrl;
|
|
213
|
+
},
|
|
214
|
+
getBoundaryModules(id) {
|
|
215
|
+
return boundaryModules.get(id) || null;
|
|
216
|
+
},
|
|
217
|
+
getBoundaryStyles(id) {
|
|
218
|
+
return boundaryStyles.get(id) || null;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function applyAssetTracking(context, tracking, manifest) {
|
|
223
|
+
Object.defineProperty(context, "_currentBoundaryId", {
|
|
224
|
+
get() {
|
|
225
|
+
return tracking.currentBoundaryId;
|
|
226
|
+
},
|
|
227
|
+
set(v) {
|
|
228
|
+
tracking.currentBoundaryId = v;
|
|
229
|
+
},
|
|
230
|
+
configurable: true,
|
|
231
|
+
enumerable: true
|
|
232
|
+
});
|
|
233
|
+
context.registerModule = tracking.registerModule;
|
|
234
|
+
context.getBoundaryModules = tracking.getBoundaryModules;
|
|
235
|
+
if (typeof manifest === "function") {
|
|
236
|
+
context.resolveAssets = manifest;
|
|
237
|
+
} else if (manifest && typeof manifest.resolve === "function") {
|
|
238
|
+
context.resolveAssets = key => manifest.resolve(key);
|
|
239
|
+
if (typeof manifest.resolveSync === "function") {
|
|
240
|
+
context.resolveAssetsSync = key => manifest.resolveSync(key);
|
|
241
|
+
}
|
|
242
|
+
} else if (manifest) {
|
|
243
|
+
const resolve = moduleUrl => resolveAssets(moduleUrl, manifest);
|
|
244
|
+
context.resolveAssets = resolve;
|
|
245
|
+
context.resolveAssetsSync = resolve;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const REPLACE_SCRIPT = `function $df(e,n,o,t){if(!(n=document.getElementById(e)))return 0;if(!(o=document.getElementById("pl-"+e)))return(_$HY.dq=_$HY.dq||{})[e]=1,0;for(;o&&(8!==o.nodeType||o.nodeValue!=="pl-"+e);)t=o.nextSibling,o.remove(),o=t;_$HY.done?o.remove():o.replaceWith(n.content),n.remove(),_$HY.fe(e),$dfd();return 1}function $dfl(e,o,n){if(!(o=document.getElementById("pl-"+e)))return(_$HY.dlq=_$HY.dlq||{})[e]=1,0;if(o._$fl)return 1;for(n=o.nextSibling;n;){if(8===n.nodeType&&n.nodeValue==="pl-"+e){o.parentNode&&o.parentNode.insertBefore(o.content.cloneNode(!0),n),o._$fl=1,$dfd();return 1}n=n.nextSibling}return 0}function $dflj(e,i){for(i=0;i<e.length;i++)$dfl(e[i])}function $dfd(e,i){if(e=_$HY.dq){_$HY.dq=0;for(i in e)$df(i)}if(e=_$HY.dlq){_$HY.dlq=0;for(i in e)$dfl(i)}}function $dfs(e,c,d){(_$HY.sc=_$HY.sc||{})[e]=c,d&&((_$HY.sd=_$HY.sd||{})[e]=1)}function $dfg(e,g,i,k){if(!(g=_$HY.sg&&_$HY.sg[e]))return;for(i=0;i<g.length;i++)if(_$HY.sc&&_$HY.sc[g[i]]>0)return;for(i=0;i<g.length;i++)k=g[i],delete _$HY.sg[k],$df(k)}function $dfc(e){if(--_$HY.sc[e]<=0){delete _$HY.sc[e],_$HY.sg&&_$HY.sg[e]?$dfg(e):!(_$HY.sd&&_$HY.sd[e])&&$df(e);_$HY.sd&&delete _$HY.sd[e]}}function $dfj(e,i,n){for(i=0;i<e.length;i++)if(_$HY.sc&&_$HY.sc[e[i]]>0){for(n=0;n<e.length;n++)(_$HY.sg=_$HY.sg||{})[e[n]]=e;return}for(i=0;i<e.length;i++)$df(e[i])}`;
|
|
249
|
+
function renderToStream(code, options = {}) {
|
|
250
|
+
let {
|
|
251
|
+
nonce,
|
|
252
|
+
onCompleteShell,
|
|
253
|
+
onCompleteAll,
|
|
254
|
+
renderId = "",
|
|
255
|
+
noScripts,
|
|
256
|
+
manifest
|
|
257
|
+
} = options;
|
|
258
|
+
let dispose;
|
|
259
|
+
const blockingPromises = new Set();
|
|
260
|
+
let headerEmitted = false;
|
|
261
|
+
const pushTask = task => {
|
|
262
|
+
if (noScripts) return;
|
|
263
|
+
if (!headerEmitted) {
|
|
264
|
+
headerEmitted = true;
|
|
265
|
+
tasks += getLocalHeaderScript(renderId);
|
|
266
|
+
}
|
|
267
|
+
tasks += task + ";";
|
|
268
|
+
if (!timer && firstFlushed) {
|
|
269
|
+
timer = setTimeout(writeTasks);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
const onDone = () => {
|
|
273
|
+
writeTasks();
|
|
274
|
+
doShell();
|
|
275
|
+
onCompleteAll && onCompleteAll({
|
|
276
|
+
write(v) {
|
|
277
|
+
!completed && buffer.write(v);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
writable && writable.end();
|
|
281
|
+
completed = true;
|
|
282
|
+
if (firstFlushed) dispose();
|
|
283
|
+
};
|
|
284
|
+
const sink = {
|
|
285
|
+
data(payload) {
|
|
286
|
+
pushTask(payload);
|
|
287
|
+
},
|
|
288
|
+
fragment(key, value, meta) {
|
|
289
|
+
const deferActivation = !!meta.revealGroup;
|
|
290
|
+
const styles = meta.styles;
|
|
291
|
+
for (let i = 0; i < styles.inline.length; i++) {
|
|
292
|
+
buffer.write(renderInlineStyle(styles.inline[i], nonce));
|
|
293
|
+
}
|
|
294
|
+
if (styles.links.length) {
|
|
295
|
+
emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
|
|
296
|
+
writeTasks();
|
|
297
|
+
for (const url of styles.links) {
|
|
298
|
+
buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
|
|
299
|
+
}
|
|
300
|
+
buffer.write(`<template id="${key}">${value}</template>`);
|
|
301
|
+
} else {
|
|
302
|
+
buffer.write(`<template id="${key}">${value}</template>`);
|
|
303
|
+
if (!deferActivation) {
|
|
304
|
+
emitTask(`$df("${key}")`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
reveal(keys, meta) {
|
|
309
|
+
emitTask(`${meta.fallback ? "$dflj" : "$dfj"}(${JSON.stringify(keys)})`);
|
|
310
|
+
},
|
|
311
|
+
asset(type, value) {
|
|
312
|
+
if (type === "module") {
|
|
313
|
+
buffer.write(`<link rel="modulepreload" href="${value}">`);
|
|
314
|
+
} else if (type === "inline-style") {
|
|
315
|
+
buffer.write(renderInlineStyle(value, nonce));
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
shell(shellHtml, meta) {
|
|
319
|
+
shellHtml = injectBeforeHead(shellHtml, meta.assets);
|
|
320
|
+
shellHtml = injectPreloadLinks(meta.preloads, shellHtml);
|
|
321
|
+
shellHtml = injectInlineStyles(meta.inlineStyles, shellHtml, nonce);
|
|
322
|
+
if (meta.tasks.length) shellHtml = injectScripts(shellHtml, meta.tasks, nonce);
|
|
323
|
+
buffer.write(shellHtml);
|
|
324
|
+
},
|
|
325
|
+
...options.sink
|
|
326
|
+
};
|
|
327
|
+
const serializer = (options.serializer || createHydrationSerializer)({
|
|
328
|
+
scopeId: options.renderId,
|
|
329
|
+
plugins: options.plugins,
|
|
330
|
+
onData: payload => sink.data(payload),
|
|
331
|
+
onDone,
|
|
332
|
+
onError: options.onError
|
|
333
|
+
});
|
|
334
|
+
let rootAssetsSerialized = false;
|
|
335
|
+
const serializeRootAssets = () => {
|
|
336
|
+
if (rootAssetsSerialized) return;
|
|
337
|
+
rootAssetsSerialized = true;
|
|
338
|
+
serializeFragmentAssets("", tracking.boundaryModules, context);
|
|
339
|
+
};
|
|
340
|
+
const flushEnd = () => {
|
|
341
|
+
if (!registry.size) {
|
|
342
|
+
serializeRootAssets();
|
|
343
|
+
queue(() => queue(() => serializer.flush()));
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const registry = new Map();
|
|
347
|
+
const writeTasks = () => {
|
|
348
|
+
if (tasks.length && !completed && firstFlushed) {
|
|
349
|
+
buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks}</script>`);
|
|
350
|
+
tasks = "";
|
|
351
|
+
}
|
|
352
|
+
timer && clearTimeout(timer);
|
|
353
|
+
timer = null;
|
|
354
|
+
};
|
|
355
|
+
let context;
|
|
356
|
+
let writable;
|
|
357
|
+
let tmp = "";
|
|
358
|
+
let tasks = "";
|
|
359
|
+
let firstFlushed = false;
|
|
360
|
+
let completed = false;
|
|
361
|
+
let shellCompleted = false;
|
|
362
|
+
let scriptFlushed = false;
|
|
363
|
+
let headStyles;
|
|
364
|
+
const revealGroups = new Map();
|
|
365
|
+
let timer = null;
|
|
366
|
+
const emitTask = task => {
|
|
367
|
+
pushTask(`${task}${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
|
|
368
|
+
scriptFlushed = true;
|
|
369
|
+
};
|
|
370
|
+
function resolveRevealKeys(groupOrKeys, release, consume) {
|
|
371
|
+
if (Array.isArray(groupOrKeys)) return groupOrKeys.slice();
|
|
372
|
+
let group = revealGroups.get(groupOrKeys);
|
|
373
|
+
if (!group) {
|
|
374
|
+
if (!release) return;
|
|
375
|
+
group = {
|
|
376
|
+
order: [],
|
|
377
|
+
keys: new Set(),
|
|
378
|
+
released: true
|
|
379
|
+
};
|
|
380
|
+
revealGroups.set(groupOrKeys, group);
|
|
381
|
+
} else if (release) group.released = true;
|
|
382
|
+
if (!group.order.length) return;
|
|
383
|
+
const keys = group.order.slice();
|
|
384
|
+
if (consume) revealGroups.delete(groupOrKeys);
|
|
385
|
+
return keys;
|
|
386
|
+
}
|
|
387
|
+
let rootHoles = null;
|
|
388
|
+
let nextHoleId = 0;
|
|
389
|
+
let buffer = {
|
|
390
|
+
write(payload) {
|
|
391
|
+
tmp += payload;
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
const tracking = createAssetTracking();
|
|
395
|
+
solidJs.sharedConfig.context = context = {
|
|
396
|
+
async: true,
|
|
397
|
+
assets: [],
|
|
398
|
+
nonce,
|
|
399
|
+
registerAsset(type, value) {
|
|
400
|
+
if (type === "inline-style") {
|
|
401
|
+
const entry = tracking.registerInlineStyle(value);
|
|
402
|
+
if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
|
|
403
|
+
entry.emitted = true;
|
|
404
|
+
sink.asset("inline-style", entry);
|
|
405
|
+
}
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (tracking.currentBoundaryId && type === "style") {
|
|
409
|
+
let styles = tracking.boundaryStyles.get(tracking.currentBoundaryId);
|
|
410
|
+
if (!styles) {
|
|
411
|
+
styles = new Set();
|
|
412
|
+
tracking.boundaryStyles.set(tracking.currentBoundaryId, styles);
|
|
413
|
+
}
|
|
414
|
+
styles.add(value);
|
|
415
|
+
}
|
|
416
|
+
if (!tracking.emittedAssets.has(value)) {
|
|
417
|
+
tracking.emittedAssets.add(value);
|
|
418
|
+
if (firstFlushed) sink.asset(type, value);
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
block(p) {
|
|
422
|
+
if (!firstFlushed) blockingPromises.add(p);
|
|
423
|
+
},
|
|
424
|
+
replace(id, payloadFn) {
|
|
425
|
+
if (firstFlushed) return;
|
|
426
|
+
const placeholder = `<!--!$${id}-->`;
|
|
427
|
+
const first = html.indexOf(placeholder);
|
|
428
|
+
if (first === -1) return;
|
|
429
|
+
const last = html.indexOf(`<!--!$/${id}-->`, first + placeholder.length);
|
|
430
|
+
html = html.slice(0, first) + resolveSSRSync(escape(payloadFn())) + html.slice(last + placeholder.length + 1);
|
|
431
|
+
},
|
|
432
|
+
serialize(id, p, deferStream) {
|
|
433
|
+
if (solidJs.sharedConfig.context.noHydrate) return;
|
|
434
|
+
if (!firstFlushed && deferStream && typeof p === "object" && "then" in p) {
|
|
435
|
+
blockingPromises.add(p);
|
|
436
|
+
p.then(d => serializer.write(id, d)).catch(e => serializer.write(id, e));
|
|
437
|
+
} else serializer.write(id, p);
|
|
438
|
+
},
|
|
439
|
+
escape: escape,
|
|
440
|
+
resolve: resolveSSRNode,
|
|
441
|
+
ssr: ssr,
|
|
442
|
+
registerFragment(key, options) {
|
|
443
|
+
const revealGroup = options && options.revealGroup;
|
|
444
|
+
if (revealGroup) {
|
|
445
|
+
let group = revealGroups.get(revealGroup);
|
|
446
|
+
if (!group) {
|
|
447
|
+
group = {
|
|
448
|
+
order: [],
|
|
449
|
+
keys: new Set(),
|
|
450
|
+
released: false
|
|
451
|
+
};
|
|
452
|
+
revealGroups.set(revealGroup, group);
|
|
453
|
+
}
|
|
454
|
+
if (!group.keys.has(key)) {
|
|
455
|
+
group.keys.add(key);
|
|
456
|
+
group.order.push(key);
|
|
457
|
+
}
|
|
458
|
+
if (group.released) {
|
|
459
|
+
throw new Error("registerFragment() for reveal group '" + revealGroup + "' was called after revealFragments(). Ensure template payload is emitted before grouped reveal.");
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (!registry.has(key)) {
|
|
463
|
+
let resolve, reject;
|
|
464
|
+
const p = new Promise((r, rej) => (resolve = r, reject = rej));
|
|
465
|
+
registry.set(key, {
|
|
466
|
+
resolve: err => queue(() => queue(() => {
|
|
467
|
+
err ? reject(err) : resolve(true);
|
|
468
|
+
queue(flushEnd);
|
|
469
|
+
}))
|
|
470
|
+
});
|
|
471
|
+
serializer.write(key + "_fr", p);
|
|
472
|
+
}
|
|
473
|
+
return (value, error) => {
|
|
474
|
+
if (registry.has(key)) {
|
|
475
|
+
const item = registry.get(key);
|
|
476
|
+
registry.delete(key);
|
|
477
|
+
if (item.children) {
|
|
478
|
+
for (const k in item.children) {
|
|
479
|
+
value = replacePlaceholder(value, k, item.children[k]);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
const parentKey = waitForFragments(registry, key);
|
|
483
|
+
if (parentKey) {
|
|
484
|
+
const parent = registry.get(parentKey);
|
|
485
|
+
parent.children ||= {};
|
|
486
|
+
parent.children[key] = value !== undefined ? value : "";
|
|
487
|
+
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
488
|
+
propagateBoundaryStyles(key, parentKey, tracking);
|
|
489
|
+
item.resolve();
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
if (!completed) {
|
|
493
|
+
if (!firstFlushed) {
|
|
494
|
+
queue(() => html = replacePlaceholder(html, key, value !== undefined ? value : ""));
|
|
495
|
+
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
496
|
+
item.resolve(error);
|
|
497
|
+
} else {
|
|
498
|
+
serializeFragmentAssets(key, tracking.boundaryModules, context);
|
|
499
|
+
const styles = collectStreamStyles(key, tracking, headStyles);
|
|
500
|
+
sink.fragment(key, value !== undefined ? value : " ", {
|
|
501
|
+
styles,
|
|
502
|
+
revealGroup,
|
|
503
|
+
error
|
|
504
|
+
});
|
|
505
|
+
item.resolve(error);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
return firstFlushed;
|
|
510
|
+
};
|
|
511
|
+
},
|
|
512
|
+
revealFragments(groupOrKeys) {
|
|
513
|
+
const keys = resolveRevealKeys(groupOrKeys, true, true);
|
|
514
|
+
if (!keys) return;
|
|
515
|
+
sink.reveal(keys, {
|
|
516
|
+
fallback: false
|
|
517
|
+
});
|
|
518
|
+
},
|
|
519
|
+
revealFallbacks(groupOrKeys) {
|
|
520
|
+
const keys = resolveRevealKeys(groupOrKeys, false, false);
|
|
521
|
+
if (!keys) return;
|
|
522
|
+
sink.reveal(keys, {
|
|
523
|
+
fallback: true
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
applyAssetTracking(context, tracking, manifest);
|
|
528
|
+
registerEntryAssets(manifest);
|
|
529
|
+
let html = solidJs.createRoot(d => {
|
|
530
|
+
dispose = d;
|
|
531
|
+
const res = resolveSSRNode(escape(code()));
|
|
532
|
+
if (!res.h.length) return res.t[0];
|
|
533
|
+
rootHoles = [];
|
|
534
|
+
let out = res.t[0];
|
|
535
|
+
for (let i = 0; i < res.h.length; i++) {
|
|
536
|
+
const id = nextHoleId++;
|
|
537
|
+
rootHoles.push({
|
|
538
|
+
id,
|
|
539
|
+
fn: res.h[i]
|
|
540
|
+
});
|
|
541
|
+
out += `<!--rh${id}-->` + res.t[i + 1];
|
|
542
|
+
}
|
|
543
|
+
for (const p of res.p) blockingPromises.add(p);
|
|
544
|
+
return out;
|
|
545
|
+
}, {
|
|
546
|
+
id: renderId
|
|
547
|
+
});
|
|
548
|
+
function resolveRootHoles() {
|
|
549
|
+
if (!rootHoles) return true;
|
|
550
|
+
const pending = [];
|
|
551
|
+
for (const {
|
|
552
|
+
id,
|
|
553
|
+
fn
|
|
554
|
+
} of rootHoles) {
|
|
555
|
+
const marker = `<!--rh${id}-->`;
|
|
556
|
+
const res = resolveSSRNode(fn);
|
|
557
|
+
if (!res.h.length) {
|
|
558
|
+
html = html.replace(marker, res.t[0]);
|
|
559
|
+
} else {
|
|
560
|
+
let out = res.t[0];
|
|
561
|
+
for (let j = 0; j < res.h.length; j++) {
|
|
562
|
+
const newId = nextHoleId++;
|
|
563
|
+
pending.push({
|
|
564
|
+
id: newId,
|
|
565
|
+
fn: res.h[j]
|
|
566
|
+
});
|
|
567
|
+
out += `<!--rh${newId}-->` + res.t[j + 1];
|
|
568
|
+
}
|
|
569
|
+
html = html.replace(marker, out);
|
|
570
|
+
for (const p of res.p) blockingPromises.add(p);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
if (pending.length) {
|
|
574
|
+
rootHoles = pending;
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
rootHoles = null;
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
function doShell() {
|
|
581
|
+
if (shellCompleted) return;
|
|
582
|
+
if (!resolveRootHoles()) return;
|
|
583
|
+
solidJs.sharedConfig.context = context;
|
|
584
|
+
const assetsHtml = resolveAssetsHtml(context.assets);
|
|
585
|
+
headStyles = new Set();
|
|
586
|
+
for (const url of tracking.emittedAssets) {
|
|
587
|
+
if (url.endsWith(".css")) headStyles.add(url);
|
|
588
|
+
}
|
|
589
|
+
serializeRootAssets();
|
|
590
|
+
sink.shell(html, {
|
|
591
|
+
assets: assetsHtml,
|
|
592
|
+
preloads: tracking.emittedAssets,
|
|
593
|
+
inlineStyles: tracking.inlineStyles,
|
|
594
|
+
tasks
|
|
595
|
+
});
|
|
596
|
+
tasks = "";
|
|
597
|
+
onCompleteShell && onCompleteShell({
|
|
598
|
+
write(v) {
|
|
599
|
+
!completed && buffer.write(v);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
shellCompleted = true;
|
|
603
|
+
}
|
|
604
|
+
return {
|
|
605
|
+
then(fn) {
|
|
606
|
+
function complete() {
|
|
607
|
+
dispose();
|
|
608
|
+
fn(tmp);
|
|
609
|
+
}
|
|
610
|
+
if (onCompleteAll) {
|
|
611
|
+
let ogComplete = onCompleteAll;
|
|
612
|
+
onCompleteAll = options => {
|
|
613
|
+
ogComplete(options);
|
|
614
|
+
complete();
|
|
615
|
+
};
|
|
616
|
+
} else onCompleteAll = complete;
|
|
617
|
+
function flush() {
|
|
618
|
+
allSettled(blockingPromises).then(() => {
|
|
619
|
+
setTimeout(() => {
|
|
620
|
+
if (!resolveRootHoles()) return flush();
|
|
621
|
+
queue(flushEnd);
|
|
622
|
+
});
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
flush();
|
|
626
|
+
},
|
|
627
|
+
pipe(w) {
|
|
628
|
+
function flush() {
|
|
629
|
+
allSettled(blockingPromises).then(() => {
|
|
630
|
+
setTimeout(() => {
|
|
631
|
+
doShell();
|
|
632
|
+
if (!shellCompleted) return flush();
|
|
633
|
+
buffer = writable = w;
|
|
634
|
+
buffer.write(tmp);
|
|
635
|
+
firstFlushed = true;
|
|
636
|
+
if (completed) {
|
|
637
|
+
dispose();
|
|
638
|
+
writable.end();
|
|
639
|
+
} else flushEnd();
|
|
640
|
+
});
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
flush();
|
|
644
|
+
},
|
|
645
|
+
pipeTo(w) {
|
|
646
|
+
let resolve;
|
|
647
|
+
const p = new Promise(r => resolve = r);
|
|
648
|
+
function flush() {
|
|
649
|
+
allSettled(blockingPromises).then(() => {
|
|
650
|
+
setTimeout(() => {
|
|
651
|
+
doShell();
|
|
652
|
+
if (!shellCompleted) return flush();
|
|
653
|
+
const encoder = new TextEncoder();
|
|
654
|
+
const writer = w.getWriter();
|
|
655
|
+
writable = {
|
|
656
|
+
end() {
|
|
657
|
+
writer.releaseLock();
|
|
658
|
+
w.close().catch(() => {});
|
|
659
|
+
resolve();
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
buffer = {
|
|
663
|
+
write(payload) {
|
|
664
|
+
writer.write(encoder.encode(payload)).catch(() => {});
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
buffer.write(tmp);
|
|
668
|
+
firstFlushed = true;
|
|
669
|
+
if (completed) {
|
|
670
|
+
dispose();
|
|
671
|
+
writable.end();
|
|
672
|
+
} else flushEnd();
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
flush();
|
|
677
|
+
return p;
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
function buildAsyncWrap(err, node) {
|
|
682
|
+
const p = solidJs.ssrHandleError(err);
|
|
683
|
+
if (!p) return null;
|
|
684
|
+
const owner = solidJs.getOwner();
|
|
685
|
+
return {
|
|
686
|
+
fn: owner ? () => solidJs.runWithOwner(owner, node) : node,
|
|
687
|
+
p
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function ssrFirstGroupHit(hole) {
|
|
691
|
+
try {
|
|
692
|
+
return hole();
|
|
693
|
+
} catch (err) {
|
|
694
|
+
return buildAsyncWrap(err, hole);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
function tryResolveFunctionHole(hole) {
|
|
698
|
+
let value;
|
|
699
|
+
try {
|
|
700
|
+
value = hole();
|
|
701
|
+
} catch (err) {
|
|
702
|
+
return buildAsyncWrap(err, hole) || "";
|
|
703
|
+
}
|
|
704
|
+
const t = typeof value;
|
|
705
|
+
if (t === "string") return value;
|
|
706
|
+
if (t === "number") return "" + value;
|
|
707
|
+
if (value == null || t === "boolean") return "";
|
|
708
|
+
return tryResolveString(value);
|
|
709
|
+
}
|
|
710
|
+
function mergeTemplateInto(result, node) {
|
|
711
|
+
result.t[result.t.length - 1] += node.t[0];
|
|
712
|
+
if (node.t.length > 1) {
|
|
713
|
+
result.t.push(...node.t.slice(1));
|
|
714
|
+
result.h.push(...node.h);
|
|
715
|
+
result.p.push(...node.p);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
function appendResolvedNode(result, node) {
|
|
719
|
+
if (node.fn !== undefined) {
|
|
720
|
+
result.h.push(node.fn);
|
|
721
|
+
result.p.push(node.p);
|
|
722
|
+
result.t.push("");
|
|
723
|
+
} else if (node.merge !== undefined) mergeTemplateInto(result, node.merge);else resolveSSRNode(node.bail, result);
|
|
724
|
+
}
|
|
725
|
+
let _lastGroupFn = null;
|
|
726
|
+
let _lastGroupArr = null;
|
|
727
|
+
let _lastGroupErr = null;
|
|
728
|
+
function ssrGroupSlot(fn, idx) {
|
|
729
|
+
return () => {
|
|
730
|
+
if (idx > 0 && _lastGroupFn === fn) {
|
|
731
|
+
if (_lastGroupArr !== null) return _lastGroupArr[idx];
|
|
732
|
+
throw _lastGroupErr;
|
|
733
|
+
}
|
|
734
|
+
_lastGroupFn = fn;
|
|
735
|
+
_lastGroupArr = null;
|
|
736
|
+
_lastGroupErr = null;
|
|
737
|
+
try {
|
|
738
|
+
_lastGroupArr = fn();
|
|
739
|
+
return _lastGroupArr[idx];
|
|
740
|
+
} catch (err) {
|
|
741
|
+
_lastGroupErr = err;
|
|
742
|
+
throw err;
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function ssr(t) {
|
|
747
|
+
const len = arguments.length;
|
|
748
|
+
if (len === 1) return {
|
|
749
|
+
t
|
|
750
|
+
};
|
|
751
|
+
let s = t[0];
|
|
752
|
+
let result = null;
|
|
753
|
+
let lastGroup = null;
|
|
754
|
+
let lastGroupVal = null;
|
|
755
|
+
let lastGroupIdx = 0;
|
|
756
|
+
for (let i = 1; i < len; i++) {
|
|
757
|
+
const hole = arguments[i];
|
|
758
|
+
const ht = typeof hole;
|
|
759
|
+
if (ht === "string") {
|
|
760
|
+
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
761
|
+
} else if (ht === "number") {
|
|
762
|
+
if (result === null) s += hole;else result.t[result.t.length - 1] += hole;
|
|
763
|
+
} else if (hole == null || ht === "boolean") ; else if (ht === "function" && hole.$g) {
|
|
764
|
+
let value;
|
|
765
|
+
let hasValue = false;
|
|
766
|
+
if (lastGroup !== hole) {
|
|
767
|
+
const r = ssrFirstGroupHit(hole);
|
|
768
|
+
if (r !== null) {
|
|
769
|
+
lastGroup = hole;
|
|
770
|
+
lastGroupVal = r;
|
|
771
|
+
lastGroupIdx = 0;
|
|
772
|
+
if (!Array.isArray(r) && result === null) {
|
|
773
|
+
result = {
|
|
774
|
+
t: [s],
|
|
775
|
+
h: [],
|
|
776
|
+
p: []
|
|
777
|
+
};
|
|
778
|
+
s = "";
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (lastGroup === hole) {
|
|
783
|
+
if (Array.isArray(lastGroupVal)) {
|
|
784
|
+
value = lastGroupVal[lastGroupIdx++];
|
|
785
|
+
hasValue = true;
|
|
786
|
+
} else {
|
|
787
|
+
result.h.push(ssrGroupSlot(lastGroupVal.fn, lastGroupIdx++));
|
|
788
|
+
result.p.push(lastGroupVal.p);
|
|
789
|
+
result.t.push("");
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (hasValue) {
|
|
793
|
+
const vt = typeof value;
|
|
794
|
+
if (vt === "string" || vt === "number") {
|
|
795
|
+
if (result === null) s += value;else result.t[result.t.length - 1] += value;
|
|
796
|
+
} else if (value == null || vt === "boolean") ; else if (result !== null) {
|
|
797
|
+
resolveSSRNode(value, result);
|
|
798
|
+
} else {
|
|
799
|
+
const rs = tryResolveString(value);
|
|
800
|
+
if (typeof rs === "string") {
|
|
801
|
+
s += rs;
|
|
802
|
+
} else {
|
|
803
|
+
result = {
|
|
804
|
+
t: [s],
|
|
805
|
+
h: [],
|
|
806
|
+
p: []
|
|
807
|
+
};
|
|
808
|
+
s = "";
|
|
809
|
+
if (rs.merge !== undefined) mergeTemplateInto(result, rs.merge);else resolveSSRNode(rs.bail, result);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
} else if (result !== null) {
|
|
814
|
+
resolveSSRNode(hole, result);
|
|
815
|
+
} else if (ht === "function") {
|
|
816
|
+
const r = tryResolveFunctionHole(hole);
|
|
817
|
+
if (typeof r === "string") s += r;else {
|
|
818
|
+
result = {
|
|
819
|
+
t: [s],
|
|
820
|
+
h: [],
|
|
821
|
+
p: []
|
|
822
|
+
};
|
|
823
|
+
s = "";
|
|
824
|
+
appendResolvedNode(result, r);
|
|
825
|
+
}
|
|
826
|
+
} else {
|
|
827
|
+
const r = tryResolveString(hole);
|
|
828
|
+
if (typeof r === "string") {
|
|
829
|
+
s += r;
|
|
830
|
+
} else {
|
|
831
|
+
result = {
|
|
832
|
+
t: [s],
|
|
833
|
+
h: [],
|
|
834
|
+
p: []
|
|
835
|
+
};
|
|
836
|
+
s = "";
|
|
837
|
+
appendResolvedNode(result, r);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
const next = t[i];
|
|
841
|
+
if (result === null) s += next;else result.t[result.t.length - 1] += next;
|
|
842
|
+
}
|
|
843
|
+
if (result === null) return {
|
|
844
|
+
t: s
|
|
845
|
+
};
|
|
846
|
+
return result;
|
|
847
|
+
}
|
|
848
|
+
function escape(s, attr) {
|
|
849
|
+
const t = typeof s;
|
|
850
|
+
if (t !== "string") {
|
|
851
|
+
if (!attr && Array.isArray(s)) {
|
|
852
|
+
const joined = tryJoinPlainSSRArray(s);
|
|
853
|
+
if (joined !== undefined) return joined;
|
|
854
|
+
s = s.slice();
|
|
855
|
+
for (let i = 0; i < s.length; i++) s[i] = escape(s[i]);
|
|
856
|
+
return s;
|
|
857
|
+
}
|
|
858
|
+
if (attr) {
|
|
859
|
+
if (s == null || t === "boolean" || t === "number") return s;
|
|
860
|
+
return escape(String(s), attr);
|
|
861
|
+
}
|
|
862
|
+
return s;
|
|
863
|
+
}
|
|
864
|
+
const delimCode = attr ? 34 : 60;
|
|
865
|
+
const len = s.length;
|
|
866
|
+
for (let i = 0; i < len; i++) {
|
|
867
|
+
const c = s.charCodeAt(i);
|
|
868
|
+
if (c === 38 || c === delimCode) return escapeSlow(s, attr, i);
|
|
869
|
+
}
|
|
870
|
+
return s;
|
|
871
|
+
}
|
|
872
|
+
function escapeSlow(s, attr, start) {
|
|
873
|
+
const delim = attr ? '"' : "<";
|
|
874
|
+
const delimCode = attr ? 34 : 60;
|
|
875
|
+
const escDelim = attr ? """ : "<";
|
|
876
|
+
const c0 = s.charCodeAt(start);
|
|
877
|
+
let iDelim = c0 === delimCode ? start : s.indexOf(delim, start);
|
|
878
|
+
let iAmp = c0 === 38 ? start : s.indexOf("&", start);
|
|
879
|
+
let left = 0,
|
|
880
|
+
out = "";
|
|
881
|
+
while (iDelim >= 0 && iAmp >= 0) {
|
|
882
|
+
if (iDelim < iAmp) {
|
|
883
|
+
if (left < iDelim) out += s.substring(left, iDelim);
|
|
884
|
+
out += escDelim;
|
|
885
|
+
left = iDelim + 1;
|
|
886
|
+
iDelim = s.indexOf(delim, left);
|
|
887
|
+
} else {
|
|
888
|
+
if (left < iAmp) out += s.substring(left, iAmp);
|
|
889
|
+
out += "&";
|
|
890
|
+
left = iAmp + 1;
|
|
891
|
+
iAmp = s.indexOf("&", left);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
if (iDelim >= 0) {
|
|
895
|
+
do {
|
|
896
|
+
if (left < iDelim) out += s.substring(left, iDelim);
|
|
897
|
+
out += escDelim;
|
|
898
|
+
left = iDelim + 1;
|
|
899
|
+
iDelim = s.indexOf(delim, left);
|
|
900
|
+
} while (iDelim >= 0);
|
|
901
|
+
} else while (iAmp >= 0) {
|
|
902
|
+
if (left < iAmp) out += s.substring(left, iAmp);
|
|
903
|
+
out += "&";
|
|
904
|
+
left = iAmp + 1;
|
|
905
|
+
iAmp = s.indexOf("&", left);
|
|
906
|
+
}
|
|
907
|
+
return left < s.length ? out + s.substring(left) : out;
|
|
908
|
+
}
|
|
909
|
+
function tryJoinPlainSSRArray(nodes) {
|
|
910
|
+
if (nodes.length === 0) return undefined;
|
|
911
|
+
let out = "";
|
|
912
|
+
for (let i = 0, len = nodes.length; i < len; i++) {
|
|
913
|
+
const node = nodes[i];
|
|
914
|
+
if (node == null || typeof node !== "object" || node.h || typeof node.t !== "string") {
|
|
915
|
+
return undefined;
|
|
916
|
+
}
|
|
917
|
+
out += node.t;
|
|
918
|
+
}
|
|
919
|
+
return out;
|
|
920
|
+
}
|
|
921
|
+
function queue(fn) {
|
|
922
|
+
return Promise.resolve().then(fn);
|
|
923
|
+
}
|
|
924
|
+
function allSettled(promises) {
|
|
925
|
+
let size = promises.size;
|
|
926
|
+
return Promise.allSettled(promises).then(() => {
|
|
927
|
+
if (promises.size !== size) return allSettled(promises);
|
|
928
|
+
return;
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
function resolveAssetsHtml(assets) {
|
|
932
|
+
if (!assets || !assets.length) return "";
|
|
933
|
+
let out = "";
|
|
934
|
+
for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
|
|
935
|
+
return out;
|
|
936
|
+
}
|
|
937
|
+
function injectBeforeHead(html, content) {
|
|
938
|
+
if (!content) return html;
|
|
939
|
+
const index = html.indexOf("</head>");
|
|
940
|
+
if (index === -1) return html;
|
|
941
|
+
return html.slice(0, index) + content + html.slice(index);
|
|
942
|
+
}
|
|
943
|
+
function injectPreloadLinks(emittedAssets, html, nonce) {
|
|
944
|
+
if (!emittedAssets.size) return html;
|
|
945
|
+
let links = "";
|
|
946
|
+
for (const url of emittedAssets) {
|
|
947
|
+
if (url.endsWith(".css")) {
|
|
948
|
+
links += `<link rel="stylesheet" href="${url}">`;
|
|
949
|
+
} else {
|
|
950
|
+
links += `<link rel="modulepreload" href="${url}">`;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
const index = html.indexOf("</head>");
|
|
954
|
+
if (index === -1) return html;
|
|
955
|
+
return html.slice(0, index) + links + html.slice(index);
|
|
956
|
+
}
|
|
957
|
+
function serializeFragmentAssets(key, boundaryModules, context) {
|
|
958
|
+
const map = boundaryModules.get(key);
|
|
959
|
+
if (!map || !Object.keys(map).length) return;
|
|
960
|
+
context.serialize(key + "_assets", map);
|
|
961
|
+
}
|
|
962
|
+
function propagateBoundaryStyles(childKey, parentKey, tracking) {
|
|
963
|
+
const childStyles = tracking.getBoundaryStyles(childKey);
|
|
964
|
+
if (!childStyles) return;
|
|
965
|
+
let parentStyles = tracking.boundaryStyles.get(parentKey);
|
|
966
|
+
if (!parentStyles) {
|
|
967
|
+
parentStyles = new Set();
|
|
968
|
+
tracking.boundaryStyles.set(parentKey, parentStyles);
|
|
969
|
+
}
|
|
970
|
+
for (const url of childStyles) {
|
|
971
|
+
parentStyles.add(url);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
function collectStreamStyles(key, tracking, headStyles) {
|
|
975
|
+
const styles = tracking.getBoundaryStyles(key);
|
|
976
|
+
const links = [];
|
|
977
|
+
const inline = [];
|
|
978
|
+
if (!styles) return {
|
|
979
|
+
links,
|
|
980
|
+
inline
|
|
981
|
+
};
|
|
982
|
+
for (const entry of styles) {
|
|
983
|
+
if (typeof entry === "string") {
|
|
984
|
+
if (!headStyles || !headStyles.has(entry)) links.push(entry);
|
|
985
|
+
} else if (!entry.emitted) {
|
|
986
|
+
entry.emitted = true;
|
|
987
|
+
inline.push(entry);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
return {
|
|
991
|
+
links,
|
|
992
|
+
inline
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
function escapeStyleContent(content) {
|
|
996
|
+
return content.replace(/<\/(style)/gi, "<\\/$1");
|
|
997
|
+
}
|
|
998
|
+
function renderInlineStyle(entry, nonce) {
|
|
999
|
+
let attrs = "";
|
|
1000
|
+
if (entry.attrs) {
|
|
1001
|
+
for (const name in entry.attrs) {
|
|
1002
|
+
attrs += ` ${name}="${escape(String(entry.attrs[name]), true)}"`;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
return `<style${nonce ? ` nonce="${nonce}"` : ""} data-asset="${escape(entry.id, true)}"${attrs}>${escapeStyleContent(entry.content)}</style>`;
|
|
1006
|
+
}
|
|
1007
|
+
function injectInlineStyles(inlineStyles, html, nonce) {
|
|
1008
|
+
if (!inlineStyles.size) return html;
|
|
1009
|
+
const index = html.indexOf("</head>");
|
|
1010
|
+
if (index === -1) return html;
|
|
1011
|
+
let out = "";
|
|
1012
|
+
for (const entry of inlineStyles.values()) {
|
|
1013
|
+
if (entry.emitted) continue;
|
|
1014
|
+
entry.emitted = true;
|
|
1015
|
+
out += renderInlineStyle(entry, nonce);
|
|
1016
|
+
}
|
|
1017
|
+
return out ? html.slice(0, index) + out + html.slice(index) : html;
|
|
1018
|
+
}
|
|
1019
|
+
function injectScripts(html, scripts, nonce) {
|
|
1020
|
+
const tag = `<script${nonce ? ` nonce="${nonce}"` : ""}>${scripts}</script>`;
|
|
1021
|
+
const index = html.indexOf("<!--xs-->");
|
|
1022
|
+
if (index > -1) {
|
|
1023
|
+
return html.slice(0, index) + tag + html.slice(index);
|
|
1024
|
+
}
|
|
1025
|
+
return html + tag;
|
|
1026
|
+
}
|
|
1027
|
+
function waitForFragments(registry, key) {
|
|
1028
|
+
for (const k of [...registry.keys()].reverse()) {
|
|
1029
|
+
if (key.startsWith(k)) return k;
|
|
1030
|
+
}
|
|
1031
|
+
return false;
|
|
1032
|
+
}
|
|
1033
|
+
function replacePlaceholder(html, key, value) {
|
|
1034
|
+
const marker = `<template id="pl-${key}">`;
|
|
1035
|
+
const close = `<!--pl-${key}-->`;
|
|
1036
|
+
const first = html.indexOf(marker);
|
|
1037
|
+
if (first === -1) return html;
|
|
1038
|
+
const last = html.indexOf(close, first + marker.length);
|
|
1039
|
+
return html.slice(0, first) + value + html.slice(last + close.length);
|
|
1040
|
+
}
|
|
1041
|
+
function tryResolveString(node) {
|
|
1042
|
+
const t = typeof node;
|
|
1043
|
+
if (t === "string") return node;
|
|
1044
|
+
if (t === "number") return "" + node;
|
|
1045
|
+
if (node == null || t === "boolean") return "";
|
|
1046
|
+
if (t === "object") {
|
|
1047
|
+
if (Array.isArray(node)) {
|
|
1048
|
+
const joined = tryJoinPlainSSRArray(node);
|
|
1049
|
+
if (joined !== undefined) return joined;
|
|
1050
|
+
let s = "";
|
|
1051
|
+
let prevNonObj = false;
|
|
1052
|
+
for (let i = 0, len = node.length; i < len; i++) {
|
|
1053
|
+
const item = node[i];
|
|
1054
|
+
const itemNonObj = item !== null && typeof item !== "object";
|
|
1055
|
+
if (prevNonObj && itemNonObj) s += "<!--!$-->";
|
|
1056
|
+
prevNonObj = itemNonObj;
|
|
1057
|
+
const r = tryResolveString(item);
|
|
1058
|
+
if (typeof r !== "string") return {
|
|
1059
|
+
bail: node
|
|
1060
|
+
};
|
|
1061
|
+
s += r;
|
|
1062
|
+
}
|
|
1063
|
+
return s;
|
|
1064
|
+
}
|
|
1065
|
+
if (node.h && node.h.length > 0) return {
|
|
1066
|
+
merge: node
|
|
1067
|
+
};
|
|
1068
|
+
if (node.t === undefined) {
|
|
1069
|
+
console.warn(`Unrecognized value. Skipped inserting`, node);
|
|
1070
|
+
return "";
|
|
1071
|
+
}
|
|
1072
|
+
return Array.isArray(node.t) ? node.t[0] : node.t;
|
|
1073
|
+
}
|
|
1074
|
+
if (t === "function") {
|
|
1075
|
+
let v;
|
|
1076
|
+
try {
|
|
1077
|
+
v = node();
|
|
1078
|
+
} catch (err) {
|
|
1079
|
+
return buildAsyncWrap(err, node) || "";
|
|
1080
|
+
}
|
|
1081
|
+
return tryResolveString(v);
|
|
1082
|
+
}
|
|
1083
|
+
return "";
|
|
1084
|
+
}
|
|
1085
|
+
function resolveSSRNode(node, result = {
|
|
1086
|
+
t: [""],
|
|
1087
|
+
h: [],
|
|
1088
|
+
p: []
|
|
1089
|
+
}, top) {
|
|
1090
|
+
const t = typeof node;
|
|
1091
|
+
if (t === "string" || t === "number") {
|
|
1092
|
+
result.t[result.t.length - 1] += node;
|
|
1093
|
+
} else if (node == null || t === "boolean") ; else if (Array.isArray(node)) {
|
|
1094
|
+
let prevNonObj = false;
|
|
1095
|
+
for (let i = 0, len = node.length; i < len; i++) {
|
|
1096
|
+
const item = node[i];
|
|
1097
|
+
const itemNonObj = item !== null && typeof item !== "object";
|
|
1098
|
+
if (!top && prevNonObj && itemNonObj) result.t[result.t.length - 1] += `<!--!$-->`;
|
|
1099
|
+
prevNonObj = itemNonObj;
|
|
1100
|
+
resolveSSRNode(item, result);
|
|
1101
|
+
}
|
|
1102
|
+
} else if (t === "object") {
|
|
1103
|
+
if (node.h) {
|
|
1104
|
+
result.t[result.t.length - 1] += node.t[0];
|
|
1105
|
+
if (node.t.length > 1) {
|
|
1106
|
+
result.t.push(...node.t.slice(1));
|
|
1107
|
+
result.h.push(...node.h);
|
|
1108
|
+
result.p.push(...node.p);
|
|
1109
|
+
}
|
|
1110
|
+
} else if (node.t !== undefined) {
|
|
1111
|
+
result.t[result.t.length - 1] += node.t;
|
|
1112
|
+
} else console.warn(`Unrecognized value. Skipped inserting`, node);
|
|
1113
|
+
} else if (t === "function") {
|
|
1114
|
+
try {
|
|
1115
|
+
resolveSSRNode(node(), result);
|
|
1116
|
+
} catch (err) {
|
|
1117
|
+
const wrap = buildAsyncWrap(err, node);
|
|
1118
|
+
if (wrap) {
|
|
1119
|
+
result.h.push(wrap.fn);
|
|
1120
|
+
result.p.push(wrap.p);
|
|
1121
|
+
result.t.push("");
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return result;
|
|
1126
|
+
}
|
|
1127
|
+
function resolveSSRSync(node) {
|
|
1128
|
+
const res = resolveSSRNode(node);
|
|
1129
|
+
if (!res.h.length) return res.t[0];
|
|
1130
|
+
throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
function createChunk(data) {
|
|
1134
|
+
const encodeData = new TextEncoder().encode(data);
|
|
1135
|
+
const bytes = encodeData.length;
|
|
1136
|
+
const baseHex = bytes.toString(16);
|
|
1137
|
+
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex;
|
|
1138
|
+
const head = new TextEncoder().encode(`;0x${totalHex};`);
|
|
1139
|
+
const chunk = new Uint8Array(12 + bytes);
|
|
1140
|
+
chunk.set(head);
|
|
1141
|
+
chunk.set(encodeData, 12);
|
|
1142
|
+
return chunk;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
1146
|
+
function isResponseEnvelope(value) {
|
|
1147
|
+
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
const FRAME_STREAM_HEADER = "X-Frame-Stream";
|
|
1151
|
+
function isFrameStreamResponse(response) {
|
|
1152
|
+
return response.headers.has(FRAME_STREAM_HEADER);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
function serverOwned(render) {
|
|
1156
|
+
return solidJs.NoHydration ? solidJs.NoHydration({
|
|
1157
|
+
get children() {
|
|
1158
|
+
return render();
|
|
1159
|
+
}
|
|
1160
|
+
}) : render();
|
|
1161
|
+
}
|
|
1162
|
+
function createFrameSink(emit, frame) {
|
|
1163
|
+
const {
|
|
1164
|
+
id,
|
|
1165
|
+
version
|
|
1166
|
+
} = frame;
|
|
1167
|
+
const styledKeys = new Set();
|
|
1168
|
+
return {
|
|
1169
|
+
shell(html, meta = {}) {
|
|
1170
|
+
if (meta.preloads && meta.preloads.size) {
|
|
1171
|
+
const styles = [];
|
|
1172
|
+
const modules = [];
|
|
1173
|
+
for (const url of meta.preloads) {
|
|
1174
|
+
(url.endsWith(".css") ? styles : modules).push(url);
|
|
1175
|
+
}
|
|
1176
|
+
const chunk = {
|
|
1177
|
+
type: "assets",
|
|
1178
|
+
id,
|
|
1179
|
+
version,
|
|
1180
|
+
key: ""
|
|
1181
|
+
};
|
|
1182
|
+
if (styles.length) chunk.styles = styles;
|
|
1183
|
+
if (modules.length) chunk.modules = modules;
|
|
1184
|
+
emit(chunk);
|
|
1185
|
+
}
|
|
1186
|
+
emit({
|
|
1187
|
+
type: "html",
|
|
1188
|
+
id,
|
|
1189
|
+
version,
|
|
1190
|
+
html
|
|
1191
|
+
});
|
|
1192
|
+
},
|
|
1193
|
+
data(record) {
|
|
1194
|
+
if (record && typeof record.key === "string" && (record.key.endsWith("_fr") || /^\d+$/.test(record.key))) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
if (typeof record === "string") {
|
|
1198
|
+
emit({
|
|
1199
|
+
type: "data",
|
|
1200
|
+
id,
|
|
1201
|
+
version,
|
|
1202
|
+
payload: record
|
|
1203
|
+
});
|
|
1204
|
+
} else {
|
|
1205
|
+
emit({
|
|
1206
|
+
type: "data",
|
|
1207
|
+
id,
|
|
1208
|
+
version,
|
|
1209
|
+
key: record.key,
|
|
1210
|
+
node: record.node,
|
|
1211
|
+
initial: record.initial
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
fragment(key, value, meta = {}) {
|
|
1216
|
+
const links = meta.styles && meta.styles.links || [];
|
|
1217
|
+
const inline = meta.styles && meta.styles.inline || [];
|
|
1218
|
+
if (links.length || inline.length) {
|
|
1219
|
+
if (links.length) styledKeys.add(key);
|
|
1220
|
+
const chunk = {
|
|
1221
|
+
type: "assets",
|
|
1222
|
+
id,
|
|
1223
|
+
version,
|
|
1224
|
+
key
|
|
1225
|
+
};
|
|
1226
|
+
if (links.length) chunk.styles = links;
|
|
1227
|
+
if (inline.length) {
|
|
1228
|
+
chunk.inlineStyles = inline.map(e => ({
|
|
1229
|
+
id: e.id,
|
|
1230
|
+
content: e.content,
|
|
1231
|
+
attrs: e.attrs
|
|
1232
|
+
}));
|
|
1233
|
+
}
|
|
1234
|
+
emit(chunk);
|
|
1235
|
+
}
|
|
1236
|
+
emit({
|
|
1237
|
+
type: "fragment",
|
|
1238
|
+
id,
|
|
1239
|
+
version,
|
|
1240
|
+
key,
|
|
1241
|
+
html: value
|
|
1242
|
+
});
|
|
1243
|
+
if (meta.error) {
|
|
1244
|
+
emit({
|
|
1245
|
+
type: "error",
|
|
1246
|
+
id,
|
|
1247
|
+
version,
|
|
1248
|
+
key,
|
|
1249
|
+
error: {
|
|
1250
|
+
message: String(meta.error && meta.error.message || meta.error)
|
|
1251
|
+
}
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
if (!meta.revealGroup) {
|
|
1255
|
+
emit({
|
|
1256
|
+
type: "reveal",
|
|
1257
|
+
id,
|
|
1258
|
+
version,
|
|
1259
|
+
keys: [key],
|
|
1260
|
+
waitForStyles: !!links.length
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
},
|
|
1264
|
+
reveal(keys, meta = {}) {
|
|
1265
|
+
let waitForStyles = false;
|
|
1266
|
+
for (const key of keys) if (styledKeys.has(key)) waitForStyles = true;
|
|
1267
|
+
const chunk = {
|
|
1268
|
+
type: "reveal",
|
|
1269
|
+
id,
|
|
1270
|
+
version,
|
|
1271
|
+
keys,
|
|
1272
|
+
waitForStyles
|
|
1273
|
+
};
|
|
1274
|
+
if (meta.fallback) chunk.fallback = true;
|
|
1275
|
+
emit(chunk);
|
|
1276
|
+
},
|
|
1277
|
+
asset(type, url) {
|
|
1278
|
+
if (type !== "module") return;
|
|
1279
|
+
emit({
|
|
1280
|
+
type: "assets",
|
|
1281
|
+
id,
|
|
1282
|
+
version,
|
|
1283
|
+
key: "",
|
|
1284
|
+
modules: [url]
|
|
1285
|
+
});
|
|
1286
|
+
},
|
|
1287
|
+
end() {
|
|
1288
|
+
emit({
|
|
1289
|
+
type: "complete",
|
|
1290
|
+
id,
|
|
1291
|
+
version
|
|
1292
|
+
});
|
|
1293
|
+
},
|
|
1294
|
+
error(errorId, error) {
|
|
1295
|
+
emit({
|
|
1296
|
+
type: "error",
|
|
1297
|
+
id,
|
|
1298
|
+
version,
|
|
1299
|
+
key: errorId,
|
|
1300
|
+
error
|
|
1301
|
+
});
|
|
1302
|
+
},
|
|
1303
|
+
slot(key, args) {
|
|
1304
|
+
emit({
|
|
1305
|
+
type: "slot",
|
|
1306
|
+
id,
|
|
1307
|
+
version,
|
|
1308
|
+
key,
|
|
1309
|
+
args
|
|
1310
|
+
});
|
|
1311
|
+
},
|
|
1312
|
+
region(childId, html) {
|
|
1313
|
+
emit({
|
|
1314
|
+
type: "html",
|
|
1315
|
+
id: childId,
|
|
1316
|
+
version,
|
|
1317
|
+
html
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
}
|
|
1322
|
+
function renderToFrameStream(code, options = {}) {
|
|
1323
|
+
return frameStream(() => code, options);
|
|
1324
|
+
}
|
|
1325
|
+
function renderServerComponent(component, options = {}) {
|
|
1326
|
+
return frameStream((sink, frame) => {
|
|
1327
|
+
const props = createSlotProps(sink, frame);
|
|
1328
|
+
return () => component(props);
|
|
1329
|
+
}, options);
|
|
1330
|
+
}
|
|
1331
|
+
function frameStream(makeCode, options) {
|
|
1332
|
+
const {
|
|
1333
|
+
id = "",
|
|
1334
|
+
version = 1
|
|
1335
|
+
} = options.frame || {};
|
|
1336
|
+
const frame = {
|
|
1337
|
+
id,
|
|
1338
|
+
version
|
|
1339
|
+
};
|
|
1340
|
+
function stream(w) {
|
|
1341
|
+
const emit = chunk => w.write(chunk);
|
|
1342
|
+
const sink = createFrameSink(emit, frame);
|
|
1343
|
+
emit({
|
|
1344
|
+
type: "start",
|
|
1345
|
+
id,
|
|
1346
|
+
version
|
|
1347
|
+
});
|
|
1348
|
+
const code = makeCode(sink, frame);
|
|
1349
|
+
try {
|
|
1350
|
+
renderToStream(() => serverOwned(code), {
|
|
1351
|
+
serializer: createJSONSerializer,
|
|
1352
|
+
...options,
|
|
1353
|
+
sink
|
|
1354
|
+
}).pipe({
|
|
1355
|
+
write() {},
|
|
1356
|
+
end() {
|
|
1357
|
+
sink.end();
|
|
1358
|
+
w.end && w.end();
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
} catch (err) {
|
|
1362
|
+
sink.error("", err instanceof Error ? err.message : String(err));
|
|
1363
|
+
sink.end();
|
|
1364
|
+
w.end && w.end();
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
return {
|
|
1368
|
+
pipe: stream,
|
|
1369
|
+
then(onFulfilled, onRejected) {
|
|
1370
|
+
return new Promise((resolve, reject) => {
|
|
1371
|
+
const chunks = [];
|
|
1372
|
+
try {
|
|
1373
|
+
stream({
|
|
1374
|
+
write: chunk => chunks.push(chunk),
|
|
1375
|
+
end: () => resolve(chunks)
|
|
1376
|
+
});
|
|
1377
|
+
} catch (err) {
|
|
1378
|
+
reject(err);
|
|
1379
|
+
}
|
|
1380
|
+
}).then(onFulfilled, onRejected);
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
function slotRange(occurrence) {
|
|
1385
|
+
return {
|
|
1386
|
+
t: `<!--slot:${occurrence}:start--><!--slot:${occurrence}:end-->`
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
function createDocumentSlotProps(clientProps, frameId) {
|
|
1390
|
+
const counts = Object.create(null);
|
|
1391
|
+
const getters = new Map();
|
|
1392
|
+
const range = (occurrence, content) => [{
|
|
1393
|
+
t: `<!--slot:${occurrence}:start-->`
|
|
1394
|
+
}, content, {
|
|
1395
|
+
t: `<!--slot:${occurrence}:end-->`
|
|
1396
|
+
}];
|
|
1397
|
+
const zoneOwner = solidJs.getOwner ? solidJs.getOwner() : null;
|
|
1398
|
+
const scoped = (occurrence, render) => {
|
|
1399
|
+
const id = `sc-${frameId}-${occurrence}-`;
|
|
1400
|
+
const run = () => solidJs.Hydration ? solidJs.Hydration({
|
|
1401
|
+
id,
|
|
1402
|
+
get children() {
|
|
1403
|
+
return render();
|
|
1404
|
+
}
|
|
1405
|
+
}) : runWithHydrationScope(id, render);
|
|
1406
|
+
return zoneOwner ? solidJs.runWithOwner(zoneOwner, run) : run();
|
|
1407
|
+
};
|
|
1408
|
+
return new Proxy(Object.create(null), {
|
|
1409
|
+
has() {
|
|
1410
|
+
return true;
|
|
1411
|
+
},
|
|
1412
|
+
get(_, prop) {
|
|
1413
|
+
if (typeof prop !== "string") return undefined;
|
|
1414
|
+
if (prop === "then") return undefined;
|
|
1415
|
+
let fn = getters.get(prop);
|
|
1416
|
+
if (!fn) {
|
|
1417
|
+
fn = (...callArgs) => {
|
|
1418
|
+
if (callArgs.length === 0 || callArgs[0] === undefined) {
|
|
1419
|
+
return scoped(prop, () => {
|
|
1420
|
+
const value = clientProps[prop];
|
|
1421
|
+
return range(prop, typeof value === "function" ? value() : value);
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
const raw = callArgs[0];
|
|
1425
|
+
let occurrence;
|
|
1426
|
+
const k = raw.$key;
|
|
1427
|
+
if (typeof k === "string" || typeof k === "number") {
|
|
1428
|
+
occurrence = `${prop}#${k}`;
|
|
1429
|
+
} else {
|
|
1430
|
+
const n = counts[prop] || 0;
|
|
1431
|
+
counts[prop] = n + 1;
|
|
1432
|
+
occurrence = `${prop}#${n}`;
|
|
1433
|
+
}
|
|
1434
|
+
const slot = clientProps[prop];
|
|
1435
|
+
if (typeof slot !== "function") return range(occurrence, undefined);
|
|
1436
|
+
const resolved = {};
|
|
1437
|
+
const regions = [];
|
|
1438
|
+
for (const key of Object.keys(raw)) {
|
|
1439
|
+
const value = raw[key];
|
|
1440
|
+
if (key !== "$key" && isServerContent(value)) {
|
|
1441
|
+
const childId = `${frameId}.${occurrence}.${key}`;
|
|
1442
|
+
const region = {
|
|
1443
|
+
key,
|
|
1444
|
+
childId,
|
|
1445
|
+
value,
|
|
1446
|
+
used: false
|
|
1447
|
+
};
|
|
1448
|
+
regions.push(region);
|
|
1449
|
+
resolved[key] = () => {
|
|
1450
|
+
region.used = true;
|
|
1451
|
+
return [{
|
|
1452
|
+
t: `<!--frame:${childId}:start-->`
|
|
1453
|
+
}, value, {
|
|
1454
|
+
t: `<!--frame:${childId}:end-->`
|
|
1455
|
+
}];
|
|
1456
|
+
};
|
|
1457
|
+
} else {
|
|
1458
|
+
resolved[key] = value;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
const out = scoped(occurrence, () => range(occurrence, slot(resolved)));
|
|
1462
|
+
const unused = regions.filter(r => !r.used);
|
|
1463
|
+
if (solidJs.sharedConfig.context) {
|
|
1464
|
+
const rendered = renderedHtmlOf(out);
|
|
1465
|
+
const args = {};
|
|
1466
|
+
let any = false;
|
|
1467
|
+
for (const key of Object.keys(raw)) {
|
|
1468
|
+
const value = raw[key];
|
|
1469
|
+
if (key === "$key") continue;
|
|
1470
|
+
const region = regions.find(r => r.key === key);
|
|
1471
|
+
if (region) {
|
|
1472
|
+
if (!region.used) {
|
|
1473
|
+
args[key] = {
|
|
1474
|
+
$frame: region.childId
|
|
1475
|
+
};
|
|
1476
|
+
any = true;
|
|
1477
|
+
}
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1480
|
+
if (isServerContent(value)) continue;
|
|
1481
|
+
const t = typeof value;
|
|
1482
|
+
if ((t === "string" || t === "number") && rendered !== null) {
|
|
1483
|
+
const needle = t === "string" ? solidJs.sharedConfig.context.escape(String(value)) : String(value);
|
|
1484
|
+
if (needle !== "" && rendered.includes(needle)) continue;
|
|
1485
|
+
}
|
|
1486
|
+
args[key] = value;
|
|
1487
|
+
any = true;
|
|
1488
|
+
}
|
|
1489
|
+
if (any) solidJs.sharedConfig.context.serialize(`sc:slot:${frameId}:${occurrence}`, args);
|
|
1490
|
+
for (const region of unused) {
|
|
1491
|
+
solidJs.sharedConfig.context.serialize(`sc:region:${region.childId}`, resolveRegionHtml(solidJs.sharedConfig.context, region.value));
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
return out;
|
|
1495
|
+
};
|
|
1496
|
+
getters.set(prop, fn);
|
|
1497
|
+
}
|
|
1498
|
+
return fn;
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
function frameTransformDirectResult(value, {
|
|
1503
|
+
id
|
|
1504
|
+
}) {
|
|
1505
|
+
if (typeof value !== "function") return value;
|
|
1506
|
+
const component = value;
|
|
1507
|
+
const wrapped = props => [{
|
|
1508
|
+
t: `<!--frame:${id}:start-->`
|
|
1509
|
+
}, serverOwned(() => component(createDocumentSlotProps(props, id))), {
|
|
1510
|
+
t: `<!--frame:${id}:end-->`
|
|
1511
|
+
}];
|
|
1512
|
+
wrapped[SERVER_COMPONENT] = id;
|
|
1513
|
+
return wrapped;
|
|
1514
|
+
}
|
|
1515
|
+
function renderedHtmlOf(out) {
|
|
1516
|
+
try {
|
|
1517
|
+
const res = solidJs.sharedConfig.context.resolve(out);
|
|
1518
|
+
if (res && res.t && (!res.h || !res.h.length)) {
|
|
1519
|
+
return res.t[0].replace(/<!--[^>]*-->/g, "");
|
|
1520
|
+
}
|
|
1521
|
+
} catch (e) {}
|
|
1522
|
+
return null;
|
|
1523
|
+
}
|
|
1524
|
+
function resolveRegionHtml(ctx, node) {
|
|
1525
|
+
const res = ctx.resolve(node);
|
|
1526
|
+
if (!res || !res.t) return String(res ?? "");
|
|
1527
|
+
if (!res.h || !res.h.length) return res.t[0];
|
|
1528
|
+
return Promise.all(res.p).then(() => {
|
|
1529
|
+
let out = Promise.resolve(res.t[0]);
|
|
1530
|
+
for (let i = 0; i < res.h.length; i++) {
|
|
1531
|
+
const hole = res.h[i];
|
|
1532
|
+
const tail = res.t[i + 1];
|
|
1533
|
+
out = out.then(acc => Promise.resolve(resolveRegionHtml(ctx, hole)).then(part => acc + part + tail));
|
|
1534
|
+
}
|
|
1535
|
+
return out;
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
const SERVER_COMPONENT = /*#__PURE__*/Symbol.for("dom-expressions.server-component");
|
|
1539
|
+
const ServerComponentPlugin = /*#__PURE__*/seroval.createPlugin({
|
|
1540
|
+
tag: "dom-expressions/server-component",
|
|
1541
|
+
test(value) {
|
|
1542
|
+
return typeof value === "function" && SERVER_COMPONENT in value;
|
|
1543
|
+
},
|
|
1544
|
+
parse: {
|
|
1545
|
+
sync(value, ctx) {
|
|
1546
|
+
return {
|
|
1547
|
+
id: ctx.parse(value[SERVER_COMPONENT])
|
|
1548
|
+
};
|
|
1549
|
+
},
|
|
1550
|
+
async async(value, ctx) {
|
|
1551
|
+
return {
|
|
1552
|
+
id: await ctx.parse(value[SERVER_COMPONENT])
|
|
1553
|
+
};
|
|
1554
|
+
},
|
|
1555
|
+
stream(value, ctx) {
|
|
1556
|
+
return {
|
|
1557
|
+
id: ctx.parse(value[SERVER_COMPONENT])
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
},
|
|
1561
|
+
serialize(node, ctx) {
|
|
1562
|
+
return "self._$SC.r(" + ctx.serialize(node.id) + ")";
|
|
1563
|
+
},
|
|
1564
|
+
deserialize(node, ctx) {
|
|
1565
|
+
return globalThis._$SC.r(ctx.deserialize(node.id));
|
|
1566
|
+
}
|
|
1567
|
+
});
|
|
1568
|
+
const SERVER_COMPONENT_BOOTSTRAP = "self._$SC={c:{},r(i){return this.c[i]||(this.c[i]=(p)=>self._$SC.impl(i,p))}};";
|
|
1569
|
+
function isServerContent(value) {
|
|
1570
|
+
if (value && typeof value === "object") {
|
|
1571
|
+
if ("t" in value) return true;
|
|
1572
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
1573
|
+
for (const item of value) {
|
|
1574
|
+
if (!(item && typeof item === "object" && "t" in item)) return false;
|
|
1575
|
+
}
|
|
1576
|
+
return true;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
return false;
|
|
1580
|
+
}
|
|
1581
|
+
function createSlotProps(sink, frame) {
|
|
1582
|
+
const counts = Object.create(null);
|
|
1583
|
+
const getters = new Map();
|
|
1584
|
+
return new Proxy(Object.create(null), {
|
|
1585
|
+
has() {
|
|
1586
|
+
return true;
|
|
1587
|
+
},
|
|
1588
|
+
get(_, prop) {
|
|
1589
|
+
if (typeof prop !== "string") return undefined;
|
|
1590
|
+
if (prop === "then") return undefined;
|
|
1591
|
+
let fn = getters.get(prop);
|
|
1592
|
+
if (!fn) {
|
|
1593
|
+
fn = (...callArgs) => {
|
|
1594
|
+
if (callArgs.length === 0 || callArgs[0] === undefined) {
|
|
1595
|
+
return slotRange(prop);
|
|
1596
|
+
}
|
|
1597
|
+
const raw = callArgs[0];
|
|
1598
|
+
let occurrence;
|
|
1599
|
+
const k = raw.$key;
|
|
1600
|
+
if (typeof k === "string" || typeof k === "number") {
|
|
1601
|
+
occurrence = `${prop}#${k}`;
|
|
1602
|
+
} else {
|
|
1603
|
+
const n = counts[prop] || 0;
|
|
1604
|
+
counts[prop] = n + 1;
|
|
1605
|
+
occurrence = `${prop}#${n}`;
|
|
1606
|
+
}
|
|
1607
|
+
const args = {};
|
|
1608
|
+
for (const key of Object.keys(raw)) {
|
|
1609
|
+
const value = raw[key];
|
|
1610
|
+
const t = typeof value;
|
|
1611
|
+
if (value == null || t === "string" || t === "number" || t === "boolean") {
|
|
1612
|
+
args[key] = value;
|
|
1613
|
+
} else if (isServerContent(value)) {
|
|
1614
|
+
const resolved = solidJs.sharedConfig.context.resolve(value);
|
|
1615
|
+
if (resolved.h.length) {
|
|
1616
|
+
throw new Error("Async server content in slot args is not supported yet (arg '" + key + "' of " + occurrence + "). Move the async read above the slot or into a fragment.");
|
|
1617
|
+
}
|
|
1618
|
+
const childId = `${frame.id}.${occurrence}.${key}`;
|
|
1619
|
+
sink.region(childId, resolved.t[0]);
|
|
1620
|
+
args[key] = {
|
|
1621
|
+
$frame: childId
|
|
1622
|
+
};
|
|
1623
|
+
} else {
|
|
1624
|
+
const ref = `arg:${occurrence}:${key}`;
|
|
1625
|
+
solidJs.sharedConfig.context.serialize(ref, value);
|
|
1626
|
+
args[key] = {
|
|
1627
|
+
$ref: ref
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
sink.slot(occurrence, args);
|
|
1632
|
+
return slotRange(occurrence);
|
|
1633
|
+
};
|
|
1634
|
+
getters.set(prop, fn);
|
|
1635
|
+
}
|
|
1636
|
+
return fn;
|
|
1637
|
+
}
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1640
|
+
function serverComponentResponse(component, options = {}, init = {}) {
|
|
1641
|
+
const {
|
|
1642
|
+
id = "",
|
|
1643
|
+
version = 1
|
|
1644
|
+
} = options.frame || {};
|
|
1645
|
+
const headers = new Headers(init.headers);
|
|
1646
|
+
headers.set("Content-Type", "application/x-frame-stream");
|
|
1647
|
+
headers.set(FRAME_STREAM_HEADER, id);
|
|
1648
|
+
headers.set("X-Content-Raw", "1");
|
|
1649
|
+
const stream = renderServerComponent(component, {
|
|
1650
|
+
...options,
|
|
1651
|
+
frame: {
|
|
1652
|
+
id,
|
|
1653
|
+
version
|
|
1654
|
+
}
|
|
1655
|
+
});
|
|
1656
|
+
const body = new ReadableStream({
|
|
1657
|
+
start(controller) {
|
|
1658
|
+
stream.pipe({
|
|
1659
|
+
write(chunk) {
|
|
1660
|
+
controller.enqueue(createChunk(JSON.stringify(chunk)));
|
|
1661
|
+
},
|
|
1662
|
+
end() {
|
|
1663
|
+
controller.close();
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
}
|
|
1667
|
+
});
|
|
1668
|
+
return new Response(body, {
|
|
1669
|
+
status: init.status || 200,
|
|
1670
|
+
headers
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
function frameTransformResult(event, result) {
|
|
1674
|
+
let init;
|
|
1675
|
+
if (isResponseEnvelope(result)) {
|
|
1676
|
+
const {
|
|
1677
|
+
response,
|
|
1678
|
+
value
|
|
1679
|
+
} = result;
|
|
1680
|
+
if (typeof value !== "function") return result;
|
|
1681
|
+
init = response ? {
|
|
1682
|
+
headers: response.headers,
|
|
1683
|
+
status: response.status
|
|
1684
|
+
} : undefined;
|
|
1685
|
+
result = value;
|
|
1686
|
+
}
|
|
1687
|
+
if (typeof result !== "function") return result;
|
|
1688
|
+
const meta = event && event.locals && event.locals.serverFunctionMeta;
|
|
1689
|
+
return serverComponentResponse(result, {
|
|
1690
|
+
frame: {
|
|
1691
|
+
id: meta && meta.id || ""
|
|
1692
|
+
}
|
|
1693
|
+
}, init);
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
exports.FRAME_STREAM_HEADER = FRAME_STREAM_HEADER;
|
|
1697
|
+
exports.SERVER_COMPONENT_BOOTSTRAP = SERVER_COMPONENT_BOOTSTRAP;
|
|
1698
|
+
exports.ServerComponentPlugin = ServerComponentPlugin;
|
|
1699
|
+
exports.createFrameSink = createFrameSink;
|
|
1700
|
+
exports.frameTransformDirectResult = frameTransformDirectResult;
|
|
1701
|
+
exports.frameTransformResult = frameTransformResult;
|
|
1702
|
+
exports.isFrameStreamResponse = isFrameStreamResponse;
|
|
1703
|
+
exports.renderServerComponent = renderServerComponent;
|
|
1704
|
+
exports.renderToFrameStream = renderToFrameStream;
|
|
1705
|
+
exports.serverComponentResponse = serverComponentResponse;
|