sibujs 4.13.0 → 4.14.0

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.
Files changed (107) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +15 -2
  3. package/dist/browser.js +9 -7
  4. package/dist/build.cjs +880 -281
  5. package/dist/build.d.cts +68 -3
  6. package/dist/build.d.ts +68 -3
  7. package/dist/build.js +88 -30
  8. package/dist/cdn.dev.global.js +12 -12
  9. package/dist/cdn.full.dev.global.js +13 -13
  10. package/dist/cdn.full.global.js +12 -12
  11. package/dist/cdn.global.js +12 -12
  12. package/dist/{chunk-7K7W4AA5.js → chunk-2TTRW2TE.js} +6 -6
  13. package/dist/{chunk-J6FW5TV6.js → chunk-3HEX6QJQ.js} +5 -3
  14. package/dist/chunk-3HZOSMPX.js +90 -0
  15. package/dist/{chunk-GNSRXK34.js → chunk-4FJSAUKB.js} +11 -3
  16. package/dist/{chunk-IV74C2YX.js → chunk-4TQDTWWN.js} +6 -5
  17. package/dist/{chunk-L3QHS4O4.js → chunk-7ILEHTVX.js} +1 -1
  18. package/dist/{chunk-CK5F2IR5.js → chunk-A454RAEK.js} +4 -4
  19. package/dist/{chunk-BRRRVLHQ.js → chunk-AE32RGWX.js} +10 -6
  20. package/dist/{chunk-EXXSN3BW.js → chunk-B3HOT4TK.js} +1 -1
  21. package/dist/{chunk-F4W7WYXY.js → chunk-BKZ5N6NK.js} +8 -6
  22. package/dist/{chunk-MNEITZ27.js → chunk-BNXRWZZV.js} +49 -8
  23. package/dist/chunk-BOYKGGVD.js +2015 -0
  24. package/dist/{chunk-G6366I2A.js → chunk-CCKUNHVU.js} +2 -2
  25. package/dist/{chunk-346BYZL2.js → chunk-CJ7KS3DF.js} +16 -10
  26. package/dist/chunk-CNPT6NKV.js +1859 -0
  27. package/dist/{chunk-ENFRHCMK.js → chunk-F67F77IA.js} +2 -2
  28. package/dist/{chunk-TUCPL2HB.js → chunk-GIJ33UJZ.js} +1 -1
  29. package/dist/chunk-GVAMIU6K.js +195 -0
  30. package/dist/{chunk-HDKDBC6V.js → chunk-HQIAL7F2.js} +8 -6
  31. package/dist/{chunk-ZE5LF44R.js → chunk-JTFQ7IL4.js} +8 -8
  32. package/dist/{chunk-AM6DZLBM.js → chunk-LJMX4SQ7.js} +2 -2
  33. package/dist/{chunk-HVVRXRGO.js → chunk-MIRKTVH4.js} +7 -14
  34. package/dist/{chunk-YJ57VR6Y.js → chunk-N7A6FKWW.js} +5 -3
  35. package/dist/chunk-NT3ZYB5S.js +167 -0
  36. package/dist/{chunk-Z3EZX6DZ.js → chunk-QS6GMWDD.js} +151 -86
  37. package/dist/chunk-R5U7XKVJ.js +16 -0
  38. package/dist/{chunk-3C56VNCK.js → chunk-RVR5NPFL.js} +3 -3
  39. package/dist/{chunk-F2UWOZ6J.js → chunk-RVWJGWCL.js} +2 -2
  40. package/dist/{chunk-NYNYSPK7.js → chunk-S37PZD6I.js} +30 -45
  41. package/dist/{chunk-QV5WEOFD.js → chunk-SVULV7O4.js} +119 -26
  42. package/dist/{chunk-C2FAO6VQ.js → chunk-TLS4NVIB.js} +5 -5
  43. package/dist/{chunk-M25RIH6Y.js → chunk-UUIKJJIK.js} +10 -8
  44. package/dist/chunk-UYTYNCMZ.js +199 -0
  45. package/dist/chunk-VM2U5LEL.js +2596 -0
  46. package/dist/{chunk-24L5RDPS.js → chunk-Y4LUM2XS.js} +8 -6
  47. package/dist/data.cjs +265 -35
  48. package/dist/data.d.cts +31 -1
  49. package/dist/data.d.ts +31 -1
  50. package/dist/data.js +16 -10
  51. package/dist/devtools.cjs +15 -2
  52. package/dist/devtools.js +9 -7
  53. package/dist/{dispose-GEIG2KOF.js → dispose-EIHHHDC7.js} +3 -1
  54. package/dist/ecosystem.cjs +62 -23
  55. package/dist/ecosystem.js +14 -12
  56. package/dist/extras.cjs +3520 -270
  57. package/dist/extras.d.cts +3 -3
  58. package/dist/extras.d.ts +3 -3
  59. package/dist/extras.js +39 -29
  60. package/dist/index.cjs +442 -253
  61. package/dist/index.d.cts +93 -283
  62. package/dist/index.d.ts +93 -283
  63. package/dist/index.js +26 -16
  64. package/dist/motion.cjs +12 -1
  65. package/dist/motion.js +6 -4
  66. package/dist/patterns.cjs +15 -2
  67. package/dist/patterns.js +10 -8
  68. package/dist/performance.cjs +36 -2
  69. package/dist/performance.d.cts +2 -2
  70. package/dist/performance.d.ts +2 -2
  71. package/dist/performance.js +14 -10
  72. package/dist/plugins.cjs +5225 -1807
  73. package/dist/plugins.d.cts +8 -834
  74. package/dist/plugins.d.ts +8 -834
  75. package/dist/plugins.js +64 -2329
  76. package/dist/prerenderServer-MXJEVWA3.js +350 -0
  77. package/dist/renderRoute-DP20XwMS.d.cts +86 -0
  78. package/dist/renderRoute-fxgsm2Ir.d.ts +86 -0
  79. package/dist/routeHead-CE9SV-cH.d.cts +995 -0
  80. package/dist/routeHead-DzVxPviY.d.ts +995 -0
  81. package/dist/{routeMiddleware-B1sp4P7a.d.ts → routeMiddleware-BySbueoE.d.ts} +0 -25
  82. package/dist/{routeMiddleware-CedQTsLK.d.cts → routeMiddleware-CijZD5eW.d.cts} +0 -25
  83. package/dist/ssr-JpGpHnpC.d.cts +841 -0
  84. package/dist/ssr-JpGpHnpC.d.ts +841 -0
  85. package/dist/{ssr-VBM6J5SJ.js → ssr-NECEU4X4.js} +15 -6
  86. package/dist/ssr-dom.cjs +1862 -0
  87. package/dist/ssr-dom.d.cts +341 -0
  88. package/dist/ssr-dom.d.ts +341 -0
  89. package/dist/ssr-dom.js +19 -0
  90. package/dist/ssr.cjs +7630 -2064
  91. package/dist/ssr.d.cts +63 -5
  92. package/dist/ssr.d.ts +63 -5
  93. package/dist/ssr.js +136 -14
  94. package/dist/testing.cjs +6543 -87
  95. package/dist/testing.d.cts +80 -1
  96. package/dist/testing.d.ts +80 -1
  97. package/dist/testing.js +117 -4
  98. package/dist/ui.cjs +36 -2
  99. package/dist/ui.js +17 -14
  100. package/dist/widgets.cjs +14 -1
  101. package/dist/widgets.js +11 -9
  102. package/package.json +9 -2
  103. package/dist/chunk-2F4PSJ5Z.js +0 -765
  104. package/dist/chunk-7XHATCIH.js +0 -121
  105. package/dist/chunk-B36ADEIR.js +0 -21
  106. package/dist/ssr-Db0Sgdu3.d.cts +0 -245
  107. package/dist/ssr-Db0Sgdu3.d.ts +0 -245
