@absolutejs/absolute 0.19.0-beta.367 → 0.19.0-beta.368
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/angular/browser.js +13 -8
- package/dist/angular/browser.js.map +4 -4
- package/dist/angular/components/core/streamingSlotRegistrar.js +4 -3
- package/dist/angular/components/core/streamingSlotRegistry.js +4 -3
- package/dist/angular/index.js +668 -622
- package/dist/angular/index.js.map +8 -8
- package/dist/build.js +23 -578
- package/dist/build.js.map +4 -10
- package/dist/client/index.js +45 -44
- package/dist/client/index.js.map +4 -4
- package/dist/index.js +1316 -1134
- package/dist/index.js.map +28 -22
- package/dist/react/components/browser/index.js +9 -20
- package/dist/react/components/index.js +17 -35
- package/dist/react/components/index.js.map +5 -6
- package/dist/react/index.js +1125 -1095
- package/dist/react/index.js.map +12 -12
- package/dist/react/server.js +3 -574
- package/dist/react/server.js.map +4 -11
- package/dist/src/core/pageHandlers.d.ts +1 -1
- package/dist/src/react/index.d.ts +1 -1
- package/dist/svelte/index.js +1506 -1460
- package/dist/svelte/index.js.map +8 -8
- package/dist/vue/components/index.js +13 -8
- package/dist/vue/components/index.js.map +5 -5
- package/dist/vue/index.js +667 -619
- package/dist/vue/index.js.map +8 -8
- package/package.json +1 -1
- package/dist/src/react/streamingSlotCollection.d.ts +0 -9
package/dist/react/index.js
CHANGED
|
@@ -78,8 +78,24 @@ var __legacyMetadataTS = (k, v) => {
|
|
|
78
78
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
79
79
|
var __require = import.meta.require;
|
|
80
80
|
|
|
81
|
+
// src/utils/escapeScriptContent.ts
|
|
82
|
+
var ESCAPE_LOOKUP, ESCAPE_REGEX, escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
|
|
83
|
+
const escaped = ESCAPE_LOOKUP[char];
|
|
84
|
+
return escaped !== undefined ? escaped : char;
|
|
85
|
+
});
|
|
86
|
+
var init_escapeScriptContent = __esm(() => {
|
|
87
|
+
ESCAPE_LOOKUP = {
|
|
88
|
+
"\u2028": "\\u2028",
|
|
89
|
+
"\u2029": "\\u2029",
|
|
90
|
+
"&": "\\u0026",
|
|
91
|
+
"<": "\\u003C",
|
|
92
|
+
">": "\\u003E"
|
|
93
|
+
};
|
|
94
|
+
ESCAPE_REGEX = /[&><\u2028\u2029]/g;
|
|
95
|
+
});
|
|
96
|
+
|
|
81
97
|
// src/core/islandPageContext.ts
|
|
82
|
-
var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__", ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__",
|
|
98
|
+
var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__", ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__", CLOSING_HEAD_TAG2 = "</head>", buildIslandsHeadMarkup = (manifest) => {
|
|
83
99
|
const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
|
|
84
100
|
const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
|
|
85
101
|
const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
|
|
@@ -98,10 +114,10 @@ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="tr
|
|
|
98
114
|
}
|
|
99
115
|
}
|
|
100
116
|
return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
|
|
101
|
-
},
|
|
117
|
+
}, streamChunkToString2 = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true }), pipeStreamWithHeadInjection = (stream, markup) => {
|
|
102
118
|
const encoder = new TextEncoder;
|
|
103
119
|
const decoder = new TextDecoder;
|
|
104
|
-
const lookbehind =
|
|
120
|
+
const lookbehind = CLOSING_HEAD_TAG2.length - 1;
|
|
105
121
|
return new ReadableStream({
|
|
106
122
|
async start(controller) {
|
|
107
123
|
const reader = stream.getReader();
|
|
@@ -114,13 +130,13 @@ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="tr
|
|
|
114
130
|
break;
|
|
115
131
|
if (!value)
|
|
116
132
|
continue;
|
|
117
|
-
pending +=
|
|
133
|
+
pending += streamChunkToString2(value, decoder);
|
|
118
134
|
if (injected) {
|
|
119
135
|
controller.enqueue(encoder.encode(pending));
|
|
120
136
|
pending = "";
|
|
121
137
|
continue;
|
|
122
138
|
}
|
|
123
|
-
const headIndex = pending.indexOf(
|
|
139
|
+
const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
|
|
124
140
|
if (headIndex >= 0) {
|
|
125
141
|
const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
|
|
126
142
|
controller.enqueue(encoder.encode(next));
|
|
@@ -163,7 +179,7 @@ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="tr
|
|
|
163
179
|
break;
|
|
164
180
|
if (!value)
|
|
165
181
|
continue;
|
|
166
|
-
pending +=
|
|
182
|
+
pending += streamChunkToString2(value, decoder);
|
|
167
183
|
if (injected) {
|
|
168
184
|
controller.enqueue(encoder.encode(pending));
|
|
169
185
|
pending = "";
|
|
@@ -221,698 +237,150 @@ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="tr
|
|
|
221
237
|
globalThis.__absoluteManifest = manifest;
|
|
222
238
|
};
|
|
223
239
|
|
|
224
|
-
// src/
|
|
225
|
-
var
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (!node) {
|
|
234
|
-
pending[id] = html;
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
node.innerHTML = html;
|
|
238
|
-
delete pending[id];
|
|
239
|
-
};
|
|
240
|
-
const flush = () => {
|
|
241
|
-
for (const id in pending) {
|
|
242
|
-
if (!Object.prototype.hasOwnProperty.call(pending, id))
|
|
243
|
-
continue;
|
|
244
|
-
apply(id, pending[id] ?? "");
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
window.__ABS_SLOT_ENQUEUE__ = (id, html) => {
|
|
248
|
-
apply(id, html);
|
|
249
|
-
};
|
|
250
|
-
if (typeof MutationObserver === "function") {
|
|
251
|
-
const observer = new MutationObserver(flush);
|
|
252
|
-
const root = document.documentElement ?? document.body ?? document;
|
|
253
|
-
observer.observe(root, { childList: true, subtree: true });
|
|
254
|
-
}
|
|
255
|
-
if (document.readyState === "loading") {
|
|
256
|
-
document.addEventListener("DOMContentLoaded", flush, { once: true });
|
|
257
|
-
}
|
|
258
|
-
flush();
|
|
259
|
-
}, stripFunctionWrapper = (value) => {
|
|
260
|
-
const start = value.indexOf("{");
|
|
261
|
-
const end = value.lastIndexOf("}");
|
|
262
|
-
if (start < 0 || end <= start)
|
|
263
|
-
return "";
|
|
264
|
-
return value.slice(start + 1, end);
|
|
265
|
-
}, getStreamSwapRuntimeScript = () => `(function(){${stripFunctionWrapper(streamSwapRuntime.toString())}})();`;
|
|
266
|
-
|
|
267
|
-
// src/utils/escapeScriptContent.ts
|
|
268
|
-
var ESCAPE_LOOKUP, ESCAPE_REGEX, escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
|
|
269
|
-
const escaped = ESCAPE_LOOKUP[char];
|
|
270
|
-
return escaped !== undefined ? escaped : char;
|
|
271
|
-
});
|
|
272
|
-
var init_escapeScriptContent = __esm(() => {
|
|
273
|
-
ESCAPE_LOOKUP = {
|
|
274
|
-
"\u2028": "\\u2028",
|
|
275
|
-
"\u2029": "\\u2029",
|
|
276
|
-
"&": "\\u0026",
|
|
277
|
-
"<": "\\u003C",
|
|
278
|
-
">": "\\u003E"
|
|
240
|
+
// src/utils/ssrErrorPage.ts
|
|
241
|
+
var ssrErrorPage = (framework, error) => {
|
|
242
|
+
const frameworkColors = {
|
|
243
|
+
angular: "#dd0031",
|
|
244
|
+
html: "#e34c26",
|
|
245
|
+
htmx: "#1a365d",
|
|
246
|
+
react: "#61dafb",
|
|
247
|
+
svelte: "#ff3e00",
|
|
248
|
+
vue: "#42b883"
|
|
279
249
|
};
|
|
280
|
-
|
|
281
|
-
|
|
250
|
+
const accent = frameworkColors[framework] ?? "#94a3b8";
|
|
251
|
+
const label = framework.charAt(0).toUpperCase() + framework.slice(1);
|
|
252
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
253
|
+
return `<!DOCTYPE html>
|
|
254
|
+
<html>
|
|
255
|
+
<head>
|
|
256
|
+
<meta charset="utf-8">
|
|
257
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
258
|
+
<title>SSR Error - AbsoluteJS</title>
|
|
259
|
+
<style>
|
|
260
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
261
|
+
body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,rgba(30,41,59,0.98) 100%);color:#e2e8f0;font-family:"JetBrains Mono","Fira Code",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:14px;line-height:1.6;display:flex;align-items:flex-start;justify-content:center;padding:32px}
|
|
262
|
+
.card{max-width:720px;width:100%;background:rgba(30,41,59,0.6);border:1px solid rgba(71,85,105,0.5);border-radius:16px;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5),0 0 0 1px rgba(255,255,255,0.05);overflow:hidden}
|
|
263
|
+
.header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 24px;background:rgba(15,23,42,0.5);border-bottom:1px solid rgba(71,85,105,0.4)}
|
|
264
|
+
.brand{font-weight:700;font-size:20px;color:#fff;letter-spacing:-0.02em}
|
|
265
|
+
.badge{padding:5px 10px;border-radius:8px;font-size:12px;font-weight:600;background:${accent};color:#fff;opacity:0.95;box-shadow:0 2px 4px rgba(0,0,0,0.2)}
|
|
266
|
+
.kind{color:#94a3b8;font-size:13px;font-weight:500}
|
|
267
|
+
.content{padding:24px}
|
|
268
|
+
.label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin-bottom:8px}
|
|
269
|
+
.message{margin:0;padding:16px 20px;background:rgba(239,68,68,0.12);border:1px solid rgba(239,68,68,0.25);border-radius:10px;overflow-x:auto;white-space:pre-wrap;word-break:break-word;color:#fca5a5;font-size:13px;line-height:1.5}
|
|
270
|
+
.hint{margin-top:20px;padding:12px 20px;background:rgba(71,85,105,0.3);border-radius:10px;border:1px solid rgba(71,85,105,0.4);color:#cbd5e1;font-size:13px}
|
|
271
|
+
</style>
|
|
272
|
+
</head>
|
|
273
|
+
<body>
|
|
274
|
+
<div class="card">
|
|
275
|
+
<div class="header">
|
|
276
|
+
<div style="display:flex;align-items:center;gap:12px">
|
|
277
|
+
<span class="brand">AbsoluteJS</span>
|
|
278
|
+
<span class="badge">${label}</span>
|
|
279
|
+
</div>
|
|
280
|
+
<span class="kind">Server Render Error</span>
|
|
281
|
+
</div>
|
|
282
|
+
<div class="content">
|
|
283
|
+
<div class="label">What went wrong</div>
|
|
284
|
+
<pre class="message">${message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</pre>
|
|
285
|
+
<div class="hint">A component threw during server-side rendering. Check the terminal for the full stack trace.</div>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
288
|
+
</body>
|
|
289
|
+
</html>`;
|
|
290
|
+
};
|
|
282
291
|
|
|
283
|
-
// src/utils/
|
|
284
|
-
var
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return `${html.slice(0, closingHeadIndex)}${injection}${html.slice(closingHeadIndex)}`;
|
|
288
|
-
}
|
|
289
|
-
return `${html}${injection}`;
|
|
290
|
-
}, toUint8 = (value, encoder) => encoder.encode(value), currentStreamingSlotPolicy, clonePolicy = (policy) => ({
|
|
291
|
-
...policy
|
|
292
|
-
}), normalizeSlotBytes = (value, fallback) => {
|
|
293
|
-
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
294
|
-
return Math.floor(value);
|
|
292
|
+
// src/utils/stringModifiers.ts
|
|
293
|
+
var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
|
|
294
|
+
if (!str.includes("-") && !str.includes("_")) {
|
|
295
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
295
296
|
}
|
|
296
|
-
return
|
|
297
|
-
},
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
|
|
298
|
+
}, toScreamingSnake = (str) => str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase();
|
|
299
|
+
|
|
300
|
+
// src/utils/resolveConvention.ts
|
|
301
|
+
import { basename } from "path";
|
|
302
|
+
var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
|
|
303
|
+
const value = Reflect.get(globalThis, CONVENTIONS_KEY);
|
|
304
|
+
if (isConventionsMap(value))
|
|
305
|
+
return value;
|
|
306
|
+
const empty = {};
|
|
307
|
+
return empty;
|
|
308
|
+
}, derivePageName = (pagePath) => {
|
|
309
|
+
const base = basename(pagePath);
|
|
310
|
+
const dotIndex = base.indexOf(".");
|
|
311
|
+
const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
|
|
312
|
+
return toPascal(name);
|
|
313
|
+
}, resolveErrorConventionPath = (framework, pageName) => {
|
|
314
|
+
const conventions = getMap()[framework];
|
|
315
|
+
if (!conventions)
|
|
307
316
|
return;
|
|
308
|
-
return
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
},
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
onError?.(new Error(`Streaming slot "${slot.id}" dropped because ${maxSlotsPerResponse} slots is the configured maximum`), slot);
|
|
376
|
-
emitSlotMetric({
|
|
377
|
-
type: "dropped",
|
|
378
|
-
slotId: slot.id,
|
|
379
|
-
reason: `maxSlotsPerResponse is ${maxSlotsPerResponse}`
|
|
380
|
-
}, onSlotMetric);
|
|
381
|
-
});
|
|
382
|
-
keptSlots.forEach((slot) => emitSlotMetric({
|
|
383
|
-
type: "prepared",
|
|
384
|
-
slotId: slot.id
|
|
385
|
-
}, onSlotMetric));
|
|
386
|
-
return keptSlots;
|
|
387
|
-
}, htmlByteLength = (value, encoder) => encoder.encode(value).length, resolveSlot = async (slot, onError, policy, onSlotMetric) => {
|
|
388
|
-
const safePolicy = policy ?? getStreamingSlotPolicy();
|
|
389
|
-
const encoder = new TextEncoder;
|
|
390
|
-
const start = Date.now();
|
|
391
|
-
try {
|
|
392
|
-
const maybeAsyncValue = Promise.resolve(slot.resolve());
|
|
393
|
-
const resolved = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
|
|
394
|
-
maybeAsyncValue,
|
|
395
|
-
new Promise((_, reject) => setTimeout(() => {
|
|
396
|
-
reject(createTimeoutError(slot, slot.timeoutMs ?? 0));
|
|
397
|
-
}, slot.timeoutMs))
|
|
398
|
-
]) : await maybeAsyncValue;
|
|
399
|
-
const html = typeof resolved === "string" ? resolved : `${resolved}`;
|
|
400
|
-
if (safePolicy.maxSlotHtmlSizeBytes > 0 && htmlByteLength(html, encoder) > safePolicy.maxSlotHtmlSizeBytes) {
|
|
401
|
-
const bytes2 = htmlByteLength(html, encoder);
|
|
402
|
-
const error = new Error(`Streaming slot "${slot.id}" exceeded max payload size of ${safePolicy.maxSlotHtmlSizeBytes} bytes`);
|
|
403
|
-
const durationMs2 = Date.now() - start;
|
|
404
|
-
onError?.(error, slot);
|
|
405
|
-
emitSlotMetric({
|
|
406
|
-
type: "size_exceeded",
|
|
407
|
-
slotId: slot.id,
|
|
408
|
-
durationMs: durationMs2,
|
|
409
|
-
bytes: bytes2,
|
|
410
|
-
error
|
|
411
|
-
}, onSlotMetric);
|
|
412
|
-
const fallbackHtml = typeof slot.errorHtml === "string" ? slot.errorHtml : null;
|
|
413
|
-
return {
|
|
414
|
-
html: fallbackHtml,
|
|
415
|
-
id: slot.id,
|
|
416
|
-
durationMs: durationMs2,
|
|
417
|
-
bytes: fallbackHtml === null ? 0 : htmlByteLength(fallbackHtml, encoder)
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
const durationMs = Date.now() - start;
|
|
421
|
-
const bytes = htmlByteLength(html, encoder);
|
|
422
|
-
emitSlotMetric({
|
|
423
|
-
type: "resolved",
|
|
424
|
-
slotId: slot.id,
|
|
425
|
-
durationMs,
|
|
426
|
-
bytes
|
|
427
|
-
}, onSlotMetric);
|
|
428
|
-
return {
|
|
429
|
-
html,
|
|
430
|
-
id: slot.id,
|
|
431
|
-
durationMs,
|
|
432
|
-
bytes
|
|
433
|
-
};
|
|
434
|
-
} catch (error) {
|
|
435
|
-
const durationMs = Date.now() - start;
|
|
436
|
-
onError?.(error, slot);
|
|
437
|
-
emitSlotMetric({
|
|
438
|
-
type: error?.__absTimeout === true ? "timeout" : "error",
|
|
439
|
-
slotId: slot.id,
|
|
440
|
-
durationMs,
|
|
441
|
-
error
|
|
442
|
-
}, onSlotMetric);
|
|
443
|
-
if (typeof slot.errorHtml === "string") {
|
|
444
|
-
const html = slot.errorHtml;
|
|
445
|
-
return {
|
|
446
|
-
html,
|
|
447
|
-
id: slot.id,
|
|
448
|
-
durationMs,
|
|
449
|
-
bytes: htmlByteLength(html, encoder)
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
return {
|
|
453
|
-
html: null,
|
|
454
|
-
id: slot.id,
|
|
455
|
-
durationMs,
|
|
456
|
-
bytes: 0
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
}, nextResolvedSlot = async (pending) => {
|
|
460
|
-
const wrapped = pending.map((promise) => promise.then((result) => ({
|
|
461
|
-
original: promise,
|
|
462
|
-
result
|
|
463
|
-
})));
|
|
464
|
-
return Promise.race(wrapped);
|
|
465
|
-
}, streamChunkToString2 = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true }), streamOutOfOrderSlots = ({
|
|
466
|
-
footerHtml = "",
|
|
467
|
-
headerHtml = "",
|
|
468
|
-
nonce,
|
|
469
|
-
policy,
|
|
470
|
-
onSlotMetric,
|
|
471
|
-
onError,
|
|
472
|
-
slots
|
|
473
|
-
}) => {
|
|
474
|
-
const resolvedPolicy = resolveStreamingSlotPolicy(policy);
|
|
475
|
-
const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
|
|
476
|
-
const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
|
|
477
|
-
const effectivePolicy = {
|
|
478
|
-
...resolvedPolicy,
|
|
479
|
-
onSlotMetric: combinedOnSlotMetric
|
|
480
|
-
};
|
|
481
|
-
const preparedSlots = prepareSlots({
|
|
482
|
-
policy: effectivePolicy,
|
|
483
|
-
slots,
|
|
484
|
-
onError: combinedOnError,
|
|
485
|
-
onSlotMetric: combinedOnSlotMetric
|
|
486
|
-
});
|
|
487
|
-
const encoder = new TextEncoder;
|
|
488
|
-
return new ReadableStream({
|
|
489
|
-
async start(controller) {
|
|
490
|
-
try {
|
|
491
|
-
let header = headerHtml;
|
|
492
|
-
if (preparedSlots.length > 0 && !header.includes(STREAMING_RUNTIME_GLOBAL)) {
|
|
493
|
-
header = injectHtmlIntoHead(header, renderStreamingSlotsRuntimeTag(nonce));
|
|
494
|
-
}
|
|
495
|
-
controller.enqueue(toUint8(header, encoder));
|
|
496
|
-
const pending = preparedSlots.map((slot) => {
|
|
497
|
-
const fallback = renderStreamingSlotPlaceholder(slot.id, slot.fallbackHtml ?? "");
|
|
498
|
-
controller.enqueue(toUint8(fallback, encoder));
|
|
499
|
-
return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
|
|
500
|
-
});
|
|
501
|
-
while (pending.length > 0) {
|
|
502
|
-
const { original, result } = await nextResolvedSlot(pending);
|
|
503
|
-
const index = pending.indexOf(original);
|
|
504
|
-
if (index >= 0)
|
|
505
|
-
pending.splice(index, 1);
|
|
506
|
-
if (result.html === null)
|
|
507
|
-
continue;
|
|
508
|
-
emitSlotMetric({
|
|
509
|
-
type: "patched",
|
|
510
|
-
slotId: result.id,
|
|
511
|
-
durationMs: result.durationMs,
|
|
512
|
-
bytes: result.bytes
|
|
513
|
-
}, combinedOnSlotMetric);
|
|
514
|
-
controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.html, nonce), encoder));
|
|
515
|
-
}
|
|
516
|
-
if (footerHtml.length > 0) {
|
|
517
|
-
controller.enqueue(toUint8(footerHtml, encoder));
|
|
518
|
-
}
|
|
519
|
-
controller.close();
|
|
520
|
-
} catch (error) {
|
|
521
|
-
controller.error(error);
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
}, injectStreamingRuntimeIntoStream = (stream, nonce) => {
|
|
526
|
-
const runtimeTag = renderStreamingSlotsRuntimeTag(nonce);
|
|
527
|
-
const encoder = new TextEncoder;
|
|
528
|
-
const decoder = new TextDecoder;
|
|
529
|
-
const lookbehind = CLOSING_HEAD_TAG_LENGTH - 1;
|
|
530
|
-
return new ReadableStream({
|
|
531
|
-
async start(controller) {
|
|
532
|
-
const reader = stream.getReader();
|
|
533
|
-
let injected = false;
|
|
534
|
-
let pending = "";
|
|
535
|
-
try {
|
|
536
|
-
for (;; ) {
|
|
537
|
-
const { done, value } = await reader.read();
|
|
538
|
-
if (done)
|
|
539
|
-
break;
|
|
540
|
-
if (!value)
|
|
541
|
-
continue;
|
|
542
|
-
pending += streamChunkToString2(value, decoder);
|
|
543
|
-
if (injected) {
|
|
544
|
-
controller.enqueue(encoder.encode(pending));
|
|
545
|
-
pending = "";
|
|
546
|
-
continue;
|
|
547
|
-
}
|
|
548
|
-
const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
|
|
549
|
-
if (headIndex >= 0) {
|
|
550
|
-
const withRuntime = `${pending.slice(0, headIndex)}${runtimeTag}${pending.slice(headIndex)}`;
|
|
551
|
-
controller.enqueue(encoder.encode(withRuntime));
|
|
552
|
-
pending = "";
|
|
553
|
-
injected = true;
|
|
554
|
-
continue;
|
|
555
|
-
}
|
|
556
|
-
if (pending.length > lookbehind) {
|
|
557
|
-
const safeText = pending.slice(0, pending.length - lookbehind);
|
|
558
|
-
controller.enqueue(encoder.encode(safeText));
|
|
559
|
-
pending = pending.slice(-lookbehind);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
pending += decoder.decode();
|
|
563
|
-
if (!injected) {
|
|
564
|
-
pending = injectHtmlIntoHead(pending, runtimeTag);
|
|
565
|
-
}
|
|
566
|
-
if (pending.length > 0) {
|
|
567
|
-
controller.enqueue(encoder.encode(pending));
|
|
568
|
-
}
|
|
569
|
-
controller.close();
|
|
570
|
-
} catch (error) {
|
|
571
|
-
controller.error(error);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
});
|
|
575
|
-
}, appendStreamingSlotPatchesToStream = (stream, slots = [], {
|
|
576
|
-
injectRuntime = true,
|
|
577
|
-
nonce,
|
|
578
|
-
onError,
|
|
579
|
-
onSlotMetric,
|
|
580
|
-
policy
|
|
581
|
-
} = {}) => {
|
|
582
|
-
const resolvedPolicy = resolveStreamingSlotPolicy(policy);
|
|
583
|
-
const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
|
|
584
|
-
const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
|
|
585
|
-
const effectivePolicy = {
|
|
586
|
-
...resolvedPolicy,
|
|
587
|
-
onSlotMetric: combinedOnSlotMetric
|
|
588
|
-
};
|
|
589
|
-
const preparedSlots = prepareSlots({
|
|
590
|
-
policy: effectivePolicy,
|
|
591
|
-
slots,
|
|
592
|
-
onError: combinedOnError,
|
|
593
|
-
onSlotMetric: combinedOnSlotMetric
|
|
594
|
-
});
|
|
595
|
-
if (preparedSlots.length === 0)
|
|
596
|
-
return stream;
|
|
597
|
-
const source = injectRuntime ? injectStreamingRuntimeIntoStream(stream, nonce) : stream;
|
|
598
|
-
const encoder = new TextEncoder;
|
|
599
|
-
const decoder = new TextDecoder;
|
|
600
|
-
const reader = source.getReader();
|
|
601
|
-
const pending = preparedSlots.map((slot) => resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric));
|
|
602
|
-
return new ReadableStream({
|
|
603
|
-
async start(controller) {
|
|
604
|
-
let baseDone = false;
|
|
605
|
-
let baseRead = reader.read();
|
|
606
|
-
let tail = "";
|
|
607
|
-
let footer = "";
|
|
608
|
-
try {
|
|
609
|
-
while (!baseDone || pending.length > 0) {
|
|
610
|
-
const racers = [];
|
|
611
|
-
if (!baseDone) {
|
|
612
|
-
racers.push(baseRead.then(({ done, value }) => ({
|
|
613
|
-
done,
|
|
614
|
-
kind: "base",
|
|
615
|
-
value
|
|
616
|
-
})));
|
|
617
|
-
}
|
|
618
|
-
if (pending.length > 0) {
|
|
619
|
-
racers.push(nextResolvedSlot(pending).then((resolved) => ({
|
|
620
|
-
kind: "slot",
|
|
621
|
-
...resolved
|
|
622
|
-
})));
|
|
623
|
-
}
|
|
624
|
-
if (racers.length === 0)
|
|
625
|
-
break;
|
|
626
|
-
const winner = await Promise.race(racers);
|
|
627
|
-
if (winner.kind === "base") {
|
|
628
|
-
if (winner.done) {
|
|
629
|
-
baseDone = true;
|
|
630
|
-
tail += decoder.decode();
|
|
631
|
-
const footerStart = tail.search(CLOSING_PAGE_TAG_REGEX);
|
|
632
|
-
if (footerStart >= 0) {
|
|
633
|
-
const content = tail.slice(0, footerStart);
|
|
634
|
-
footer = tail.slice(footerStart);
|
|
635
|
-
if (content.length > 0) {
|
|
636
|
-
controller.enqueue(encoder.encode(content));
|
|
637
|
-
}
|
|
638
|
-
} else if (tail.length > 0) {
|
|
639
|
-
controller.enqueue(encoder.encode(tail));
|
|
640
|
-
}
|
|
641
|
-
tail = "";
|
|
642
|
-
} else if (winner.value) {
|
|
643
|
-
tail += streamChunkToString2(winner.value, decoder);
|
|
644
|
-
if (tail.length > STREAM_TAIL_LOOKBEHIND) {
|
|
645
|
-
const content = tail.slice(0, tail.length - STREAM_TAIL_LOOKBEHIND);
|
|
646
|
-
controller.enqueue(encoder.encode(content));
|
|
647
|
-
tail = tail.slice(-STREAM_TAIL_LOOKBEHIND);
|
|
648
|
-
}
|
|
649
|
-
baseRead = reader.read();
|
|
650
|
-
}
|
|
651
|
-
continue;
|
|
652
|
-
}
|
|
653
|
-
const index = pending.indexOf(winner.original);
|
|
654
|
-
if (index >= 0)
|
|
655
|
-
pending.splice(index, 1);
|
|
656
|
-
if (winner.result.html === null)
|
|
657
|
-
continue;
|
|
658
|
-
emitSlotMetric({
|
|
659
|
-
type: "patched",
|
|
660
|
-
slotId: winner.result.id,
|
|
661
|
-
durationMs: winner.result.durationMs,
|
|
662
|
-
bytes: winner.result.bytes
|
|
663
|
-
}, combinedOnSlotMetric);
|
|
664
|
-
controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.html, nonce)));
|
|
665
|
-
}
|
|
666
|
-
if (footer.length > 0)
|
|
667
|
-
controller.enqueue(encoder.encode(footer));
|
|
668
|
-
controller.close();
|
|
669
|
-
} catch (error) {
|
|
670
|
-
controller.error(error);
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
};
|
|
675
|
-
var init_streamingSlots = __esm(() => {
|
|
676
|
-
init_escapeScriptContent();
|
|
677
|
-
CLOSING_HEAD_TAG_LENGTH = CLOSING_HEAD_TAG2.length;
|
|
678
|
-
CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
|
|
679
|
-
currentStreamingSlotPolicy = {
|
|
680
|
-
timeoutMs: STREAMING_SLOT_TIMEOUT_MS,
|
|
681
|
-
fallbackHtml: "",
|
|
682
|
-
errorHtml: undefined,
|
|
683
|
-
maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
|
|
684
|
-
maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES
|
|
685
|
-
};
|
|
686
|
-
});
|
|
687
|
-
|
|
688
|
-
// src/core/streamingSlotRegistrar.ts
|
|
689
|
-
var registrar = null, setStreamingSlotRegistrar = (nextRegistrar) => {
|
|
690
|
-
registrar = nextRegistrar;
|
|
691
|
-
}, registerStreamingSlot = (slot) => {
|
|
692
|
-
registrar?.(slot);
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
// src/core/streamingSlotRegistry.ts
|
|
696
|
-
var asyncLocalStorage, isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string", ensureAsyncLocalStorage = async () => {
|
|
697
|
-
if (typeof asyncLocalStorage !== "undefined")
|
|
698
|
-
return asyncLocalStorage;
|
|
699
|
-
if (!isServerRuntime()) {
|
|
700
|
-
asyncLocalStorage = null;
|
|
701
|
-
return asyncLocalStorage;
|
|
702
|
-
}
|
|
703
|
-
const mod = await import("async_hooks");
|
|
704
|
-
asyncLocalStorage = new mod.AsyncLocalStorage;
|
|
705
|
-
return asyncLocalStorage;
|
|
706
|
-
}, registerStreamingSlot2 = (slot) => {
|
|
707
|
-
if (!asyncLocalStorage)
|
|
708
|
-
return;
|
|
709
|
-
const store = asyncLocalStorage.getStore();
|
|
710
|
-
if (!store)
|
|
711
|
-
return;
|
|
712
|
-
store.set(slot.id, slot);
|
|
713
|
-
}, runWithStreamingSlotRegistry = async (task) => {
|
|
714
|
-
const storage = await ensureAsyncLocalStorage();
|
|
715
|
-
if (!storage) {
|
|
716
|
-
return {
|
|
717
|
-
result: await task(),
|
|
718
|
-
slots: []
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
return storage.run(new Map, async () => {
|
|
722
|
-
const result = await task();
|
|
723
|
-
const store = storage.getStore();
|
|
724
|
-
return {
|
|
725
|
-
result,
|
|
726
|
-
slots: store ? [...store.values()] : []
|
|
727
|
-
};
|
|
728
|
-
});
|
|
729
|
-
};
|
|
730
|
-
var init_streamingSlotRegistry = __esm(() => {
|
|
731
|
-
setStreamingSlotRegistrar(registerStreamingSlot2);
|
|
732
|
-
});
|
|
733
|
-
|
|
734
|
-
// src/core/responseEnhancers.ts
|
|
735
|
-
var toResponse = async (responseLike) => await responseLike, cloneHeaders = (response) => {
|
|
736
|
-
const headers = new Headers(response.headers);
|
|
737
|
-
return headers;
|
|
738
|
-
}, enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [], policy } = {}) => {
|
|
739
|
-
if (!response.body || streamingSlots.length === 0) {
|
|
740
|
-
return response;
|
|
741
|
-
}
|
|
742
|
-
const body = appendStreamingSlotPatchesToStream(response.body, streamingSlots, {
|
|
743
|
-
nonce,
|
|
744
|
-
onError,
|
|
745
|
-
policy
|
|
746
|
-
});
|
|
747
|
-
return new Response(body, {
|
|
748
|
-
headers: cloneHeaders(response),
|
|
749
|
-
status: response.status,
|
|
750
|
-
statusText: response.statusText
|
|
751
|
-
});
|
|
752
|
-
}, withStreamingSlots = async (responseLike, options = {}) => enhanceHtmlResponseWithStreamingSlots(await toResponse(responseLike), options), mergeStreamingSlots = (registered, explicit) => {
|
|
753
|
-
const merged = new Map;
|
|
754
|
-
for (const slot of registered)
|
|
755
|
-
merged.set(slot.id, slot);
|
|
756
|
-
for (const slot of explicit)
|
|
757
|
-
merged.set(slot.id, slot);
|
|
758
|
-
return [...merged.values()];
|
|
759
|
-
}, withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
|
|
760
|
-
const { result, slots } = await runWithStreamingSlotRegistry(renderResponse);
|
|
761
|
-
const explicit = options.streamingSlots ?? [];
|
|
762
|
-
return withStreamingSlots(result, {
|
|
763
|
-
...options,
|
|
764
|
-
streamingSlots: mergeStreamingSlots(slots, explicit)
|
|
765
|
-
});
|
|
766
|
-
};
|
|
767
|
-
var init_responseEnhancers = __esm(() => {
|
|
768
|
-
init_streamingSlots();
|
|
769
|
-
init_streamingSlotRegistry();
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
// src/utils/ssrErrorPage.ts
|
|
773
|
-
var ssrErrorPage = (framework, error) => {
|
|
774
|
-
const frameworkColors = {
|
|
775
|
-
angular: "#dd0031",
|
|
776
|
-
html: "#e34c26",
|
|
777
|
-
htmx: "#1a365d",
|
|
778
|
-
react: "#61dafb",
|
|
779
|
-
svelte: "#ff3e00",
|
|
780
|
-
vue: "#42b883"
|
|
781
|
-
};
|
|
782
|
-
const accent = frameworkColors[framework] ?? "#94a3b8";
|
|
783
|
-
const label = framework.charAt(0).toUpperCase() + framework.slice(1);
|
|
784
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
785
|
-
return `<!DOCTYPE html>
|
|
786
|
-
<html>
|
|
787
|
-
<head>
|
|
788
|
-
<meta charset="utf-8">
|
|
789
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
790
|
-
<title>SSR Error - AbsoluteJS</title>
|
|
791
|
-
<style>
|
|
792
|
-
*{margin:0;padding:0;box-sizing:border-box}
|
|
793
|
-
body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,rgba(30,41,59,0.98) 100%);color:#e2e8f0;font-family:"JetBrains Mono","Fira Code",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:14px;line-height:1.6;display:flex;align-items:flex-start;justify-content:center;padding:32px}
|
|
794
|
-
.card{max-width:720px;width:100%;background:rgba(30,41,59,0.6);border:1px solid rgba(71,85,105,0.5);border-radius:16px;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5),0 0 0 1px rgba(255,255,255,0.05);overflow:hidden}
|
|
795
|
-
.header{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 24px;background:rgba(15,23,42,0.5);border-bottom:1px solid rgba(71,85,105,0.4)}
|
|
796
|
-
.brand{font-weight:700;font-size:20px;color:#fff;letter-spacing:-0.02em}
|
|
797
|
-
.badge{padding:5px 10px;border-radius:8px;font-size:12px;font-weight:600;background:${accent};color:#fff;opacity:0.95;box-shadow:0 2px 4px rgba(0,0,0,0.2)}
|
|
798
|
-
.kind{color:#94a3b8;font-size:13px;font-weight:500}
|
|
799
|
-
.content{padding:24px}
|
|
800
|
-
.label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin-bottom:8px}
|
|
801
|
-
.message{margin:0;padding:16px 20px;background:rgba(239,68,68,0.12);border:1px solid rgba(239,68,68,0.25);border-radius:10px;overflow-x:auto;white-space:pre-wrap;word-break:break-word;color:#fca5a5;font-size:13px;line-height:1.5}
|
|
802
|
-
.hint{margin-top:20px;padding:12px 20px;background:rgba(71,85,105,0.3);border-radius:10px;border:1px solid rgba(71,85,105,0.4);color:#cbd5e1;font-size:13px}
|
|
803
|
-
</style>
|
|
804
|
-
</head>
|
|
805
|
-
<body>
|
|
806
|
-
<div class="card">
|
|
807
|
-
<div class="header">
|
|
808
|
-
<div style="display:flex;align-items:center;gap:12px">
|
|
809
|
-
<span class="brand">AbsoluteJS</span>
|
|
810
|
-
<span class="badge">${label}</span>
|
|
811
|
-
</div>
|
|
812
|
-
<span class="kind">Server Render Error</span>
|
|
813
|
-
</div>
|
|
814
|
-
<div class="content">
|
|
815
|
-
<div class="label">What went wrong</div>
|
|
816
|
-
<pre class="message">${message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</pre>
|
|
817
|
-
<div class="hint">A component threw during server-side rendering. Check the terminal for the full stack trace.</div>
|
|
818
|
-
</div>
|
|
819
|
-
</div>
|
|
820
|
-
</body>
|
|
821
|
-
</html>`;
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
// src/utils/stringModifiers.ts
|
|
825
|
-
var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
|
|
826
|
-
if (!str.includes("-") && !str.includes("_")) {
|
|
827
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
828
|
-
}
|
|
829
|
-
return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
|
|
830
|
-
}, toScreamingSnake = (str) => str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase();
|
|
831
|
-
|
|
832
|
-
// src/utils/resolveConvention.ts
|
|
833
|
-
import { basename } from "path";
|
|
834
|
-
var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
|
|
835
|
-
const value = Reflect.get(globalThis, CONVENTIONS_KEY);
|
|
836
|
-
if (isConventionsMap(value))
|
|
837
|
-
return value;
|
|
838
|
-
const empty = {};
|
|
839
|
-
return empty;
|
|
840
|
-
}, derivePageName = (pagePath) => {
|
|
841
|
-
const base = basename(pagePath);
|
|
842
|
-
const dotIndex = base.indexOf(".");
|
|
843
|
-
const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
|
|
844
|
-
return toPascal(name);
|
|
845
|
-
}, resolveErrorConventionPath = (framework, pageName) => {
|
|
846
|
-
const conventions = getMap()[framework];
|
|
847
|
-
if (!conventions)
|
|
848
|
-
return;
|
|
849
|
-
return conventions.pages?.[pageName]?.error ?? conventions.defaults?.error;
|
|
850
|
-
}, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
|
|
851
|
-
Reflect.set(globalThis, CONVENTIONS_KEY, map);
|
|
852
|
-
}, isDev = () => true, buildErrorProps = (error) => {
|
|
853
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
854
|
-
const stack = isDev() && error instanceof Error ? error.stack : undefined;
|
|
855
|
-
return { error: { message, stack } };
|
|
856
|
-
}, renderReactError = async (conventionPath, errorProps) => {
|
|
857
|
-
const { createElement } = await import("react");
|
|
858
|
-
const { renderToReadableStream } = await import("react-dom/server");
|
|
859
|
-
const mod = await import(conventionPath);
|
|
860
|
-
const [firstKey] = Object.keys(mod);
|
|
861
|
-
const ErrorComponent = mod.default ?? (firstKey ? mod[firstKey] : undefined);
|
|
862
|
-
const element = createElement(ErrorComponent, errorProps);
|
|
863
|
-
const stream = await renderToReadableStream(element);
|
|
864
|
-
return new Response(stream, {
|
|
865
|
-
headers: { "Content-Type": "text/html" },
|
|
866
|
-
status: 500
|
|
867
|
-
});
|
|
868
|
-
}, renderSvelteError = async (conventionPath, errorProps) => {
|
|
869
|
-
const { render } = await import("svelte/server");
|
|
870
|
-
const mod = await import(conventionPath);
|
|
871
|
-
const ErrorComponent = mod.default;
|
|
872
|
-
const { head, body } = render(ErrorComponent, {
|
|
873
|
-
props: errorProps
|
|
874
|
-
});
|
|
875
|
-
const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
|
|
876
|
-
return new Response(html, {
|
|
877
|
-
headers: { "Content-Type": "text/html" },
|
|
878
|
-
status: 500
|
|
879
|
-
});
|
|
880
|
-
}, unescapeVueStyles = (ssrBody) => {
|
|
881
|
-
let styles = "";
|
|
882
|
-
const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
|
|
883
|
-
styles += `<style>${css.replace(/"/g, '"').replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</style>`;
|
|
884
|
-
return "";
|
|
885
|
-
});
|
|
886
|
-
return { body, styles };
|
|
887
|
-
}, renderVueError = async (conventionPath, errorProps) => {
|
|
888
|
-
const { createSSRApp, h } = await import("vue");
|
|
889
|
-
const { renderToString } = await import("vue/server-renderer");
|
|
890
|
-
const mod = await import(conventionPath);
|
|
891
|
-
const ErrorComponent = mod.default;
|
|
892
|
-
const app = createSSRApp({
|
|
893
|
-
render: () => h(ErrorComponent, errorProps)
|
|
894
|
-
});
|
|
895
|
-
const rawBody = await renderToString(app);
|
|
896
|
-
const { styles, body } = unescapeVueStyles(rawBody);
|
|
897
|
-
const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
|
|
898
|
-
return new Response(html, {
|
|
899
|
-
headers: { "Content-Type": "text/html" },
|
|
900
|
-
status: 500
|
|
901
|
-
});
|
|
902
|
-
}, renderAngularError = async (conventionPath, errorProps) => {
|
|
903
|
-
const mod = await import(conventionPath);
|
|
904
|
-
const renderError = mod.default ?? mod.renderError;
|
|
905
|
-
if (typeof renderError !== "function")
|
|
906
|
-
return null;
|
|
907
|
-
const html = renderError(errorProps);
|
|
908
|
-
return new Response(html, {
|
|
909
|
-
headers: { "Content-Type": "text/html" },
|
|
910
|
-
status: 500
|
|
911
|
-
});
|
|
912
|
-
}, logConventionRenderError = (framework, label, renderError) => {
|
|
913
|
-
const message = renderError instanceof Error ? renderError.message : "";
|
|
914
|
-
if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
|
|
915
|
-
console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
|
|
317
|
+
return conventions.pages?.[pageName]?.error ?? conventions.defaults?.error;
|
|
318
|
+
}, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
|
|
319
|
+
Reflect.set(globalThis, CONVENTIONS_KEY, map);
|
|
320
|
+
}, isDev = () => true, buildErrorProps = (error) => {
|
|
321
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
322
|
+
const stack = isDev() && error instanceof Error ? error.stack : undefined;
|
|
323
|
+
return { error: { message, stack } };
|
|
324
|
+
}, renderReactError = async (conventionPath, errorProps) => {
|
|
325
|
+
const { createElement } = await import("react");
|
|
326
|
+
const { renderToReadableStream } = await import("react-dom/server");
|
|
327
|
+
const mod = await import(conventionPath);
|
|
328
|
+
const [firstKey] = Object.keys(mod);
|
|
329
|
+
const ErrorComponent = mod.default ?? (firstKey ? mod[firstKey] : undefined);
|
|
330
|
+
const element = createElement(ErrorComponent, errorProps);
|
|
331
|
+
const stream = await renderToReadableStream(element);
|
|
332
|
+
return new Response(stream, {
|
|
333
|
+
headers: { "Content-Type": "text/html" },
|
|
334
|
+
status: 500
|
|
335
|
+
});
|
|
336
|
+
}, renderSvelteError = async (conventionPath, errorProps) => {
|
|
337
|
+
const { render } = await import("svelte/server");
|
|
338
|
+
const mod = await import(conventionPath);
|
|
339
|
+
const ErrorComponent = mod.default;
|
|
340
|
+
const { head, body } = render(ErrorComponent, {
|
|
341
|
+
props: errorProps
|
|
342
|
+
});
|
|
343
|
+
const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
|
|
344
|
+
return new Response(html, {
|
|
345
|
+
headers: { "Content-Type": "text/html" },
|
|
346
|
+
status: 500
|
|
347
|
+
});
|
|
348
|
+
}, unescapeVueStyles = (ssrBody) => {
|
|
349
|
+
let styles = "";
|
|
350
|
+
const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
|
|
351
|
+
styles += `<style>${css.replace(/"/g, '"').replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</style>`;
|
|
352
|
+
return "";
|
|
353
|
+
});
|
|
354
|
+
return { body, styles };
|
|
355
|
+
}, renderVueError = async (conventionPath, errorProps) => {
|
|
356
|
+
const { createSSRApp, h } = await import("vue");
|
|
357
|
+
const { renderToString } = await import("vue/server-renderer");
|
|
358
|
+
const mod = await import(conventionPath);
|
|
359
|
+
const ErrorComponent = mod.default;
|
|
360
|
+
const app = createSSRApp({
|
|
361
|
+
render: () => h(ErrorComponent, errorProps)
|
|
362
|
+
});
|
|
363
|
+
const rawBody = await renderToString(app);
|
|
364
|
+
const { styles, body } = unescapeVueStyles(rawBody);
|
|
365
|
+
const html = `<!DOCTYPE html><html><head>${styles}</head><body><div id="root">${body}</div></body></html>`;
|
|
366
|
+
return new Response(html, {
|
|
367
|
+
headers: { "Content-Type": "text/html" },
|
|
368
|
+
status: 500
|
|
369
|
+
});
|
|
370
|
+
}, renderAngularError = async (conventionPath, errorProps) => {
|
|
371
|
+
const mod = await import(conventionPath);
|
|
372
|
+
const renderError = mod.default ?? mod.renderError;
|
|
373
|
+
if (typeof renderError !== "function")
|
|
374
|
+
return null;
|
|
375
|
+
const html = renderError(errorProps);
|
|
376
|
+
return new Response(html, {
|
|
377
|
+
headers: { "Content-Type": "text/html" },
|
|
378
|
+
status: 500
|
|
379
|
+
});
|
|
380
|
+
}, logConventionRenderError = (framework, label, renderError) => {
|
|
381
|
+
const message = renderError instanceof Error ? renderError.message : "";
|
|
382
|
+
if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
|
|
383
|
+
console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
|
|
916
384
|
return;
|
|
917
385
|
}
|
|
918
386
|
console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
|
|
@@ -1021,20 +489,6 @@ var init_resolveConvention = __esm(() => {
|
|
|
1021
489
|
];
|
|
1022
490
|
});
|
|
1023
491
|
|
|
1024
|
-
// src/react/streamingSlotCollection.tsx
|
|
1025
|
-
import { createContext, useContext } from "react";
|
|
1026
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
1027
|
-
var StreamingSlotCollectorContext, StreamingSlotCollectorProvider = ({
|
|
1028
|
-
children,
|
|
1029
|
-
collector
|
|
1030
|
-
}) => /* @__PURE__ */ jsxDEV(StreamingSlotCollectorContext.Provider, {
|
|
1031
|
-
value: collector,
|
|
1032
|
-
children
|
|
1033
|
-
}, undefined, false, undefined, this), useStreamingSlotCollector = () => useContext(StreamingSlotCollectorContext);
|
|
1034
|
-
var init_streamingSlotCollection = __esm(() => {
|
|
1035
|
-
StreamingSlotCollectorContext = createContext(null);
|
|
1036
|
-
});
|
|
1037
|
-
|
|
1038
492
|
// src/react/pageHandler.ts
|
|
1039
493
|
var ssrDirty = false, buildDirtyResponse = (index, maybeProps) => {
|
|
1040
494
|
const propsScript = maybeProps ? `window.__INITIAL_PROPS__=${JSON.stringify(maybeProps)};` : "";
|
|
@@ -1053,9 +507,7 @@ var ssrDirty = false, buildDirtyResponse = (index, maybeProps) => {
|
|
|
1053
507
|
try {
|
|
1054
508
|
const { createElement } = await import("react");
|
|
1055
509
|
const { renderToReadableStream } = await import("react-dom/server");
|
|
1056
|
-
const
|
|
1057
|
-
const pageElement = maybeProps !== undefined ? createElement(PageComponent, maybeProps) : createElement(PageComponent);
|
|
1058
|
-
const element = createElement(StreamingSlotCollectorProvider, { collector: slotCollector }, pageElement);
|
|
510
|
+
const element = maybeProps !== undefined ? createElement(PageComponent, maybeProps) : createElement(PageComponent);
|
|
1059
511
|
const propsScript = maybeProps ? `window.__INITIAL_PROPS__=${JSON.stringify(maybeProps)};` : "";
|
|
1060
512
|
const refreshSetup = "window.__REFRESH_BUFFER__=[];window.$RefreshReg$=function(t,i){window.__REFRESH_BUFFER__.push([t,i])};window.$RefreshSig$=function(){return function(t){return t}};";
|
|
1061
513
|
const stream = await renderToReadableStream(element, {
|
|
@@ -1065,14 +517,9 @@ var ssrDirty = false, buildDirtyResponse = (index, maybeProps) => {
|
|
|
1065
517
|
console.error("[SSR] React streaming error:", error);
|
|
1066
518
|
}
|
|
1067
519
|
});
|
|
1068
|
-
if ("allReady" in stream && stream.allReady instanceof Promise) {
|
|
1069
|
-
await stream.allReady;
|
|
1070
|
-
}
|
|
1071
520
|
const htmlStream = injectIslandPageContextStream(stream);
|
|
1072
|
-
return
|
|
521
|
+
return new Response(htmlStream, {
|
|
1073
522
|
headers: { "Content-Type": "text/html" }
|
|
1074
|
-
}), {
|
|
1075
|
-
streamingSlots: [...slotCollector.values()]
|
|
1076
523
|
});
|
|
1077
524
|
} catch (error) {
|
|
1078
525
|
console.error("[SSR] React render error:", error);
|
|
@@ -1089,9 +536,7 @@ var ssrDirty = false, buildDirtyResponse = (index, maybeProps) => {
|
|
|
1089
536
|
ssrDirty = true;
|
|
1090
537
|
};
|
|
1091
538
|
var init_pageHandler = __esm(() => {
|
|
1092
|
-
init_responseEnhancers();
|
|
1093
539
|
init_resolveConvention();
|
|
1094
|
-
init_streamingSlotCollection();
|
|
1095
540
|
});
|
|
1096
541
|
|
|
1097
542
|
// src/core/islandManifest.ts
|
|
@@ -1665,413 +1110,995 @@ var angularIslandSelector = "abs-angular-island", getAngularIslandSelector = (_i
|
|
|
1665
1110
|
platformProviders: [],
|
|
1666
1111
|
url: "/"
|
|
1667
1112
|
}));
|
|
1668
|
-
const islandHtml = extractAngularIslandRoot(html, selector);
|
|
1669
|
-
requestCache?.set(renderCacheKey, islandHtml);
|
|
1670
|
-
return islandHtml;
|
|
1113
|
+
const islandHtml = extractAngularIslandRoot(html, selector);
|
|
1114
|
+
requestCache?.set(renderCacheKey, islandHtml);
|
|
1115
|
+
return islandHtml;
|
|
1116
|
+
};
|
|
1117
|
+
var init_islands2 = __esm(() => {
|
|
1118
|
+
init_angularDeps();
|
|
1119
|
+
init_ssrRender();
|
|
1120
|
+
init_registerClientScript();
|
|
1121
|
+
wrapperMetadataCache = new Map;
|
|
1122
|
+
requestRenderCache = new Map;
|
|
1123
|
+
});
|
|
1124
|
+
|
|
1125
|
+
// src/core/islandSsr.ts
|
|
1126
|
+
import { createElement } from "react";
|
|
1127
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
1128
|
+
import { render as renderSvelte } from "svelte/server";
|
|
1129
|
+
import { createSSRApp, h } from "vue";
|
|
1130
|
+
import { renderToString as renderVueToString } from "vue/server-renderer";
|
|
1131
|
+
var renderReactIslandToHtml = (component, props) => renderToStaticMarkup(createElement(component, props)), renderSvelteIslandToHtml = (component, props) => {
|
|
1132
|
+
const { body } = renderSvelte(component, { props });
|
|
1133
|
+
return body;
|
|
1134
|
+
}, renderVueIslandToHtml = (component, props) => {
|
|
1135
|
+
const app = createSSRApp({
|
|
1136
|
+
render: () => h(component, props)
|
|
1137
|
+
});
|
|
1138
|
+
return renderVueToString(app);
|
|
1139
|
+
};
|
|
1140
|
+
var init_islandSsr = __esm(() => {
|
|
1141
|
+
init_islands2();
|
|
1142
|
+
});
|
|
1143
|
+
|
|
1144
|
+
// src/constants.ts
|
|
1145
|
+
var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000;
|
|
1146
|
+
var init_constants = __esm(() => {
|
|
1147
|
+
MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
|
|
1148
|
+
MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
|
|
1149
|
+
TWO_THIRDS = 2 / 3;
|
|
1150
|
+
});
|
|
1151
|
+
|
|
1152
|
+
// src/svelte/lowerIslandSyntax.ts
|
|
1153
|
+
var ISLAND_TAG_RE, extractBracedExpression = (text, braceStart) => {
|
|
1154
|
+
let depth = 0;
|
|
1155
|
+
for (let index = braceStart;index < text.length; index += 1) {
|
|
1156
|
+
const char = text[index];
|
|
1157
|
+
if (char === "{")
|
|
1158
|
+
depth += 1;
|
|
1159
|
+
if (char === "}")
|
|
1160
|
+
depth -= 1;
|
|
1161
|
+
if (depth === 0) {
|
|
1162
|
+
return text.slice(braceStart + 1, index).trim();
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return null;
|
|
1166
|
+
}, extractIslandAttribute = (attributeString, name) => {
|
|
1167
|
+
const quotedMatch = attributeString.match(new RegExp(`\\b${name}\\s*=\\s*["']([^"']+)["']`));
|
|
1168
|
+
if (quotedMatch?.[1]) {
|
|
1169
|
+
return { expression: JSON.stringify(quotedMatch[1]), found: true };
|
|
1170
|
+
}
|
|
1171
|
+
const attributeIndex = attributeString.search(new RegExp(`\\b${name}\\s*=\\s*\\{`));
|
|
1172
|
+
if (attributeIndex < 0) {
|
|
1173
|
+
return { expression: "", found: false };
|
|
1174
|
+
}
|
|
1175
|
+
const braceStart = attributeString.indexOf("{", attributeIndex);
|
|
1176
|
+
if (braceStart < 0) {
|
|
1177
|
+
return { expression: "", found: false };
|
|
1178
|
+
}
|
|
1179
|
+
const expression = extractBracedExpression(attributeString, braceStart);
|
|
1180
|
+
if (expression === null) {
|
|
1181
|
+
return { expression: "", found: false };
|
|
1182
|
+
}
|
|
1183
|
+
return { expression, found: true };
|
|
1184
|
+
}, lowerSvelteIslandSyntax = (source, _mode = "server") => {
|
|
1185
|
+
if (!source.includes("<Island")) {
|
|
1186
|
+
return { code: source, transformed: false };
|
|
1187
|
+
}
|
|
1188
|
+
let islandIndex = 0;
|
|
1189
|
+
const transformedMarkup = source.replace(ISLAND_TAG_RE, (fullMatch, attributeString) => {
|
|
1190
|
+
const framework = extractIslandAttribute(attributeString, "framework");
|
|
1191
|
+
const component = extractIslandAttribute(attributeString, "component");
|
|
1192
|
+
if (!framework.found || !component.found) {
|
|
1193
|
+
return fullMatch;
|
|
1194
|
+
}
|
|
1195
|
+
const hydrate = extractIslandAttribute(attributeString, "hydrate");
|
|
1196
|
+
const props = extractIslandAttribute(attributeString, "props");
|
|
1197
|
+
const slotId = `absolute-svelte-island-${islandIndex.toString(BASE_36_RADIX)}`;
|
|
1198
|
+
islandIndex += 1;
|
|
1199
|
+
const resolveExpression = `await __absoluteResolveIslandHtml(${JSON.stringify(slotId)}, { component: ${component.expression}, framework: ${framework.expression}, hydrate: ${hydrate.found ? hydrate.expression : JSON.stringify("load")}, props: ${props.found ? props.expression : "{}"} })`;
|
|
1200
|
+
return `<div data-absolute-island-slot="${slotId}" style="display: contents">{@html ${resolveExpression}}</div>`;
|
|
1201
|
+
});
|
|
1202
|
+
const importLine = 'import { resolveIslandHtml as __absoluteResolveIslandHtml } from "@absolutejs/absolute/svelte";';
|
|
1203
|
+
if (transformedMarkup.includes("<script")) {
|
|
1204
|
+
return {
|
|
1205
|
+
code: transformedMarkup.replace(/<script(\s[^>]*)?>/, (match) => `${match}
|
|
1206
|
+
${importLine}
|
|
1207
|
+
`),
|
|
1208
|
+
transformed: true
|
|
1209
|
+
};
|
|
1210
|
+
}
|
|
1211
|
+
return {
|
|
1212
|
+
code: `<script lang="ts">
|
|
1213
|
+
${importLine}
|
|
1214
|
+
</script>
|
|
1215
|
+
${transformedMarkup}`,
|
|
1216
|
+
transformed: true
|
|
1217
|
+
};
|
|
1218
|
+
};
|
|
1219
|
+
var init_lowerIslandSyntax = __esm(() => {
|
|
1220
|
+
init_constants();
|
|
1221
|
+
ISLAND_TAG_RE = /<Island\b([\s\S]*?)\/>/g;
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
// src/core/svelteServerModule.ts
|
|
1225
|
+
import { mkdir, readdir } from "fs/promises";
|
|
1226
|
+
import { basename as basename2, dirname as dirname2, extname, join as join2, relative, resolve as resolve3 } from "path";
|
|
1227
|
+
var serverCacheRoot, compiledModuleCache, originalSourcePathCache, transpiler, ensureRelativeImportPath = (from, target) => {
|
|
1228
|
+
const importPath = relative(dirname2(from), target).replace(/\\/g, "/");
|
|
1229
|
+
return importPath.startsWith(".") ? importPath : `./${importPath}`;
|
|
1230
|
+
}, processDirectoryEntries = (entries, dir, targetFileName, stack) => {
|
|
1231
|
+
for (const entry of entries) {
|
|
1232
|
+
const entryPath = join2(dir, entry.name);
|
|
1233
|
+
if (entry.isDirectory())
|
|
1234
|
+
stack.push(entryPath);
|
|
1235
|
+
if (entry.isFile() && entry.name === targetFileName) {
|
|
1236
|
+
return entryPath;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
return null;
|
|
1240
|
+
}, searchDirectoryLevel = async (dirs, targetFileName) => {
|
|
1241
|
+
if (dirs.length === 0)
|
|
1242
|
+
return null;
|
|
1243
|
+
const nextStack = [];
|
|
1244
|
+
const dirEntries = await Promise.all(dirs.map(async (dir) => ({
|
|
1245
|
+
dir,
|
|
1246
|
+
entries: await readdir(dir, {
|
|
1247
|
+
encoding: "utf-8",
|
|
1248
|
+
withFileTypes: true
|
|
1249
|
+
})
|
|
1250
|
+
})));
|
|
1251
|
+
for (const { dir, entries } of dirEntries) {
|
|
1252
|
+
const found = processDirectoryEntries(entries, dir, targetFileName, nextStack);
|
|
1253
|
+
if (found)
|
|
1254
|
+
return found;
|
|
1255
|
+
}
|
|
1256
|
+
return searchDirectoryLevel(nextStack, targetFileName);
|
|
1257
|
+
}, findSourceFileByBasename = async (searchRoot, targetFileName) => searchDirectoryLevel([searchRoot], targetFileName), normalizeBuiltSvelteFileName = (sourcePath) => basename2(sourcePath).replace(/-[a-z0-9]{6,}(?=\.svelte$)/i, ""), resolveOriginalSourcePath = async (sourcePath) => {
|
|
1258
|
+
const cachedPath = originalSourcePathCache.get(sourcePath);
|
|
1259
|
+
if (cachedPath !== undefined) {
|
|
1260
|
+
return cachedPath;
|
|
1261
|
+
}
|
|
1262
|
+
if (!sourcePath.includes(`${join2(process.cwd(), "build")}${process.platform === "win32" ? "" : "/"}`) && !sourcePath.includes("/build/")) {
|
|
1263
|
+
originalSourcePathCache.set(sourcePath, sourcePath);
|
|
1264
|
+
return sourcePath;
|
|
1265
|
+
}
|
|
1266
|
+
const resolvedSourcePath = await findSourceFileByBasename(join2(process.cwd(), "src"), normalizeBuiltSvelteFileName(sourcePath));
|
|
1267
|
+
const nextPath = resolvedSourcePath ?? sourcePath;
|
|
1268
|
+
originalSourcePathCache.set(sourcePath, nextPath);
|
|
1269
|
+
return nextPath;
|
|
1270
|
+
}, resolveRelativeModule = async (spec, from) => {
|
|
1271
|
+
if (!spec.startsWith(".")) {
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
const basePath = resolve3(dirname2(from), spec);
|
|
1275
|
+
const candidates = [
|
|
1276
|
+
basePath,
|
|
1277
|
+
`${basePath}.ts`,
|
|
1278
|
+
`${basePath}.js`,
|
|
1279
|
+
`${basePath}.mjs`,
|
|
1280
|
+
`${basePath}.cjs`,
|
|
1281
|
+
`${basePath}.json`,
|
|
1282
|
+
join2(basePath, "index.ts"),
|
|
1283
|
+
join2(basePath, "index.js"),
|
|
1284
|
+
join2(basePath, "index.mjs"),
|
|
1285
|
+
join2(basePath, "index.cjs"),
|
|
1286
|
+
join2(basePath, "index.json")
|
|
1287
|
+
];
|
|
1288
|
+
const existResults = await Promise.all(candidates.map((candidate) => Bun.file(candidate).exists()));
|
|
1289
|
+
const foundIndex = existResults.indexOf(true);
|
|
1290
|
+
return foundIndex >= 0 ? candidates[foundIndex] ?? null : null;
|
|
1291
|
+
}, getCachedModulePath = (sourcePath) => {
|
|
1292
|
+
const relativeSourcePath = relative(process.cwd(), sourcePath).replace(/\\/g, "/");
|
|
1293
|
+
const normalizedSourcePath = relativeSourcePath.startsWith("..") ? sourcePath.replace(/[:\\/]/g, "_") : relativeSourcePath;
|
|
1294
|
+
return join2(serverCacheRoot, `${normalizedSourcePath}.server.js`);
|
|
1295
|
+
}, resolveSvelteImport = async (spec, from) => {
|
|
1296
|
+
if (spec.startsWith("/")) {
|
|
1297
|
+
return spec;
|
|
1298
|
+
}
|
|
1299
|
+
if (!spec.startsWith(".")) {
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|
|
1302
|
+
const explicitPath = resolve3(dirname2(from), spec);
|
|
1303
|
+
if (extname(explicitPath) === ".svelte") {
|
|
1304
|
+
return explicitPath;
|
|
1305
|
+
}
|
|
1306
|
+
const candidate = `${explicitPath}.svelte`;
|
|
1307
|
+
if (await Bun.file(candidate).exists() === true) {
|
|
1308
|
+
return candidate;
|
|
1309
|
+
}
|
|
1310
|
+
return null;
|
|
1311
|
+
}, writeIfChanged = async (path, content) => {
|
|
1312
|
+
const targetFile = Bun.file(path);
|
|
1313
|
+
const exists = await targetFile.exists();
|
|
1314
|
+
if (exists) {
|
|
1315
|
+
const currentContent = await targetFile.text();
|
|
1316
|
+
if (currentContent === content) {
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
await Bun.write(path, content);
|
|
1321
|
+
}, compileSvelteServerModule = async (sourcePath) => {
|
|
1322
|
+
const cachedModulePath = compiledModuleCache.get(sourcePath);
|
|
1323
|
+
if (cachedModulePath) {
|
|
1324
|
+
return cachedModulePath;
|
|
1325
|
+
}
|
|
1326
|
+
const resolutionSourcePath = await resolveOriginalSourcePath(sourcePath);
|
|
1327
|
+
const source = await Bun.file(sourcePath).text();
|
|
1328
|
+
const { compile, preprocess } = await import("svelte/compiler");
|
|
1329
|
+
const loweredSource = lowerSvelteIslandSyntax(source, "server");
|
|
1330
|
+
const preprocessed = await preprocess(loweredSource.code, {});
|
|
1331
|
+
let transpiled = sourcePath.endsWith(".ts") || sourcePath.endsWith(".svelte.ts") ? transpiler.transformSync(preprocessed.code) : preprocessed.code;
|
|
1332
|
+
const childImportSpecs = Array.from(transpiled.matchAll(/from\s+['"]([^'"]+)['"]/g)).map((match) => match[1]).filter((value) => value !== undefined);
|
|
1333
|
+
const resolvedChildModules = await Promise.all(childImportSpecs.map((spec) => resolveSvelteImport(spec, resolutionSourcePath)));
|
|
1334
|
+
const resolvedModuleImports = await Promise.all(childImportSpecs.map((spec) => resolveRelativeModule(spec, resolutionSourcePath)));
|
|
1335
|
+
const childModulePaths = new Map;
|
|
1336
|
+
const rewrittenModulePaths = new Map;
|
|
1337
|
+
const compiledChildren = await Promise.all(childImportSpecs.map(async (spec, index) => {
|
|
1338
|
+
const resolvedChild = resolvedChildModules[index];
|
|
1339
|
+
if (!spec || !resolvedChild)
|
|
1340
|
+
return null;
|
|
1341
|
+
return {
|
|
1342
|
+
compiledPath: await compileSvelteServerModule(resolvedChild),
|
|
1343
|
+
spec
|
|
1344
|
+
};
|
|
1345
|
+
}));
|
|
1346
|
+
for (const result of compiledChildren) {
|
|
1347
|
+
if (result)
|
|
1348
|
+
childModulePaths.set(result.spec, result.compiledPath);
|
|
1349
|
+
}
|
|
1350
|
+
for (let index = 0;index < childImportSpecs.length; index += 1) {
|
|
1351
|
+
const spec = childImportSpecs[index];
|
|
1352
|
+
const resolvedModuleImport = resolvedModuleImports[index];
|
|
1353
|
+
if (!spec || !resolvedModuleImport)
|
|
1354
|
+
continue;
|
|
1355
|
+
if (resolvedChildModules[index])
|
|
1356
|
+
continue;
|
|
1357
|
+
rewrittenModulePaths.set(spec, ensureRelativeImportPath(getCachedModulePath(sourcePath), resolvedModuleImport));
|
|
1358
|
+
}
|
|
1359
|
+
for (const [spec, resolvedModuleImport] of rewrittenModulePaths) {
|
|
1360
|
+
transpiled = transpiled.replaceAll(spec, resolvedModuleImport);
|
|
1361
|
+
}
|
|
1362
|
+
let compiledCode = compile(transpiled, {
|
|
1363
|
+
css: "injected",
|
|
1364
|
+
experimental: {
|
|
1365
|
+
async: loweredSource.transformed
|
|
1366
|
+
},
|
|
1367
|
+
filename: resolutionSourcePath,
|
|
1368
|
+
generate: "server"
|
|
1369
|
+
}).js.code;
|
|
1370
|
+
for (const [spec, compiledChildPath] of childModulePaths) {
|
|
1371
|
+
compiledCode = compiledCode.replaceAll(spec, ensureRelativeImportPath(getCachedModulePath(sourcePath), compiledChildPath));
|
|
1372
|
+
}
|
|
1373
|
+
for (const [spec, resolvedModuleImport] of rewrittenModulePaths) {
|
|
1374
|
+
compiledCode = compiledCode.replaceAll(spec, resolvedModuleImport);
|
|
1375
|
+
}
|
|
1376
|
+
const compiledModulePath = getCachedModulePath(sourcePath);
|
|
1377
|
+
await mkdir(dirname2(compiledModulePath), { recursive: true });
|
|
1378
|
+
await writeIfChanged(compiledModulePath, compiledCode);
|
|
1379
|
+
compiledModuleCache.set(sourcePath, compiledModulePath);
|
|
1380
|
+
return compiledModulePath;
|
|
1671
1381
|
};
|
|
1672
|
-
var
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
// src/core/islandSsr.ts
|
|
1681
|
-
import { createElement } from "react";
|
|
1682
|
-
import { renderToStaticMarkup } from "react-dom/server";
|
|
1683
|
-
import { render as renderSvelte } from "svelte/server";
|
|
1684
|
-
import { createSSRApp, h } from "vue";
|
|
1685
|
-
import { renderToString as renderVueToString } from "vue/server-renderer";
|
|
1686
|
-
var renderReactIslandToHtml = (component, props) => renderToStaticMarkup(createElement(component, props)), renderSvelteIslandToHtml = (component, props) => {
|
|
1687
|
-
const { body } = renderSvelte(component, { props });
|
|
1688
|
-
return body;
|
|
1689
|
-
}, renderVueIslandToHtml = (component, props) => {
|
|
1690
|
-
const app = createSSRApp({
|
|
1691
|
-
render: () => h(component, props)
|
|
1382
|
+
var init_svelteServerModule = __esm(() => {
|
|
1383
|
+
init_lowerIslandSyntax();
|
|
1384
|
+
serverCacheRoot = join2(process.cwd(), ".absolutejs", "islands", "svelte");
|
|
1385
|
+
compiledModuleCache = new Map;
|
|
1386
|
+
originalSourcePathCache = new Map;
|
|
1387
|
+
transpiler = new Bun.Transpiler({
|
|
1388
|
+
loader: "ts",
|
|
1389
|
+
target: "browser"
|
|
1692
1390
|
});
|
|
1693
|
-
return renderVueToString(app);
|
|
1694
|
-
};
|
|
1695
|
-
var init_islandSsr = __esm(() => {
|
|
1696
|
-
init_islands2();
|
|
1697
|
-
});
|
|
1698
|
-
|
|
1699
|
-
// src/constants.ts
|
|
1700
|
-
var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000;
|
|
1701
|
-
var init_constants = __esm(() => {
|
|
1702
|
-
MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
|
|
1703
|
-
MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
|
|
1704
|
-
TWO_THIRDS = 2 / 3;
|
|
1705
1391
|
});
|
|
1706
1392
|
|
|
1707
|
-
// src/
|
|
1708
|
-
var
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1393
|
+
// src/core/renderIslandMarkup.ts
|
|
1394
|
+
var islandSequence = 0, resolvedServerComponentCache, resolvedServerBuildComponentCache, nextIslandId = () => {
|
|
1395
|
+
islandSequence += 1;
|
|
1396
|
+
return `island-${islandSequence}`;
|
|
1397
|
+
}, isRecord2 = (value) => typeof value === "object" && value !== null, isReactServerIslandComponent = (value) => typeof value === "function", isSvelteServerIslandComponent = (value) => typeof value === "function", isVueServerIslandComponent = (value) => typeof value === "function" || isRecord2(value), isAngularServerIslandComponent = (value) => typeof value === "function", resolveBuildReferencePath = (source, registryPath) => {
|
|
1398
|
+
if (source.startsWith("file://"))
|
|
1399
|
+
return new URL(source).pathname;
|
|
1400
|
+
if (source.startsWith("."))
|
|
1401
|
+
return new URL(source, registryPath).pathname;
|
|
1402
|
+
return source;
|
|
1403
|
+
}, loadAndCompileServerBuildComponent = async (buildReferencePath) => {
|
|
1404
|
+
const compiledModulePath = await compileSvelteServerModule(buildReferencePath);
|
|
1405
|
+
const loadedModule = await import(compiledModulePath);
|
|
1406
|
+
return "default" in loadedModule ? loadedModule.default : loadedModule;
|
|
1407
|
+
}, loadServerBuildComponent = async (buildReferencePath) => {
|
|
1408
|
+
const cachedBuildComponent = resolvedServerBuildComponentCache.get(buildReferencePath);
|
|
1409
|
+
if (cachedBuildComponent) {
|
|
1410
|
+
return cachedBuildComponent;
|
|
1719
1411
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1412
|
+
const loadPromise = loadAndCompileServerBuildComponent(buildReferencePath);
|
|
1413
|
+
resolvedServerBuildComponentCache.set(buildReferencePath, loadPromise);
|
|
1414
|
+
return loadPromise;
|
|
1415
|
+
}, loadServerImportComponent = async (resolvedComponent) => {
|
|
1416
|
+
const resolvedModulePath = resolvedComponent.startsWith(".") ? new URL(resolvedComponent, import.meta.url).pathname : resolvedComponent;
|
|
1417
|
+
const importTarget = resolvedModulePath.endsWith(".svelte") ? await compileSvelteServerModule(resolvedModulePath) : resolvedModulePath;
|
|
1418
|
+
const loadedModule = await import(importTarget);
|
|
1419
|
+
return "default" in loadedModule ? loadedModule.default : loadedModule;
|
|
1420
|
+
}, resolveIslandComponent = async (component) => {
|
|
1421
|
+
const buildReference = getIslandBuildReference(component);
|
|
1422
|
+
const buildReferencePath = buildReference?.source ? resolveBuildReferencePath(buildReference.source, import.meta.url) : null;
|
|
1423
|
+
if (buildReferencePath?.endsWith(".svelte")) {
|
|
1424
|
+
return loadServerBuildComponent(buildReferencePath);
|
|
1725
1425
|
}
|
|
1726
|
-
const
|
|
1727
|
-
if (
|
|
1728
|
-
return
|
|
1426
|
+
const resolvedComponent = getIslandComponent(component);
|
|
1427
|
+
if (typeof resolvedComponent !== "string") {
|
|
1428
|
+
return resolvedComponent;
|
|
1729
1429
|
}
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1430
|
+
return loadServerImportComponent(resolvedComponent);
|
|
1431
|
+
}, resolveServerIslandComponent = async (component) => {
|
|
1432
|
+
const cachedResolvedComponent = resolvedServerComponentCache.get(component);
|
|
1433
|
+
if (cachedResolvedComponent) {
|
|
1434
|
+
return cachedResolvedComponent;
|
|
1733
1435
|
}
|
|
1734
|
-
const
|
|
1735
|
-
|
|
1736
|
-
|
|
1436
|
+
const resolutionPromise = resolveIslandComponent(component);
|
|
1437
|
+
resolvedServerComponentCache.set(component, resolutionPromise);
|
|
1438
|
+
return resolutionPromise;
|
|
1439
|
+
}, resolveReactServerIslandComponent = async (component) => {
|
|
1440
|
+
const resolvedComponent = await resolveServerIslandComponent(component);
|
|
1441
|
+
if (!isReactServerIslandComponent(resolvedComponent)) {
|
|
1442
|
+
throw new Error("Resolved React island is not a valid React component.");
|
|
1737
1443
|
}
|
|
1738
|
-
return
|
|
1739
|
-
},
|
|
1740
|
-
|
|
1741
|
-
|
|
1444
|
+
return resolvedComponent;
|
|
1445
|
+
}, resolveSvelteServerIslandComponent = async (component) => {
|
|
1446
|
+
const resolvedComponent = await resolveServerIslandComponent(component);
|
|
1447
|
+
if (!isSvelteServerIslandComponent(resolvedComponent)) {
|
|
1448
|
+
throw new Error("Resolved Svelte island is not a valid Svelte component.");
|
|
1742
1449
|
}
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1450
|
+
return resolvedComponent;
|
|
1451
|
+
}, resolveVueServerIslandComponent = async (component) => {
|
|
1452
|
+
const resolvedComponent = await resolveServerIslandComponent(component);
|
|
1453
|
+
if (!isVueServerIslandComponent(resolvedComponent)) {
|
|
1454
|
+
throw new Error("Resolved Vue island is not a valid Vue component.");
|
|
1455
|
+
}
|
|
1456
|
+
return resolvedComponent;
|
|
1457
|
+
}, resolveAngularServerIslandComponent = async (component) => {
|
|
1458
|
+
const resolvedComponent = await resolveServerIslandComponent(component);
|
|
1459
|
+
if (!isAngularServerIslandComponent(resolvedComponent)) {
|
|
1460
|
+
throw new Error("Resolved Angular island is not a valid Angular component.");
|
|
1461
|
+
}
|
|
1462
|
+
return resolvedComponent;
|
|
1463
|
+
}, renderIslandMarkup = async (registry, props) => {
|
|
1464
|
+
const result = await renderIslandResult(registry, props);
|
|
1465
|
+
return `<div ${serializeIslandAttributes(result.attributes)}>${result.html}</div>`;
|
|
1466
|
+
}, renderIslandResult = async (registry, props) => {
|
|
1467
|
+
const islandId = nextIslandId();
|
|
1468
|
+
const attributes = getIslandMarkerAttributes(props);
|
|
1469
|
+
if (props.framework === "react") {
|
|
1470
|
+
const entry = registry.react?.[props.component];
|
|
1471
|
+
if (!entry) {
|
|
1472
|
+
throw new Error(`Island component "${props.component}" is not registered for framework "react".`);
|
|
1749
1473
|
}
|
|
1750
|
-
const
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1474
|
+
const component = await resolveReactServerIslandComponent(entry);
|
|
1475
|
+
const html = renderReactIslandToHtml(component, props.props);
|
|
1476
|
+
return { attributes, html };
|
|
1477
|
+
}
|
|
1478
|
+
if (props.framework === "svelte") {
|
|
1479
|
+
const entry = registry.svelte?.[props.component];
|
|
1480
|
+
if (!entry) {
|
|
1481
|
+
throw new Error(`Island component "${props.component}" is not registered for framework "svelte".`);
|
|
1482
|
+
}
|
|
1483
|
+
const component = await resolveSvelteServerIslandComponent(entry);
|
|
1484
|
+
const html = renderSvelteIslandToHtml(component, props.props);
|
|
1485
|
+
return { attributes, html };
|
|
1486
|
+
}
|
|
1487
|
+
if (props.framework === "vue") {
|
|
1488
|
+
const entry = registry.vue?.[props.component];
|
|
1489
|
+
if (!entry) {
|
|
1490
|
+
throw new Error(`Island component "${props.component}" is not registered for framework "vue".`);
|
|
1491
|
+
}
|
|
1492
|
+
const component = await resolveVueServerIslandComponent(entry);
|
|
1493
|
+
const html = await renderVueIslandToHtml(component, props.props);
|
|
1494
|
+
return { attributes, html };
|
|
1495
|
+
}
|
|
1496
|
+
if (props.framework === "angular") {
|
|
1497
|
+
const entry = registry.angular?.[props.component];
|
|
1498
|
+
if (!entry) {
|
|
1499
|
+
throw new Error(`Island component "${props.component}" is not registered for framework "angular".`);
|
|
1500
|
+
}
|
|
1501
|
+
const component = await resolveAngularServerIslandComponent(entry);
|
|
1502
|
+
const html = await renderAngularIslandToHtml(component, props.props, islandId);
|
|
1759
1503
|
return {
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1504
|
+
attributes: {
|
|
1505
|
+
...getIslandMarkerAttributes(props, islandId)
|
|
1506
|
+
},
|
|
1507
|
+
html
|
|
1764
1508
|
};
|
|
1765
1509
|
}
|
|
1766
|
-
|
|
1767
|
-
code: `<script lang="ts">
|
|
1768
|
-
${importLine}
|
|
1769
|
-
</script>
|
|
1770
|
-
${transformedMarkup}`,
|
|
1771
|
-
transformed: true
|
|
1772
|
-
};
|
|
1510
|
+
throw new Error(`Framework "${props.framework}" is not implemented in this prototype.`);
|
|
1773
1511
|
};
|
|
1774
|
-
var
|
|
1775
|
-
|
|
1776
|
-
|
|
1512
|
+
var init_renderIslandMarkup = __esm(() => {
|
|
1513
|
+
init_islandSsr();
|
|
1514
|
+
init_svelteServerModule();
|
|
1515
|
+
init_islandMarkupAttributes();
|
|
1516
|
+
init_islands();
|
|
1517
|
+
resolvedServerComponentCache = new Map;
|
|
1518
|
+
resolvedServerBuildComponentCache = new Map;
|
|
1777
1519
|
});
|
|
1778
1520
|
|
|
1779
|
-
// src/
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
const
|
|
1788
|
-
if (
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
return entryPath;
|
|
1521
|
+
// src/client/streamSwap.ts
|
|
1522
|
+
var streamSwapRuntime = () => {
|
|
1523
|
+
if (window.__ABS_SLOT_RUNTIME__ === true)
|
|
1524
|
+
return;
|
|
1525
|
+
window.__ABS_SLOT_RUNTIME__ = true;
|
|
1526
|
+
window.__ABS_SLOT_PENDING__ = window.__ABS_SLOT_PENDING__ ?? {};
|
|
1527
|
+
const pending = window.__ABS_SLOT_PENDING__;
|
|
1528
|
+
const apply = (id, html) => {
|
|
1529
|
+
const node = document.getElementById(`slot-${id}`);
|
|
1530
|
+
if (!node) {
|
|
1531
|
+
pending[id] = html;
|
|
1532
|
+
return;
|
|
1792
1533
|
}
|
|
1534
|
+
node.innerHTML = html;
|
|
1535
|
+
delete pending[id];
|
|
1536
|
+
};
|
|
1537
|
+
const flush = () => {
|
|
1538
|
+
for (const id in pending) {
|
|
1539
|
+
if (!Object.prototype.hasOwnProperty.call(pending, id))
|
|
1540
|
+
continue;
|
|
1541
|
+
apply(id, pending[id] ?? "");
|
|
1542
|
+
}
|
|
1543
|
+
};
|
|
1544
|
+
window.__ABS_SLOT_ENQUEUE__ = (id, html) => {
|
|
1545
|
+
apply(id, html);
|
|
1546
|
+
};
|
|
1547
|
+
if (typeof MutationObserver === "function") {
|
|
1548
|
+
const observer = new MutationObserver(flush);
|
|
1549
|
+
const root = document.documentElement ?? document.body ?? document;
|
|
1550
|
+
observer.observe(root, { childList: true, subtree: true });
|
|
1793
1551
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
if (dirs.length === 0)
|
|
1797
|
-
return null;
|
|
1798
|
-
const nextStack = [];
|
|
1799
|
-
const dirEntries = await Promise.all(dirs.map(async (dir) => ({
|
|
1800
|
-
dir,
|
|
1801
|
-
entries: await readdir(dir, {
|
|
1802
|
-
encoding: "utf-8",
|
|
1803
|
-
withFileTypes: true
|
|
1804
|
-
})
|
|
1805
|
-
})));
|
|
1806
|
-
for (const { dir, entries } of dirEntries) {
|
|
1807
|
-
const found = processDirectoryEntries(entries, dir, targetFileName, nextStack);
|
|
1808
|
-
if (found)
|
|
1809
|
-
return found;
|
|
1810
|
-
}
|
|
1811
|
-
return searchDirectoryLevel(nextStack, targetFileName);
|
|
1812
|
-
}, findSourceFileByBasename = async (searchRoot, targetFileName) => searchDirectoryLevel([searchRoot], targetFileName), normalizeBuiltSvelteFileName = (sourcePath) => basename2(sourcePath).replace(/-[a-z0-9]{6,}(?=\.svelte$)/i, ""), resolveOriginalSourcePath = async (sourcePath) => {
|
|
1813
|
-
const cachedPath = originalSourcePathCache.get(sourcePath);
|
|
1814
|
-
if (cachedPath !== undefined) {
|
|
1815
|
-
return cachedPath;
|
|
1816
|
-
}
|
|
1817
|
-
if (!sourcePath.includes(`${join2(process.cwd(), "build")}${process.platform === "win32" ? "" : "/"}`) && !sourcePath.includes("/build/")) {
|
|
1818
|
-
originalSourcePathCache.set(sourcePath, sourcePath);
|
|
1819
|
-
return sourcePath;
|
|
1552
|
+
if (document.readyState === "loading") {
|
|
1553
|
+
document.addEventListener("DOMContentLoaded", flush, { once: true });
|
|
1820
1554
|
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
if (
|
|
1827
|
-
return
|
|
1555
|
+
flush();
|
|
1556
|
+
};
|
|
1557
|
+
var stripFunctionWrapper = (value) => {
|
|
1558
|
+
const start = value.indexOf("{");
|
|
1559
|
+
const end = value.lastIndexOf("}");
|
|
1560
|
+
if (start < 0 || end <= start)
|
|
1561
|
+
return "";
|
|
1562
|
+
return value.slice(start + 1, end);
|
|
1563
|
+
};
|
|
1564
|
+
var getStreamSwapRuntimeScript = () => `(function(){${stripFunctionWrapper(streamSwapRuntime.toString())}})();`;
|
|
1565
|
+
|
|
1566
|
+
// src/utils/streamingSlots.ts
|
|
1567
|
+
init_escapeScriptContent();
|
|
1568
|
+
var SLOT_ID_PREFIX = "abs-slot-";
|
|
1569
|
+
var SLOT_PLACEHOLDER_PREFIX = "slot-";
|
|
1570
|
+
var CLOSING_HEAD_TAG = "</head>";
|
|
1571
|
+
var CLOSING_HEAD_TAG_LENGTH = CLOSING_HEAD_TAG.length;
|
|
1572
|
+
var CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
|
|
1573
|
+
var STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__";
|
|
1574
|
+
var STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__";
|
|
1575
|
+
var STREAM_TAIL_LOOKBEHIND = 128;
|
|
1576
|
+
var STREAMING_SLOT_TIMEOUT_MS = 5000;
|
|
1577
|
+
var STREAMING_SLOT_MAX_PER_RESPONSE = 128;
|
|
1578
|
+
var STREAMING_SLOT_MAX_HTML_BYTES = 64000;
|
|
1579
|
+
var createSlotPlaceholderId = (id) => `${SLOT_PLACEHOLDER_PREFIX}${id}`;
|
|
1580
|
+
var createSlotPatchStatement = (id, html) => `(window.${STREAMING_RUNTIME_GLOBAL}||function(i,h){window.${STREAMING_PENDING_GLOBAL}=window.${STREAMING_PENDING_GLOBAL}||{};window.${STREAMING_PENDING_GLOBAL}[i]=h;})(${JSON.stringify(id)},${JSON.stringify(html)});`;
|
|
1581
|
+
var createNonceAttr = (nonce) => nonce ? ` nonce="${nonce}"` : "";
|
|
1582
|
+
var createStreamingSlotId = () => `${SLOT_ID_PREFIX}${Math.random().toString(36).slice(2, 10)}`;
|
|
1583
|
+
var getStreamingSlotsRuntimeScript = () => getStreamSwapRuntimeScript();
|
|
1584
|
+
var renderStreamingSlotsRuntimeTag = (nonce) => `<script${createNonceAttr(nonce)}>${escapeScriptContent(getStreamingSlotsRuntimeScript())}</script>`;
|
|
1585
|
+
var renderStreamingSlotPlaceholder = (id, fallbackHtml = "") => `<div id="${createSlotPlaceholderId(id)}" data-absolute-slot="true">${fallbackHtml}</div>`;
|
|
1586
|
+
var renderStreamingSlotPatchTag = (id, html, nonce) => `<script${createNonceAttr(nonce)}>${escapeScriptContent(createSlotPatchStatement(id, html))}</script>`;
|
|
1587
|
+
var injectHtmlIntoHead = (html, injection) => {
|
|
1588
|
+
const closingHeadIndex = html.indexOf(CLOSING_HEAD_TAG);
|
|
1589
|
+
if (closingHeadIndex >= 0) {
|
|
1590
|
+
return `${html.slice(0, closingHeadIndex)}${injection}${html.slice(closingHeadIndex)}`;
|
|
1828
1591
|
}
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
return foundIndex >= 0 ? candidates[foundIndex] ?? null : null;
|
|
1846
|
-
}, getCachedModulePath = (sourcePath) => {
|
|
1847
|
-
const relativeSourcePath = relative(process.cwd(), sourcePath).replace(/\\/g, "/");
|
|
1848
|
-
const normalizedSourcePath = relativeSourcePath.startsWith("..") ? sourcePath.replace(/[:\\/]/g, "_") : relativeSourcePath;
|
|
1849
|
-
return join2(serverCacheRoot, `${normalizedSourcePath}.server.js`);
|
|
1850
|
-
}, resolveSvelteImport = async (spec, from) => {
|
|
1851
|
-
if (spec.startsWith("/")) {
|
|
1852
|
-
return spec;
|
|
1592
|
+
return `${html}${injection}`;
|
|
1593
|
+
};
|
|
1594
|
+
var toUint8 = (value, encoder) => encoder.encode(value);
|
|
1595
|
+
var currentStreamingSlotPolicy = {
|
|
1596
|
+
timeoutMs: STREAMING_SLOT_TIMEOUT_MS,
|
|
1597
|
+
fallbackHtml: "",
|
|
1598
|
+
errorHtml: undefined,
|
|
1599
|
+
maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
|
|
1600
|
+
maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES
|
|
1601
|
+
};
|
|
1602
|
+
var clonePolicy = (policy) => ({
|
|
1603
|
+
...policy
|
|
1604
|
+
});
|
|
1605
|
+
var normalizeSlotBytes = (value, fallback) => {
|
|
1606
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
1607
|
+
return Math.floor(value);
|
|
1853
1608
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1609
|
+
return fallback;
|
|
1610
|
+
};
|
|
1611
|
+
var normalizeSlotText = (value, fallback) => typeof value === "string" ? value : fallback;
|
|
1612
|
+
var normalizeSlotError = (value, fallback) => typeof value === "string" ? value : fallback;
|
|
1613
|
+
var hasPolicyValue = (policy, key) => Object.prototype.hasOwnProperty.call(policy, key);
|
|
1614
|
+
var applyStreamingSlotPolicyOverrides = (base, overridePolicy = {}) => ({
|
|
1615
|
+
timeoutMs: hasPolicyValue(overridePolicy, "timeoutMs") ? normalizeSlotBytes(overridePolicy.timeoutMs, base.timeoutMs) : base.timeoutMs,
|
|
1616
|
+
fallbackHtml: hasPolicyValue(overridePolicy, "fallbackHtml") ? normalizeSlotText(overridePolicy.fallbackHtml, "") : base.fallbackHtml,
|
|
1617
|
+
errorHtml: hasPolicyValue(overridePolicy, "errorHtml") ? normalizeSlotError(overridePolicy.errorHtml) : base.errorHtml,
|
|
1618
|
+
maxSlotsPerResponse: hasPolicyValue(overridePolicy, "maxSlotsPerResponse") ? normalizeSlotBytes(overridePolicy.maxSlotsPerResponse, base.maxSlotsPerResponse) : base.maxSlotsPerResponse,
|
|
1619
|
+
maxSlotHtmlSizeBytes: hasPolicyValue(overridePolicy, "maxSlotHtmlSizeBytes") ? normalizeSlotBytes(overridePolicy.maxSlotHtmlSizeBytes, base.maxSlotHtmlSizeBytes) : base.maxSlotHtmlSizeBytes,
|
|
1620
|
+
onError: hasPolicyValue(overridePolicy, "onError") ? overridePolicy.onError : base.onError,
|
|
1621
|
+
onSlotMetric: hasPolicyValue(overridePolicy, "onSlotMetric") ? overridePolicy.onSlotMetric : base.onSlotMetric
|
|
1622
|
+
});
|
|
1623
|
+
var createCombinedSlotErrorHandler = (policyOnError, enhancerOnError) => {
|
|
1624
|
+
if (!policyOnError && !enhancerOnError)
|
|
1625
|
+
return;
|
|
1626
|
+
return (error, slot) => {
|
|
1627
|
+
policyOnError?.(error, slot);
|
|
1628
|
+
enhancerOnError?.(error, slot);
|
|
1629
|
+
};
|
|
1630
|
+
};
|
|
1631
|
+
var createCombinedSlotMetricHandler = (policyOnSlotMetric, callOnSlotMetric) => {
|
|
1632
|
+
if (!policyOnSlotMetric && !callOnSlotMetric)
|
|
1633
|
+
return;
|
|
1634
|
+
return (metric) => {
|
|
1635
|
+
policyOnSlotMetric?.(metric);
|
|
1636
|
+
callOnSlotMetric?.(metric);
|
|
1637
|
+
};
|
|
1638
|
+
};
|
|
1639
|
+
var resolveStreamingSlotPolicy = (overridePolicy = {}) => {
|
|
1640
|
+
const base = getStreamingSlotPolicy();
|
|
1641
|
+
return applyStreamingSlotPolicyOverrides(base, overridePolicy);
|
|
1642
|
+
};
|
|
1643
|
+
var getStreamingSlotPolicy = () => clonePolicy(currentStreamingSlotPolicy);
|
|
1644
|
+
var setStreamingSlotPolicy = (policy = {}) => {
|
|
1645
|
+
const base = getStreamingSlotPolicy();
|
|
1646
|
+
currentStreamingSlotPolicy = applyStreamingSlotPolicyOverrides(base, policy);
|
|
1647
|
+
};
|
|
1648
|
+
var withStreamingSlotPolicy = async (policy, callback) => {
|
|
1649
|
+
const previous = getStreamingSlotPolicy();
|
|
1650
|
+
setStreamingSlotPolicy(policy);
|
|
1651
|
+
try {
|
|
1652
|
+
return await callback();
|
|
1653
|
+
} finally {
|
|
1654
|
+
currentStreamingSlotPolicy = previous;
|
|
1856
1655
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1656
|
+
};
|
|
1657
|
+
var emitSlotMetric = (metric, onSlotMetric) => {
|
|
1658
|
+
onSlotMetric?.(metric);
|
|
1659
|
+
};
|
|
1660
|
+
var createTimeoutError = (slot, timeoutMs) => {
|
|
1661
|
+
const error = new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`);
|
|
1662
|
+
error.__absTimeout = true;
|
|
1663
|
+
return error;
|
|
1664
|
+
};
|
|
1665
|
+
var toStreamingSlot = (slot, policy) => ({
|
|
1666
|
+
errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
|
|
1667
|
+
fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
|
|
1668
|
+
id: slot.id ?? createStreamingSlotId(),
|
|
1669
|
+
timeoutMs: normalizeSlotBytes(slot.timeoutMs, policy.timeoutMs),
|
|
1670
|
+
resolve: slot.resolve
|
|
1671
|
+
});
|
|
1672
|
+
var prepareSlots = ({
|
|
1673
|
+
policy,
|
|
1674
|
+
slots,
|
|
1675
|
+
onError,
|
|
1676
|
+
onSlotMetric
|
|
1677
|
+
}) => {
|
|
1678
|
+
const preparedSlots = slots.map((slot) => toStreamingSlot(slot, policy));
|
|
1679
|
+
const maxSlotsPerResponse = policy.maxSlotsPerResponse;
|
|
1680
|
+
if (maxSlotsPerResponse === 0) {
|
|
1681
|
+
const error = new Error("Streaming slot limit is set to 0");
|
|
1682
|
+
for (const slot of preparedSlots) {
|
|
1683
|
+
onError?.(error, slot);
|
|
1684
|
+
emitSlotMetric({
|
|
1685
|
+
type: "dropped",
|
|
1686
|
+
slotId: slot.id,
|
|
1687
|
+
reason: "maxSlotsPerResponse is 0"
|
|
1688
|
+
}, onSlotMetric);
|
|
1689
|
+
}
|
|
1690
|
+
return [];
|
|
1860
1691
|
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1692
|
+
if (preparedSlots.length <= maxSlotsPerResponse) {
|
|
1693
|
+
preparedSlots.forEach((slot) => emitSlotMetric({
|
|
1694
|
+
type: "prepared",
|
|
1695
|
+
slotId: slot.id
|
|
1696
|
+
}, onSlotMetric));
|
|
1697
|
+
return preparedSlots;
|
|
1864
1698
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1699
|
+
const keptSlots = preparedSlots.slice(0, maxSlotsPerResponse);
|
|
1700
|
+
const droppedSlots = preparedSlots.slice(maxSlotsPerResponse);
|
|
1701
|
+
droppedSlots.forEach((slot) => {
|
|
1702
|
+
onError?.(new Error(`Streaming slot "${slot.id}" dropped because ${maxSlotsPerResponse} slots is the configured maximum`), slot);
|
|
1703
|
+
emitSlotMetric({
|
|
1704
|
+
type: "dropped",
|
|
1705
|
+
slotId: slot.id,
|
|
1706
|
+
reason: `maxSlotsPerResponse is ${maxSlotsPerResponse}`
|
|
1707
|
+
}, onSlotMetric);
|
|
1708
|
+
});
|
|
1709
|
+
keptSlots.forEach((slot) => emitSlotMetric({
|
|
1710
|
+
type: "prepared",
|
|
1711
|
+
slotId: slot.id
|
|
1712
|
+
}, onSlotMetric));
|
|
1713
|
+
return keptSlots;
|
|
1714
|
+
};
|
|
1715
|
+
var htmlByteLength = (value, encoder) => encoder.encode(value).length;
|
|
1716
|
+
var resolveSlot = async (slot, onError, policy, onSlotMetric) => {
|
|
1717
|
+
const safePolicy = policy ?? getStreamingSlotPolicy();
|
|
1718
|
+
const encoder = new TextEncoder;
|
|
1719
|
+
const start = Date.now();
|
|
1720
|
+
try {
|
|
1721
|
+
const maybeAsyncValue = Promise.resolve(slot.resolve());
|
|
1722
|
+
const resolved = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
|
|
1723
|
+
maybeAsyncValue,
|
|
1724
|
+
new Promise((_, reject) => setTimeout(() => {
|
|
1725
|
+
reject(createTimeoutError(slot, slot.timeoutMs ?? 0));
|
|
1726
|
+
}, slot.timeoutMs))
|
|
1727
|
+
]) : await maybeAsyncValue;
|
|
1728
|
+
const html = typeof resolved === "string" ? resolved : `${resolved}`;
|
|
1729
|
+
if (safePolicy.maxSlotHtmlSizeBytes > 0 && htmlByteLength(html, encoder) > safePolicy.maxSlotHtmlSizeBytes) {
|
|
1730
|
+
const bytes2 = htmlByteLength(html, encoder);
|
|
1731
|
+
const error = new Error(`Streaming slot "${slot.id}" exceeded max payload size of ${safePolicy.maxSlotHtmlSizeBytes} bytes`);
|
|
1732
|
+
const durationMs2 = Date.now() - start;
|
|
1733
|
+
onError?.(error, slot);
|
|
1734
|
+
emitSlotMetric({
|
|
1735
|
+
type: "size_exceeded",
|
|
1736
|
+
slotId: slot.id,
|
|
1737
|
+
durationMs: durationMs2,
|
|
1738
|
+
bytes: bytes2,
|
|
1739
|
+
error
|
|
1740
|
+
}, onSlotMetric);
|
|
1741
|
+
const fallbackHtml = typeof slot.errorHtml === "string" ? slot.errorHtml : null;
|
|
1742
|
+
return {
|
|
1743
|
+
html: fallbackHtml,
|
|
1744
|
+
id: slot.id,
|
|
1745
|
+
durationMs: durationMs2,
|
|
1746
|
+
bytes: fallbackHtml === null ? 0 : htmlByteLength(fallbackHtml, encoder)
|
|
1747
|
+
};
|
|
1873
1748
|
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
const source = await Bun.file(sourcePath).text();
|
|
1883
|
-
const { compile, preprocess } = await import("svelte/compiler");
|
|
1884
|
-
const loweredSource = lowerSvelteIslandSyntax(source, "server");
|
|
1885
|
-
const preprocessed = await preprocess(loweredSource.code, {});
|
|
1886
|
-
let transpiled = sourcePath.endsWith(".ts") || sourcePath.endsWith(".svelte.ts") ? transpiler.transformSync(preprocessed.code) : preprocessed.code;
|
|
1887
|
-
const childImportSpecs = Array.from(transpiled.matchAll(/from\s+['"]([^'"]+)['"]/g)).map((match) => match[1]).filter((value) => value !== undefined);
|
|
1888
|
-
const resolvedChildModules = await Promise.all(childImportSpecs.map((spec) => resolveSvelteImport(spec, resolutionSourcePath)));
|
|
1889
|
-
const resolvedModuleImports = await Promise.all(childImportSpecs.map((spec) => resolveRelativeModule(spec, resolutionSourcePath)));
|
|
1890
|
-
const childModulePaths = new Map;
|
|
1891
|
-
const rewrittenModulePaths = new Map;
|
|
1892
|
-
const compiledChildren = await Promise.all(childImportSpecs.map(async (spec, index) => {
|
|
1893
|
-
const resolvedChild = resolvedChildModules[index];
|
|
1894
|
-
if (!spec || !resolvedChild)
|
|
1895
|
-
return null;
|
|
1749
|
+
const durationMs = Date.now() - start;
|
|
1750
|
+
const bytes = htmlByteLength(html, encoder);
|
|
1751
|
+
emitSlotMetric({
|
|
1752
|
+
type: "resolved",
|
|
1753
|
+
slotId: slot.id,
|
|
1754
|
+
durationMs,
|
|
1755
|
+
bytes
|
|
1756
|
+
}, onSlotMetric);
|
|
1896
1757
|
return {
|
|
1897
|
-
|
|
1898
|
-
|
|
1758
|
+
html,
|
|
1759
|
+
id: slot.id,
|
|
1760
|
+
durationMs,
|
|
1761
|
+
bytes
|
|
1762
|
+
};
|
|
1763
|
+
} catch (error) {
|
|
1764
|
+
const durationMs = Date.now() - start;
|
|
1765
|
+
onError?.(error, slot);
|
|
1766
|
+
emitSlotMetric({
|
|
1767
|
+
type: error?.__absTimeout === true ? "timeout" : "error",
|
|
1768
|
+
slotId: slot.id,
|
|
1769
|
+
durationMs,
|
|
1770
|
+
error
|
|
1771
|
+
}, onSlotMetric);
|
|
1772
|
+
if (typeof slot.errorHtml === "string") {
|
|
1773
|
+
const html = slot.errorHtml;
|
|
1774
|
+
return {
|
|
1775
|
+
html,
|
|
1776
|
+
id: slot.id,
|
|
1777
|
+
durationMs,
|
|
1778
|
+
bytes: htmlByteLength(html, encoder)
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
html: null,
|
|
1783
|
+
id: slot.id,
|
|
1784
|
+
durationMs,
|
|
1785
|
+
bytes: 0
|
|
1899
1786
|
};
|
|
1900
|
-
}));
|
|
1901
|
-
for (const result of compiledChildren) {
|
|
1902
|
-
if (result)
|
|
1903
|
-
childModulePaths.set(result.spec, result.compiledPath);
|
|
1904
|
-
}
|
|
1905
|
-
for (let index = 0;index < childImportSpecs.length; index += 1) {
|
|
1906
|
-
const spec = childImportSpecs[index];
|
|
1907
|
-
const resolvedModuleImport = resolvedModuleImports[index];
|
|
1908
|
-
if (!spec || !resolvedModuleImport)
|
|
1909
|
-
continue;
|
|
1910
|
-
if (resolvedChildModules[index])
|
|
1911
|
-
continue;
|
|
1912
|
-
rewrittenModulePaths.set(spec, ensureRelativeImportPath(getCachedModulePath(sourcePath), resolvedModuleImport));
|
|
1913
|
-
}
|
|
1914
|
-
for (const [spec, resolvedModuleImport] of rewrittenModulePaths) {
|
|
1915
|
-
transpiled = transpiled.replaceAll(spec, resolvedModuleImport);
|
|
1916
|
-
}
|
|
1917
|
-
let compiledCode = compile(transpiled, {
|
|
1918
|
-
css: "injected",
|
|
1919
|
-
experimental: {
|
|
1920
|
-
async: loweredSource.transformed
|
|
1921
|
-
},
|
|
1922
|
-
filename: resolutionSourcePath,
|
|
1923
|
-
generate: "server"
|
|
1924
|
-
}).js.code;
|
|
1925
|
-
for (const [spec, compiledChildPath] of childModulePaths) {
|
|
1926
|
-
compiledCode = compiledCode.replaceAll(spec, ensureRelativeImportPath(getCachedModulePath(sourcePath), compiledChildPath));
|
|
1927
|
-
}
|
|
1928
|
-
for (const [spec, resolvedModuleImport] of rewrittenModulePaths) {
|
|
1929
|
-
compiledCode = compiledCode.replaceAll(spec, resolvedModuleImport);
|
|
1930
1787
|
}
|
|
1931
|
-
const compiledModulePath = getCachedModulePath(sourcePath);
|
|
1932
|
-
await mkdir(dirname2(compiledModulePath), { recursive: true });
|
|
1933
|
-
await writeIfChanged(compiledModulePath, compiledCode);
|
|
1934
|
-
compiledModuleCache.set(sourcePath, compiledModulePath);
|
|
1935
|
-
return compiledModulePath;
|
|
1936
1788
|
};
|
|
1937
|
-
var
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1789
|
+
var nextResolvedSlot = async (pending) => {
|
|
1790
|
+
const wrapped = pending.map((promise) => promise.then((result) => ({
|
|
1791
|
+
original: promise,
|
|
1792
|
+
result
|
|
1793
|
+
})));
|
|
1794
|
+
return Promise.race(wrapped);
|
|
1795
|
+
};
|
|
1796
|
+
var streamChunkToString = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true });
|
|
1797
|
+
var streamOutOfOrderSlots = ({
|
|
1798
|
+
footerHtml = "",
|
|
1799
|
+
headerHtml = "",
|
|
1800
|
+
nonce,
|
|
1801
|
+
policy,
|
|
1802
|
+
onSlotMetric,
|
|
1803
|
+
onError,
|
|
1804
|
+
slots
|
|
1805
|
+
}) => {
|
|
1806
|
+
const resolvedPolicy = resolveStreamingSlotPolicy(policy);
|
|
1807
|
+
const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
|
|
1808
|
+
const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
|
|
1809
|
+
const effectivePolicy = {
|
|
1810
|
+
...resolvedPolicy,
|
|
1811
|
+
onSlotMetric: combinedOnSlotMetric
|
|
1812
|
+
};
|
|
1813
|
+
const preparedSlots = prepareSlots({
|
|
1814
|
+
policy: effectivePolicy,
|
|
1815
|
+
slots,
|
|
1816
|
+
onError: combinedOnError,
|
|
1817
|
+
onSlotMetric: combinedOnSlotMetric
|
|
1945
1818
|
});
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
const
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
1819
|
+
const encoder = new TextEncoder;
|
|
1820
|
+
return new ReadableStream({
|
|
1821
|
+
async start(controller) {
|
|
1822
|
+
try {
|
|
1823
|
+
let header = headerHtml;
|
|
1824
|
+
if (preparedSlots.length > 0 && !header.includes(STREAMING_RUNTIME_GLOBAL)) {
|
|
1825
|
+
header = injectHtmlIntoHead(header, renderStreamingSlotsRuntimeTag(nonce));
|
|
1826
|
+
}
|
|
1827
|
+
controller.enqueue(toUint8(header, encoder));
|
|
1828
|
+
const pending = preparedSlots.map((slot) => {
|
|
1829
|
+
const fallback = renderStreamingSlotPlaceholder(slot.id, slot.fallbackHtml ?? "");
|
|
1830
|
+
controller.enqueue(toUint8(fallback, encoder));
|
|
1831
|
+
return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
|
|
1832
|
+
});
|
|
1833
|
+
while (pending.length > 0) {
|
|
1834
|
+
const { original, result } = await nextResolvedSlot(pending);
|
|
1835
|
+
const index = pending.indexOf(original);
|
|
1836
|
+
if (index >= 0)
|
|
1837
|
+
pending.splice(index, 1);
|
|
1838
|
+
if (result.html === null)
|
|
1839
|
+
continue;
|
|
1840
|
+
emitSlotMetric({
|
|
1841
|
+
type: "patched",
|
|
1842
|
+
slotId: result.id,
|
|
1843
|
+
durationMs: result.durationMs,
|
|
1844
|
+
bytes: result.bytes
|
|
1845
|
+
}, combinedOnSlotMetric);
|
|
1846
|
+
controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.html, nonce), encoder));
|
|
1847
|
+
}
|
|
1848
|
+
if (footerHtml.length > 0) {
|
|
1849
|
+
controller.enqueue(toUint8(footerHtml, encoder));
|
|
1850
|
+
}
|
|
1851
|
+
controller.close();
|
|
1852
|
+
} catch (error) {
|
|
1853
|
+
controller.error(error);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
});
|
|
1857
|
+
};
|
|
1858
|
+
var injectStreamingRuntimeIntoStream = (stream, nonce) => {
|
|
1859
|
+
const runtimeTag = renderStreamingSlotsRuntimeTag(nonce);
|
|
1860
|
+
const encoder = new TextEncoder;
|
|
1861
|
+
const decoder = new TextDecoder;
|
|
1862
|
+
const lookbehind = CLOSING_HEAD_TAG_LENGTH - 1;
|
|
1863
|
+
return new ReadableStream({
|
|
1864
|
+
async start(controller) {
|
|
1865
|
+
const reader = stream.getReader();
|
|
1866
|
+
let injected = false;
|
|
1867
|
+
let pending = "";
|
|
1868
|
+
try {
|
|
1869
|
+
for (;; ) {
|
|
1870
|
+
const { done, value } = await reader.read();
|
|
1871
|
+
if (done)
|
|
1872
|
+
break;
|
|
1873
|
+
if (!value)
|
|
1874
|
+
continue;
|
|
1875
|
+
pending += streamChunkToString(value, decoder);
|
|
1876
|
+
if (injected) {
|
|
1877
|
+
controller.enqueue(encoder.encode(pending));
|
|
1878
|
+
pending = "";
|
|
1879
|
+
continue;
|
|
1880
|
+
}
|
|
1881
|
+
const headIndex = pending.indexOf(CLOSING_HEAD_TAG);
|
|
1882
|
+
if (headIndex >= 0) {
|
|
1883
|
+
const withRuntime = `${pending.slice(0, headIndex)}${runtimeTag}${pending.slice(headIndex)}`;
|
|
1884
|
+
controller.enqueue(encoder.encode(withRuntime));
|
|
1885
|
+
pending = "";
|
|
1886
|
+
injected = true;
|
|
1887
|
+
continue;
|
|
1888
|
+
}
|
|
1889
|
+
if (pending.length > lookbehind) {
|
|
1890
|
+
const safeText = pending.slice(0, pending.length - lookbehind);
|
|
1891
|
+
controller.enqueue(encoder.encode(safeText));
|
|
1892
|
+
pending = pending.slice(-lookbehind);
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
pending += decoder.decode();
|
|
1896
|
+
if (!injected) {
|
|
1897
|
+
pending = injectHtmlIntoHead(pending, runtimeTag);
|
|
1898
|
+
}
|
|
1899
|
+
if (pending.length > 0) {
|
|
1900
|
+
controller.enqueue(encoder.encode(pending));
|
|
1901
|
+
}
|
|
1902
|
+
controller.close();
|
|
1903
|
+
} catch (error) {
|
|
1904
|
+
controller.error(error);
|
|
1905
|
+
}
|
|
2028
1906
|
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
1907
|
+
});
|
|
1908
|
+
};
|
|
1909
|
+
var appendStreamingSlotPatchesToStream = (stream, slots = [], {
|
|
1910
|
+
injectRuntime = true,
|
|
1911
|
+
nonce,
|
|
1912
|
+
onError,
|
|
1913
|
+
onSlotMetric,
|
|
1914
|
+
policy
|
|
1915
|
+
} = {}) => {
|
|
1916
|
+
const resolvedPolicy = resolveStreamingSlotPolicy(policy);
|
|
1917
|
+
const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
|
|
1918
|
+
const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
|
|
1919
|
+
const effectivePolicy = {
|
|
1920
|
+
...resolvedPolicy,
|
|
1921
|
+
onSlotMetric: combinedOnSlotMetric
|
|
1922
|
+
};
|
|
1923
|
+
const preparedSlots = prepareSlots({
|
|
1924
|
+
policy: effectivePolicy,
|
|
1925
|
+
slots,
|
|
1926
|
+
onError: combinedOnError,
|
|
1927
|
+
onSlotMetric: combinedOnSlotMetric
|
|
1928
|
+
});
|
|
1929
|
+
if (preparedSlots.length === 0)
|
|
1930
|
+
return stream;
|
|
1931
|
+
const source = injectRuntime ? injectStreamingRuntimeIntoStream(stream, nonce) : stream;
|
|
1932
|
+
const encoder = new TextEncoder;
|
|
1933
|
+
const decoder = new TextDecoder;
|
|
1934
|
+
const reader = source.getReader();
|
|
1935
|
+
const pending = preparedSlots.map((slot) => resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric));
|
|
1936
|
+
return new ReadableStream({
|
|
1937
|
+
async start(controller) {
|
|
1938
|
+
let baseDone = false;
|
|
1939
|
+
let baseRead = reader.read();
|
|
1940
|
+
let tail = "";
|
|
1941
|
+
let footer = "";
|
|
1942
|
+
try {
|
|
1943
|
+
while (!baseDone || pending.length > 0) {
|
|
1944
|
+
const racers = [];
|
|
1945
|
+
if (!baseDone) {
|
|
1946
|
+
racers.push(baseRead.then(({ done, value }) => ({
|
|
1947
|
+
done,
|
|
1948
|
+
kind: "base",
|
|
1949
|
+
value
|
|
1950
|
+
})));
|
|
1951
|
+
}
|
|
1952
|
+
if (pending.length > 0) {
|
|
1953
|
+
racers.push(nextResolvedSlot(pending).then((resolved) => ({
|
|
1954
|
+
kind: "slot",
|
|
1955
|
+
...resolved
|
|
1956
|
+
})));
|
|
1957
|
+
}
|
|
1958
|
+
if (racers.length === 0)
|
|
1959
|
+
break;
|
|
1960
|
+
const winner = await Promise.race(racers);
|
|
1961
|
+
if (winner.kind === "base") {
|
|
1962
|
+
if (winner.done) {
|
|
1963
|
+
baseDone = true;
|
|
1964
|
+
tail += decoder.decode();
|
|
1965
|
+
const footerStart = tail.search(CLOSING_PAGE_TAG_REGEX);
|
|
1966
|
+
if (footerStart >= 0) {
|
|
1967
|
+
const content = tail.slice(0, footerStart);
|
|
1968
|
+
footer = tail.slice(footerStart);
|
|
1969
|
+
if (content.length > 0) {
|
|
1970
|
+
controller.enqueue(encoder.encode(content));
|
|
1971
|
+
}
|
|
1972
|
+
} else if (tail.length > 0) {
|
|
1973
|
+
controller.enqueue(encoder.encode(tail));
|
|
1974
|
+
}
|
|
1975
|
+
tail = "";
|
|
1976
|
+
} else if (winner.value) {
|
|
1977
|
+
tail += streamChunkToString(winner.value, decoder);
|
|
1978
|
+
if (tail.length > STREAM_TAIL_LOOKBEHIND) {
|
|
1979
|
+
const content = tail.slice(0, tail.length - STREAM_TAIL_LOOKBEHIND);
|
|
1980
|
+
controller.enqueue(encoder.encode(content));
|
|
1981
|
+
tail = tail.slice(-STREAM_TAIL_LOOKBEHIND);
|
|
1982
|
+
}
|
|
1983
|
+
baseRead = reader.read();
|
|
1984
|
+
}
|
|
1985
|
+
continue;
|
|
1986
|
+
}
|
|
1987
|
+
const index = pending.indexOf(winner.original);
|
|
1988
|
+
if (index >= 0)
|
|
1989
|
+
pending.splice(index, 1);
|
|
1990
|
+
if (winner.result.html === null)
|
|
1991
|
+
continue;
|
|
1992
|
+
emitSlotMetric({
|
|
1993
|
+
type: "patched",
|
|
1994
|
+
slotId: winner.result.id,
|
|
1995
|
+
durationMs: winner.result.durationMs,
|
|
1996
|
+
bytes: winner.result.bytes
|
|
1997
|
+
}, combinedOnSlotMetric);
|
|
1998
|
+
controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.html, nonce)));
|
|
1999
|
+
}
|
|
2000
|
+
if (footer.length > 0)
|
|
2001
|
+
controller.enqueue(encoder.encode(footer));
|
|
2002
|
+
controller.close();
|
|
2003
|
+
} catch (error) {
|
|
2004
|
+
controller.error(error);
|
|
2005
|
+
}
|
|
2037
2006
|
}
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2007
|
+
});
|
|
2008
|
+
};
|
|
2009
|
+
|
|
2010
|
+
// src/core/streamingSlotRegistrar.ts
|
|
2011
|
+
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
2012
|
+
var getRegistrarGlobal = () => globalThis;
|
|
2013
|
+
var setStreamingSlotRegistrar = (nextRegistrar) => {
|
|
2014
|
+
getRegistrarGlobal()[STREAMING_SLOT_REGISTRAR_KEY] = nextRegistrar;
|
|
2015
|
+
};
|
|
2016
|
+
var registerStreamingSlot = (slot) => {
|
|
2017
|
+
getRegistrarGlobal()[STREAMING_SLOT_REGISTRAR_KEY]?.(slot);
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
// src/core/streamingSlotRegistry.ts
|
|
2021
|
+
var asyncLocalStorage;
|
|
2022
|
+
var isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string";
|
|
2023
|
+
var ensureAsyncLocalStorage = async () => {
|
|
2024
|
+
if (typeof asyncLocalStorage !== "undefined")
|
|
2025
|
+
return asyncLocalStorage;
|
|
2026
|
+
if (!isServerRuntime()) {
|
|
2027
|
+
asyncLocalStorage = null;
|
|
2028
|
+
return asyncLocalStorage;
|
|
2041
2029
|
}
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2030
|
+
const mod = await import("async_hooks");
|
|
2031
|
+
asyncLocalStorage = new mod.AsyncLocalStorage;
|
|
2032
|
+
return asyncLocalStorage;
|
|
2033
|
+
};
|
|
2034
|
+
var registerStreamingSlot2 = (slot) => {
|
|
2035
|
+
if (!asyncLocalStorage)
|
|
2036
|
+
return;
|
|
2037
|
+
const store = asyncLocalStorage.getStore();
|
|
2038
|
+
if (!store)
|
|
2039
|
+
return;
|
|
2040
|
+
store.set(slot.id, slot);
|
|
2041
|
+
};
|
|
2042
|
+
setStreamingSlotRegistrar(registerStreamingSlot2);
|
|
2043
|
+
var runWithStreamingSlotRegistry = async (task) => {
|
|
2044
|
+
const storage = await ensureAsyncLocalStorage();
|
|
2045
|
+
if (!storage) {
|
|
2046
|
+
return {
|
|
2047
|
+
result: await task(),
|
|
2048
|
+
slots: []
|
|
2049
|
+
};
|
|
2050
2050
|
}
|
|
2051
|
-
|
|
2052
|
-
const
|
|
2053
|
-
|
|
2054
|
-
throw new Error(`Island component "${props.component}" is not registered for framework "angular".`);
|
|
2055
|
-
}
|
|
2056
|
-
const component = await resolveAngularServerIslandComponent(entry);
|
|
2057
|
-
const html = await renderAngularIslandToHtml(component, props.props, islandId);
|
|
2051
|
+
return storage.run(new Map, async () => {
|
|
2052
|
+
const result = await task();
|
|
2053
|
+
const store = storage.getStore();
|
|
2058
2054
|
return {
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
},
|
|
2062
|
-
html
|
|
2055
|
+
result,
|
|
2056
|
+
slots: store ? [...store.values()] : []
|
|
2063
2057
|
};
|
|
2058
|
+
});
|
|
2059
|
+
};
|
|
2060
|
+
|
|
2061
|
+
// src/core/responseEnhancers.ts
|
|
2062
|
+
var toResponse = async (responseLike) => await responseLike;
|
|
2063
|
+
var cloneHeaders = (response) => {
|
|
2064
|
+
const headers = new Headers(response.headers);
|
|
2065
|
+
return headers;
|
|
2066
|
+
};
|
|
2067
|
+
var enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [], policy } = {}) => {
|
|
2068
|
+
if (!response.body || streamingSlots.length === 0) {
|
|
2069
|
+
return response;
|
|
2064
2070
|
}
|
|
2065
|
-
|
|
2071
|
+
const body = appendStreamingSlotPatchesToStream(response.body, streamingSlots, {
|
|
2072
|
+
nonce,
|
|
2073
|
+
onError,
|
|
2074
|
+
policy
|
|
2075
|
+
});
|
|
2076
|
+
return new Response(body, {
|
|
2077
|
+
headers: cloneHeaders(response),
|
|
2078
|
+
status: response.status,
|
|
2079
|
+
statusText: response.statusText
|
|
2080
|
+
});
|
|
2081
|
+
};
|
|
2082
|
+
var withStreamingSlots = async (responseLike, options = {}) => enhanceHtmlResponseWithStreamingSlots(await toResponse(responseLike), options);
|
|
2083
|
+
var mergeStreamingSlots = (registered, explicit) => {
|
|
2084
|
+
const merged = new Map;
|
|
2085
|
+
for (const slot of registered)
|
|
2086
|
+
merged.set(slot.id, slot);
|
|
2087
|
+
for (const slot of explicit)
|
|
2088
|
+
merged.set(slot.id, slot);
|
|
2089
|
+
return [...merged.values()];
|
|
2090
|
+
};
|
|
2091
|
+
var withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
|
|
2092
|
+
const { result, slots } = await runWithStreamingSlotRegistry(renderResponse);
|
|
2093
|
+
const explicit = options.streamingSlots ?? [];
|
|
2094
|
+
return withStreamingSlots(result, {
|
|
2095
|
+
...options,
|
|
2096
|
+
streamingSlots: mergeStreamingSlots(slots, explicit)
|
|
2097
|
+
});
|
|
2066
2098
|
};
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
init_islandMarkupAttributes();
|
|
2071
|
-
init_islands();
|
|
2072
|
-
resolvedServerComponentCache = new Map;
|
|
2073
|
-
resolvedServerBuildComponentCache = new Map;
|
|
2074
|
-
});
|
|
2099
|
+
|
|
2100
|
+
// src/core/wrapPageHandlerWithStreamingSlots.ts
|
|
2101
|
+
var wrapPageHandlerWithStreamingSlots = (handler) => (...args) => withRegisteredStreamingSlots(() => handler(...args));
|
|
2075
2102
|
|
|
2076
2103
|
// src/react/index.ts
|
|
2077
2104
|
init_pageHandler();
|
|
@@ -2079,16 +2106,16 @@ init_pageHandler();
|
|
|
2079
2106
|
// src/react/Island.tsx
|
|
2080
2107
|
init_islandMarkupAttributes();
|
|
2081
2108
|
init_renderIslandMarkup();
|
|
2082
|
-
import { jsxDEV
|
|
2109
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
2083
2110
|
var Island = async (props) => {
|
|
2084
2111
|
if (typeof window !== "undefined") {
|
|
2085
|
-
return /* @__PURE__ */
|
|
2112
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
2086
2113
|
...getIslandMarkerAttributes(props),
|
|
2087
2114
|
suppressHydrationWarning: true
|
|
2088
2115
|
}, undefined, false, undefined, this);
|
|
2089
2116
|
}
|
|
2090
2117
|
const result = await renderIslandResult(requireCurrentIslandRegistry(), props);
|
|
2091
|
-
return /* @__PURE__ */
|
|
2118
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
2092
2119
|
...result.attributes,
|
|
2093
2120
|
dangerouslySetInnerHTML: { __html: result.html }
|
|
2094
2121
|
}, undefined, false, undefined, this);
|
|
@@ -2096,17 +2123,17 @@ var Island = async (props) => {
|
|
|
2096
2123
|
// src/react/createIsland.tsx
|
|
2097
2124
|
init_islandMarkupAttributes();
|
|
2098
2125
|
init_renderIslandMarkup();
|
|
2099
|
-
import { jsxDEV as
|
|
2126
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
2100
2127
|
var createTypedIsland = (registry) => {
|
|
2101
2128
|
const Island2 = async (props) => {
|
|
2102
2129
|
if (typeof window !== "undefined") {
|
|
2103
|
-
return /* @__PURE__ */
|
|
2130
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
2104
2131
|
...getIslandMarkerAttributes(props),
|
|
2105
2132
|
suppressHydrationWarning: true
|
|
2106
2133
|
}, undefined, false, undefined, this);
|
|
2107
2134
|
}
|
|
2108
2135
|
const result = await renderIslandResult(registry, props);
|
|
2109
|
-
return /* @__PURE__ */
|
|
2136
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
2110
2137
|
...result.attributes,
|
|
2111
2138
|
dangerouslySetInnerHTML: { __html: result.html }
|
|
2112
2139
|
}, undefined, false, undefined, this);
|
|
@@ -2233,12 +2260,15 @@ var subscribeIslandStore = (store, selector, listener) => {
|
|
|
2233
2260
|
var useIslandStore = (store, selector) => useSyncExternalStore((listener) => subscribeIslandStore(store, selector, () => {
|
|
2234
2261
|
listener();
|
|
2235
2262
|
}), () => readIslandStore(store, selector), () => getIslandStoreServerSnapshot(store, selector));
|
|
2263
|
+
|
|
2264
|
+
// src/react/index.ts
|
|
2265
|
+
var handleReactPageRequest2 = wrapPageHandlerWithStreamingSlots(handleReactPageRequest);
|
|
2236
2266
|
export {
|
|
2237
2267
|
useIslandStore,
|
|
2238
|
-
handleReactPageRequest,
|
|
2268
|
+
handleReactPageRequest2 as handleReactPageRequest,
|
|
2239
2269
|
createTypedIsland,
|
|
2240
2270
|
Island
|
|
2241
2271
|
};
|
|
2242
2272
|
|
|
2243
|
-
//# debugId=
|
|
2273
|
+
//# debugId=67E457AEF1FAE72B64756E2164756E21
|
|
2244
2274
|
//# sourceMappingURL=index.js.map
|