@fluixi/start 0.1.0-alpha.73 → 0.1.0-alpha.75

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 (123) hide show
  1. package/dist/adapter.cjs +750 -0
  2. package/dist/adapter.d.ts +9 -9
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js +10 -10
  5. package/dist/adapter.mjs +719 -0
  6. package/dist/adapters/entry.cjs +122 -0
  7. package/dist/adapters/entry.js +1 -1
  8. package/dist/adapters/entry.mjs +95 -0
  9. package/dist/adapters/platforms.cjs +311 -0
  10. package/dist/adapters/platforms.d.ts +2 -2
  11. package/dist/adapters/platforms.js +8 -8
  12. package/dist/adapters/platforms.mjs +284 -0
  13. package/dist/api-HD7KU3BS.mjs +114 -0
  14. package/dist/api.cjs +145 -0
  15. package/dist/api.js +1 -1
  16. package/dist/api.mjs +116 -0
  17. package/dist/commands/api-HD7KU3BS.mjs +114 -0
  18. package/dist/commands/api-PBT4QZ34.mjs +16 -0
  19. package/dist/commands/api-PJL37LV3.mjs +17 -0
  20. package/dist/commands/build.cjs +877 -0
  21. package/dist/commands/build.js +6 -6
  22. package/dist/commands/build.mjs +717 -0
  23. package/dist/commands/chunk-GFQ4MUIC.mjs +117 -0
  24. package/dist/commands/chunk-MTM6M3TC.mjs +115 -0
  25. package/dist/commands/dev.cjs +670 -0
  26. package/dist/commands/dev.js +3 -3
  27. package/dist/commands/dev.mjs +512 -0
  28. package/dist/commands/index.cjs +1145 -0
  29. package/dist/commands/index.d.ts +1 -1
  30. package/dist/commands/index.js +1 -1
  31. package/dist/commands/index.mjs +982 -0
  32. package/dist/commands/prerender.cjs +404 -0
  33. package/dist/commands/prerender.d.ts +1 -1
  34. package/dist/commands/prerender.js +2 -2
  35. package/dist/commands/prerender.mjs +377 -0
  36. package/dist/commands/start.cjs +463 -0
  37. package/dist/commands/start.d.ts +1 -1
  38. package/dist/commands/start.js +2 -2
  39. package/dist/commands/start.mjs +428 -0
  40. package/dist/config.cjs +150 -0
  41. package/dist/config.d.ts +24 -7
  42. package/dist/config.d.ts.map +1 -1
  43. package/dist/config.js +8 -6
  44. package/dist/config.mjs +114 -0
  45. package/dist/define-config.cjs +32 -0
  46. package/dist/define-config.d.ts +12 -0
  47. package/dist/define-config.d.ts.map +1 -0
  48. package/dist/define-config.js +3 -0
  49. package/dist/define-config.mjs +7 -0
  50. package/dist/di.cjs +200 -0
  51. package/dist/di.d.ts +4 -4
  52. package/dist/di.d.ts.map +1 -1
  53. package/dist/di.js +9 -9
  54. package/dist/di.mjs +169 -0
  55. package/dist/document.cjs +115 -0
  56. package/dist/document.d.ts +1 -1
  57. package/dist/document.js +1 -1
  58. package/dist/document.mjs +86 -0
  59. package/dist/generated-api.cjs +43 -0
  60. package/dist/generated-api.js +1 -1
  61. package/dist/generated-api.mjs +18 -0
  62. package/dist/generated-server-fns.cjs +43 -0
  63. package/dist/generated-server-fns.mjs +18 -0
  64. package/dist/handler-core.cjs +211 -0
  65. package/dist/handler-core.d.ts +2 -2
  66. package/dist/handler-core.js +2 -2
  67. package/dist/handler-core.mjs +185 -0
  68. package/dist/handler.cjs +182 -0
  69. package/dist/handler.d.ts +3 -3
  70. package/dist/handler.js +3 -3
  71. package/dist/handler.mjs +152 -0
  72. package/dist/head.cjs +25 -0
  73. package/dist/head.d.ts +1 -1
  74. package/dist/head.js +1 -1
  75. package/dist/head.mjs +4 -0
  76. package/dist/image-loader.cjs +37 -0
  77. package/dist/image-loader.d.ts +25 -0
  78. package/dist/image-loader.d.ts.map +1 -0
  79. package/dist/image-loader.js +18 -0
  80. package/dist/image-loader.mjs +12 -0
  81. package/dist/image.cjs +151 -0
  82. package/dist/image.d.ts +2 -19
  83. package/dist/image.d.ts.map +1 -1
  84. package/dist/image.js +5 -21
  85. package/dist/image.mjs +126 -0
  86. package/dist/index.cjs +303 -0
  87. package/dist/index.d.ts +28 -8
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +33 -17
  90. package/dist/index.mjs +262 -0
  91. package/dist/interceptors.cjs +72 -0
  92. package/dist/interceptors.js +1 -1
  93. package/dist/interceptors.mjs +44 -0
  94. package/dist/internal.cjs +393 -0
  95. package/dist/internal.d.ts +6 -6
  96. package/dist/internal.d.ts.map +1 -1
  97. package/dist/internal.js +23 -15
  98. package/dist/internal.mjs +223 -0
  99. package/dist/middleware.cjs +58 -0
  100. package/dist/middleware.d.ts +3 -3
  101. package/dist/middleware.d.ts.map +1 -1
  102. package/dist/middleware.js +1 -1
  103. package/dist/middleware.mjs +31 -0
  104. package/dist/preload.cjs +42 -0
  105. package/dist/preload.js +1 -1
  106. package/dist/preload.mjs +18 -0
  107. package/dist/router.cjs +25 -0
  108. package/dist/router.d.ts +3 -3
  109. package/dist/router.js +3 -3
  110. package/dist/router.mjs +4 -0
  111. package/dist/server-fn-setup.cjs +46 -0
  112. package/dist/server-fn-setup.d.ts +1 -1
  113. package/dist/server-fn-setup.js +2 -2
  114. package/dist/server-fn-setup.mjs +22 -0
  115. package/dist/server-fn.cjs +109 -0
  116. package/dist/server-fn.d.ts +2 -2
  117. package/dist/server-fn.js +2 -2
  118. package/dist/server-fn.mjs +79 -0
  119. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  120. package/dist/ui.cjs +123 -0
  121. package/dist/ui.js +1 -1
  122. package/dist/ui.mjs +93 -0
  123. package/package.json +63 -25
