@absolutejs/absolute 0.20.0-beta.169 → 0.20.0-beta.170
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/CHANGELOG.md +80 -0
- package/README.md +232 -0
- package/changelog.json +228 -0
- package/dist/angular/browser.js +7 -8
- package/dist/angular/browser.js.map +6 -5
- package/dist/angular/components/core/streamingSlotRegistrar.js +6 -2
- package/dist/angular/components/core/streamingSlotRegistry.js +7 -3
- package/dist/angular/index.js +555 -156
- package/dist/angular/index.js.map +29 -23
- package/dist/angular/server.js +555 -156
- package/dist/angular/server.js.map +29 -23
- package/dist/build/buildWorker.js +14 -8
- package/dist/build.js +4949 -1941
- package/dist/build.js.map +72 -42
- package/dist/cli/{add-7azr0c83.js → add-6a7pjkn9.js} +11 -7
- package/dist/cli/{analyze-3cyek6v3.js → analyze-606fshwa.js} +1 -1
- package/dist/cli/{build-25rz8v25.js → build-g81xqbb9.js} +1 -1
- package/dist/cli/{compile-4jnfxts9.js → compile-9y1w9zpj.js} +3 -3
- package/dist/cli/config/server.js +10699 -1538
- package/dist/cli/{dev-9tk5hn2e.js → dev-hyeb89hp.js} +5 -1
- package/dist/cli/{doctor-4nv2c2j3.js → doctor-h55y9hj1.js} +1 -1
- package/dist/cli/{generate-v75p2fct.js → generate-20x1pkf7.js} +4 -4
- package/dist/cli/{htmx-427swtdz.js → htmx-6mz2h7k1.js} +2 -2
- package/dist/cli/{index-bhbs6d5z.js → index-32ge2w1f.js} +12 -4
- package/dist/cli/{index-a4ws2jwd.js → index-3wz3mktm.js} +1 -1
- package/dist/cli/{index-b7hjgknf.js → index-9sksd8c8.js} +13 -4
- package/dist/cli/{index-eyzwc7gz.js → index-qbrzvmh9.js} +4 -2
- package/dist/cli/index-qw98g1p6.js +269 -0
- package/dist/cli/{index-434b7j4a.js → index-vtp20gwf.js} +69 -1
- package/dist/cli/{index-h7qhz02e.js → index-wk0pyxrg.js} +3 -0
- package/dist/cli/{index-k3y8cb6c.js → index-z6f43b20.js} +1 -1
- package/dist/cli/index.js +16 -16
- package/dist/cli/{islands-8sgky9gh.js → islands-dc54e5y1.js} +1 -1
- package/dist/cli/{ls-4m4yqwww.js → ls-b6zz24nt.js} +1 -1
- package/dist/cli/{mobile-hcxjr2gf.js → mobile-ajnnvqtv.js} +3 -3
- package/dist/cli/prerender-fqpp0m1j.js +10 -0
- package/dist/cli/{remove-1ycjx85k.js → remove-t8x1mrxg.js} +4 -4
- package/dist/cli/{start-mbaejxhm.js → start-d6p831ny.js} +3 -3
- package/dist/cli/{typecheck-dr068pmh.js → typecheck-stbt0qt5.js} +6 -1
- package/dist/cli/{workspace-1sycp9g1.js → workspace-61hh6jq1.js} +1 -1
- package/dist/client/chunks/index-6b66nzyf.js +381 -0
- package/dist/client/chunks/index-6b66nzyf.js.map +11 -0
- package/dist/client/chunks/{islands-rc28k5sx.js → islands-s2ta5ajb.js} +5 -2
- package/dist/client/chunks/{islands-rc28k5sx.js.map → islands-s2ta5ajb.js.map} +7 -6
- package/dist/client/index.js +160 -3
- package/dist/client/index.js.map +6 -4
- package/dist/client/navigation.js +764 -0
- package/dist/client/navigation.js.map +10 -0
- package/dist/client/prefetch.js +33 -375
- package/dist/client/prefetch.js.map +3 -4
- package/dist/core/streamingSlotRegistrar.js +5 -2
- package/dist/core/streamingSlotRegistrar.js.map +5 -4
- package/dist/core/streamingSlotRegistry.js +5 -2
- package/dist/core/streamingSlotRegistry.js.map +5 -4
- package/dist/dev/client/cspNonce.ts +28 -0
- package/dist/dev/client/handlers/html.ts +4 -3
- package/dist/dev/client/handlers/htmx.ts +3 -2
- package/dist/dev/client/handlers/svelte.ts +15 -90
- package/dist/dev/client/syncDevtools.ts +2 -1
- package/dist/dev/serverBootstrap.js +11 -4
- package/dist/i18n/index.js +543 -0
- package/dist/i18n/index.js.map +15 -0
- package/dist/index.js +6339 -2233
- package/dist/index.js.map +89 -54
- package/dist/islands/index.js +282 -40
- package/dist/islands/index.js.map +14 -10
- package/dist/mobile/browser.js +7 -2
- package/dist/mobile/browser.js.map +5 -4
- package/dist/mobile/index.js +7 -2
- package/dist/mobile/index.js.map +5 -4
- package/dist/mobile/remoteMacAgentEntry.js +1 -1
- package/dist/react/components/browser/index.js +94 -4
- package/dist/react/components/index.js +150 -10
- package/dist/react/components/index.js.map +15 -10
- package/dist/react/hooks/index.js +479 -13
- package/dist/react/hooks/index.js.map +12 -4
- package/dist/react/index.js +769 -166
- package/dist/react/index.js.map +32 -21
- package/dist/react/router/browser.js +21 -4
- package/dist/react/router/browser.js.map +5 -4
- package/dist/react/router/index.js +21 -4
- package/dist/react/router/index.js.map +5 -4
- package/dist/react/server.js +597 -203
- package/dist/react/server.js.map +25 -15
- package/dist/src/angular/zoneRuntime.d.ts +5 -0
- package/dist/src/build/buildReactServerComponents.d.ts +22 -0
- package/dist/src/build/downlevelAsyncForZone.d.ts +1 -0
- package/dist/src/build/fileRoutes.d.ts +65 -0
- package/dist/src/build/fonts/buildFonts.d.ts +25 -0
- package/dist/src/build/fonts/fallbackMetrics.d.ts +13 -0
- package/dist/src/build/fonts/googleFonts.d.ts +18 -0
- package/dist/src/build/fonts/injectFontTags.d.ts +7 -0
- package/dist/src/build/fonts/parseFontMetrics.d.ts +4 -0
- package/dist/src/build/generateReactIndexes.d.ts +7 -1
- package/dist/src/build/htmlIncludes.d.ts +16 -0
- package/dist/src/build/inlineSourceMapComment.d.ts +1 -0
- package/dist/src/build/scanConventions.d.ts +3 -0
- package/dist/src/build/vitals.d.ts +21 -0
- package/dist/src/client/formActions.d.ts +29 -0
- package/dist/src/client/index.d.ts +2 -0
- package/dist/src/client/navigation.d.ts +16 -0
- package/dist/src/client/prefetch.d.ts +2 -30
- package/dist/src/core/build.d.ts +2 -2
- package/dist/src/core/cspNonce.d.ts +12 -0
- package/dist/src/core/fileRouteAdapter.d.ts +15 -0
- package/dist/src/core/fileRoutes.d.ts +5 -0
- package/dist/src/core/formActionFlash.d.ts +25 -0
- package/dist/src/core/formActions.d.ts +249 -0
- package/dist/src/core/index.d.ts +5 -0
- package/dist/src/core/partialPrerender.d.ts +28 -0
- package/dist/src/core/partialPrerenderServe.d.ts +24 -0
- package/dist/src/core/precompressed.d.ts +11 -1
- package/dist/src/core/prerenderNonce.d.ts +9 -0
- package/dist/src/core/productionRuntime.d.ts +4 -2
- package/dist/src/core/serverOnlyStaticFiles.d.ts +8 -0
- package/dist/src/core/staticHtmlNonce.d.ts +2 -0
- package/dist/src/core/vitals.d.ts +108 -0
- package/dist/src/dev/angular/fastHmrCompiler.d.ts +1 -1
- package/dist/src/dev/client/cspNonce.d.ts +2 -0
- package/dist/src/dev/fileRouteRefresher.d.ts +5 -0
- package/dist/src/dev/importCost/instrument.d.ts +1 -1
- package/dist/src/dev/reactServerComponentsRebuild.d.ts +3 -0
- package/dist/src/i18n/defineMessages.d.ts +5 -0
- package/dist/src/i18n/formatMessage.d.ts +26 -0
- package/dist/src/i18n/index.d.ts +6 -0
- package/dist/src/i18n/intlCache.d.ts +5 -0
- package/dist/src/i18n/routing.d.ts +28 -0
- package/dist/src/i18n/translator.d.ts +11 -0
- package/dist/src/mobile/androidRelease.d.ts +2 -2
- package/dist/src/mobile/iosRelease.d.ts +4 -4
- package/dist/src/mobile/materializedBundle.d.ts +1 -1
- package/dist/src/mobile/mobileInspect.d.ts +1 -1
- package/dist/src/mobile/releaseArtifact.d.ts +2 -2
- package/dist/src/mobile/remoteMacProtocol.d.ts +2 -2
- package/dist/src/plugins/i18n.d.ts +30 -0
- package/dist/src/plugins/index.d.ts +2 -1
- package/dist/src/plugins/secureHeaders.d.ts +48 -0
- package/dist/src/react/components/Head.d.ts +1 -1
- package/dist/src/react/components/StreamSlot.browser.d.ts +1 -0
- package/dist/src/react/components/StreamSlot.d.ts +5 -1
- package/dist/src/react/components/SuspenseSlot.browser.d.ts +2 -0
- package/dist/src/react/components/SuspenseSlot.d.ts +12 -0
- package/dist/src/react/fileRoute.d.ts +18 -0
- package/dist/src/react/hooks/index.d.ts +4 -0
- package/dist/src/react/hooks/useFormAction.d.ts +42 -0
- package/dist/src/react/hooks/useI18n.d.ts +15 -0
- package/dist/src/react/index.d.ts +2 -0
- package/dist/src/react/server.d.ts +2 -0
- package/dist/src/react/serverComponents/constants.d.ts +11 -0
- package/dist/src/react/serverComponents/flightPayload.d.ts +2 -0
- package/dist/src/react/serverComponents/pageHandler.d.ts +14 -0
- package/dist/src/svelte/browser.d.ts +1 -0
- package/dist/src/svelte/fileRoute.d.ts +15 -0
- package/dist/src/svelte/i18n.d.ts +8 -0
- package/dist/src/svelte/index.d.ts +2 -0
- package/dist/src/svelte/lowerAwaitSlotSyntax.d.ts +5 -1
- package/dist/src/svelte/renderToReadableStream.d.ts +10 -2
- package/dist/src/svelte/router/browser.d.ts +3 -1
- package/dist/src/svelte/router/goto.d.ts +13 -10
- package/dist/src/svelte/router/guards.d.ts +43 -0
- package/dist/src/svelte/router/index.d.ts +3 -1
- package/dist/src/svelte/router/lazy.d.ts +17 -0
- package/dist/src/svelte/router/lazyModule.d.ts +29 -0
- package/dist/src/svelte/router/navigation.d.ts +55 -0
- package/dist/src/svelte/router/pushState.d.ts +4 -2
- package/dist/src/svelte/router/scroll.d.ts +34 -0
- package/dist/src/svelte/routerSsr.d.ts +9 -0
- package/dist/src/svelte/server.d.ts +1 -0
- package/dist/src/utils/cspNonceRef.d.ts +8 -0
- package/dist/src/utils/fontAssets.d.ts +17 -0
- package/dist/src/utils/formActionProtocol.d.ts +10 -0
- package/dist/src/utils/generateHeadElement.d.ts +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/inlinePageCss.d.ts +18 -0
- package/dist/src/utils/loadConfig.d.ts +5 -0
- package/dist/src/utils/localeRef.d.ts +10 -0
- package/dist/src/utils/resolveConvention.d.ts +6 -1
- package/dist/src/utils/streamingSlots.d.ts +5 -0
- package/dist/src/vue/browser.d.ts +2 -0
- package/dist/src/vue/components/Image.d.ts +2 -2
- package/dist/src/vue/index.d.ts +2 -0
- package/dist/src/vue/serverDataPayload.d.ts +32 -0
- package/dist/src/vue/serverDataState.d.ts +9 -0
- package/dist/src/vue/useServerData.browser.d.ts +6 -0
- package/dist/src/vue/useServerData.d.ts +24 -0
- package/dist/svelte/browser.js +330 -3
- package/dist/svelte/browser.js.map +8 -4
- package/dist/svelte/components/AwaitSlot.svelte +5 -0
- package/dist/svelte/components/Head.svelte +50 -0
- package/dist/svelte/components/JsonLd.svelte +9 -1
- package/dist/svelte/components/StreamSlot.svelte +5 -0
- package/dist/svelte/index.js +1017 -117
- package/dist/svelte/index.js.map +38 -24
- package/dist/svelte/router/Link.svelte +40 -8
- package/dist/svelte/router/Route.svelte +157 -12
- package/dist/svelte/router/Route.svelte.d.ts +39 -5
- package/dist/svelte/router/Router.svelte +140 -25
- package/dist/svelte/router/Router.svelte.d.ts +5 -1
- package/dist/svelte/router/browser.ts +10 -0
- package/dist/svelte/router/goto.ts +15 -86
- package/dist/svelte/router/guards.ts +112 -0
- package/dist/svelte/router/index.ts +10 -0
- package/dist/svelte/router/lazy.ts +82 -0
- package/dist/svelte/router/lazyModule.ts +74 -0
- package/dist/svelte/router/navigation.ts +412 -0
- package/dist/svelte/router/pushState.ts +7 -4
- package/dist/svelte/router/scroll.ts +286 -0
- package/dist/svelte/server.js +747 -252
- package/dist/svelte/server.js.map +30 -20
- package/dist/types/angular.d.ts +2 -0
- package/dist/types/build.d.ts +37 -0
- package/dist/types/conventions.d.ts +3 -0
- package/dist/types/fileRoutes.d.ts +72 -0
- package/dist/types/fonts.d.ts +86 -0
- package/dist/types/formAction.d.ts +54 -0
- package/dist/types/globals.d.ts +10 -0
- package/dist/types/i18n.d.ts +185 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/metadata.d.ts +11 -0
- package/dist/types/navigation.d.ts +37 -0
- package/dist/types/prefetch.d.ts +10 -0
- package/dist/types/sitemap.d.ts +4 -0
- package/dist/types/svelteRouter.d.ts +89 -2
- package/dist/types/svelteRouter.ts +112 -2
- package/dist/types/vue.d.ts +46 -1
- package/dist/utils/iconVersion.ts +34 -0
- package/dist/vue/browser.js +107 -11
- package/dist/vue/browser.js.map +7 -4
- package/dist/vue/components/index.js +5 -2
- package/dist/vue/components/index.js.map +5 -4
- package/dist/vue/index.js +712 -158
- package/dist/vue/index.js.map +32 -23
- package/dist/vue/server.js +310 -79
- package/dist/vue/server.js.map +20 -15
- package/package.json +9 -1
- package/dist/cli/prerender-mfnwsvyt.js +0 -7
- package/dist/src/plugins/pageRouter.d.ts +0 -1
- /package/dist/cli/{index-j7m8pq48.js → index-rervww4p.js} +0 -0
package/dist/svelte/index.js
CHANGED
|
@@ -72,6 +72,20 @@ var __esm = (fn, res, err) => () => {
|
|
|
72
72
|
};
|
|
73
73
|
var __require = import.meta.require;
|
|
74
74
|
|
|
75
|
+
// src/utils/cspNonceRef.ts
|
|
76
|
+
var GETTER_KEY, nonceAttr = (nonce = readCspNonce()) => nonce ? ` nonce="${nonce}"` : "", nonceSvelteHeadStyles = (head, nonce = readCspNonce()) => nonce ? head.replace(/<style(?=\s+id="svelte-[^"]*")(?![^>]*\snonce=)/g, `<style nonce="${nonce}"`) : head, readCspNonce = () => {
|
|
77
|
+
const getter = Reflect.get(globalThis, GETTER_KEY);
|
|
78
|
+
if (typeof getter !== "function")
|
|
79
|
+
return;
|
|
80
|
+
const nonce = getter();
|
|
81
|
+
return typeof nonce === "string" ? nonce : undefined;
|
|
82
|
+
}, registerCspNonceGetter = (getter) => {
|
|
83
|
+
Reflect.set(globalThis, GETTER_KEY, getter);
|
|
84
|
+
};
|
|
85
|
+
var init_cspNonceRef = __esm(() => {
|
|
86
|
+
GETTER_KEY = Symbol.for("absolutejs.cspNonceGetter");
|
|
87
|
+
});
|
|
88
|
+
|
|
75
89
|
// src/build/resolvePackageImport.ts
|
|
76
90
|
import { resolve, join } from "path";
|
|
77
91
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -220,47 +234,140 @@ var init_lowerIslandSyntax = __esm(() => {
|
|
|
220
234
|
});
|
|
221
235
|
|
|
222
236
|
// src/svelte/lowerAwaitSlotSyntax.ts
|
|
223
|
-
var
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
if (
|
|
237
|
+
var AWAIT_STREAM_DIRECTIVE = "<!-- absolute:stream -->", DIRECTIVE_RE, BRANCH_TAG_RE, SVELTE_ONLY_MARKUP_RE, QUOTES, scanCharacter = (scan, char) => {
|
|
238
|
+
if (scan.escaped) {
|
|
239
|
+
scan.escaped = false;
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (scan.quote) {
|
|
243
|
+
scan.escaped = char === "\\";
|
|
244
|
+
if (char === scan.quote)
|
|
245
|
+
scan.quote = null;
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (QUOTES.has(char))
|
|
249
|
+
scan.quote = char;
|
|
250
|
+
if (char === "{")
|
|
251
|
+
scan.depth += 1;
|
|
252
|
+
if (char === "}")
|
|
253
|
+
scan.depth -= 1;
|
|
254
|
+
}, findTagEnd = (source, start) => {
|
|
255
|
+
const scan = { depth: 0, escaped: false, quote: null };
|
|
256
|
+
for (let index = start;index < source.length; index += 1) {
|
|
257
|
+
scanCharacter(scan, source[index] ?? "");
|
|
258
|
+
if (scan.depth === 0)
|
|
259
|
+
return index + 1;
|
|
260
|
+
}
|
|
261
|
+
return -1;
|
|
262
|
+
}, topLevelTags = (markup) => {
|
|
263
|
+
const tags = [];
|
|
264
|
+
let index = markup.indexOf("{");
|
|
265
|
+
while (index !== -1) {
|
|
266
|
+
const end = findTagEnd(markup, index);
|
|
267
|
+
if (end === -1)
|
|
268
|
+
break;
|
|
269
|
+
tags.push({ end, start: index, text: markup.slice(index, end) });
|
|
270
|
+
index = markup.indexOf("{", end);
|
|
271
|
+
}
|
|
272
|
+
return tags;
|
|
273
|
+
}, escapeTemplateLiteral = (value) => value.replaceAll("\\", "\\\\").replaceAll("`", "\\`").replaceAll("${", "\\${"), markupToTemplateLiteral = (markup) => {
|
|
274
|
+
const parts = topLevelTags(markup.trim());
|
|
275
|
+
const trimmed = markup.trim();
|
|
276
|
+
let cursor = 0;
|
|
277
|
+
let literal = "";
|
|
278
|
+
for (const { end, start, text } of parts) {
|
|
279
|
+
literal += escapeTemplateLiteral(trimmed.slice(cursor, start));
|
|
280
|
+
literal += `\${${text.slice(1, -1).trim()}}`;
|
|
281
|
+
cursor = end;
|
|
282
|
+
}
|
|
283
|
+
literal += escapeTemplateLiteral(trimmed.slice(cursor));
|
|
284
|
+
return `\`${literal}\``;
|
|
285
|
+
}, fail = (filePath, message) => {
|
|
286
|
+
throw new Error(`${filePath ? `${filePath}: ` : ""}${message} (${AWAIT_STREAM_DIRECTIVE} streams plain HTML; remove the directive to let Svelte render the block and hydrate it)`);
|
|
287
|
+
}, assertPlainHtml = (markup, branch, filePath) => {
|
|
288
|
+
const withoutExpressions = topLevelTags(markup).reduceRight((text, { end, start }) => text.slice(0, start) + text.slice(end), markup);
|
|
289
|
+
const nestedTag = topLevelTags(markup).find(({ text }) => /^\{[#:/@]/.test(text));
|
|
290
|
+
if (nestedTag || SVELTE_ONLY_MARKUP_RE.test(withoutExpressions)) {
|
|
291
|
+
fail(filePath, `the ${branch} branch of a streamed {#await} holds Svelte markup (${nestedTag?.text ?? withoutExpressions.match(SVELTE_ONLY_MARKUP_RE)?.[0]}\u2026)`);
|
|
292
|
+
}
|
|
293
|
+
}, parseStreamedAwait = (source, start, filePath) => {
|
|
294
|
+
if (!source.startsWith("{#await", start)) {
|
|
295
|
+
fail(filePath, `${AWAIT_STREAM_DIRECTIVE} must come directly before an {#await} block`);
|
|
296
|
+
}
|
|
297
|
+
const headerEnd = findTagEnd(source, start);
|
|
298
|
+
if (headerEnd === -1)
|
|
299
|
+
fail(filePath, "unterminated {#await} tag");
|
|
300
|
+
const expression = source.slice(start + "{#await".length, headerEnd - 1).trim();
|
|
301
|
+
if (!expression)
|
|
302
|
+
fail(filePath, "{#await} without an expression");
|
|
303
|
+
if (/\s(?:then|catch)\b/.test(` ${expression}`)) {
|
|
304
|
+
fail(filePath, "a streamed {#await} needs a pending branch; the shorthand {#await \u2026 then \u2026} has none");
|
|
305
|
+
}
|
|
306
|
+
const close = source.indexOf("{/await}", headerEnd);
|
|
307
|
+
if (close === -1)
|
|
308
|
+
fail(filePath, "{#await} without a matching {/await}");
|
|
309
|
+
const body = source.slice(headerEnd, close);
|
|
310
|
+
const branchTags = topLevelTags(body).filter(({ text }) => /^\{:/.test(text));
|
|
311
|
+
const [thenTag, catchTag, extra] = branchTags;
|
|
312
|
+
const thenMatch = thenTag?.text.match(BRANCH_TAG_RE);
|
|
313
|
+
const catchMatch = catchTag?.text.match(BRANCH_TAG_RE);
|
|
314
|
+
if (!thenTag || thenMatch?.[1] !== "then" || catchTag && catchMatch?.[1] !== "catch" || extra) {
|
|
315
|
+
fail(filePath, "a streamed {#await} takes exactly one {:then} and at most one {:catch}, in that order");
|
|
316
|
+
}
|
|
317
|
+
const pendingMarkup = body.slice(0, thenTag?.start);
|
|
318
|
+
const thenMarkup = body.slice(thenTag?.end, catchTag?.start);
|
|
319
|
+
const catchMarkup = catchTag ? body.slice(catchTag.end) : undefined;
|
|
320
|
+
assertPlainHtml(pendingMarkup, "pending", filePath);
|
|
321
|
+
assertPlainHtml(thenMarkup, "then", filePath);
|
|
322
|
+
if (catchMarkup !== undefined)
|
|
323
|
+
assertPlainHtml(catchMarkup, "catch", filePath);
|
|
324
|
+
return {
|
|
325
|
+
catchIdentifier: catchMatch?.[2],
|
|
326
|
+
catchMarkup,
|
|
327
|
+
end: close + "{/await}".length,
|
|
328
|
+
expression,
|
|
329
|
+
pendingMarkup,
|
|
330
|
+
thenIdentifier: thenMatch?.[2],
|
|
331
|
+
thenMarkup
|
|
332
|
+
};
|
|
333
|
+
}, renderSlot = (block, slotId, dynamic) => {
|
|
334
|
+
const thenValueIdentifier = block.thenIdentifier ?? "__awaitValue";
|
|
335
|
+
const catchValueIdentifier = block.catchIdentifier ?? "__awaitError";
|
|
336
|
+
const catchBranch = block.catchMarkup === undefined ? "catch (_absoluteAwaitError) { throw _absoluteAwaitError; }" : `catch (${catchValueIdentifier}) { return ${markupToTemplateLiteral(block.catchMarkup)}; }`;
|
|
337
|
+
return `<AbsoluteAwaitSlot id="${slotId}"${dynamic ? " dynamic" : ""} fallbackHtml={${markupToTemplateLiteral(block.pendingMarkup)}} resolve={async () => { try { const ${thenValueIdentifier} = await (${block.expression}); return ${markupToTemplateLiteral(block.thenMarkup)}; } ${catchBranch} }} />`;
|
|
338
|
+
}, IMPORT_LINE = 'import AbsoluteAwaitSlot from "@absolutejs/absolute/svelte/components/AwaitSlot.svelte";', lowerSvelteAwaitSlotSyntax = (source, filePath) => {
|
|
339
|
+
if (!source.includes("absolute:stream")) {
|
|
229
340
|
return { code: source, transformed: false };
|
|
230
341
|
}
|
|
342
|
+
let lowered = "";
|
|
343
|
+
let cursor = 0;
|
|
231
344
|
let awaitIndex = 0;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
345
|
+
for (const directive of source.matchAll(DIRECTIVE_RE)) {
|
|
346
|
+
const awaitStart = directive.index + directive[0].length;
|
|
347
|
+
if (awaitStart < cursor)
|
|
348
|
+
continue;
|
|
349
|
+
const block = parseStreamedAwait(source, awaitStart, filePath);
|
|
238
350
|
const slotId = `absolute-svelte-await-${awaitIndex.toString(BASE_36_RADIX)}`;
|
|
239
351
|
awaitIndex += 1;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const rejectedHtml = typeof catchMarkup === "string" ? markupToTemplateLiteral(catchMarkup) : null;
|
|
246
|
-
const catchBranch = rejectedHtml ? `catch (${catchValueIdentifier}) { return ${rejectedHtml}; }` : "catch (_absoluteAwaitError) { throw _absoluteAwaitError; }";
|
|
247
|
-
return `<AbsoluteAwaitSlot id="${slotId}" fallbackHtml={${fallbackHtml}} resolve={async () => { try { const ${thenValueIdentifier} = await (${trimmedAwaitExpression}); return ${resolvedHtml}; } ${catchBranch} }} />`;
|
|
248
|
-
});
|
|
249
|
-
if (!transformed) {
|
|
352
|
+
lowered += source.slice(cursor, directive.index);
|
|
353
|
+
lowered += renderSlot(block, slotId, directive[1] !== undefined);
|
|
354
|
+
cursor = block.end;
|
|
355
|
+
}
|
|
356
|
+
if (awaitIndex === 0) {
|
|
250
357
|
return { code: source, transformed: false };
|
|
251
358
|
}
|
|
252
|
-
|
|
359
|
+
lowered += source.slice(cursor);
|
|
253
360
|
if (lowered.includes("<script")) {
|
|
254
361
|
return {
|
|
255
362
|
code: lowered.replace(/<script(\s[^>]*)?>/, (match) => `${match}
|
|
256
|
-
${
|
|
363
|
+
${IMPORT_LINE}
|
|
257
364
|
`),
|
|
258
365
|
transformed: true
|
|
259
366
|
};
|
|
260
367
|
}
|
|
261
368
|
return {
|
|
262
369
|
code: `<script lang="ts">
|
|
263
|
-
${
|
|
370
|
+
${IMPORT_LINE}
|
|
264
371
|
</script>
|
|
265
372
|
${lowered}`,
|
|
266
373
|
transformed: true
|
|
@@ -268,9 +375,15 @@ ${lowered}`,
|
|
|
268
375
|
};
|
|
269
376
|
var init_lowerAwaitSlotSyntax = __esm(() => {
|
|
270
377
|
init_constants();
|
|
271
|
-
|
|
378
|
+
DIRECTIVE_RE = /<!--\s*absolute:stream(\s+dynamic)?\s*-->\s*/g;
|
|
379
|
+
BRANCH_TAG_RE = /^\{:(then|catch)(?:\s+([A-Za-z_$][\w$]*))?\s*\}$/;
|
|
380
|
+
SVELTE_ONLY_MARKUP_RE = /\{[#:/@]|<[A-Z]|<svelte:/;
|
|
381
|
+
QUOTES = new Set(['"', "'", "`"]);
|
|
272
382
|
});
|
|
273
383
|
|
|
384
|
+
// src/utils/runtimeMode.ts
|
|
385
|
+
var ENV_VAR = "NODE_ENV", getNodeEnv = () => process.env[ENV_VAR], isDevelopmentRuntime = () => process.env[ENV_VAR] === "development", isProductionRuntime = () => process.env[ENV_VAR] === "production";
|
|
386
|
+
|
|
274
387
|
// src/build/stylePreprocessor.ts
|
|
275
388
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
276
389
|
import { readFile } from "fs/promises";
|
|
@@ -460,7 +573,7 @@ ${contents}` : contents, normalizePostcssModule = (mod) => {
|
|
|
460
573
|
const config = normalizePostcssModule(loaded);
|
|
461
574
|
const value = typeof config === "function" ? await config({
|
|
462
575
|
cwd: process.cwd(),
|
|
463
|
-
env:
|
|
576
|
+
env: getNodeEnv()
|
|
464
577
|
}) : config;
|
|
465
578
|
return normalizePostcssModule(value) ?? {};
|
|
466
579
|
}, normalizePostcssPlugins = (plugins) => {
|
|
@@ -826,10 +939,10 @@ ${contents}` : contents, normalizePostcssModule = (mod) => {
|
|
|
826
939
|
return resolveCssImportsSync(result.css, dirname(filePath), new Set([filePath]));
|
|
827
940
|
}
|
|
828
941
|
if (language === "less") {
|
|
829
|
-
throw new Error(`Unable to compile ${filePath}: Less
|
|
942
|
+
throw new Error(`Unable to compile ${filePath} synchronously: Less only has an async compiler. Compile it with compileStyleFileIfNeeded() instead.`);
|
|
830
943
|
}
|
|
831
944
|
if (language === "stylus") {
|
|
832
|
-
throw new Error(`Unable to compile ${filePath}: Stylus
|
|
945
|
+
throw new Error(`Unable to compile ${filePath} synchronously: Stylus only has an async compiler. Compile it with compileStyleFileIfNeeded() instead.`);
|
|
833
946
|
}
|
|
834
947
|
return resolveCssImportsSync(rawContents, dirname(filePath), new Set([filePath]));
|
|
835
948
|
};
|
|
@@ -847,6 +960,32 @@ var init_stylePreprocessor = __esm(() => {
|
|
|
847
960
|
CSS_IMPORT_PATTERN = /@import\s+["']([^"']+)["']\s*;?/g;
|
|
848
961
|
});
|
|
849
962
|
|
|
963
|
+
// src/svelte/router/lazyModule.ts
|
|
964
|
+
var LAZY_RESOLVED_KEY, LAZY_SOURCE_EXPORT = "__ABSOLUTE_SVELTE_SOURCE__", isRecord = (value) => typeof value === "object" && value !== null, isComponent = (value) => typeof value === "function", toLazyComponent = (value) => {
|
|
965
|
+
if (isComponent(value))
|
|
966
|
+
return value;
|
|
967
|
+
if (!isRecord(value))
|
|
968
|
+
return;
|
|
969
|
+
const fallback = value.default;
|
|
970
|
+
return isComponent(fallback) ? fallback : undefined;
|
|
971
|
+
}, readSourceFrom = (value) => {
|
|
972
|
+
if (!isRecord(value) && !isComponent(value))
|
|
973
|
+
return;
|
|
974
|
+
const source = Reflect.get(value, LAZY_SOURCE_EXPORT);
|
|
975
|
+
return typeof source === "string" ? source : undefined;
|
|
976
|
+
}, lazyModuleRegistration = (sourceId, specifier) => `
|
|
977
|
+
;(globalThis[Symbol.for("absolutejs.svelte.lazy-modules")] ??= new Map()).set(${JSON.stringify(sourceId)}, () => import(${JSON.stringify(specifier)}));`, readLazySource = (value) => {
|
|
978
|
+
const fromValue = readSourceFrom(value);
|
|
979
|
+
if (fromValue !== undefined)
|
|
980
|
+
return fromValue;
|
|
981
|
+
if (!isRecord(value))
|
|
982
|
+
return;
|
|
983
|
+
return readSourceFrom(value.default);
|
|
984
|
+
};
|
|
985
|
+
var init_lazyModule = __esm(() => {
|
|
986
|
+
LAZY_RESOLVED_KEY = Symbol.for("absolutejs.svelte.lazy-resolved");
|
|
987
|
+
});
|
|
988
|
+
|
|
850
989
|
// src/core/svelteServerModule.ts
|
|
851
990
|
import { mkdir, readdir } from "fs/promises";
|
|
852
991
|
import { basename, dirname as dirname2, extname as extname2, join as join3, relative as relative2, resolve as resolve3 } from "path";
|
|
@@ -956,11 +1095,11 @@ var serverCacheRoot, compiledModuleCache, originalSourcePathCache, transpiler, e
|
|
|
956
1095
|
const resolutionSourcePath = await resolveOriginalSourcePath(sourcePath);
|
|
957
1096
|
const source = await Bun.file(sourcePath).text();
|
|
958
1097
|
const { compile, preprocess } = await import("svelte/compiler");
|
|
959
|
-
const loweredAwaitSource = lowerSvelteAwaitSlotSyntax(source);
|
|
1098
|
+
const loweredAwaitSource = lowerSvelteAwaitSlotSyntax(source, sourcePath);
|
|
960
1099
|
const loweredSource = lowerSvelteIslandSyntax(loweredAwaitSource.code, "server");
|
|
961
1100
|
const preprocessed = await preprocess(loweredSource.code, createSvelteStylePreprocessor());
|
|
962
1101
|
let transpiled = sourcePath.endsWith(".ts") || sourcePath.endsWith(".svelte.ts") ? transpiler.transformSync(preprocessed.code) : preprocessed.code;
|
|
963
|
-
const childImportSpecs = Array.from(transpiled.matchAll(/from\s
|
|
1102
|
+
const childImportSpecs = Array.from(new Set(Array.from(transpiled.matchAll(/(?:from\s+|\bimport\s*\(\s*)['"]([^'"]+)['"]/g)).map((match) => match[1]).filter((value) => value !== undefined)));
|
|
964
1103
|
const resolvedChildModules = await Promise.all(childImportSpecs.map((spec) => resolveSvelteImport(spec, resolutionSourcePath)));
|
|
965
1104
|
const resolvedModuleImports = await Promise.all(childImportSpecs.map((spec) => resolveRelativeModule(spec, resolutionSourcePath)));
|
|
966
1105
|
const childModulePaths = new Map;
|
|
@@ -1007,6 +1146,14 @@ var serverCacheRoot, compiledModuleCache, originalSourcePathCache, transpiler, e
|
|
|
1007
1146
|
for (const [spec, resolvedModuleImport] of rewrittenModulePaths) {
|
|
1008
1147
|
compiledCode = compiledCode.replaceAll(spec, resolvedModuleImport);
|
|
1009
1148
|
}
|
|
1149
|
+
const sourceId = JSON.stringify(relative2(process.cwd(), resolutionSourcePath).replace(/\\/g, "/"));
|
|
1150
|
+
const componentName = /export default function ([\w$]+)\s*\(/.exec(compiledCode)?.[1];
|
|
1151
|
+
compiledCode += `
|
|
1152
|
+
export const ${LAZY_SOURCE_EXPORT} = ${sourceId};`;
|
|
1153
|
+
if (componentName) {
|
|
1154
|
+
compiledCode += `
|
|
1155
|
+
${componentName}.${LAZY_SOURCE_EXPORT} = ${sourceId};`;
|
|
1156
|
+
}
|
|
1010
1157
|
const compiledModulePath = getCachedModulePath(sourcePath);
|
|
1011
1158
|
await mkdir(dirname2(compiledModulePath), { recursive: true });
|
|
1012
1159
|
await writeIfChanged(compiledModulePath, compiledCode);
|
|
@@ -1018,6 +1165,7 @@ var init_svelteServerModule = __esm(() => {
|
|
|
1018
1165
|
init_lowerIslandSyntax();
|
|
1019
1166
|
init_lowerAwaitSlotSyntax();
|
|
1020
1167
|
init_stylePreprocessor();
|
|
1168
|
+
init_lazyModule();
|
|
1021
1169
|
serverCacheRoot = join3(process.cwd(), ".absolutejs", "islands", "svelte");
|
|
1022
1170
|
compiledModuleCache = new Map;
|
|
1023
1171
|
originalSourcePathCache = new Map;
|
|
@@ -1027,6 +1175,20 @@ var init_svelteServerModule = __esm(() => {
|
|
|
1027
1175
|
});
|
|
1028
1176
|
});
|
|
1029
1177
|
|
|
1178
|
+
// src/utils/escapeScriptContent.ts
|
|
1179
|
+
var ESCAPE_LOOKUP, ESCAPE_REGEX, escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
|
|
1180
|
+
const escaped = ESCAPE_LOOKUP[char];
|
|
1181
|
+
return escaped !== undefined ? escaped : char;
|
|
1182
|
+
});
|
|
1183
|
+
var init_escapeScriptContent = __esm(() => {
|
|
1184
|
+
ESCAPE_LOOKUP = {
|
|
1185
|
+
"\u2028": "\\u2028",
|
|
1186
|
+
"\u2029": "\\u2029",
|
|
1187
|
+
"<": "\\u003C"
|
|
1188
|
+
};
|
|
1189
|
+
ESCAPE_REGEX = /[<\u2028\u2029]/g;
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1030
1192
|
// src/utils/getDurationString.ts
|
|
1031
1193
|
var getDurationString = (duration) => {
|
|
1032
1194
|
let durationString;
|
|
@@ -1223,15 +1385,15 @@ var ISLAND_BOOTSTRAP_MANIFEST_KEY = "AbsoluteIslandBootstrap", LEGACY_ISLAND_BOO
|
|
|
1223
1385
|
var ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__", ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__", CLOSING_HEAD_TAG = "</head>", warnedMissingBootstrap = false, warnIfBootstrapMissing = (manifest) => {
|
|
1224
1386
|
if (warnedMissingBootstrap || getIslandBootstrapPath(manifest))
|
|
1225
1387
|
return;
|
|
1226
|
-
if (
|
|
1227
|
-
;
|
|
1388
|
+
if (isProductionRuntime())
|
|
1389
|
+
return;
|
|
1228
1390
|
warnedMissingBootstrap = true;
|
|
1229
1391
|
logWarn("A page contains islands, but the build manifest has no islands bootstrap, so they will render without hydrating. Set `islands.registry` in absolute.config.ts (a default bootstrap is generated from it) or point `islands.bootstrap` at a file that calls startIslands().");
|
|
1230
1392
|
}, buildIslandsHeadMarkup = (manifest) => {
|
|
1231
|
-
const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
|
|
1232
|
-
const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
|
|
1393
|
+
const manifestScript = `<script${nonceAttr()}>window.__ABSOLUTE_MANIFEST__ = ${escapeScriptContent(JSON.stringify(manifest))}</script>`;
|
|
1394
|
+
const islandStateScript = `<script${nonceAttr()}>window.__ABS_ISLAND_STATE__ = ${escapeScriptContent(JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {}))}</script>`;
|
|
1233
1395
|
const bootstrapPath = getIslandBootstrapPath(manifest);
|
|
1234
|
-
const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
|
|
1396
|
+
const bootstrapScript = bootstrapPath ? `<script${nonceAttr()} type="module" src="${bootstrapPath}"></script>` : "";
|
|
1235
1397
|
return `${manifestScript}${islandStateScript}${bootstrapScript}`;
|
|
1236
1398
|
}, injectHeadMarkup = (html, markup) => {
|
|
1237
1399
|
const closingHeadIndex = html.indexOf("</head>");
|
|
@@ -1432,6 +1594,8 @@ var ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST
|
|
|
1432
1594
|
globalThis.__absoluteManifest = manifest;
|
|
1433
1595
|
};
|
|
1434
1596
|
var init_islandPageContext = __esm(() => {
|
|
1597
|
+
init_escapeScriptContent();
|
|
1598
|
+
init_cspNonceRef();
|
|
1435
1599
|
init_logger();
|
|
1436
1600
|
});
|
|
1437
1601
|
|
|
@@ -1561,7 +1725,7 @@ var errorPageHtml = ({
|
|
|
1561
1725
|
<meta charset="utf-8">
|
|
1562
1726
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1563
1727
|
<title>SSR Error - AbsoluteJS</title>
|
|
1564
|
-
<style>
|
|
1728
|
+
<style${nonceAttr()}>
|
|
1565
1729
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
1566
1730
|
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}
|
|
1567
1731
|
.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}
|
|
@@ -1593,20 +1757,23 @@ body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,r
|
|
|
1593
1757
|
${script}
|
|
1594
1758
|
</body>
|
|
1595
1759
|
</html>`;
|
|
1596
|
-
},
|
|
1760
|
+
}, reloadOnRebuild = () => `<script${nonceAttr()}>(()=>{const url=(location.protocol==='https:'?'wss://':'ws://')+location.host+'/hmr';let seen=false;const connect=()=>{const socket=new WebSocket(url);socket.onopen=()=>{if(seen)location.reload();seen=true;};socket.onmessage=(event)=>{try{const message=JSON.parse(event.data);const type=message&&typeof message.type==='string'?message.type:'';if(type==='rebuild-complete'||type==='server-entry-reloaded'||type.endsWith('-update'))location.reload();}catch{}};socket.onclose=()=>setTimeout(connect,500);};connect();})();</script>`, buildErrorPage = (framework, pageName, error) => errorPageHtml({
|
|
1597
1761
|
framework,
|
|
1598
1762
|
hint: "Fix the file and save. This page reloads by itself when the build succeeds.",
|
|
1599
1763
|
kind: "Build Error",
|
|
1600
1764
|
message: `${pageName || "This page"} could not be built.
|
|
1601
1765
|
|
|
1602
1766
|
${error ?? "The dev-server terminal has the build output."}`,
|
|
1603
|
-
script:
|
|
1767
|
+
script: reloadOnRebuild()
|
|
1604
1768
|
}), ssrErrorPage = (framework, error) => errorPageHtml({
|
|
1605
1769
|
framework,
|
|
1606
1770
|
hint: "A component threw during server-side rendering. Check the terminal for the full stack trace.",
|
|
1607
1771
|
kind: "Server Render Error",
|
|
1608
1772
|
message: error instanceof Error ? error.message : String(error)
|
|
1609
1773
|
});
|
|
1774
|
+
var init_ssrErrorPage = __esm(() => {
|
|
1775
|
+
init_cspNonceRef();
|
|
1776
|
+
});
|
|
1610
1777
|
|
|
1611
1778
|
// src/core/requestContext.ts
|
|
1612
1779
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
@@ -1680,6 +1847,7 @@ var REQUEST_STORAGE_KEY, PAGE_WARMER_KEY, isAbsoluteRequestStorage = (value) =>
|
|
|
1680
1847
|
return headClose ? head.slice(0, headClose.index) + links + head.slice(headClose.index) : head + links;
|
|
1681
1848
|
};
|
|
1682
1849
|
var init_requestContext = __esm(() => {
|
|
1850
|
+
init_ssrErrorPage();
|
|
1683
1851
|
REQUEST_STORAGE_KEY = Symbol.for("absolutejs.requestAsyncLocalStorage");
|
|
1684
1852
|
PAGE_WARMER_KEY = Symbol.for("absolutejs.devPageWarmer");
|
|
1685
1853
|
absoluteRequestContext = new Elysia2({
|
|
@@ -1807,13 +1975,13 @@ var ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE = "application/vnd.absolute.page+json", ABSO
|
|
|
1807
1975
|
}, headerVaryValues, envelopeResponse = (response, status) => new Response(JSON.stringify({
|
|
1808
1976
|
protocol: ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
|
|
1809
1977
|
response
|
|
1810
|
-
}), { headers: responseHeaders(), status }),
|
|
1978
|
+
}), { headers: responseHeaders(), status }), isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), normalizeJsonValue = (value) => {
|
|
1811
1979
|
const serialized = JSON.stringify(value);
|
|
1812
1980
|
if (serialized === undefined) {
|
|
1813
1981
|
throw new TypeError("Mobile page props must be JSON-serializable.");
|
|
1814
1982
|
}
|
|
1815
1983
|
const parsed = JSON.parse(serialized);
|
|
1816
|
-
if (!
|
|
1984
|
+
if (!isRecord2(parsed)) {
|
|
1817
1985
|
throw new TypeError("Mobile page props must serialize to an object.");
|
|
1818
1986
|
}
|
|
1819
1987
|
return parsed;
|
|
@@ -1843,7 +2011,9 @@ var ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE = "application/vnd.absolute.page+json", ABSO
|
|
|
1843
2011
|
return createAbsoluteMobilePageErrorResponse(page.pageId);
|
|
1844
2012
|
}
|
|
1845
2013
|
}, finalizeAbsoluteNativeRouteDevelopmentPage = (input) => {
|
|
1846
|
-
if (
|
|
2014
|
+
if (!isDevelopmentRuntime()) {
|
|
2015
|
+
return createAbsoluteMobileInvalidRequestResponse("The native-route development representation is disabled outside development.");
|
|
2016
|
+
}
|
|
1847
2017
|
if (input.request?.method !== "GET") {
|
|
1848
2018
|
return createAbsoluteMobileInvalidRequestResponse("Native-route data requests must use GET.");
|
|
1849
2019
|
}
|
|
@@ -2185,22 +2355,15 @@ var streamSwapRuntime = () => {
|
|
|
2185
2355
|
return value.slice(start + 1, end);
|
|
2186
2356
|
}, getStreamSwapRuntimeScript = () => `(function(){${stripFunctionWrapper(streamSwapRuntime.toString())}})();`;
|
|
2187
2357
|
|
|
2188
|
-
// src/utils/escapeScriptContent.ts
|
|
2189
|
-
var ESCAPE_LOOKUP, ESCAPE_REGEX, escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
|
|
2190
|
-
const escaped = ESCAPE_LOOKUP[char];
|
|
2191
|
-
return escaped !== undefined ? escaped : char;
|
|
2192
|
-
});
|
|
2193
|
-
var init_escapeScriptContent = __esm(() => {
|
|
2194
|
-
ESCAPE_LOOKUP = {
|
|
2195
|
-
"\u2028": "\\u2028",
|
|
2196
|
-
"\u2029": "\\u2029",
|
|
2197
|
-
"<": "\\u003C"
|
|
2198
|
-
};
|
|
2199
|
-
ESCAPE_REGEX = /[<\u2028\u2029]/g;
|
|
2200
|
-
});
|
|
2201
|
-
|
|
2202
2358
|
// src/utils/streamingSlots.ts
|
|
2203
|
-
var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG2 = "</head>", CLOSING_BODY_TAG_LENGTH, CLOSING_HEAD_TAG_LENGTH, CLOSING_PAGE_TAG_REGEX, STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__", STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__", STREAM_TAIL_LOOKBEHIND = 128, STREAMING_SLOT_TIMEOUT_MS = 5000,
|
|
2359
|
+
var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG2 = "</head>", CLOSING_BODY_TAG_LENGTH, CLOSING_HEAD_TAG_LENGTH, CLOSING_PAGE_TAG_REGEX, STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__", STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__", STREAM_TAIL_LOOKBEHIND = 128, STREAMING_SLOT_TIMEOUT_MS = 5000, findSafeFlushIndex = (text, cut) => {
|
|
2360
|
+
const head = text.slice(0, cut);
|
|
2361
|
+
const openScript = head.lastIndexOf("<script");
|
|
2362
|
+
const scriptCut = openScript > head.lastIndexOf("</script>") ? openScript : cut;
|
|
2363
|
+
const beforeScript = text.slice(0, scriptCut);
|
|
2364
|
+
const openTag = beforeScript.lastIndexOf("<");
|
|
2365
|
+
return openTag > beforeScript.lastIndexOf(">") ? openTag : scriptCut;
|
|
2366
|
+
}, STREAMING_SLOT_MAX_PER_RESPONSE = 128, STREAMING_SLOT_MAX_HTML_BYTES = 64000, createSlotPatchStatement = (id, payload) => `(window.${STREAMING_RUNTIME_GLOBAL}||function(i,p){window.${STREAMING_PENDING_GLOBAL}=window.${STREAMING_PENDING_GLOBAL}||{};window.${STREAMING_PENDING_GLOBAL}[i]=p;})(${JSON.stringify(id)},${JSON.stringify(payload)});`, createNonceAttr = (nonce) => nonceAttr(nonce), createStreamingSlotId = () => `${SLOT_ID_PREFIX}${Math.random().toString(BASE_36_RADIX).slice(2, RANDOM_ID_END_INDEX)}`, getStreamingSlotsRuntimeScript = () => getStreamSwapRuntimeScript(), injectHtmlIntoBody = (html, injection) => {
|
|
2204
2367
|
const closingBodyIndex = html.indexOf(CLOSING_BODY_TAG);
|
|
2205
2368
|
if (closingBodyIndex >= 0) {
|
|
2206
2369
|
return `${html.slice(0, closingBodyIndex)}${injection}${html.slice(closingBodyIndex)}`;
|
|
@@ -2218,7 +2381,7 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
|
|
|
2218
2381
|
getStreamingSlotsRuntimeScript()
|
|
2219
2382
|
].filter(Boolean).join(";");
|
|
2220
2383
|
return `<script${createNonceAttr(nonce)}>${escapeScriptContent(runtimeBody)}</script>`;
|
|
2221
|
-
}, toUint8 = (value, encoder) => encoder.encode(value),
|
|
2384
|
+
}, toUint8 = (value, encoder) => encoder.encode(value), isRecord3 = (value) => Boolean(value) && typeof value === "object", isSafeHtmlLike = (value) => isRecord3(value) && typeof value.changingThisBreaksApplicationSecurity === "string", normalizeSafeHtml = (value) => {
|
|
2222
2385
|
if (isSafeHtmlLike(value)) {
|
|
2223
2386
|
return value.changingThisBreaksApplicationSecurity;
|
|
2224
2387
|
}
|
|
@@ -2279,7 +2442,8 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
|
|
|
2279
2442
|
}, createTimeoutError = (slot, timeoutMs) => {
|
|
2280
2443
|
const error = Object.assign(new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`), { __absTimeout: true });
|
|
2281
2444
|
return error;
|
|
2282
|
-
}, isSlotPatchPayloadObject = (value) =>
|
|
2445
|
+
}, isSlotPatchPayloadObject = (value) => isRecord3(value) && ("html" in value), isTimeoutError = (error) => isRecord3(error) && error.__absTimeout === true, toStreamingSlot = (slot, policy) => ({
|
|
2446
|
+
dynamic: slot.dynamic,
|
|
2283
2447
|
errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
|
|
2284
2448
|
fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
|
|
2285
2449
|
id: slot.id ?? createStreamingSlotId(),
|
|
@@ -2504,9 +2668,10 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
|
|
|
2504
2668
|
if (tail.length <= STREAM_TAIL_LOOKBEHIND) {
|
|
2505
2669
|
return tail;
|
|
2506
2670
|
}
|
|
2507
|
-
const
|
|
2508
|
-
|
|
2509
|
-
|
|
2671
|
+
const cut = findSafeFlushIndex(tail, tail.length - STREAM_TAIL_LOOKBEHIND);
|
|
2672
|
+
if (cut > 0)
|
|
2673
|
+
controller.enqueue(encoder.encode(tail.slice(0, cut)));
|
|
2674
|
+
return tail.slice(cut);
|
|
2510
2675
|
};
|
|
2511
2676
|
const finalizeCompletedBaseWinner = (controller, decodedTail, baseRead) => {
|
|
2512
2677
|
const footerStart = decodedTail.search(CLOSING_PAGE_TAG_REGEX);
|
|
@@ -2739,6 +2904,7 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
|
|
|
2739
2904
|
});
|
|
2740
2905
|
};
|
|
2741
2906
|
var init_streamingSlots = __esm(() => {
|
|
2907
|
+
init_cspNonceRef();
|
|
2742
2908
|
init_constants();
|
|
2743
2909
|
init_escapeScriptContent();
|
|
2744
2910
|
CLOSING_BODY_TAG_LENGTH = CLOSING_BODY_TAG.length;
|
|
@@ -2753,6 +2919,42 @@ var init_streamingSlots = __esm(() => {
|
|
|
2753
2919
|
};
|
|
2754
2920
|
});
|
|
2755
2921
|
|
|
2922
|
+
// src/core/partialPrerender.ts
|
|
2923
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
|
|
2924
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
2925
|
+
import { rm } from "fs/promises";
|
|
2926
|
+
var PARTIAL_HOLES_HEADER = "X-Absolute-Partial-Holes", PARTIAL_SHELL_HEADER = "X-Absolute-Partial-Shell", SINK_STORAGE_KEY, isSinkStorage = (value) => value instanceof AsyncLocalStorage3, getSinkStorage = () => {
|
|
2927
|
+
const existing = Reflect.get(globalThis, SINK_STORAGE_KEY);
|
|
2928
|
+
if (isSinkStorage(existing))
|
|
2929
|
+
return existing;
|
|
2930
|
+
const created = new AsyncLocalStorage3;
|
|
2931
|
+
Reflect.set(globalThis, SINK_STORAGE_KEY, created);
|
|
2932
|
+
return created;
|
|
2933
|
+
}, activePartialHolesSink = () => getSinkStorage().getStore(), collectPartialHoles = async (render) => {
|
|
2934
|
+
const sink = { slots: undefined };
|
|
2935
|
+
const response = await getSinkStorage().run(sink, render);
|
|
2936
|
+
return { response, slots: sink.slots };
|
|
2937
|
+
}, decodePartialHoles = (value) => value ? value.split(",").filter(Boolean).map((id) => decodeURIComponent(id)) : [], encodePartialHoles = (ids) => ids.map((id) => encodeURIComponent(id)).join(","), isDynamicStreamingSlot = (slot) => slot.dynamic === true, isPartialShellCapture = (request) => request?.headers.get(PARTIAL_SHELL_HEADER) === "1", holesPath = (htmlPath) => htmlPath.replace(/\.html$/, ".holes"), readPartialHoles = (htmlPath) => {
|
|
2938
|
+
const path = holesPath(htmlPath);
|
|
2939
|
+
if (!existsSync3(path))
|
|
2940
|
+
return [];
|
|
2941
|
+
return decodePartialHoles(readFileSync3(path, "utf-8").trim().split(`
|
|
2942
|
+
`).join(","));
|
|
2943
|
+
}, writePartialHoles = async (htmlPath, response) => {
|
|
2944
|
+
const ids = decodePartialHoles(response.headers.get(PARTIAL_HOLES_HEADER));
|
|
2945
|
+
if (ids.length > 0) {
|
|
2946
|
+
await Bun.write(holesPath(htmlPath), `${encodePartialHoles(ids).split(",").join(`
|
|
2947
|
+
`)}
|
|
2948
|
+
`);
|
|
2949
|
+
} else {
|
|
2950
|
+
await rm(holesPath(htmlPath), { force: true });
|
|
2951
|
+
}
|
|
2952
|
+
return ids;
|
|
2953
|
+
};
|
|
2954
|
+
var init_partialPrerender = __esm(() => {
|
|
2955
|
+
SINK_STORAGE_KEY = Symbol.for("absolutejs.partialPrerenderHolesSink");
|
|
2956
|
+
});
|
|
2957
|
+
|
|
2756
2958
|
// src/core/routeAssets.ts
|
|
2757
2959
|
var LINK_TAG_RE, REL_STYLESHEET_RE, HREF_RE, TITLE_RE, ENTITIES, ENTITY_RE, decodeEntities = (value) => value.replace(ENTITY_RE, (match) => ENTITIES[match] ?? match), readHeadStylesheets = (head) => {
|
|
2758
2960
|
if (!head)
|
|
@@ -2796,7 +2998,7 @@ var siblingCssCache, clearSiblingCssCache = () => {
|
|
|
2796
2998
|
}, injectInlineCss = (headTag, css) => {
|
|
2797
2999
|
if (!css)
|
|
2798
3000
|
return headTag;
|
|
2799
|
-
const styleBlock = `<style data-absolute-page-css>${css}</style>`;
|
|
3001
|
+
const styleBlock = `<style data-absolute-page-css${nonceAttr()}>${css}</style>`;
|
|
2800
3002
|
return headTag.replace("</head>", `${styleBlock}</head>`);
|
|
2801
3003
|
}, readSiblingCss = async (siblingJsPath) => {
|
|
2802
3004
|
if (!siblingJsPath)
|
|
@@ -2818,6 +3020,7 @@ var siblingCssCache, clearSiblingCssCache = () => {
|
|
|
2818
3020
|
}
|
|
2819
3021
|
};
|
|
2820
3022
|
var init_inlinePageCss = __esm(() => {
|
|
3023
|
+
init_cspNonceRef();
|
|
2821
3024
|
siblingCssCache = new Map;
|
|
2822
3025
|
});
|
|
2823
3026
|
|
|
@@ -2829,6 +3032,45 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
|
|
|
2829
3032
|
return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
|
|
2830
3033
|
};
|
|
2831
3034
|
|
|
3035
|
+
// src/core/staticHtmlNonce.ts
|
|
3036
|
+
var nonceStaticHtml = async (html, nonce = readCspNonce()) => {
|
|
3037
|
+
if (!nonce)
|
|
3038
|
+
return html;
|
|
3039
|
+
const stamp = {
|
|
3040
|
+
element: (element) => {
|
|
3041
|
+
if (!element.hasAttribute("nonce"))
|
|
3042
|
+
element.setAttribute("nonce", nonce);
|
|
3043
|
+
}
|
|
3044
|
+
};
|
|
3045
|
+
return new HTMLRewriter().on("script", stamp).on("style", stamp).transform(new Response(html)).text();
|
|
3046
|
+
}, isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), parseHtmxConfig = (content) => {
|
|
3047
|
+
try {
|
|
3048
|
+
const parsed = JSON.parse(content ?? "{}");
|
|
3049
|
+
return isRecord4(parsed) ? parsed : {};
|
|
3050
|
+
} catch {
|
|
3051
|
+
return {};
|
|
3052
|
+
}
|
|
3053
|
+
}, withHtmxStyleNonce = async (html, nonce = readCspNonce()) => {
|
|
3054
|
+
if (!nonce)
|
|
3055
|
+
return html;
|
|
3056
|
+
let found = false;
|
|
3057
|
+
const merged = await new HTMLRewriter().on('meta[name="htmx-config"]', {
|
|
3058
|
+
element: (element) => {
|
|
3059
|
+
found = true;
|
|
3060
|
+
const config = parseHtmxConfig(element.getAttribute("content"));
|
|
3061
|
+
element.setAttribute("content", JSON.stringify({ ...config, inlineStyleNonce: nonce }));
|
|
3062
|
+
}
|
|
3063
|
+
}).transform(new Response(html)).text();
|
|
3064
|
+
if (found)
|
|
3065
|
+
return merged;
|
|
3066
|
+
const meta = `<meta name="htmx-config" content='${JSON.stringify({ inlineStyleNonce: nonce })}'>`;
|
|
3067
|
+
const headClose = merged.search(/<\/head>/i);
|
|
3068
|
+
return headClose >= 0 ? `${merged.slice(0, headClose)}${meta}${merged.slice(headClose)}` : `${meta}${merged}`;
|
|
3069
|
+
};
|
|
3070
|
+
var init_staticHtmlNonce = __esm(() => {
|
|
3071
|
+
init_cspNonceRef();
|
|
3072
|
+
});
|
|
3073
|
+
|
|
2832
3074
|
// src/utils/resolveConvention.ts
|
|
2833
3075
|
import { basename as basename2 } from "path";
|
|
2834
3076
|
var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
|
|
@@ -2865,7 +3107,7 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
2865
3107
|
return conventions.defaults?.error;
|
|
2866
3108
|
}, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
|
|
2867
3109
|
Reflect.set(globalThis, CONVENTIONS_KEY, map);
|
|
2868
|
-
}, isDev = () =>
|
|
3110
|
+
}, isDev = () => isDevelopmentRuntime(), buildErrorProps = (error) => {
|
|
2869
3111
|
if (error instanceof Error) {
|
|
2870
3112
|
return {
|
|
2871
3113
|
message: error.message,
|
|
@@ -2882,7 +3124,9 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
2882
3124
|
if (typeof ErrorComponent !== "function")
|
|
2883
3125
|
return null;
|
|
2884
3126
|
const element = createElement(ErrorComponent, errorProps);
|
|
2885
|
-
const stream = await renderToReadableStream(element
|
|
3127
|
+
const stream = await renderToReadableStream(element, {
|
|
3128
|
+
nonce: readCspNonce()
|
|
3129
|
+
});
|
|
2886
3130
|
return new Response(stream, {
|
|
2887
3131
|
headers: { "Content-Type": "text/html" },
|
|
2888
3132
|
status: 500
|
|
@@ -2893,10 +3137,12 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
2893
3137
|
const ErrorComponent = mod.default;
|
|
2894
3138
|
if (!ErrorComponent)
|
|
2895
3139
|
return null;
|
|
3140
|
+
const nonce = readCspNonce();
|
|
2896
3141
|
const { head, body } = render(ErrorComponent, {
|
|
2897
|
-
props: errorProps
|
|
3142
|
+
props: errorProps,
|
|
3143
|
+
...nonce ? { csp: { nonce } } : {}
|
|
2898
3144
|
});
|
|
2899
|
-
const html = `<!DOCTYPE html><html><head>${head}</head><body>${body}</body></html>`;
|
|
3145
|
+
const html = `<!DOCTYPE html><html><head>${nonceSvelteHeadStyles(head)}</head><body>${body}</body></html>`;
|
|
2900
3146
|
return new Response(html, {
|
|
2901
3147
|
headers: { "Content-Type": "text/html" },
|
|
2902
3148
|
status: 500
|
|
@@ -2904,7 +3150,7 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
2904
3150
|
}, unescapeVueStyles = (ssrBody) => {
|
|
2905
3151
|
let styles = "";
|
|
2906
3152
|
const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
|
|
2907
|
-
styles += `<style>${css.replace(/"/g, '"').replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</style>`;
|
|
3153
|
+
styles += `<style${nonceAttr()}>${css.replace(/"/g, '"').replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</style>`;
|
|
2908
3154
|
return "";
|
|
2909
3155
|
});
|
|
2910
3156
|
return { body, styles };
|
|
@@ -2936,7 +3182,7 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
2936
3182
|
status: 500
|
|
2937
3183
|
});
|
|
2938
3184
|
}, escapeHtml = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"), replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml(errorProps.stack) : ""), renderHtmlError = async (conventionPath, errorProps) => {
|
|
2939
|
-
const template = await Bun.file(conventionPath).text();
|
|
3185
|
+
const template = await nonceStaticHtml(await Bun.file(conventionPath).text());
|
|
2940
3186
|
const html = replaceErrorTokens(template, errorProps);
|
|
2941
3187
|
return new Response(html, {
|
|
2942
3188
|
headers: { "Content-Type": "text/html" },
|
|
@@ -2991,7 +3237,9 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
2991
3237
|
if (typeof NotFoundComponent !== "function")
|
|
2992
3238
|
return null;
|
|
2993
3239
|
const element = createElement(NotFoundComponent);
|
|
2994
|
-
const stream = await renderToReadableStream(element
|
|
3240
|
+
const stream = await renderToReadableStream(element, {
|
|
3241
|
+
nonce: readCspNonce()
|
|
3242
|
+
});
|
|
2995
3243
|
return new Response(stream, {
|
|
2996
3244
|
headers: { "Content-Type": "text/html" },
|
|
2997
3245
|
status: 404
|
|
@@ -3002,8 +3250,9 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
3002
3250
|
const NotFoundComponent = mod.default;
|
|
3003
3251
|
if (!NotFoundComponent)
|
|
3004
3252
|
return null;
|
|
3005
|
-
const
|
|
3006
|
-
const
|
|
3253
|
+
const nonce = readCspNonce();
|
|
3254
|
+
const { head, body } = render(NotFoundComponent, nonce ? { csp: { nonce } } : {});
|
|
3255
|
+
const html = `<!DOCTYPE html><html><head>${nonceSvelteHeadStyles(head)}</head><body>${body}</body></html>`;
|
|
3007
3256
|
return new Response(html, {
|
|
3008
3257
|
headers: { "Content-Type": "text/html" },
|
|
3009
3258
|
status: 404
|
|
@@ -3036,7 +3285,7 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
3036
3285
|
status: 404
|
|
3037
3286
|
});
|
|
3038
3287
|
}, renderHtmlNotFound = async (conventionPath) => {
|
|
3039
|
-
const html = await Bun.file(conventionPath).text();
|
|
3288
|
+
const html = await nonceStaticHtml(await Bun.file(conventionPath).text());
|
|
3040
3289
|
return new Response(html, {
|
|
3041
3290
|
headers: { "Content-Type": "text/html" },
|
|
3042
3291
|
status: 404
|
|
@@ -3054,7 +3303,7 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
3054
3303
|
logConventionRenderError(framework, "not-found", renderError);
|
|
3055
3304
|
}
|
|
3056
3305
|
return null;
|
|
3057
|
-
}, NOT_FOUND_PRIORITY, renderFirstNotFound = async () => {
|
|
3306
|
+
}, NOT_FOUND_PRIORITY, renderFirstNotFound = async (options = {}) => {
|
|
3058
3307
|
const renderNext = async (frameworks) => {
|
|
3059
3308
|
const [framework, ...remaining] = frameworks;
|
|
3060
3309
|
if (!framework) {
|
|
@@ -3069,13 +3318,16 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
|
|
|
3069
3318
|
}
|
|
3070
3319
|
return renderNext(remaining);
|
|
3071
3320
|
};
|
|
3072
|
-
return renderNext(NOT_FOUND_PRIORITY);
|
|
3321
|
+
return renderNext(options.preferHtmx ? ["htmx", ...NOT_FOUND_PRIORITY.filter((key) => key !== "htmx")] : NOT_FOUND_PRIORITY);
|
|
3073
3322
|
};
|
|
3074
3323
|
var init_resolveConvention = __esm(() => {
|
|
3324
|
+
init_cspNonceRef();
|
|
3325
|
+
init_staticHtmlNonce();
|
|
3075
3326
|
ERROR_RENDERERS = {
|
|
3076
3327
|
angular: renderAngularError,
|
|
3077
3328
|
ember: renderEmberError,
|
|
3078
3329
|
html: renderHtmlError,
|
|
3330
|
+
htmx: renderHtmlError,
|
|
3079
3331
|
react: renderReactError,
|
|
3080
3332
|
svelte: renderSvelteError,
|
|
3081
3333
|
vue: renderVueError
|
|
@@ -3084,6 +3336,7 @@ var init_resolveConvention = __esm(() => {
|
|
|
3084
3336
|
angular: renderAngularNotFound,
|
|
3085
3337
|
ember: renderEmberNotFound,
|
|
3086
3338
|
html: renderHtmlNotFound,
|
|
3339
|
+
htmx: renderHtmlNotFound,
|
|
3087
3340
|
react: renderReactNotFound,
|
|
3088
3341
|
svelte: renderSvelteNotFound,
|
|
3089
3342
|
vue: renderVueNotFound
|
|
@@ -3093,7 +3346,8 @@ var init_resolveConvention = __esm(() => {
|
|
|
3093
3346
|
"svelte",
|
|
3094
3347
|
"vue",
|
|
3095
3348
|
"angular",
|
|
3096
|
-
"html"
|
|
3349
|
+
"html",
|
|
3350
|
+
"htmx"
|
|
3097
3351
|
];
|
|
3098
3352
|
});
|
|
3099
3353
|
|
|
@@ -3178,7 +3432,7 @@ var init_browserTranslationAttributes = __esm(() => {
|
|
|
3178
3432
|
});
|
|
3179
3433
|
|
|
3180
3434
|
// src/core/browserTranslation.ts
|
|
3181
|
-
var BASELINE_MARKER = "__ABSOLUTE_SSR_TEXT_BASELINES__", BROWSER_TRANSLATION_BASELINE_SCRIPT, browserTranslationBaselineTag = () => `<script>${BROWSER_TRANSLATION_BASELINE_SCRIPT}</script>`, injectBrowserTranslationBaseline = (html) => {
|
|
3435
|
+
var BASELINE_MARKER = "__ABSOLUTE_SSR_TEXT_BASELINES__", BROWSER_TRANSLATION_BASELINE_SCRIPT, browserTranslationBaselineTag = () => `<script${nonceAttr()}>${BROWSER_TRANSLATION_BASELINE_SCRIPT}</script>`, injectBrowserTranslationBaseline = (html) => {
|
|
3182
3436
|
if (html.includes(BASELINE_MARKER))
|
|
3183
3437
|
return html;
|
|
3184
3438
|
const script = browserTranslationBaselineTag();
|
|
@@ -3188,12 +3442,40 @@ var BASELINE_MARKER = "__ABSOLUTE_SSR_TEXT_BASELINES__", BROWSER_TRANSLATION_BAS
|
|
|
3188
3442
|
return `${html.slice(0, closingBodyIndex)}${script}${html.slice(closingBodyIndex)}`;
|
|
3189
3443
|
};
|
|
3190
3444
|
var init_browserTranslation = __esm(() => {
|
|
3445
|
+
init_cspNonceRef();
|
|
3191
3446
|
init_browserTranslationAttributes();
|
|
3192
3447
|
BROWSER_TRANSLATION_BASELINE_SCRIPT = "window.__ABSOLUTE_SSR_TEXT_BASELINES__=new WeakMap();" + "window.__ABSOLUTE_SSR_ATTRIBUTE_BASELINES__=new WeakMap();" + "{const r=document.body,b=window.__ABSOLUTE_SSR_TEXT_BASELINES__," + "a=window.__ABSOLUTE_SSR_ATTRIBUTE_BASELINES__;" + 'if(r)for(const e of [r,...r.querySelectorAll("*")]){' + "const t=new Map();for(const [i,n]of[...e.childNodes].entries())" + 'if(n.nodeType===3)t.set(i,n.nodeValue??"");if(t.size)b.set(e,t);' + `const v=new Map();for(const k of ${JSON.stringify(TRANSLATABLE_ATTRIBUTES)}){` + "const s=e.getAttribute(k);if(s!==null)v.set(k,s);}if(v.size)a.set(e,v);}}";
|
|
3193
3448
|
});
|
|
3194
3449
|
|
|
3450
|
+
// src/utils/localeRef.ts
|
|
3451
|
+
var GETTER_KEY2, isRequestLocale = (value) => typeof value === "object" && value !== null && ("locale" in value) && typeof value.locale === "string" && ("dir" in value) && (value.dir === "ltr" || value.dir === "rtl"), escapeAttribute = (value) => value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<"), htmlLangAttributes = (fallback = "en") => {
|
|
3452
|
+
const current = readRequestLocale();
|
|
3453
|
+
if (!current)
|
|
3454
|
+
return ` lang="${escapeAttribute(fallback)}"`;
|
|
3455
|
+
return ` lang="${escapeAttribute(current.locale)}" dir="${current.dir}"`;
|
|
3456
|
+
}, readRequestLocale = () => {
|
|
3457
|
+
const getter = Reflect.get(globalThis, GETTER_KEY2);
|
|
3458
|
+
if (typeof getter !== "function")
|
|
3459
|
+
return;
|
|
3460
|
+
const value = getter();
|
|
3461
|
+
return isRequestLocale(value) ? value : undefined;
|
|
3462
|
+
}, registerRequestLocaleGetter = (getter) => {
|
|
3463
|
+
Reflect.set(globalThis, GETTER_KEY2, getter);
|
|
3464
|
+
};
|
|
3465
|
+
var init_localeRef = __esm(() => {
|
|
3466
|
+
GETTER_KEY2 = Symbol.for("absolutejs.requestLocaleGetter");
|
|
3467
|
+
});
|
|
3468
|
+
|
|
3195
3469
|
// src/svelte/renderToReadableStream.ts
|
|
3196
|
-
var SVELTE_PAGE_ROOT_ID = "__absolute_svelte_root__",
|
|
3470
|
+
var SVELTE_PAGE_ROOT_ID = "__absolute_svelte_root__", MAX_RENDER_PASSES = 5, renderUntilSettled = async (renderPass, settle, pass = 1) => {
|
|
3471
|
+
const rendered = await renderPass();
|
|
3472
|
+
if (!settle || pass >= MAX_RENDER_PASSES)
|
|
3473
|
+
return rendered;
|
|
3474
|
+
const again = await settle();
|
|
3475
|
+
if (!again)
|
|
3476
|
+
return rendered;
|
|
3477
|
+
return renderUntilSettled(renderPass, settle, pass + 1);
|
|
3478
|
+
}, renderToReadableStream = async (component, props, {
|
|
3197
3479
|
bootstrapScriptContent,
|
|
3198
3480
|
bootstrapScripts = [],
|
|
3199
3481
|
bootstrapModules = [],
|
|
@@ -3202,17 +3484,28 @@ var SVELTE_PAGE_ROOT_ID = "__absolute_svelte_root__", renderToReadableStream = a
|
|
|
3202
3484
|
progressiveChunkSize = DEFAULT_CHUNK_SIZE,
|
|
3203
3485
|
signal,
|
|
3204
3486
|
headContent,
|
|
3205
|
-
bodyContent
|
|
3487
|
+
bodyContent,
|
|
3488
|
+
context,
|
|
3489
|
+
settle
|
|
3206
3490
|
} = {}) => {
|
|
3207
3491
|
try {
|
|
3208
3492
|
const { render } = await import("svelte/server");
|
|
3209
3493
|
const renderComponent = render;
|
|
3210
|
-
const
|
|
3494
|
+
const resolvedNonce = nonce ?? readCspNonce();
|
|
3495
|
+
const svelteCsp = resolvedNonce ? { csp: { nonce: resolvedNonce } } : {};
|
|
3496
|
+
const renderPass = async () => {
|
|
3497
|
+
if (typeof props === "undefined" && !context) {
|
|
3498
|
+
return renderComponent(component, svelteCsp);
|
|
3499
|
+
}
|
|
3500
|
+
return renderComponent(component, { ...svelteCsp, context, props });
|
|
3501
|
+
};
|
|
3502
|
+
const rendered = await renderUntilSettled(renderPass, settle);
|
|
3211
3503
|
const { head, body } = rendered;
|
|
3212
|
-
const
|
|
3213
|
-
const
|
|
3504
|
+
const nonceAttr2 = nonceAttr(resolvedNonce);
|
|
3505
|
+
const inlineScript = typeof bootstrapScriptContent === "function" ? bootstrapScriptContent() : bootstrapScriptContent;
|
|
3506
|
+
const scripts = (inlineScript ? `<script${nonceAttr2}>${escapeScriptContent(inlineScript)}</script>` : "") + bootstrapScripts.map((src) => `<script${nonceAttr2} src="${src}"></script>`).join("") + bootstrapModules.map((src) => `<script${nonceAttr2} type="module" src="${src}"></script>`).join("");
|
|
3214
3507
|
const encoder = new TextEncoder;
|
|
3215
|
-
const full = encoder.encode(`<!DOCTYPE html><html
|
|
3508
|
+
const full = encoder.encode(`<!DOCTYPE html><html${htmlLangAttributes()}><head>${nonceSvelteHeadStyles(head, resolvedNonce)}${headContent ?? ""}</head><body><div id="${SVELTE_PAGE_ROOT_ID}">${body}</div>${scripts}${bodyContent ?? ""}</body></html>`);
|
|
3216
3509
|
let offset = 0;
|
|
3217
3510
|
return new ReadableStream({
|
|
3218
3511
|
type: "bytes",
|
|
@@ -3239,26 +3532,28 @@ var SVELTE_PAGE_ROOT_ID = "__absolute_svelte_root__", renderToReadableStream = a
|
|
|
3239
3532
|
}
|
|
3240
3533
|
};
|
|
3241
3534
|
var init_renderToReadableStream = __esm(() => {
|
|
3535
|
+
init_cspNonceRef();
|
|
3242
3536
|
init_constants();
|
|
3243
3537
|
init_escapeScriptContent();
|
|
3538
|
+
init_localeRef();
|
|
3244
3539
|
});
|
|
3245
3540
|
|
|
3246
3541
|
// src/angular/resolveAngularPackage.ts
|
|
3247
|
-
import { existsSync as
|
|
3542
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
3248
3543
|
import { join as join4, resolve as resolve4 } from "path";
|
|
3249
3544
|
var resolveAngularPackageDir = (specifier) => {
|
|
3250
3545
|
const fromCompiledRuntime = process.env.ABSOLUTE_BUILD_DIR ? resolve4(process.env.ABSOLUTE_BUILD_DIR, "node_modules", specifier) : null;
|
|
3251
|
-
if (fromCompiledRuntime &&
|
|
3546
|
+
if (fromCompiledRuntime && existsSync4(fromCompiledRuntime)) {
|
|
3252
3547
|
return fromCompiledRuntime;
|
|
3253
3548
|
}
|
|
3254
3549
|
const fromProject = resolve4(process.cwd(), "node_modules", specifier);
|
|
3255
|
-
if (
|
|
3550
|
+
if (existsSync4(fromProject)) {
|
|
3256
3551
|
return fromProject;
|
|
3257
3552
|
}
|
|
3258
3553
|
return null;
|
|
3259
3554
|
}, resolvePackageEntry = (packageDir) => {
|
|
3260
3555
|
try {
|
|
3261
|
-
const pkg = JSON.parse(
|
|
3556
|
+
const pkg = JSON.parse(readFileSync4(join4(packageDir, "package.json"), "utf-8"));
|
|
3262
3557
|
const rootExport = pkg.exports?.["."];
|
|
3263
3558
|
const entry = (typeof rootExport === "string" ? rootExport : rootExport?.default) ?? pkg.module ?? pkg.main ?? "index.js";
|
|
3264
3559
|
return join4(packageDir, entry);
|
|
@@ -3277,16 +3572,13 @@ var resolveAngularPackageDir = (specifier) => {
|
|
|
3277
3572
|
].filter((value) => Boolean(value));
|
|
3278
3573
|
for (const buildDir of buildDirs) {
|
|
3279
3574
|
const vendorPath = join4(buildDir, "angular", "vendor", "server", `${toSafeVendorName(specifier)}.js`);
|
|
3280
|
-
if (
|
|
3575
|
+
if (existsSync4(vendorPath))
|
|
3281
3576
|
return vendorPath;
|
|
3282
3577
|
}
|
|
3283
3578
|
return resolveAngularPackage(specifier);
|
|
3284
3579
|
};
|
|
3285
3580
|
var init_resolveAngularPackage = () => {};
|
|
3286
3581
|
|
|
3287
|
-
// src/utils/runtimeMode.ts
|
|
3288
|
-
var ENV_VAR = "NODE_ENV", isDevelopmentRuntime = () => process.env[ENV_VAR] === "development", isProductionRuntime = () => process.env[ENV_VAR] === "production";
|
|
3289
|
-
|
|
3290
3582
|
// src/angular/angularPatch.ts
|
|
3291
3583
|
var ensureHead = (doc) => {
|
|
3292
3584
|
if (!doc || doc.head || !doc.documentElement) {
|
|
@@ -3460,6 +3752,7 @@ var initDominoAdapter = (platformServer) => {
|
|
|
3460
3752
|
APP_BASE_HREF: common.APP_BASE_HREF,
|
|
3461
3753
|
bootstrapApplication: platformBrowser.bootstrapApplication,
|
|
3462
3754
|
Component: core.Component,
|
|
3755
|
+
CSP_NONCE: core.CSP_NONCE,
|
|
3463
3756
|
DomSanitizer: platformBrowser.DomSanitizer,
|
|
3464
3757
|
ENVIRONMENT_INITIALIZER: core.ENVIRONMENT_INITIALIZER,
|
|
3465
3758
|
inject: core.inject,
|
|
@@ -3467,6 +3760,7 @@ var initDominoAdapter = (platformServer) => {
|
|
|
3467
3760
|
NgComponentOutlet: common.NgComponentOutlet,
|
|
3468
3761
|
provideClientHydration: platformBrowser.provideClientHydration,
|
|
3469
3762
|
provideServerRendering: platformServer.provideServerRendering,
|
|
3763
|
+
provideZoneChangeDetection: core.provideZoneChangeDetection,
|
|
3470
3764
|
provideZonelessChangeDetection: core.provideZonelessChangeDetection,
|
|
3471
3765
|
reflectComponentType: core.reflectComponentType,
|
|
3472
3766
|
renderApplication: platformServer.renderApplication,
|
|
@@ -3542,7 +3836,7 @@ var scriptRegistry, requestCounter = 0, getRequestId = () => `req_${Date.now()}_
|
|
|
3542
3836
|
})();`;
|
|
3543
3837
|
}).join(`
|
|
3544
3838
|
`);
|
|
3545
|
-
return `<script>
|
|
3839
|
+
return `<script${nonceAttr()}>
|
|
3546
3840
|
(function() {
|
|
3547
3841
|
${scriptCode}
|
|
3548
3842
|
})();
|
|
@@ -3560,6 +3854,7 @@ ${scriptCode}
|
|
|
3560
3854
|
return scriptArray;
|
|
3561
3855
|
};
|
|
3562
3856
|
var init_registerClientScript = __esm(() => {
|
|
3857
|
+
init_cspNonceRef();
|
|
3563
3858
|
scriptRegistry = new Map;
|
|
3564
3859
|
if (typeof globalThis !== "undefined") {
|
|
3565
3860
|
Object.assign(globalThis, { registerClientScript });
|
|
@@ -3588,6 +3883,81 @@ var buildRequestProviders = (deps, request, requestContext, responseInit) => [
|
|
|
3588
3883
|
{ provide: deps.RESPONSE_INIT, useValue: responseInit ?? null }
|
|
3589
3884
|
];
|
|
3590
3885
|
|
|
3886
|
+
// src/angular/zoneRuntime.ts
|
|
3887
|
+
var ZONE_NODE_SPECIFIER = "zone.js/node", MISSING_ZONE_MESSAGE = 'angular.changeDetection is "zone" but zone.js could not be loaded. Install it in your app (bun add zone.js).', isAngularZoneMode = () => globalThis.__absoluteAngularChangeDetection === "zone", setAngularChangeDetection = (mode) => {
|
|
3888
|
+
globalThis.__absoluteAngularChangeDetection = mode ?? "zoneless";
|
|
3889
|
+
}, isRecord7 = (value) => typeof value === "object" && value !== null, adoptIntoNativePromise = (NativePromise, value) => {
|
|
3890
|
+
if (value instanceof NativePromise || !isRecord7(value))
|
|
3891
|
+
return value;
|
|
3892
|
+
const { then } = value;
|
|
3893
|
+
if (typeof then !== "function")
|
|
3894
|
+
return value;
|
|
3895
|
+
return new NativePromise((resolve, reject) => {
|
|
3896
|
+
Reflect.apply(then, value, [resolve, reject]);
|
|
3897
|
+
});
|
|
3898
|
+
}, wrapHandler = (NativePromise, handler) => {
|
|
3899
|
+
if (typeof handler !== "function")
|
|
3900
|
+
return handler;
|
|
3901
|
+
return function nativePromiseHandler(...args) {
|
|
3902
|
+
return adoptIntoNativePromise(NativePromise, Reflect.apply(handler, this, args));
|
|
3903
|
+
};
|
|
3904
|
+
}, wrapRoute = (NativePromise, route) => {
|
|
3905
|
+
if (typeof route === "function")
|
|
3906
|
+
return wrapHandler(NativePromise, route);
|
|
3907
|
+
if (!isRecord7(route) || route instanceof Response || route instanceof Blob)
|
|
3908
|
+
return route;
|
|
3909
|
+
return Object.fromEntries(Object.entries(route).map(([method, handler]) => [
|
|
3910
|
+
method,
|
|
3911
|
+
wrapHandler(NativePromise, handler)
|
|
3912
|
+
]));
|
|
3913
|
+
}, wrapServeOptions = (NativePromise, options) => {
|
|
3914
|
+
if (!isRecord7(options))
|
|
3915
|
+
return options;
|
|
3916
|
+
const wrapped = { ...options };
|
|
3917
|
+
if (options.fetch)
|
|
3918
|
+
wrapped.fetch = wrapHandler(NativePromise, options.fetch);
|
|
3919
|
+
if (options.error)
|
|
3920
|
+
wrapped.error = wrapHandler(NativePromise, options.error);
|
|
3921
|
+
if (isRecord7(options.routes))
|
|
3922
|
+
wrapped.routes = Object.fromEntries(Object.entries(options.routes).map(([path, route]) => [
|
|
3923
|
+
path,
|
|
3924
|
+
wrapRoute(NativePromise, route)
|
|
3925
|
+
]));
|
|
3926
|
+
return wrapped;
|
|
3927
|
+
}, wrapServerReload = (NativePromise, server) => {
|
|
3928
|
+
if (!isRecord7(server))
|
|
3929
|
+
return;
|
|
3930
|
+
const { reload } = server;
|
|
3931
|
+
if (typeof reload !== "function")
|
|
3932
|
+
return;
|
|
3933
|
+
Reflect.set(server, "reload", (options) => Reflect.apply(reload, server, [
|
|
3934
|
+
wrapServeOptions(NativePromise, options)
|
|
3935
|
+
]));
|
|
3936
|
+
}, patchBunServe = (NativePromise) => {
|
|
3937
|
+
const originalServe = Bun.serve;
|
|
3938
|
+
Reflect.set(Bun, "serve", (options) => {
|
|
3939
|
+
const server = Reflect.apply(originalServe, Bun, [
|
|
3940
|
+
wrapServeOptions(NativePromise, options)
|
|
3941
|
+
]);
|
|
3942
|
+
wrapServerReload(NativePromise, server);
|
|
3943
|
+
return server;
|
|
3944
|
+
});
|
|
3945
|
+
wrapServerReload(NativePromise, globalThis.__absoluteBunServer);
|
|
3946
|
+
}, installation = null, isPromiseConstructor = (value) => typeof value === "function", install = async () => {
|
|
3947
|
+
setAngularChangeDetection("zone");
|
|
3948
|
+
const savedNative = Reflect.get(globalThis, "__zone_symbol__Promise");
|
|
3949
|
+
const NativePromise = isPromiseConstructor(savedNative) ? savedNative : globalThis.Promise;
|
|
3950
|
+
try {
|
|
3951
|
+
await import(ZONE_NODE_SPECIFIER);
|
|
3952
|
+
} catch (error) {
|
|
3953
|
+
throw new Error(MISSING_ZONE_MESSAGE, { cause: error });
|
|
3954
|
+
}
|
|
3955
|
+
patchBunServe(NativePromise);
|
|
3956
|
+
}, installAngularZoneRuntime = () => {
|
|
3957
|
+
installation ??= install();
|
|
3958
|
+
return installation;
|
|
3959
|
+
};
|
|
3960
|
+
|
|
3591
3961
|
// src/angular/ssrRender.ts
|
|
3592
3962
|
var routeContextCache, cacheRouteData = (pagePath, data) => {
|
|
3593
3963
|
const cacheKey = pagePath.split("?")[0] ?? pagePath;
|
|
@@ -3595,7 +3965,7 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
|
|
|
3595
3965
|
}, getCachedRouteData = (pagePath) => routeContextCache.get(pagePath), selectorCache, buildProviders = (deps, sanitizer, request, requestContext, responseInit, userProviders = []) => [
|
|
3596
3966
|
deps.provideServerRendering(),
|
|
3597
3967
|
deps.provideClientHydration(deps.withHttpTransferCacheOptions(buildAbsoluteHttpTransferCacheOptions())),
|
|
3598
|
-
deps.provideZonelessChangeDetection(),
|
|
3968
|
+
isAngularZoneMode() ? deps.provideZoneChangeDetection({ eventCoalescing: true }) : deps.provideZonelessChangeDetection(),
|
|
3599
3969
|
{ provide: deps.APP_BASE_HREF, useValue: "/" },
|
|
3600
3970
|
{ provide: deps.DomSanitizer, useValue: sanitizer },
|
|
3601
3971
|
{ provide: deps.Sanitizer, useValue: sanitizer },
|
|
@@ -3624,15 +3994,17 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
|
|
|
3624
3994
|
result = injectBeforeClose(result, generateClientScriptCode(registeredScripts));
|
|
3625
3995
|
}
|
|
3626
3996
|
if (requestContext !== undefined) {
|
|
3627
|
-
result = injectBeforeClose(result, `<script>window.__ABS_ANGULAR_REQUEST_CONTEXT__ = ${JSON.stringify(requestContext)};</script>`);
|
|
3997
|
+
result = injectBeforeClose(result, `<script${nonceAttr()}>window.__ABS_ANGULAR_REQUEST_CONTEXT__ = ${escapeScriptContent(JSON.stringify(requestContext))};</script>`);
|
|
3628
3998
|
}
|
|
3629
3999
|
if (indexPath) {
|
|
3630
4000
|
const escapedIndexPath = JSON.stringify(indexPath);
|
|
3631
|
-
result = injectBeforeClose(result, `<script>import(${escapedIndexPath});</script>`);
|
|
4001
|
+
result = injectBeforeClose(result, `<script${nonceAttr()}>import(${escapeScriptContent(escapedIndexPath)});</script>`);
|
|
3632
4002
|
}
|
|
3633
4003
|
return result;
|
|
3634
4004
|
}, renderAngularApp = async (deps, PageComponent, providers, document2, url = "/") => {
|
|
3635
|
-
const
|
|
4005
|
+
const nonce = readCspNonce();
|
|
4006
|
+
const cspProviders = nonce ? [{ provide: deps.CSP_NONCE, useValue: nonce }] : [];
|
|
4007
|
+
const bootstrap = (context) => deps.bootstrapApplication(PageComponent, { providers: [...providers, ...cspProviders] }, context);
|
|
3636
4008
|
return withSuppressedAngularDevLogs(() => deps.renderApplication(bootstrap, {
|
|
3637
4009
|
document: document2,
|
|
3638
4010
|
platformProviders: [],
|
|
@@ -3653,6 +4025,8 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
|
|
|
3653
4025
|
}
|
|
3654
4026
|
};
|
|
3655
4027
|
var init_ssrRender = __esm(() => {
|
|
4028
|
+
init_escapeScriptContent();
|
|
4029
|
+
init_cspNonceRef();
|
|
3656
4030
|
init_registerClientScript();
|
|
3657
4031
|
init_browserTranslation();
|
|
3658
4032
|
routeContextCache = new Map;
|
|
@@ -4040,14 +4414,14 @@ var init_maskLiterals = __esm(() => {
|
|
|
4040
4414
|
});
|
|
4041
4415
|
|
|
4042
4416
|
// src/build/specifierRewriter.ts
|
|
4043
|
-
var escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), PLACEHOLDER, GAP, QUOTE = `["']`, ADJACENT_PREFIXES, ADJACENT_DYNAMIC_PREFIX, ADJACENT_DYNAMIC_SUFFIX, SWEEP_PREFIXES, rewriterCache,
|
|
4417
|
+
var escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), PLACEHOLDER, GAP, QUOTE = `["']`, ADJACENT_PREFIXES, ADJACENT_DYNAMIC_PREFIX, ADJACENT_DYNAMIC_SUFFIX, SWEEP_PREFIXES, rewriterCache, cacheKey2 = (vendorPaths) => Object.entries(vendorPaths).sort(([left], [right]) => left.localeCompare(right)).map(([specifier, webPath]) => `${specifier}\x00${webPath}\x00`).join(""), compileRegex = (prefixes, alternation, withAdjacentDynamic) => {
|
|
4044
4418
|
const plain = `(${prefixes.join("|")})(${alternation})(${QUOTE})`;
|
|
4045
4419
|
if (!withAdjacentDynamic)
|
|
4046
4420
|
return new RegExp(plain, "g");
|
|
4047
4421
|
const dynamic = `(${ADJACENT_DYNAMIC_PREFIX})(${alternation})(${ADJACENT_DYNAMIC_SUFFIX})`;
|
|
4048
4422
|
return new RegExp(`${plain}|${dynamic}`, "g");
|
|
4049
4423
|
}, compileSpecifierRewriter = (vendorPaths) => {
|
|
4050
|
-
const key =
|
|
4424
|
+
const key = cacheKey2(vendorPaths);
|
|
4051
4425
|
const cached = rewriterCache.get(key);
|
|
4052
4426
|
if (cached)
|
|
4053
4427
|
return cached;
|
|
@@ -4291,7 +4665,7 @@ var createVueCompiler = async () => {
|
|
|
4291
4665
|
};
|
|
4292
4666
|
|
|
4293
4667
|
// src/core/vueServerModule.ts
|
|
4294
|
-
import { readFileSync as
|
|
4668
|
+
import { readFileSync as readFileSync5, realpathSync } from "fs";
|
|
4295
4669
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
4296
4670
|
import { dirname as dirname4, join as join7, relative as relative4, resolve as resolve5 } from "path";
|
|
4297
4671
|
var {Transpiler } = globalThis.Bun;
|
|
@@ -4340,7 +4714,7 @@ var ISLAND_COMPONENT_ID_LENGTH = 8, serverCacheRoot3, compiledModuleCache3, tran
|
|
|
4340
4714
|
fs: {
|
|
4341
4715
|
fileExists: isFile,
|
|
4342
4716
|
realpath: realpathSync,
|
|
4343
|
-
readFile: (file) => isFile(file) ?
|
|
4717
|
+
readFile: (file) => isFile(file) ? readFileSync5(file, "utf-8") : undefined
|
|
4344
4718
|
},
|
|
4345
4719
|
id: componentId,
|
|
4346
4720
|
inlineTemplate: false
|
|
@@ -4402,14 +4776,14 @@ var defineIslandComponent = (component, options) => ({
|
|
|
4402
4776
|
component,
|
|
4403
4777
|
export: options.export,
|
|
4404
4778
|
source: options.source
|
|
4405
|
-
}), defineIslandRegistry = (registry) => registry,
|
|
4779
|
+
}), defineIslandRegistry = (registry) => registry, isRecord8 = (value) => typeof value === "object" && value !== null, getIslandBuildReference = (component) => {
|
|
4406
4780
|
if (!isIslandComponentDefinition(component))
|
|
4407
4781
|
return null;
|
|
4408
4782
|
return {
|
|
4409
4783
|
export: component.export,
|
|
4410
4784
|
source: component.source
|
|
4411
4785
|
};
|
|
4412
|
-
}, isIslandComponentDefinition = (value) =>
|
|
4786
|
+
}, isIslandComponentDefinition = (value) => isRecord8(value) && ("component" in value) && ("source" in value) && typeof value.source === "string", parseIslandProps = (rawProps) => {
|
|
4413
4787
|
if (!rawProps)
|
|
4414
4788
|
return {};
|
|
4415
4789
|
return JSON.parse(rawProps);
|
|
@@ -4433,7 +4807,7 @@ var init_islandMarkupAttributes = __esm(() => {
|
|
|
4433
4807
|
var islandSequence = 0, resolvedServerComponentCache, resolvedServerBuildComponentCache, nextIslandId = () => {
|
|
4434
4808
|
islandSequence += 1;
|
|
4435
4809
|
return `island-${islandSequence}`;
|
|
4436
|
-
},
|
|
4810
|
+
}, isRecord9 = (value) => typeof value === "object" && value !== null, isReactServerIslandComponent = (value) => typeof value === "function", isSvelteServerIslandComponent = (value) => typeof value === "function", isVueServerIslandComponent = (value) => typeof value === "function" || isRecord9(value), isAngularServerIslandComponent = (value) => typeof value === "function", resolveBuildReferencePath = (source, registryPath) => {
|
|
4437
4811
|
if (source.startsWith("file://"))
|
|
4438
4812
|
return new URL(source).pathname;
|
|
4439
4813
|
if (source.startsWith("."))
|
|
@@ -4594,6 +4968,7 @@ var requireCurrentIslandRegistry = () => {
|
|
|
4594
4968
|
};
|
|
4595
4969
|
|
|
4596
4970
|
// src/svelte/pageHandler.ts
|
|
4971
|
+
init_cspNonceRef();
|
|
4597
4972
|
init_svelteServerModule();
|
|
4598
4973
|
init_islandPageContext();
|
|
4599
4974
|
init_devRouteRegistrationCallsite();
|
|
@@ -4604,6 +4979,8 @@ init_pageResponseCache();
|
|
|
4604
4979
|
// src/core/responseEnhancers.ts
|
|
4605
4980
|
init_streamingSlots();
|
|
4606
4981
|
init_pageResponseCache();
|
|
4982
|
+
init_partialPrerender();
|
|
4983
|
+
init_requestContext();
|
|
4607
4984
|
|
|
4608
4985
|
// src/core/streamingSlotRegistrar.ts
|
|
4609
4986
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
@@ -4646,7 +5023,7 @@ var setStreamingSlotWarningController = (controller) => {
|
|
|
4646
5023
|
Reflect.set(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY, controller);
|
|
4647
5024
|
};
|
|
4648
5025
|
var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
4649
|
-
if (isStreamingSlotCollectionActive()) {
|
|
5026
|
+
if (isProductionRuntime() || isStreamingSlotCollectionActive()) {
|
|
4650
5027
|
return;
|
|
4651
5028
|
}
|
|
4652
5029
|
getWarningController()?.maybeWarn(primitiveName);
|
|
@@ -4754,18 +5131,51 @@ var mergeStreamingSlots = (registered, explicit) => {
|
|
|
4754
5131
|
merged.set(slot.id, slot);
|
|
4755
5132
|
return [...merged.values()];
|
|
4756
5133
|
};
|
|
5134
|
+
var captureStaticShell = async (responseLike, slots, options) => {
|
|
5135
|
+
const holes = slots.filter(isDynamicStreamingSlot);
|
|
5136
|
+
const staticSlots = slots.filter((slot) => !isDynamicStreamingSlot(slot));
|
|
5137
|
+
const response = await withStreamingSlots(responseLike, {
|
|
5138
|
+
...options,
|
|
5139
|
+
streamingSlots: staticSlots
|
|
5140
|
+
});
|
|
5141
|
+
if (holes.length === 0 || !response.body)
|
|
5142
|
+
return response;
|
|
5143
|
+
const headers = cloneHeaders(response);
|
|
5144
|
+
headers.set(PARTIAL_HOLES_HEADER, encodePartialHoles(holes.map((slot) => slot.id)));
|
|
5145
|
+
const body = staticSlots.length > 0 ? response.body : injectStreamingRuntimeIntoStream(response.body, options.nonce, options.runtimePlacement, options.runtimePreludeScript);
|
|
5146
|
+
return new Response(body, {
|
|
5147
|
+
headers,
|
|
5148
|
+
status: response.status,
|
|
5149
|
+
statusText: response.statusText
|
|
5150
|
+
});
|
|
5151
|
+
};
|
|
5152
|
+
var handOverHoles = async (responseLike, slots, sink) => {
|
|
5153
|
+
sink.slots = slots.filter(isDynamicStreamingSlot);
|
|
5154
|
+
const response = await toResponse(responseLike);
|
|
5155
|
+
await response.body?.cancel().catch(() => {
|
|
5156
|
+
return;
|
|
5157
|
+
});
|
|
5158
|
+
return new Response(null, { status: 204 });
|
|
5159
|
+
};
|
|
4757
5160
|
var withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
|
|
4758
5161
|
const { result, slots } = await runWithStreamingSlotRegistry(renderResponse);
|
|
4759
5162
|
const explicit = options.streamingSlots ?? [];
|
|
5163
|
+
const streamingSlots = mergeStreamingSlots(slots, explicit);
|
|
5164
|
+
const holesSink = activePartialHolesSink();
|
|
5165
|
+
if (holesSink)
|
|
5166
|
+
return handOverHoles(result, streamingSlots, holesSink);
|
|
5167
|
+
if (isPartialShellCapture(getCurrentAbsoluteRequest())) {
|
|
5168
|
+
return captureStaticShell(result, streamingSlots, options);
|
|
5169
|
+
}
|
|
4760
5170
|
return withStreamingSlots(result, {
|
|
4761
5171
|
...options,
|
|
4762
|
-
streamingSlots
|
|
5172
|
+
streamingSlots
|
|
4763
5173
|
});
|
|
4764
5174
|
};
|
|
4765
5175
|
|
|
4766
5176
|
// src/core/streamingSlotWarningScope.ts
|
|
4767
5177
|
init_logger();
|
|
4768
|
-
import { AsyncLocalStorage as
|
|
5178
|
+
import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
|
|
4769
5179
|
var STREAMING_SLOT_WARNING_STORAGE_KEY2 = Symbol.for("absolutejs.streamingSlotWarningAsyncLocalStorage");
|
|
4770
5180
|
var isObjectRecord4 = (value) => Boolean(value) && typeof value === "object";
|
|
4771
5181
|
var isAsyncLocalStorage3 = (value) => isObjectRecord4(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
|
@@ -4781,7 +5191,7 @@ var ensureWarningStorage = () => {
|
|
|
4781
5191
|
if (existing) {
|
|
4782
5192
|
return existing;
|
|
4783
5193
|
}
|
|
4784
|
-
const storage = new
|
|
5194
|
+
const storage = new AsyncLocalStorage4;
|
|
4785
5195
|
Reflect.set(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY2, storage);
|
|
4786
5196
|
return storage;
|
|
4787
5197
|
};
|
|
@@ -4812,7 +5222,9 @@ setStreamingSlotWarningController({
|
|
|
4812
5222
|
}
|
|
4813
5223
|
});
|
|
4814
5224
|
var captureStreamingSlotWarningCallsite = () => {
|
|
4815
|
-
if (
|
|
5225
|
+
if (isProductionRuntime()) {
|
|
5226
|
+
return;
|
|
5227
|
+
}
|
|
4816
5228
|
const { stack } = new Error;
|
|
4817
5229
|
if (!stack) {
|
|
4818
5230
|
return;
|
|
@@ -4824,18 +5236,112 @@ var runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage(
|
|
|
4824
5236
|
// src/svelte/pageHandler.ts
|
|
4825
5237
|
init_routeAssets();
|
|
4826
5238
|
init_inlinePageCss();
|
|
5239
|
+
init_ssrErrorPage();
|
|
4827
5240
|
init_spaRouteManifest();
|
|
4828
5241
|
init_resolveConvention();
|
|
4829
5242
|
init_browserTranslation();
|
|
4830
|
-
|
|
4831
|
-
|
|
5243
|
+
|
|
5244
|
+
// src/svelte/routerSsr.ts
|
|
5245
|
+
init_lazyModule();
|
|
5246
|
+
var SVELTE_ROUTER_SSR_CONTEXT_KEY = Symbol.for("absolutejs.svelte-router.ssr");
|
|
5247
|
+
var REDIRECT_STATUS = 302;
|
|
5248
|
+
var FORBIDDEN_STATUS = 403;
|
|
5249
|
+
var runSequentially = async (tasks, index = 0) => {
|
|
5250
|
+
const task = tasks[index];
|
|
5251
|
+
if (!task)
|
|
5252
|
+
return;
|
|
5253
|
+
await task();
|
|
5254
|
+
await runSequentially(tasks, index + 1);
|
|
5255
|
+
};
|
|
5256
|
+
var toResolved = (value) => {
|
|
5257
|
+
const component = toLazyComponent(value);
|
|
5258
|
+
const resolved = component ? { component, source: readLazySource(value) } : {
|
|
5259
|
+
error: new Error('A lazy <Route> loader must resolve to a Svelte component or to a module whose default export is one, e.g. `() => import("./Page.svelte")`.')
|
|
5260
|
+
};
|
|
5261
|
+
return resolved;
|
|
5262
|
+
};
|
|
5263
|
+
var createSvelteRouterSsr = (request) => {
|
|
5264
|
+
const tasks = [];
|
|
5265
|
+
const pending = new Map;
|
|
5266
|
+
const resolved = new Map;
|
|
5267
|
+
let outcome;
|
|
5268
|
+
const state = {
|
|
5269
|
+
request,
|
|
5270
|
+
resolved,
|
|
5271
|
+
settledGuards: new Set,
|
|
5272
|
+
afterRender: (task) => {
|
|
5273
|
+
tasks.push(task);
|
|
5274
|
+
},
|
|
5275
|
+
load: (key, loader) => {
|
|
5276
|
+
if (resolved.has(key) || pending.has(key))
|
|
5277
|
+
return;
|
|
5278
|
+
const settle = Promise.resolve().then(loader).then((value) => {
|
|
5279
|
+
resolved.set(key, toResolved(value));
|
|
5280
|
+
}, (error) => {
|
|
5281
|
+
resolved.set(key, { error });
|
|
5282
|
+
});
|
|
5283
|
+
pending.set(key, settle);
|
|
5284
|
+
},
|
|
5285
|
+
outcome: () => outcome,
|
|
5286
|
+
setOutcome: (next) => {
|
|
5287
|
+
outcome ??= next;
|
|
5288
|
+
}
|
|
5289
|
+
};
|
|
5290
|
+
const settle = async () => {
|
|
5291
|
+
await runSequentially(tasks.splice(0));
|
|
5292
|
+
if (outcome !== undefined)
|
|
5293
|
+
return false;
|
|
5294
|
+
if (pending.size === 0)
|
|
5295
|
+
return false;
|
|
5296
|
+
const loads = Array.from(pending.values());
|
|
5297
|
+
pending.clear();
|
|
5298
|
+
await Promise.all(loads);
|
|
5299
|
+
return true;
|
|
5300
|
+
};
|
|
5301
|
+
const response = () => {
|
|
5302
|
+
if (!outcome)
|
|
5303
|
+
return;
|
|
5304
|
+
if (outcome.kind === "redirect") {
|
|
5305
|
+
return new Response(null, {
|
|
5306
|
+
headers: { Location: outcome.location },
|
|
5307
|
+
status: REDIRECT_STATUS
|
|
5308
|
+
});
|
|
5309
|
+
}
|
|
5310
|
+
return new Response("Forbidden", {
|
|
5311
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
|
5312
|
+
status: FORBIDDEN_STATUS
|
|
5313
|
+
});
|
|
5314
|
+
};
|
|
5315
|
+
const bootstrapScript = () => {
|
|
5316
|
+
const sources = {};
|
|
5317
|
+
for (const [key, entry] of resolved) {
|
|
5318
|
+
if ("component" in entry && entry.source)
|
|
5319
|
+
sources[key] = entry.source;
|
|
5320
|
+
}
|
|
5321
|
+
if (Object.keys(sources).length === 0)
|
|
5322
|
+
return "";
|
|
5323
|
+
return `window.__ABS_SVELTE_LAZY_ROUTES__=${JSON.stringify(sources)};`;
|
|
5324
|
+
};
|
|
5325
|
+
return {
|
|
5326
|
+
bootstrapScript,
|
|
5327
|
+
context: new Map([
|
|
5328
|
+
[SVELTE_ROUTER_SSR_CONTEXT_KEY, state]
|
|
5329
|
+
]),
|
|
5330
|
+
response,
|
|
5331
|
+
settle
|
|
5332
|
+
};
|
|
5333
|
+
};
|
|
5334
|
+
|
|
5335
|
+
// src/svelte/pageHandler.ts
|
|
5336
|
+
var isRecord5 = (value) => typeof value === "object" && value !== null;
|
|
5337
|
+
var isGenericSvelteComponent = (value) => typeof value === "function" || isRecord5(value);
|
|
4832
5338
|
var readHasIslands = (value) => {
|
|
4833
|
-
if (!
|
|
5339
|
+
if (!isRecord5(value))
|
|
4834
5340
|
return false;
|
|
4835
5341
|
const hasIslands = value["__ABSOLUTE_PAGE_HAS_ISLANDS__"];
|
|
4836
5342
|
return typeof hasIslands === "boolean" ? hasIslands : false;
|
|
4837
5343
|
};
|
|
4838
|
-
var readDefaultExport = (value) =>
|
|
5344
|
+
var readDefaultExport = (value) => isRecord5(value) ? value.default : undefined;
|
|
4839
5345
|
var primeSvelteStream = async (stream) => {
|
|
4840
5346
|
const reader = stream.getReader();
|
|
4841
5347
|
const firstChunk = await reader.read();
|
|
@@ -4881,7 +5387,7 @@ var handleSveltePageRequest = async (input) => {
|
|
|
4881
5387
|
const userProps = input.props;
|
|
4882
5388
|
const request = input.request ?? getCurrentAbsoluteRequest();
|
|
4883
5389
|
const requestPathname = resolveRequestPathname(request);
|
|
4884
|
-
const resolvedProps = requestPathname !== undefined && (!
|
|
5390
|
+
const resolvedProps = requestPathname !== undefined && (!isRecord5(userProps) || !("url" in userProps)) ? {
|
|
4885
5391
|
...userProps ?? {},
|
|
4886
5392
|
url: requestPathname
|
|
4887
5393
|
} : userProps;
|
|
@@ -4947,13 +5453,19 @@ var handleSveltePageRequest = async (input) => {
|
|
|
4947
5453
|
await Promise.resolve().then(() => init_renderToReadableStream());
|
|
4948
5454
|
const resolvedPage = await resolvePageComponent();
|
|
4949
5455
|
const siblingCss = await readSiblingCss(resolvedPagePath);
|
|
4950
|
-
const cssBlock = siblingCss ? `<style data-absolute-page-css>${siblingCss}</style>` : "";
|
|
5456
|
+
const cssBlock = siblingCss ? `<style data-absolute-page-css${nonceAttr()}>${siblingCss}</style>` : "";
|
|
4951
5457
|
const composedHeadContent = `${cssBlock}${withDeferredStylesheets(resolvedOptions?.headContent ?? "", deferredAssets)}`;
|
|
5458
|
+
const routerSsr = createSvelteRouterSsr(request);
|
|
4952
5459
|
const stream = await renderToReadableStream(resolvedPage.component, resolvedProps, {
|
|
4953
5460
|
bodyContent: resolvedOptions?.bodyContent,
|
|
4954
|
-
|
|
4955
|
-
headContent: composedHeadContent
|
|
5461
|
+
context: routerSsr.context,
|
|
5462
|
+
headContent: composedHeadContent,
|
|
5463
|
+
settle: routerSsr.settle,
|
|
5464
|
+
bootstrapScriptContent: () => `${BROWSER_TRANSLATION_BASELINE_SCRIPT}window.__ABS_SLOT_HYDRATION_PENDING__=true;${routerSsr.bootstrapScript()}window.__INITIAL_PROPS__=${JSON.stringify(resolvedProps)};${resolvedIndexPath ? `import(${JSON.stringify(resolvedIndexPath)});` : ""}`
|
|
4956
5465
|
});
|
|
5466
|
+
const routerResponse = routerSsr.response();
|
|
5467
|
+
if (routerResponse)
|
|
5468
|
+
return routerResponse;
|
|
4957
5469
|
const htmlStream = injectIslandPageContextStream(stream, {
|
|
4958
5470
|
hasIslands: resolvedPage.hasIslands ? true : undefined
|
|
4959
5471
|
});
|
|
@@ -4982,6 +5494,391 @@ var handleSveltePageRequest = async (input) => {
|
|
|
4982
5494
|
}), request);
|
|
4983
5495
|
}
|
|
4984
5496
|
};
|
|
5497
|
+
// src/core/fileRouteAdapter.ts
|
|
5498
|
+
var PARAM_NAME_RE = /:([A-Za-z_$][\w$]*)/g;
|
|
5499
|
+
var paramNamesOf = (path) => [...path.matchAll(PARAM_NAME_RE)].map((match) => match[1]).filter((name) => name !== undefined);
|
|
5500
|
+
var hasRouteParams = (context, names) => names.every((name) => typeof context.params[name] === "string");
|
|
5501
|
+
var serverHooksOf = ({
|
|
5502
|
+
path,
|
|
5503
|
+
server
|
|
5504
|
+
}) => {
|
|
5505
|
+
if (!server)
|
|
5506
|
+
return {};
|
|
5507
|
+
const names = paramNamesOf(path);
|
|
5508
|
+
const withParams = async (context, run) => {
|
|
5509
|
+
const module = await server();
|
|
5510
|
+
if (!module || !hasRouteParams(context, names))
|
|
5511
|
+
return;
|
|
5512
|
+
return run(module, context);
|
|
5513
|
+
};
|
|
5514
|
+
const hooks = {
|
|
5515
|
+
beforeHandle: (context) => withParams(context, (module, typed) => module.beforeHandle?.(typed)),
|
|
5516
|
+
load: (context) => withParams(context, (module, typed) => module.load?.(typed))
|
|
5517
|
+
};
|
|
5518
|
+
return hooks;
|
|
5519
|
+
};
|
|
5520
|
+
var defineFileRouteWith = (framework, route, render) => {
|
|
5521
|
+
const definition = {
|
|
5522
|
+
framework,
|
|
5523
|
+
name: route.name,
|
|
5524
|
+
path: route.path,
|
|
5525
|
+
render,
|
|
5526
|
+
source: route.source,
|
|
5527
|
+
...serverHooksOf(route)
|
|
5528
|
+
};
|
|
5529
|
+
return definition;
|
|
5530
|
+
};
|
|
5531
|
+
|
|
5532
|
+
// src/core/lookup.ts
|
|
5533
|
+
init_requestContext();
|
|
5534
|
+
var asset = (source, name) => {
|
|
5535
|
+
const assetPath = source[name];
|
|
5536
|
+
if (assetPath === undefined) {
|
|
5537
|
+
if (isProductionRuntime()) {
|
|
5538
|
+
throw new Error(`Asset "${name}" not found in manifest.`);
|
|
5539
|
+
}
|
|
5540
|
+
recordMissingAsset(name);
|
|
5541
|
+
const page = getDevPageWarmer()?.describe(name);
|
|
5542
|
+
if (page !== undefined && !page.built)
|
|
5543
|
+
return "";
|
|
5544
|
+
console.warn(`[asset] key "${name}" not found in manifest (dev mode \u2014 skipping)`);
|
|
5545
|
+
return "";
|
|
5546
|
+
}
|
|
5547
|
+
return assetPath;
|
|
5548
|
+
};
|
|
5549
|
+
|
|
5550
|
+
// src/svelte/fileRoute.ts
|
|
5551
|
+
var svelteFileRoute = (route) => defineFileRouteWith("svelte", route, async ({ manifest, props, request }) => handleSveltePageRequest({
|
|
5552
|
+
indexPath: asset(manifest, `${route.name}Index`),
|
|
5553
|
+
pagePath: asset(manifest, route.name),
|
|
5554
|
+
props,
|
|
5555
|
+
request
|
|
5556
|
+
}));
|
|
5557
|
+
// src/svelte/i18n.ts
|
|
5558
|
+
import { getContext, hasContext, setContext } from "svelte";
|
|
5559
|
+
|
|
5560
|
+
// src/i18n/intlCache.ts
|
|
5561
|
+
var numberFormats = new Map;
|
|
5562
|
+
var dateTimeFormats = new Map;
|
|
5563
|
+
var pluralRules = new Map;
|
|
5564
|
+
var relativeTimeFormats = new Map;
|
|
5565
|
+
var listFormats = new Map;
|
|
5566
|
+
var cacheKey = (locale, options) => `${locale}|${options ? JSON.stringify(options) : ""}`;
|
|
5567
|
+
var cached = (cache, key, create) => {
|
|
5568
|
+
const existing = cache.get(key);
|
|
5569
|
+
if (existing)
|
|
5570
|
+
return existing;
|
|
5571
|
+
const created = create();
|
|
5572
|
+
cache.set(key, created);
|
|
5573
|
+
return created;
|
|
5574
|
+
};
|
|
5575
|
+
var getDateTimeFormat = (locale, options) => cached(dateTimeFormats, cacheKey(locale, options), () => new Intl.DateTimeFormat(locale, options));
|
|
5576
|
+
var getListFormat = (locale, options) => cached(listFormats, cacheKey(locale, options), () => new Intl.ListFormat(locale, options));
|
|
5577
|
+
var getNumberFormat = (locale, options) => cached(numberFormats, cacheKey(locale, options), () => new Intl.NumberFormat(locale, options));
|
|
5578
|
+
var getPluralRules = (locale, options) => cached(pluralRules, cacheKey(locale, options), () => new Intl.PluralRules(locale, options));
|
|
5579
|
+
var getRelativeTimeFormat = (locale, options) => cached(relativeTimeFormats, cacheKey(locale, options), () => new Intl.RelativeTimeFormat(locale, options));
|
|
5580
|
+
|
|
5581
|
+
// src/i18n/formatMessage.ts
|
|
5582
|
+
var SYNTAX_CHARS = new Set(["{", "}", "#", "|"]);
|
|
5583
|
+
var WHITESPACE = /\s/;
|
|
5584
|
+
var isBranchKind = (value) => value === "plural" || value === "select" || value === "selectordinal";
|
|
5585
|
+
var skipWhitespace = (cursor) => {
|
|
5586
|
+
while (cursor.index < cursor.source.length && WHITESPACE.test(cursor.source.charAt(cursor.index))) {
|
|
5587
|
+
cursor.index += 1;
|
|
5588
|
+
}
|
|
5589
|
+
};
|
|
5590
|
+
var syntaxError = (cursor, expected) => new SyntaxError(`Invalid ICU message (expected ${expected} at ${cursor.index}): ${cursor.source}`);
|
|
5591
|
+
var readToken = (cursor, stops) => {
|
|
5592
|
+
const start = cursor.index;
|
|
5593
|
+
while (cursor.index < cursor.source.length && !stops.includes(cursor.source.charAt(cursor.index))) {
|
|
5594
|
+
cursor.index += 1;
|
|
5595
|
+
}
|
|
5596
|
+
return cursor.source.slice(start, cursor.index).trim();
|
|
5597
|
+
};
|
|
5598
|
+
var expectChar = (cursor, char) => {
|
|
5599
|
+
skipWhitespace(cursor);
|
|
5600
|
+
if (cursor.source.charAt(cursor.index) !== char)
|
|
5601
|
+
throw syntaxError(cursor, `"${char}"`);
|
|
5602
|
+
cursor.index += 1;
|
|
5603
|
+
};
|
|
5604
|
+
var readQuoted = (cursor, inPlural) => {
|
|
5605
|
+
const next = cursor.source.charAt(cursor.index + 1);
|
|
5606
|
+
if (next === "'") {
|
|
5607
|
+
cursor.index += 2;
|
|
5608
|
+
return "'";
|
|
5609
|
+
}
|
|
5610
|
+
const opensQuote = SYNTAX_CHARS.has(next) && (next !== "#" || inPlural);
|
|
5611
|
+
if (!opensQuote) {
|
|
5612
|
+
cursor.index += 1;
|
|
5613
|
+
return "'";
|
|
5614
|
+
}
|
|
5615
|
+
cursor.index += 1;
|
|
5616
|
+
let text = "";
|
|
5617
|
+
while (cursor.index < cursor.source.length) {
|
|
5618
|
+
const char = cursor.source.charAt(cursor.index);
|
|
5619
|
+
const isEscapedQuote = char === "'" && cursor.source.charAt(cursor.index + 1) === "'";
|
|
5620
|
+
if (char === "'" && !isEscapedQuote)
|
|
5621
|
+
break;
|
|
5622
|
+
text += char;
|
|
5623
|
+
cursor.index += isEscapedQuote ? 2 : 1;
|
|
5624
|
+
}
|
|
5625
|
+
cursor.index += 1;
|
|
5626
|
+
return text;
|
|
5627
|
+
};
|
|
5628
|
+
var pushText = (nodes, value) => {
|
|
5629
|
+
const last = nodes[nodes.length - 1];
|
|
5630
|
+
if (last?.kind === "text") {
|
|
5631
|
+
last.value += value;
|
|
5632
|
+
return;
|
|
5633
|
+
}
|
|
5634
|
+
nodes.push({ kind: "text", value });
|
|
5635
|
+
};
|
|
5636
|
+
var parseBranchOption = (cursor, kind, branches) => {
|
|
5637
|
+
if (cursor.index >= cursor.source.length)
|
|
5638
|
+
throw syntaxError(cursor, '"}"');
|
|
5639
|
+
const selector = readToken(cursor, `{}
|
|
5640
|
+
\r`);
|
|
5641
|
+
const offsetMatch = /^offset:(\d+)$/.exec(selector);
|
|
5642
|
+
if (offsetMatch && kind !== "select") {
|
|
5643
|
+
branches.offset = Number(offsetMatch[1]);
|
|
5644
|
+
skipWhitespace(cursor);
|
|
5645
|
+
return;
|
|
5646
|
+
}
|
|
5647
|
+
if (selector === "")
|
|
5648
|
+
throw syntaxError(cursor, "a selector");
|
|
5649
|
+
expectChar(cursor, "{");
|
|
5650
|
+
branches.options[selector] = parseNodes(cursor, kind !== "select");
|
|
5651
|
+
expectChar(cursor, "}");
|
|
5652
|
+
skipWhitespace(cursor);
|
|
5653
|
+
};
|
|
5654
|
+
var parseBranchOptions = (cursor, kind) => {
|
|
5655
|
+
const branches = { offset: 0, options: {} };
|
|
5656
|
+
skipWhitespace(cursor);
|
|
5657
|
+
while (cursor.source.charAt(cursor.index) !== "}") {
|
|
5658
|
+
parseBranchOption(cursor, kind, branches);
|
|
5659
|
+
}
|
|
5660
|
+
if (branches.options.other === undefined)
|
|
5661
|
+
throw syntaxError(cursor, 'an "other" branch');
|
|
5662
|
+
return branches;
|
|
5663
|
+
};
|
|
5664
|
+
var parseArgument = (cursor) => {
|
|
5665
|
+
skipWhitespace(cursor);
|
|
5666
|
+
const name = readToken(cursor, ",}");
|
|
5667
|
+
if (name === "")
|
|
5668
|
+
throw syntaxError(cursor, "an argument name");
|
|
5669
|
+
if (cursor.source.charAt(cursor.index) === "}") {
|
|
5670
|
+
cursor.index += 1;
|
|
5671
|
+
return { format: undefined, kind: "argument", name, style: undefined };
|
|
5672
|
+
}
|
|
5673
|
+
cursor.index += 1;
|
|
5674
|
+
const format = readToken(cursor, ",}");
|
|
5675
|
+
if (isBranchKind(format)) {
|
|
5676
|
+
expectChar(cursor, ",");
|
|
5677
|
+
const { offset, options } = parseBranchOptions(cursor, format);
|
|
5678
|
+
expectChar(cursor, "}");
|
|
5679
|
+
return { kind: format, name, offset, options };
|
|
5680
|
+
}
|
|
5681
|
+
let style;
|
|
5682
|
+
if (cursor.source.charAt(cursor.index) === ",") {
|
|
5683
|
+
cursor.index += 1;
|
|
5684
|
+
style = readToken(cursor, "}");
|
|
5685
|
+
}
|
|
5686
|
+
expectChar(cursor, "}");
|
|
5687
|
+
return { format, kind: "argument", name, style };
|
|
5688
|
+
};
|
|
5689
|
+
var parseNode = (cursor, inPlural, nodes) => {
|
|
5690
|
+
const char = cursor.source.charAt(cursor.index);
|
|
5691
|
+
if (char === "{") {
|
|
5692
|
+
cursor.index += 1;
|
|
5693
|
+
nodes.push(parseArgument(cursor));
|
|
5694
|
+
return;
|
|
5695
|
+
}
|
|
5696
|
+
if (char === "#" && inPlural) {
|
|
5697
|
+
cursor.index += 1;
|
|
5698
|
+
nodes.push({ kind: "pound" });
|
|
5699
|
+
return;
|
|
5700
|
+
}
|
|
5701
|
+
if (char === "'") {
|
|
5702
|
+
pushText(nodes, readQuoted(cursor, inPlural));
|
|
5703
|
+
return;
|
|
5704
|
+
}
|
|
5705
|
+
pushText(nodes, char);
|
|
5706
|
+
cursor.index += 1;
|
|
5707
|
+
};
|
|
5708
|
+
var parseNodes = (cursor, inPlural) => {
|
|
5709
|
+
const nodes = [];
|
|
5710
|
+
while (cursor.index < cursor.source.length && cursor.source.charAt(cursor.index) !== "}") {
|
|
5711
|
+
parseNode(cursor, inPlural, nodes);
|
|
5712
|
+
}
|
|
5713
|
+
return nodes;
|
|
5714
|
+
};
|
|
5715
|
+
var parseMessage = (source) => {
|
|
5716
|
+
const cursor = { index: 0, source };
|
|
5717
|
+
const nodes = parseNodes(cursor, false);
|
|
5718
|
+
if (cursor.index < source.length)
|
|
5719
|
+
throw syntaxError(cursor, "end of message");
|
|
5720
|
+
return nodes;
|
|
5721
|
+
};
|
|
5722
|
+
var parsedCache = new Map;
|
|
5723
|
+
var parseCached = (source) => {
|
|
5724
|
+
const cached = parsedCache.get(source);
|
|
5725
|
+
if (cached)
|
|
5726
|
+
return cached;
|
|
5727
|
+
let parsed;
|
|
5728
|
+
try {
|
|
5729
|
+
parsed = parseMessage(source);
|
|
5730
|
+
} catch (error) {
|
|
5731
|
+
parsed = error instanceof SyntaxError ? error : new SyntaxError(String(error));
|
|
5732
|
+
}
|
|
5733
|
+
parsedCache.set(source, parsed);
|
|
5734
|
+
return parsed;
|
|
5735
|
+
};
|
|
5736
|
+
var INTEGER_OPTIONS = { maximumFractionDigits: 0 };
|
|
5737
|
+
var PERCENT_OPTIONS = { style: "percent" };
|
|
5738
|
+
var numberOptions = (style) => {
|
|
5739
|
+
if (style === "integer")
|
|
5740
|
+
return INTEGER_OPTIONS;
|
|
5741
|
+
if (style === "percent")
|
|
5742
|
+
return PERCENT_OPTIONS;
|
|
5743
|
+
const currency = /^::currency\/([A-Za-z]{3})$/.exec(style ?? "");
|
|
5744
|
+
const options = currency?.[1] ? { currency: currency[1].toUpperCase(), style: "currency" } : {};
|
|
5745
|
+
return options;
|
|
5746
|
+
};
|
|
5747
|
+
var toDate = (value) => {
|
|
5748
|
+
if (value instanceof Date)
|
|
5749
|
+
return value;
|
|
5750
|
+
if (typeof value === "number" || typeof value === "string")
|
|
5751
|
+
return new Date(value);
|
|
5752
|
+
return;
|
|
5753
|
+
};
|
|
5754
|
+
var dateStyleOf = (style) => {
|
|
5755
|
+
if (style === "full" || style === "long" || style === "short")
|
|
5756
|
+
return style;
|
|
5757
|
+
return "medium";
|
|
5758
|
+
};
|
|
5759
|
+
var formatDateArgument = (locale, value, format, style) => {
|
|
5760
|
+
const date = toDate(value);
|
|
5761
|
+
if (!date || Number.isNaN(date.getTime()))
|
|
5762
|
+
return String(value);
|
|
5763
|
+
const resolvedStyle = dateStyleOf(style);
|
|
5764
|
+
const options = format === "date" ? { dateStyle: resolvedStyle } : { timeStyle: resolvedStyle };
|
|
5765
|
+
return getDateTimeFormat(locale, options).format(date);
|
|
5766
|
+
};
|
|
5767
|
+
var formatValue = (locale, value) => {
|
|
5768
|
+
if (typeof value === "number" || typeof value === "bigint")
|
|
5769
|
+
return getNumberFormat(locale).format(value);
|
|
5770
|
+
if (value instanceof Date)
|
|
5771
|
+
return getDateTimeFormat(locale).format(value);
|
|
5772
|
+
return String(value);
|
|
5773
|
+
};
|
|
5774
|
+
var formatArgument = (locale, node, params) => {
|
|
5775
|
+
if (!(node.name in params))
|
|
5776
|
+
return `{${node.name}}`;
|
|
5777
|
+
const value = params[node.name];
|
|
5778
|
+
if (node.format === "number") {
|
|
5779
|
+
const numeric = typeof value === "bigint" ? value : Number(value);
|
|
5780
|
+
return getNumberFormat(locale, numberOptions(node.style)).format(numeric);
|
|
5781
|
+
}
|
|
5782
|
+
if (node.format === "date" || node.format === "time")
|
|
5783
|
+
return formatDateArgument(locale, value, node.format, node.style);
|
|
5784
|
+
return formatValue(locale, value);
|
|
5785
|
+
};
|
|
5786
|
+
var selectBranch = (locale, node, value) => {
|
|
5787
|
+
if (node.kind === "select") {
|
|
5788
|
+
return node.options[String(value)] ?? node.options.other ?? [];
|
|
5789
|
+
}
|
|
5790
|
+
const numeric = Number(value);
|
|
5791
|
+
const exact = node.options[`=${numeric}`];
|
|
5792
|
+
if (exact)
|
|
5793
|
+
return exact;
|
|
5794
|
+
const category = getPluralRules(locale, {
|
|
5795
|
+
type: node.kind === "selectordinal" ? "ordinal" : "cardinal"
|
|
5796
|
+
}).select(numeric - node.offset);
|
|
5797
|
+
return node.options[category] ?? node.options.other ?? [];
|
|
5798
|
+
};
|
|
5799
|
+
var formatNodes = (locale, nodes, params, pound) => nodes.map((node) => {
|
|
5800
|
+
if (node.kind === "text")
|
|
5801
|
+
return node.value;
|
|
5802
|
+
if (node.kind === "pound")
|
|
5803
|
+
return pound ?? "#";
|
|
5804
|
+
if (node.kind === "argument")
|
|
5805
|
+
return formatArgument(locale, node, params);
|
|
5806
|
+
if (!(node.name in params))
|
|
5807
|
+
return `{${node.name}}`;
|
|
5808
|
+
const value = params[node.name];
|
|
5809
|
+
const branch = selectBranch(locale, node, value);
|
|
5810
|
+
const branchPound = node.kind === "select" ? pound : getNumberFormat(locale).format(Number(value) - node.offset);
|
|
5811
|
+
return formatNodes(locale, branch, params, branchPound);
|
|
5812
|
+
}).join("");
|
|
5813
|
+
var formatMessage = (locale, message, params = {}) => {
|
|
5814
|
+
if (!message.includes("{") && !message.includes("'"))
|
|
5815
|
+
return message;
|
|
5816
|
+
const parsed = parseCached(message);
|
|
5817
|
+
if (parsed instanceof SyntaxError)
|
|
5818
|
+
return message;
|
|
5819
|
+
return formatNodes(locale, parsed, params, undefined);
|
|
5820
|
+
};
|
|
5821
|
+
|
|
5822
|
+
// src/i18n/translator.ts
|
|
5823
|
+
var isRecord6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5824
|
+
var lookupMessage = (messages, key) => {
|
|
5825
|
+
let node = messages;
|
|
5826
|
+
for (const segment of key.split(".")) {
|
|
5827
|
+
if (typeof node !== "object")
|
|
5828
|
+
return;
|
|
5829
|
+
node = node[segment];
|
|
5830
|
+
}
|
|
5831
|
+
return typeof node === "string" ? node : undefined;
|
|
5832
|
+
};
|
|
5833
|
+
var isMessageTreeValue = (value) => typeof value === "string" || isMessageTree(value);
|
|
5834
|
+
var isI18nPayload = (value) => isRecord6(value) && typeof value.locale === "string" && typeof value.defaultLocale === "string" && (value.dir === "ltr" || value.dir === "rtl") && isMessageTree(value.messages);
|
|
5835
|
+
var isMessageTree = (value) => isRecord6(value) && Object.values(value).every(isMessageTreeValue);
|
|
5836
|
+
var toDate2 = (value) => value instanceof Date ? value : new Date(value);
|
|
5837
|
+
var warnedKeys = new Set;
|
|
5838
|
+
var warnMissing = (locale, key) => {
|
|
5839
|
+
const id = `${locale}:${key}`;
|
|
5840
|
+
if (warnedKeys.has(id))
|
|
5841
|
+
return;
|
|
5842
|
+
warnedKeys.add(id);
|
|
5843
|
+
console.warn(`[i18n] Missing message "${key}" for locale "${locale}"`);
|
|
5844
|
+
};
|
|
5845
|
+
var createTranslator = (payload) => {
|
|
5846
|
+
const { locale, messages } = payload;
|
|
5847
|
+
const t = (key, ...args) => {
|
|
5848
|
+
const message = lookupMessage(messages, key);
|
|
5849
|
+
if (message === undefined) {
|
|
5850
|
+
warnMissing(locale, key);
|
|
5851
|
+
return key;
|
|
5852
|
+
}
|
|
5853
|
+
const [params] = args;
|
|
5854
|
+
return formatMessage(locale, message, isRecord6(params) ? params : {});
|
|
5855
|
+
};
|
|
5856
|
+
const translator = {
|
|
5857
|
+
dir: payload.dir,
|
|
5858
|
+
locale,
|
|
5859
|
+
t,
|
|
5860
|
+
formatDate: (value, options) => getDateTimeFormat(locale, options).format(toDate2(value)),
|
|
5861
|
+
formatList: (items, options) => getListFormat(locale, options).format(items),
|
|
5862
|
+
formatNumber: (value, options) => getNumberFormat(locale, options).format(value),
|
|
5863
|
+
formatRelativeTime: (value, unit, options) => getRelativeTimeFormat(locale, options).format(value, unit),
|
|
5864
|
+
has: (key) => lookupMessage(messages, key) !== undefined
|
|
5865
|
+
};
|
|
5866
|
+
return translator;
|
|
5867
|
+
};
|
|
5868
|
+
|
|
5869
|
+
// src/svelte/i18n.ts
|
|
5870
|
+
var I18N_CONTEXT = Symbol.for("absolutejs.i18n");
|
|
5871
|
+
var getI18n = () => {
|
|
5872
|
+
const payload = hasContext(I18N_CONTEXT) ? getContext(I18N_CONTEXT) : undefined;
|
|
5873
|
+
if (!isI18nPayload(payload)) {
|
|
5874
|
+
throw new Error("getI18n() found no messages: call setI18n(payload) in the page component first");
|
|
5875
|
+
}
|
|
5876
|
+
return createTranslator(payload);
|
|
5877
|
+
};
|
|
5878
|
+
var setI18n = (payload) => {
|
|
5879
|
+
setContext(I18N_CONTEXT, payload);
|
|
5880
|
+
return createTranslator(payload);
|
|
5881
|
+
};
|
|
4985
5882
|
// src/svelte/createIsland.ts
|
|
4986
5883
|
init_renderIslandMarkup();
|
|
4987
5884
|
var createTypedIsland = (registry) => (props) => renderIslandMarkup(registry, props);
|
|
@@ -5100,12 +5997,15 @@ var resolveIslandHtml = (_slotId, props) => renderIslandMarkup(requireCurrentIsl
|
|
|
5100
5997
|
init_renderToReadableStream();
|
|
5101
5998
|
export {
|
|
5102
5999
|
createTypedIsland,
|
|
6000
|
+
getI18n,
|
|
5103
6001
|
handleSveltePageRequest,
|
|
5104
6002
|
renderIsland,
|
|
5105
6003
|
renderToReadableStream,
|
|
5106
6004
|
resolveIslandHtml,
|
|
6005
|
+
setI18n,
|
|
6006
|
+
svelteFileRoute,
|
|
5107
6007
|
useIslandStore
|
|
5108
6008
|
};
|
|
5109
6009
|
|
|
5110
|
-
//# debugId=
|
|
6010
|
+
//# debugId=BBD497D139E396B564756E2164756E21
|
|
5111
6011
|
//# sourceMappingURL=index.js.map
|