@@ -0,0 +1,350 @@
1
+ import "./chunk-R5U7XKVJ.js";
2
+
3
+ // src/build/prerenderServer.ts
4
+ var DRIVER_ID = "virtual:sibu-prerender-driver";
5
+ var DRIVER_RESOLVED = `\0${DRIVER_ID}`;
6
+ function joinPath(parent, child) {
7
+ if (child === "*" || child.startsWith("/*")) return child;
8
+ const p = parent.replace(/\/+$/, "");
9
+ const c = child.startsWith("/") ? child : `/${child}`;
10
+ return (p + c).replace(/\/{2,}/g, "/") || "/";
11
+ }
12
+ async function expandRoutes(routes) {
13
+ const out = [];
14
+ const visit = async (records, parent) => {
15
+ for (const record of records) {
16
+ if (!record || typeof record.path !== "string") continue;
17
+ const full = parent ? joinPath(parent, record.path) : record.path;
18
+ if (record.children?.length) await visit(record.children, full);
19
+ if (full.includes("*")) continue;
20
+ if ("redirect" in record && record.redirect !== void 0) {
21
+ if (!/:/.test(full)) out.push(full);
22
+ continue;
23
+ }
24
+ if (/:/.test(full)) {
25
+ if (typeof record.getStaticPaths !== "function") continue;
26
+ let entries;
27
+ try {
28
+ entries = await record.getStaticPaths();
29
+ } catch (err) {
30
+ throw new Error(
31
+ `[sibu prerender] getStaticPaths() of "${full}" failed: ${err instanceof Error ? err.message : String(err)}. If it reads an API, start it and point \`prerender.fetch\` at it.`,
32
+ { cause: err }
33
+ );
34
+ }
35
+ for (const entry of entries) {
36
+ if (typeof entry === "string") {
37
+ out.push(entry);
38
+ continue;
39
+ }
40
+ let path = full;
41
+ for (const [key, value] of Object.entries(entry)) {
42
+ path = path.replace(new RegExp(`:${key}(?=[/?#]|$)`, "g"), encodeURIComponent(String(value)));
43
+ }
44
+ if (/:[A-Za-z_]/.test(path)) {
45
+ throw new Error(
46
+ `[sibu prerender] getStaticPaths() of "${full}" returned ${JSON.stringify(entry)}, which leaves a param unset`
47
+ );
48
+ }
49
+ out.push(path);
50
+ }
51
+ continue;
52
+ }
53
+ if (record.children?.length) continue;
54
+ out.push(full);
55
+ }
56
+ };
57
+ await visit(routes, "");
58
+ return Array.from(new Set(out));
59
+ }
60
+ function escapeAttr(value) {
61
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
62
+ }
63
+ function escapeXml(value) {
64
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
65
+ }
66
+ function decodeTitleText(text) {
67
+ const named = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: "\xA0" };
68
+ return text.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z]+);/gi, (ref, body) => {
69
+ if (body[0] !== "#") return named[body.toLowerCase()] ?? ref;
70
+ const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number(body.slice(1));
71
+ return code > 0 && code <= 1114111 ? String.fromCodePoint(code) : ref;
72
+ });
73
+ }
74
+ function injectIntoShell(shell, parts, container = "app") {
75
+ let html = shell;
76
+ const shellTitle = /<title>([\s\S]*?)<\/title>/i.exec(html)?.[1] ?? "";
77
+ if (parts.head) {
78
+ let head = parts.head;
79
+ if (/<title>/i.test(head)) {
80
+ html = html.replace(/\s*<title>[\s\S]*?<\/title>/i, () => "");
81
+ const baseTitle = `<title data-sibu-base-title="${escapeAttr(decodeTitleText(shellTitle))}">`;
82
+ head = head.replace(/<title>/i, () => baseTitle);
83
+ }
84
+ const headHtml = head;
85
+ html = html.replace(/<\/head>/i, () => ` ${headHtml}
86
+ </head>`);
87
+ }
88
+ if (parts.body) {
89
+ const id = container.replace(/[^A-Za-z0-9_-]/g, "");
90
+ const open = new RegExp(`(<([a-z][a-z0-9-]*)\\b[^>]*\\bid\\s*=\\s*["']${id}["'][^>]*>)([\\s\\S]*?)(</\\2>)`, "i");
91
+ if (!open.test(html))
92
+ throw new Error(`[sibu prerender] the built index.html has no element with id="${id}" to render into`);
93
+ html = html.replace(
94
+ open,
95
+ (_m, openTag, _tag, _inner, close) => `${openTag}${parts.body}${close}`
96
+ );
97
+ }
98
+ if (parts.state) html = html.replace(/<\/body>/i, () => ` ${parts.state}
99
+ </body>`);
100
+ return html;
101
+ }
102
+ function assertPrerendered(url, result, failures, timeout) {
103
+ if (failures.length > 0) {
104
+ throw new Error(
105
+ `[sibu prerender] ${url}: ${failures[0]}. The page needs data from an API that is not reachable at build time \u2014 start it and point \`prerender.fetch\` at it, or skip the request with isPrerendering().`
106
+ );
107
+ }
108
+ const pending = result.diagnostics.pending.join(", ");
109
+ if (result.failure === "timeout") {
110
+ throw new Error(
111
+ `[sibu prerender] ${url}: the route did not render within ${timeout} ms (pending: ${pending}). A lazy import, a guard or a route load did not finish in time; fix it or raise \`prerender.timeout\`.`
112
+ );
113
+ }
114
+ if (result.diagnostics.timedOut) {
115
+ throw new Error(`[sibu prerender] ${url}: did not settle within ${timeout} ms (pending: ${pending})`);
116
+ }
117
+ }
118
+ function buildSitemap(origin, paths) {
119
+ const urls = paths.map((p) => ` <url><loc>${escapeXml(origin + p)}</loc></url>`).join("\n");
120
+ return `<?xml version="1.0" encoding="UTF-8"?>
121
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
122
+ ${urls}
123
+ </urlset>
124
+ `;
125
+ }
126
+ async function prerenderFromServerEntry(options, ctx, helpers) {
127
+ const fs = await import("fs/promises");
128
+ const path = await import("path");
129
+ const { pathToFileURL } = await import("url");
130
+ const { AsyncLocalStorage } = await import("async_hooks");
131
+ const outDir = options.outDir ? path.resolve(ctx.root, options.outDir) : ctx.outDir;
132
+ const origin = (options.origin ?? "http://localhost").replace(/\/+$/, "");
133
+ const serverEntry = path.resolve(ctx.root, String(options.server).replace(/^\//, ""));
134
+ const keptShell = path.join(ctx.outDir, typeof options.shell === "string" ? options.shell : "200.html");
135
+ const shellPath = await fs.access(keptShell).then(() => keptShell).catch(() => path.join(ctx.outDir, "index.html"));
136
+ const shell = await fs.readFile(shellPath, "utf8");
137
+ const tmpDir = path.join(
138
+ outDir,
139
+ `.sibu-prerender-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`
140
+ );
141
+ await fs.rm(tmpDir, { recursive: true, force: true });
142
+ const viteBuild = await helpers.loadViteBuild();
143
+ const driverSource = `import { renderRoute } from "sibujs/ssr";
144
+ import * as entry from ${JSON.stringify(serverEntry.split(path.sep).join("/"))};
145
+ export { renderRoute, entry };
146
+ `;
147
+ const prev = process.env[helpers.childEnv];
148
+ process.env[helpers.childEnv] = "1";
149
+ try {
150
+ await viteBuild({
151
+ configFile: ctx.configFile,
152
+ root: ctx.root,
153
+ mode: ctx.mode,
154
+ logLevel: "warn",
155
+ plugins: [
156
+ {
157
+ name: "sibu-prerender-driver",
158
+ resolveId: (id) => id === DRIVER_ID ? DRIVER_RESOLVED : null,
159
+ load: (id) => id === DRIVER_RESOLVED ? driverSource : null
160
+ }
161
+ ],
162
+ build: {
163
+ ssr: true,
164
+ outDir: tmpDir,
165
+ emptyOutDir: true,
166
+ copyPublicDir: false,
167
+ minify: false,
168
+ sourcemap: false,
169
+ rollupOptions: { input: DRIVER_ID, output: { format: "es", entryFileNames: "driver.mjs" } }
170
+ }
171
+ });
172
+ } finally {
173
+ if (prev === void 0) delete process.env[helpers.childEnv];
174
+ else process.env[helpers.childEnv] = prev;
175
+ }
176
+ await fs.writeFile(path.join(tmpDir, "package.json"), '{ "type": "module" }\n', "utf8");
177
+ const currentRoute = new AsyncLocalStorage();
178
+ const realFetch = globalThis.fetch;
179
+ const custom = typeof options.fetch === "function" ? options.fetch : null;
180
+ const apiBase = typeof options.fetch === "string" ? options.fetch.replace(/\/+$/, "") : origin;
181
+ const buildFetch = (async (input, init) => {
182
+ const raw = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
183
+ const url = /^[a-z][a-z0-9+.-]*:/i.test(raw) ? raw : apiBase + (raw.startsWith("/") ? raw : `/${raw}`);
184
+ try {
185
+ return await (custom ?? realFetch)(
186
+ typeof input === "object" && !(input instanceof URL) ? new Request(url, input) : url,
187
+ init
188
+ );
189
+ } catch (err) {
190
+ const store = currentRoute.getStore();
191
+ const reason = err instanceof Error ? err.message : String(err);
192
+ store?.failures.push(`GET ${url} failed (${reason})`);
193
+ throw err;
194
+ }
195
+ });
196
+ const driverUrl = pathToFileURL(path.join(tmpDir, "driver.mjs")).href;
197
+ const results = [];
198
+ globalThis.fetch = buildFetch;
199
+ try {
200
+ const driver = await import(driverUrl);
201
+ const entry = driver.entry;
202
+ if (!Array.isArray(entry.routes)) {
203
+ throw new Error(
204
+ `[sibu prerender] the server entry ${options.server} must export \`routes\` (the app's route table)`
205
+ );
206
+ }
207
+ const explicit = Array.isArray(options.routes) ? options.routes : null;
208
+ const auto = explicit === null;
209
+ const listed = (explicit ? explicit.map((r) => typeof r === "string" ? { path: r } : r) : (await expandRoutes(entry.routes)).map((p) => ({ path: p }))).filter((r) => r.path !== options.notFound);
210
+ const trailingSlash = options.trailingSlash === "never" ? "never" : "always";
211
+ const planned = listed.map((route) => ({ route, file: helpers.outputFileFor(route, trailingSlash) }));
212
+ const seen = /* @__PURE__ */ new Map();
213
+ for (const { route, file } of planned) {
214
+ helpers.resolveInsideOutDir(path, outDir, file);
215
+ const other = seen.get(file);
216
+ if (other !== void 0) {
217
+ throw new Error(
218
+ `[sibu prerender] "${other}" and "${route.path}" would both be written to ${file}; a query variant needs its own \`output\` file.`
219
+ );
220
+ }
221
+ seen.set(file, route.path);
222
+ }
223
+ const renderOptions = {
224
+ router: { ...entry.routerOptions ?? {}, head: entry.head },
225
+ app: entry.app,
226
+ timeout: options.timeout ?? 15e3,
227
+ // A per-request page is written as the shell plus its route head: it is
228
+ // never rendered at build time, so its request-only fetches never run.
229
+ headOnly: ["ssr"],
230
+ hydration: options.hydration,
231
+ nonce: options.nonce,
232
+ maxStateBytes: options.maxStateBytes
233
+ };
234
+ const render = async (url) => {
235
+ const store = { route: url, failures: [] };
236
+ const result = await currentRoute.run(store, () => driver.renderRoute(entry.routes, url, renderOptions));
237
+ assertPrerendered(url, result, store.failures, renderOptions.timeout);
238
+ return result;
239
+ };
240
+ if (options.shell !== false) await fs.writeFile(path.join(outDir, options.shell ?? "200.html"), shell, "utf8");
241
+ const redirects = [];
242
+ const indexable = [];
243
+ const queue = [...planned];
244
+ const concurrency = Math.max(1, options.concurrency ?? 4);
245
+ const write = async (file, html) => {
246
+ const target = helpers.resolveInsideOutDir(path, outDir, file);
247
+ await fs.mkdir(path.dirname(target), { recursive: true });
248
+ await fs.writeFile(target, html, "utf8");
249
+ };
250
+ await Promise.all(
251
+ Array.from({ length: Math.min(concurrency, queue.length) }, async () => {
252
+ for (let job = queue.shift(); job; job = queue.shift()) {
253
+ const { route, file } = job;
254
+ const started = Date.now();
255
+ const result = await render(route.path);
256
+ if (result.location !== null && result.redirectBy === "guard") {
257
+ results.push({
258
+ route: route.path,
259
+ file: "",
260
+ ms: Date.now() - started,
261
+ status: result.status,
262
+ kind: "skipped"
263
+ });
264
+ continue;
265
+ }
266
+ if (result.location !== null) {
267
+ redirects.push({ from: route.path, to: result.location, status: result.status });
268
+ results.push({
269
+ route: route.path,
270
+ file: "",
271
+ ms: Date.now() - started,
272
+ status: result.status,
273
+ kind: "redirect"
274
+ });
275
+ continue;
276
+ }
277
+ if (auto && result.failure === "guard") {
278
+ results.push({
279
+ route: route.path,
280
+ file: "",
281
+ ms: Date.now() - started,
282
+ status: result.status,
283
+ kind: "skipped"
284
+ });
285
+ continue;
286
+ }
287
+ if (result.status >= 400) {
288
+ throw new Error(
289
+ `[sibu prerender] ${route.path} answered ${result.status}${result.failure ? ` (${result.failure})` : ""}; list only pages that exist (the \`*\` route becomes 404.html through \`notFound\`).`
290
+ );
291
+ }
292
+ const body = result.render === "client" || result.render === "ssr" ? "" : result.html;
293
+ const state = body ? result.state : "";
294
+ await write(file, injectIntoShell(shell, { body, head: result.head, state }, options.container));
295
+ if (!result.noindex && result.render !== "client") {
296
+ const pathname = route.path.split(/[?#]/)[0];
297
+ indexable.push(
298
+ trailingSlash === "always" && pathname !== "/" ? `${pathname.replace(/\/+$/, "")}/` : pathname
299
+ );
300
+ }
301
+ results.push({
302
+ route: route.path,
303
+ file,
304
+ ms: Date.now() - started,
305
+ status: result.status,
306
+ kind: body ? "page" : "shell"
307
+ });
308
+ }
309
+ })
310
+ );
311
+ const notFound = options.notFound ?? "/404";
312
+ if (notFound) {
313
+ const started = Date.now();
314
+ const result = await render(notFound);
315
+ if (result.status === 404) {
316
+ await write(
317
+ "404.html",
318
+ injectIntoShell(shell, { body: result.html, head: result.head, state: result.state }, options.container)
319
+ );
320
+ results.push({ route: notFound, file: "404.html", ms: Date.now() - started, status: 404, kind: "not-found" });
321
+ }
322
+ }
323
+ if (redirects.length > 0) await write("redirects.json", `${JSON.stringify(redirects, null, 2)}
324
+ `);
325
+ if (options.sitemap !== false && indexable.length > 0) {
326
+ indexable.sort();
327
+ await write("sitemap.xml", buildSitemap(origin, indexable));
328
+ }
329
+ if (options.robots) {
330
+ const extra = typeof options.robots === "string" ? `${options.robots.trim()}
331
+ ` : "";
332
+ const sitemapLine = options.sitemap !== false && indexable.length > 0 ? `Sitemap: ${origin}/sitemap.xml
333
+ ` : "";
334
+ await write("robots.txt", `User-agent: *
335
+ Allow: /
336
+ ${extra}${sitemapLine}`);
337
+ }
338
+ } finally {
339
+ globalThis.fetch = realFetch;
340
+ await fs.rm(tmpDir, { recursive: true, force: true });
341
+ }
342
+ return results;
343
+ }
344
+ export {
345
+ assertPrerendered,
346
+ buildSitemap,
347
+ expandRoutes,
348
+ injectIntoShell,
349
+ prerenderFromServerEntry
350
+ };
@@ -0,0 +1,86 @@
1
+ import { R as RouterOptions, a as RouteDef } from './routeHead-CE9SV-cH.cjs';
2
+ import { A as AsyncRenderOptions, D as DocumentOptions, R as RenderResult } from './ssr-JpGpHnpC.cjs';
3
+
4
+ /** How a route is treated by server renders (see `RouteBase.render`); `"default"` when no record declares one. */
5
+ type RouteRenderMode = "ssr" | "prerender" | "client" | "default";
6
+ /** Options of {@link renderRoute}. */
7
+ interface RenderRouteOptions extends AsyncRenderOptions {
8
+ /**
9
+ * Milliseconds for the whole request (default 5000): the initial navigation,
10
+ * the matched components' loads, then building and settling the page. Past
11
+ * it before the route rendered, the result is a 503 with `failure:
12
+ * "timeout"`; past it while the page settles, what is ready is serialized
13
+ * with fallbacks (`diagnostics.timedOut`), as `renderToStringAsync` does.
14
+ */
15
+ timeout?: number;
16
+ /**
17
+ * Builds the page around the routed content. Default: `() => Route()`.
18
+ * Use your app shell (`() => App()`) when it contains the outlet.
19
+ */
20
+ app?: () => Node;
21
+ /** Router options (`head`, `base`, `guardTimeout`, …). `mode` and `url` are set by `renderRoute`. */
22
+ router?: Omit<RouterOptions, "mode" | "url">;
23
+ /** Status for a navigation a guard rejected. Default 403. Redirect from the guard for a login page (302). */
24
+ rejectStatus?: number;
25
+ /**
26
+ * Wrap the body in a full document (`renderToDocument`'s), with the
27
+ * collected head tags in `<head>` and the transfer script in `<body>`.
28
+ */
29
+ document?: DocumentOptions;
30
+ /**
31
+ * Render modes answered with the head alone, as `"client"` always is: the
32
+ * route is matched, guarded and redirected as usual, and its `head` is
33
+ * resolved from the route records, but no component (the route's or
34
+ * `app`'s) is built, so nothing it would fetch runs and nothing transfers.
35
+ * The pre-renderer passes `["ssr"]`: a per-request page ships as the shell
36
+ * plus its route head, without rendering it at build time.
37
+ * @internal
38
+ */
39
+ headOnly?: readonly RouteRenderMode[];
40
+ }
41
+ /** The routed part of a {@link renderRoute} result. */
42
+ interface RenderedRoute {
43
+ /** The committed path (after redirects). */
44
+ path: string;
45
+ params: Record<string, string>;
46
+ query: Record<string, string>;
47
+ hash: string;
48
+ /** `name` of the deepest matched record, if it has one. */
49
+ name: string | null;
50
+ }
51
+ /** Result of {@link renderRoute}. */
52
+ interface RouteRenderResult extends RenderResult {
53
+ /** `Location` header value for a redirect, else `null`. */
54
+ location: string | null;
55
+ /** The committed route, or `null` when the navigation was rejected or failed. */
56
+ route: RenderedRoute | null;
57
+ /** The route's rendering mode; for `"client"` the body is empty (shell plus head). */
58
+ render: RouteRenderMode;
59
+ /** True when the route's head declares `robots: noindex` (left out of a sitemap). */
60
+ noindex: boolean;
61
+ /** Why the navigation did not commit (`"guard"`, `"redirect-loop"`, …), else `null`. */
62
+ failure: string | null;
63
+ /**
64
+ * Who answered with the redirect: a `redirect` record (`"route"`, the same
65
+ * for every visitor) or a guard (`"guard"`, it depends on the visitor).
66
+ */
67
+ redirectBy: "route" | "guard" | null;
68
+ }
69
+ /**
70
+ * Render one URL through the router, in its own request scope.
71
+ *
72
+ * @param routes The app's route table (the same one the browser uses).
73
+ * @param url The request URL path with query and hash (`"/cotizar?servicio=dtf"`).
74
+ * @param options App shell, router options, settle timeout, state transfer, document.
75
+ * @returns HTML, head, transfer state, HTTP status, redirect location, route, diagnostics.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const r = await renderRoute(routes, req.url, { router: { head }, document: { scripts: ["/assets/main.js"] } });
80
+ * if (r.location) return res.redirect(r.status, r.location);
81
+ * res.status(r.status).send(r.html);
82
+ * ```
83
+ */
84
+ declare function renderRoute(routes: RouteDef[], url: string, options?: RenderRouteOptions): Promise<RouteRenderResult>;
85
+
86
+ export { type RenderRouteOptions as R, type RouteRenderResult as a, type RenderedRoute as b, type RouteRenderMode as c, renderRoute as r };
@@ -0,0 +1,86 @@
1
+ import { R as RouterOptions, a as RouteDef } from './routeHead-DzVxPviY.js';
2
+ import { A as AsyncRenderOptions, D as DocumentOptions, R as RenderResult } from './ssr-JpGpHnpC.js';
3
+
4
+ /** How a route is treated by server renders (see `RouteBase.render`); `"default"` when no record declares one. */
5
+ type RouteRenderMode = "ssr" | "prerender" | "client" | "default";
6
+ /** Options of {@link renderRoute}. */
7
+ interface RenderRouteOptions extends AsyncRenderOptions {
8
+ /**
9
+ * Milliseconds for the whole request (default 5000): the initial navigation,
10
+ * the matched components' loads, then building and settling the page. Past
11
+ * it before the route rendered, the result is a 503 with `failure:
12
+ * "timeout"`; past it while the page settles, what is ready is serialized
13
+ * with fallbacks (`diagnostics.timedOut`), as `renderToStringAsync` does.
14
+ */
15
+ timeout?: number;
16
+ /**
17
+ * Builds the page around the routed content. Default: `() => Route()`.
18
+ * Use your app shell (`() => App()`) when it contains the outlet.
19
+ */
20
+ app?: () => Node;
21
+ /** Router options (`head`, `base`, `guardTimeout`, …). `mode` and `url` are set by `renderRoute`. */
22
+ router?: Omit<RouterOptions, "mode" | "url">;
23
+ /** Status for a navigation a guard rejected. Default 403. Redirect from the guard for a login page (302). */
24
+ rejectStatus?: number;
25
+ /**
26
+ * Wrap the body in a full document (`renderToDocument`'s), with the
27
+ * collected head tags in `<head>` and the transfer script in `<body>`.
28
+ */
29
+ document?: DocumentOptions;
30
+ /**
31
+ * Render modes answered with the head alone, as `"client"` always is: the
32
+ * route is matched, guarded and redirected as usual, and its `head` is
33
+ * resolved from the route records, but no component (the route's or
34
+ * `app`'s) is built, so nothing it would fetch runs and nothing transfers.
35
+ * The pre-renderer passes `["ssr"]`: a per-request page ships as the shell
36
+ * plus its route head, without rendering it at build time.
37
+ * @internal
38
+ */
39
+ headOnly?: readonly RouteRenderMode[];
40
+ }
41
+ /** The routed part of a {@link renderRoute} result. */
42
+ interface RenderedRoute {
43
+ /** The committed path (after redirects). */
44
+ path: string;
45
+ params: Record<string, string>;
46
+ query: Record<string, string>;
47
+ hash: string;
48
+ /** `name` of the deepest matched record, if it has one. */
49
+ name: string | null;
50
+ }
51
+ /** Result of {@link renderRoute}. */
52
+ interface RouteRenderResult extends RenderResult {
53
+ /** `Location` header value for a redirect, else `null`. */
54
+ location: string | null;
55
+ /** The committed route, or `null` when the navigation was rejected or failed. */
56
+ route: RenderedRoute | null;
57
+ /** The route's rendering mode; for `"client"` the body is empty (shell plus head). */
58
+ render: RouteRenderMode;
59
+ /** True when the route's head declares `robots: noindex` (left out of a sitemap). */
60
+ noindex: boolean;
61
+ /** Why the navigation did not commit (`"guard"`, `"redirect-loop"`, …), else `null`. */
62
+ failure: string | null;
63
+ /**
64
+ * Who answered with the redirect: a `redirect` record (`"route"`, the same
65
+ * for every visitor) or a guard (`"guard"`, it depends on the visitor).
66
+ */
67
+ redirectBy: "route" | "guard" | null;
68
+ }
69
+ /**
70
+ * Render one URL through the router, in its own request scope.
71
+ *
72
+ * @param routes The app's route table (the same one the browser uses).
73
+ * @param url The request URL path with query and hash (`"/cotizar?servicio=dtf"`).
74
+ * @param options App shell, router options, settle timeout, state transfer, document.
75
+ * @returns HTML, head, transfer state, HTTP status, redirect location, route, diagnostics.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const r = await renderRoute(routes, req.url, { router: { head }, document: { scripts: ["/assets/main.js"] } });
80
+ * if (r.location) return res.redirect(r.status, r.location);
81
+ * res.status(r.status).send(r.html);
82
+ * ```
83
+ */
84
+ declare function renderRoute(routes: RouteDef[], url: string, options?: RenderRouteOptions): Promise<RouteRenderResult>;
85
+
86
+ export { type RenderRouteOptions as R, type RouteRenderResult as a, type RenderedRoute as b, type RouteRenderMode as c, renderRoute as r };