@@ -0,0 +1,404 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/commands/prerender.ts
21
+ var prerender_exports = {};
22
+ __export(prerender_exports, {
23
+ extractLinks: () => extractLinks,
24
+ htmlPath: () => htmlPath,
25
+ prerender: () => prerender
26
+ });
27
+ module.exports = __toCommonJS(prerender_exports);
28
+ var import_promises2 = require("node:fs/promises");
29
+ var import_node_path3 = require("node:path");
30
+
31
+ // src/config.ts
32
+ var import_node_path = require("node:path");
33
+ function resolveConfig(config = {}) {
34
+ const root = (0, import_node_path.resolve)(config.root ?? process.cwd());
35
+ return {
36
+ root,
37
+ ssr: config.ssr ?? true,
38
+ port: config.port ?? 3e3,
39
+ serverEntry: config.serverEntry ?? "src/entry-server.ts",
40
+ clientEntry: config.clientEntry ?? "src/entry-client.ts",
41
+ template: config.template ?? "index.html",
42
+ mountId: config.mountId ?? "root",
43
+ routesDir: config.routesDir ?? "src/routes",
44
+ apiDir: config.apiDir ?? "src/api",
45
+ middleware: config.middleware ?? "src/middleware.ts",
46
+ ssrNoExternal: config.ssrNoExternal ?? [],
47
+ resolve: config.resolve ?? [],
48
+ vitePlugin: config.vitePlugin ?? {},
49
+ plugins: config.plugins ?? [],
50
+ adapter: config.adapter,
51
+ i18n: resolveI18n(config.i18n),
52
+ prerender: resolvePrerender(config.prerender)
53
+ };
54
+ }
55
+ function resolvePrerender(prerender2) {
56
+ if (!prerender2) return false;
57
+ const opts = typeof prerender2 === "object" ? prerender2 : {};
58
+ return {
59
+ routes: opts.routes?.length ? opts.routes : ["/"],
60
+ crawl: opts.crawl ?? true
61
+ };
62
+ }
63
+ function resolveI18n(i18n) {
64
+ if (i18n === false) return false;
65
+ const opts = typeof i18n === "object" ? i18n : {};
66
+ return {
67
+ dir: opts.dir ?? "src/i18n",
68
+ defaultLocale: opts.defaultLocale,
69
+ locales: opts.locales
70
+ };
71
+ }
72
+
73
+ // src/adapter.ts
74
+ var import_promises = require("node:fs/promises");
75
+ var import_node_fs = require("node:fs");
76
+ var import_node_path2 = require("node:path");
77
+ var import_node_url = require("node:url");
78
+
79
+ // src/handler.ts
80
+ function streamDocument(head, body, tail) {
81
+ const enc = new TextEncoder();
82
+ const stream = new ReadableStream({
83
+ async start(controller) {
84
+ try {
85
+ controller.enqueue(enc.encode(head));
86
+ const reader = body.getReader();
87
+ for (; ; ) {
88
+ const { done: done2, value } = await reader.read();
89
+ if (done2) break;
90
+ controller.enqueue(value);
91
+ }
92
+ controller.enqueue(enc.encode(tail));
93
+ controller.close();
94
+ } catch (err) {
95
+ controller.error(err);
96
+ }
97
+ }
98
+ });
99
+ return new Response(stream, {
100
+ status: 200,
101
+ headers: { "content-type": "text/html; charset=utf-8" }
102
+ });
103
+ }
104
+ function createRequestHandler(render) {
105
+ return async (request) => {
106
+ const url = new URL(request.url);
107
+ try {
108
+ const html = await render(url.pathname + url.search, request);
109
+ return new Response(html, {
110
+ status: 200,
111
+ headers: { "content-type": "text/html; charset=utf-8" }
112
+ });
113
+ } catch (e) {
114
+ return new Response(String(e?.stack || e), {
115
+ status: 500,
116
+ headers: { "content-type": "text/plain; charset=utf-8" }
117
+ });
118
+ }
119
+ };
120
+ }
121
+
122
+ // src/document.ts
123
+ var import_head = require("@fluixi/head");
124
+ function injectApp(template, appHtml, mountId = "root") {
125
+ const mount = new RegExp(`<div id=["']${mountId}["']\\s*>\\s*</div>`);
126
+ if (mount.test(template)) {
127
+ return template.replace(mount, `<div id="${mountId}">${appHtml}</div>`);
128
+ }
129
+ if (template.includes("<!--ssr-outlet-->")) {
130
+ return template.replace("<!--ssr-outlet-->", appHtml);
131
+ }
132
+ return template.replace("</body>", `<div id="${mountId}">${appHtml}</div></body>`);
133
+ }
134
+ function splitTemplate(template, mountId = "root") {
135
+ const mount = new RegExp(`<div id=["']${mountId}["']\\s*>\\s*</div>`);
136
+ const m = template.match(mount);
137
+ if (m && m.index !== void 0) {
138
+ return {
139
+ head: template.slice(0, m.index) + `<div id="${mountId}">`,
140
+ tail: `</div>` + template.slice(m.index + m[0].length)
141
+ };
142
+ }
143
+ const outlet = template.indexOf("<!--ssr-outlet-->");
144
+ if (outlet !== -1) {
145
+ return {
146
+ head: template.slice(0, outlet),
147
+ tail: template.slice(outlet + "<!--ssr-outlet-->".length)
148
+ };
149
+ }
150
+ const body = template.indexOf("</body>");
151
+ if (body !== -1) {
152
+ return {
153
+ head: template.slice(0, body) + `<div id="${mountId}">`,
154
+ tail: `</div>` + template.slice(body)
155
+ };
156
+ }
157
+ return { head: template, tail: "" };
158
+ }
159
+ function injectPreload(template, files) {
160
+ const tags = files.filter((file) => !template.includes(file)).map(
161
+ (file) => file.endsWith(".css") ? `<link rel="stylesheet" href="${file}">` : (
162
+ // `modulepreload` also fetches the chunk's own static imports.
163
+ `<link rel="modulepreload" href="${file}">`
164
+ )
165
+ );
166
+ if (tags.length === 0) return template;
167
+ const head = template.indexOf("</head>");
168
+ if (head === -1) return template;
169
+ return template.slice(0, head) + tags.join("") + template.slice(head);
170
+ }
171
+ function setHtmlAttr(html, name, value) {
172
+ const existing = new RegExp(`(<html\\b[^>]*?)\\s${name}="[^"]*"`, "i");
173
+ if (existing.test(html)) return html.replace(existing, `$1 ${name}="${value}"`);
174
+ return html.replace(/<html\b/i, `<html ${name}="${value}"`);
175
+ }
176
+ function injectAppAndHead(template, rendered, mountId = "root") {
177
+ const { head, body } = (0, import_head.extractHeadMarker)(rendered);
178
+ let html = injectApp(template, body, mountId);
179
+ if (head) {
180
+ if (head.headHtml) {
181
+ if (/<title[\s>]/i.test(head.headHtml)) html = html.replace(/<title>[\s\S]*?<\/title>/i, "");
182
+ html = html.replace("</head>", `${head.headHtml}</head>`);
183
+ }
184
+ for (const [k, v] of Object.entries(head.htmlAttrs)) html = setHtmlAttr(html, k, v);
185
+ }
186
+ return html;
187
+ }
188
+ function guardHandler(handler, onError) {
189
+ return async (request) => {
190
+ try {
191
+ return await handler(request);
192
+ } catch (e) {
193
+ onError?.(e);
194
+ return new Response(String(e?.stack || e), {
195
+ status: 500,
196
+ headers: { "content-type": "text/plain; charset=utf-8" }
197
+ });
198
+ }
199
+ };
200
+ }
201
+
202
+ // src/middleware.ts
203
+ function normalizeMiddleware(mod) {
204
+ const def = mod?.default ?? mod;
205
+ if (def == null) return [];
206
+ if (Array.isArray(def)) return def.filter((m) => typeof m === "function");
207
+ return typeof def === "function" ? [def] : [];
208
+ }
209
+ function composeMiddleware(middlewares, core) {
210
+ if (middlewares.length === 0) return core;
211
+ return (request) => {
212
+ let lastCalled = -1;
213
+ const dispatch = (i) => {
214
+ if (i <= lastCalled) {
215
+ return Promise.reject(new Error("middleware called next() more than once"));
216
+ }
217
+ lastCalled = i;
218
+ const mw = middlewares[i];
219
+ if (!mw) return Promise.resolve(core(request));
220
+ return Promise.resolve(mw(request, () => dispatch(i + 1)));
221
+ };
222
+ return dispatch(0);
223
+ };
224
+ }
225
+
226
+ // src/handler-core.ts
227
+ function createHandlerFrom({ template, mod, cfg, middleware, preload }) {
228
+ const withPreload = (html, pathname) => preload ? injectPreload(html, preload(pathname)) : html;
229
+ let core;
230
+ if (!cfg.ssr) {
231
+ core = createRequestHandler(async (url) => withPreload(template, url.split("?")[0]));
232
+ } else if (typeof mod.renderStream === "function") {
233
+ core = async (request) => {
234
+ const url = new URL(request.url);
235
+ const { head, tail } = splitTemplate(withPreload(template, url.pathname), cfg.mountId);
236
+ const body = await mod.renderStream(url.pathname + url.search, request);
237
+ return streamDocument(head, body, tail);
238
+ };
239
+ } else {
240
+ const render = mod.render ?? mod.default;
241
+ core = createRequestHandler(
242
+ async (url, request) => (
243
+ // `url` here is `pathname + search`; matching only ever wants the path.
244
+ injectAppAndHead(withPreload(template, url.split("?")[0]), await render(url, request), cfg.mountId)
245
+ )
246
+ );
247
+ }
248
+ if (typeof mod.handleServerFn === "function" && typeof mod.isServerFnRequest === "function") {
249
+ const render = core;
250
+ core = async (request) => mod.isServerFnRequest(request) ? mod.handleServerFn(request) : render(request);
251
+ }
252
+ if (typeof mod.handleApiRequest === "function" && typeof mod.isApiRequest === "function") {
253
+ const next = core;
254
+ core = async (request) => mod.isApiRequest(request) ? mod.handleApiRequest(request) : next(request);
255
+ }
256
+ if (!middleware) return guardHandler(core);
257
+ return guardHandler(composeMiddleware(normalizeMiddleware(middleware), core));
258
+ }
259
+
260
+ // src/preload.ts
261
+ var import_router = require("@fluixi/core/router");
262
+ function createPreloader(assets) {
263
+ const patterns = Object.keys(assets ?? {});
264
+ if (!patterns.length) return () => [];
265
+ const routes = patterns.map((path) => ({ path, meta: { path } }));
266
+ return (pathname) => {
267
+ const matched = (0, import_router.matchRoutes)(routes, pathname)?.matched;
268
+ const leaf = matched?.[matched.length - 1];
269
+ const pattern = leaf?.route.meta?.path;
270
+ return pattern ? assets[pattern] ?? [] : [];
271
+ };
272
+ }
273
+
274
+ // src/adapter.ts
275
+ async function createProdHandler(config = {}) {
276
+ const cfg = resolveConfig(config);
277
+ const clientDir = (0, import_node_path2.resolve)(cfg.root, "dist/client");
278
+ const template = await readTemplate(clientDir, (0, import_node_path2.resolve)(cfg.root, "dist/server"));
279
+ const serverEntry = (0, import_node_path2.resolve)(cfg.root, "dist/server", "entry-server.js");
280
+ const mod = (0, import_node_fs.existsSync)(serverEntry) ? await import(
281
+ /* @vite-ignore */
282
+ (0, import_node_url.pathToFileURL)(serverEntry).href
283
+ ) : {};
284
+ const mwFile = (0, import_node_path2.resolve)(cfg.root, "dist/server", "middleware.js");
285
+ const middleware = (0, import_node_fs.existsSync)(mwFile) ? await import(
286
+ /* @vite-ignore */
287
+ (0, import_node_url.pathToFileURL)(mwFile).href
288
+ ) : void 0;
289
+ return createHandlerFrom({ template, mod, cfg, middleware, preload: await loadPreloader(cfg) });
290
+ }
291
+ async function readTemplate(clientDir, serverDir) {
292
+ const stashed = (0, import_node_path2.join)(serverDir, "template.html");
293
+ return (0, import_promises.readFile)((0, import_node_fs.existsSync)(stashed) ? stashed : (0, import_node_path2.join)(clientDir, "index.html"), "utf-8");
294
+ }
295
+ async function loadPreloader(cfg) {
296
+ const file = (0, import_node_path2.resolve)(cfg.root, "dist/server", "route-assets.json");
297
+ if (!(0, import_node_fs.existsSync)(file)) return void 0;
298
+ try {
299
+ return createPreloader(JSON.parse(await (0, import_promises.readFile)(file, "utf-8")));
300
+ } catch {
301
+ return void 0;
302
+ }
303
+ }
304
+
305
+ // src/ui.ts
306
+ var COLOR = process.env.NO_COLOR || process.env.FORCE_COLOR === "0" ? false : (!!process.stdout.isTTY || !!process.env.FORCE_COLOR) && process.env.TERM !== "dumb";
307
+ var sgr = (open, close) => (s) => COLOR ? `\x1B[${open}m${s}\x1B[${close}m` : `${s}`;
308
+ var c = {
309
+ bold: sgr(1, 22),
310
+ dim: sgr(2, 22),
311
+ italic: sgr(3, 23),
312
+ underline: sgr(4, 24),
313
+ red: sgr(31, 39),
314
+ green: sgr(32, 39),
315
+ yellow: sgr(33, 39),
316
+ blue: sgr(34, 39),
317
+ magenta: sgr(35, 39),
318
+ cyan: sgr(36, 39),
319
+ gray: sgr(90, 39)
320
+ };
321
+ var SYM = {
322
+ arrow: c.gray("➜"),
323
+ ok: c.green("✓"),
324
+ err: c.red("✗")
325
+ };
326
+ function step(text) {
327
+ process.stdout.write(` ${c.cyan("•")} ${text}
328
+ `);
329
+ }
330
+ function done(text) {
331
+ process.stdout.write(` ${SYM.ok} ${text}
332
+ `);
333
+ }
334
+
335
+ // src/commands/prerender.ts
336
+ function htmlPath(url) {
337
+ const clean = url.split(/[?#]/)[0].replace(/\/+$/, "");
338
+ return clean === "" ? "index.html" : `${clean.replace(/^\//, "")}/index.html`;
339
+ }
340
+ function extractLinks(html) {
341
+ const out = /* @__PURE__ */ new Set();
342
+ for (const m of html.matchAll(/href=["'](\/[^"'#?]*)["']/g)) {
343
+ const href = m[1];
344
+ if (/\.[a-z0-9]+$/i.test(href)) continue;
345
+ out.add(href.replace(/\/+$/, "") || "/");
346
+ }
347
+ return [...out];
348
+ }
349
+ var norm = (u) => {
350
+ const p = (u.startsWith("/") ? u : "/" + u).replace(/\/+$/, "");
351
+ return p || "/";
352
+ };
353
+ async function prerender(config = {}) {
354
+ const cfg = resolveConfig(config);
355
+ if (!cfg.prerender) return [];
356
+ if (!cfg.ssr) {
357
+ process.stdout.write(` ${c.yellow("!")} prerender needs ssr:true — skipped
358
+ `);
359
+ return [];
360
+ }
361
+ step("prerender");
362
+ const clientDir = (0, import_node_path3.resolve)(cfg.root, "dist/client");
363
+ const handler = await createProdHandler(config);
364
+ const { routes, crawl } = cfg.prerender;
365
+ const queue = routes.map(norm);
366
+ const seen = /* @__PURE__ */ new Set();
367
+ const written = [];
368
+ while (queue.length) {
369
+ const url = queue.shift();
370
+ if (seen.has(url)) continue;
371
+ seen.add(url);
372
+ let html;
373
+ try {
374
+ const res = await handler(new Request("http://prerender.local" + url));
375
+ if (!res.ok) {
376
+ process.stdout.write(` ${c.yellow("skip")} ${url} ${c.gray("→ " + res.status)}
377
+ `);
378
+ continue;
379
+ }
380
+ if (!(res.headers.get("content-type") || "").includes("html")) continue;
381
+ html = await res.text();
382
+ } catch (e) {
383
+ process.stdout.write(` ${c.yellow("skip")} ${url} ${c.gray("→ " + e.message)}
384
+ `);
385
+ continue;
386
+ }
387
+ const file = (0, import_node_path3.join)(clientDir, htmlPath(url));
388
+ await (0, import_promises2.mkdir)((0, import_node_path3.dirname)(file), { recursive: true });
389
+ await (0, import_promises2.writeFile)(file, html);
390
+ written.push(url);
391
+ if (crawl) {
392
+ for (const link of extractLinks(html)) if (!seen.has(link)) queue.push(link);
393
+ }
394
+ }
395
+ done(`${c.bold("prerendered")} ${c.bold(String(written.length))} page(s) ${c.gray("→ dist/client")}
396
+ `);
397
+ return written;
398
+ }
399
+ // Annotate the CommonJS export names for ESM import in node:
400
+ 0 && (module.exports = {
401
+ extractLinks,
402
+ htmlPath,
403
+ prerender
404
+ });
@@ -2,7 +2,7 @@ import type { FluixiConfig } from '../config.js';
2
2
  export declare function htmlPath(url: string): string;
3
3
  export declare function extractLinks(html: string): string[];
4
4
  /**
5
- * Render routes to static HTML in dist/client, via the real prod handler so each page is
5
+ * Render routes to static HTML in dist/client, via the real prod handler, so each page is
6
6
  * byte-identical to what `fluixi start` would serve (assets, __FX_DATA__, hydration), it just
7
7
  * lives on disk. Seeds from `prerender.routes` (default `/`) and, when `crawl`, follows internal
8
8
  * links. Returns the written route paths.
@@ -8,7 +8,7 @@ export function htmlPath(url) {
8
8
  const clean = url.split(/[?#]/)[0].replace(/\/+$/, '');
9
9
  return clean === '' ? 'index.html' : `${clean.replace(/^\//, '')}/index.html`;
10
10
  }
11
- // internal links from rendered HTML skip files (.js/.css/…), anchors, queries, external
11
+ // internal links from rendered HTML: skip files (.js/.css/…), anchors, queries, external
12
12
  export function extractLinks(html) {
13
13
  const out = new Set();
14
14
  for (const m of html.matchAll(/href=["'](\/[^"'#?]*)["']/g)) {
@@ -24,7 +24,7 @@ const norm = (u) => {
24
24
  return p || '/';
25
25
  };
26
26
  /**
27
- * Render routes to static HTML in dist/client, via the real prod handler so each page is
27
+ * Render routes to static HTML in dist/client, via the real prod handler, so each page is
28
28
  * byte-identical to what `fluixi start` would serve (assets, __FX_DATA__, hydration), it just
29
29
  * lives on disk. Seeds from `prerender.routes` (default `/`) and, when `crawl`, follows internal
30
30
  * links. Returns the written route paths.