@fluixi/start 0.1.0-alpha.74 → 0.1.0-alpha.76

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 (120) hide show
  1. package/dist/adapter.cjs +6 -4
  2. package/dist/adapter.d.ts +9 -9
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js +13 -11
  5. package/dist/adapter.mjs +6 -4
  6. package/dist/adapters/entry.cjs +1 -1
  7. package/dist/adapters/entry.js +1 -1
  8. package/dist/adapters/entry.mjs +1 -1
  9. package/dist/adapters/platforms.cjs +1 -1
  10. package/dist/adapters/platforms.d.ts +2 -2
  11. package/dist/adapters/platforms.js +8 -8
  12. package/dist/adapters/platforms.mjs +1 -1
  13. package/dist/{api-RH6E5UTH.mjs → api-HD7KU3BS.mjs} +1 -1
  14. package/dist/api.cjs +2 -2
  15. package/dist/api.js +1 -1
  16. package/dist/api.mjs +2 -2
  17. package/dist/commands/{api-RH6E5UTH.mjs → api-HD7KU3BS.mjs} +1 -1
  18. package/dist/commands/{api-23MJFSYL.mjs → api-LTOLCZPE.mjs} +2 -2
  19. package/dist/commands/{api-4IYNQRKG.mjs → api-PBT4QZ34.mjs} +1 -1
  20. package/dist/commands/build.cjs +14 -7
  21. package/dist/commands/build.js +6 -6
  22. package/dist/commands/build.mjs +14 -7
  23. package/dist/commands/{chunk-OCPCK4ZJ.mjs → chunk-JACRXSN7.mjs} +2 -2
  24. package/dist/commands/{chunk-NS5GR2GX.mjs → chunk-MTM6M3TC.mjs} +1 -1
  25. package/dist/commands/dev.cjs +17 -5
  26. package/dist/commands/dev.d.ts.map +1 -1
  27. package/dist/commands/dev.js +9 -4
  28. package/dist/commands/dev.mjs +18 -6
  29. package/dist/commands/index.cjs +21 -9
  30. package/dist/commands/index.d.ts +1 -1
  31. package/dist/commands/index.js +1 -1
  32. package/dist/commands/index.mjs +22 -10
  33. package/dist/commands/prerender.cjs +2 -0
  34. package/dist/commands/prerender.d.ts +1 -1
  35. package/dist/commands/prerender.js +2 -2
  36. package/dist/commands/prerender.mjs +2 -0
  37. package/dist/commands/start.cjs +2 -0
  38. package/dist/commands/start.d.ts +1 -1
  39. package/dist/commands/start.js +2 -2
  40. package/dist/commands/start.mjs +2 -0
  41. package/dist/config.cjs +7 -1
  42. package/dist/config.d.ts +24 -7
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +8 -6
  45. package/dist/config.mjs +7 -1
  46. package/dist/define-config.cjs +32 -0
  47. package/dist/define-config.d.ts +12 -0
  48. package/dist/define-config.d.ts.map +1 -0
  49. package/dist/define-config.js +3 -0
  50. package/dist/define-config.mjs +7 -0
  51. package/dist/di.cjs +1 -1
  52. package/dist/di.d.ts +4 -4
  53. package/dist/di.d.ts.map +1 -1
  54. package/dist/di.js +9 -9
  55. package/dist/di.mjs +1 -1
  56. package/dist/document.d.ts +1 -1
  57. package/dist/document.js +1 -1
  58. package/dist/generated-api.cjs +1 -1
  59. package/dist/generated-api.js +1 -1
  60. package/dist/generated-api.mjs +1 -1
  61. package/dist/generated-server-fns.cjs +1 -1
  62. package/dist/generated-server-fns.mjs +1 -1
  63. package/dist/handler-core.cjs +1 -1
  64. package/dist/handler-core.d.ts +2 -2
  65. package/dist/handler-core.js +2 -2
  66. package/dist/handler-core.mjs +1 -1
  67. package/dist/handler.cjs +1 -0
  68. package/dist/handler.d.ts +3 -3
  69. package/dist/handler.js +3 -3
  70. package/dist/handler.mjs +2 -0
  71. package/dist/head.cjs +1 -1
  72. package/dist/head.d.ts +1 -1
  73. package/dist/head.js +1 -1
  74. package/dist/head.mjs +1 -1
  75. package/dist/image-loader.cjs +37 -0
  76. package/dist/image-loader.d.ts +25 -0
  77. package/dist/image-loader.d.ts.map +1 -0
  78. package/dist/image-loader.js +18 -0
  79. package/dist/image-loader.mjs +12 -0
  80. package/dist/image.cjs +13 -8
  81. package/dist/image.d.ts +2 -19
  82. package/dist/image.d.ts.map +1 -1
  83. package/dist/image.js +5 -21
  84. package/dist/image.mjs +14 -8
  85. package/dist/index.cjs +5 -738
  86. package/dist/index.d.ts +28 -8
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +33 -17
  89. package/dist/index.mjs +4 -710
  90. package/dist/interceptors.cjs +1 -0
  91. package/dist/interceptors.js +1 -1
  92. package/dist/interceptors.mjs +2 -0
  93. package/dist/internal.cjs +9 -4
  94. package/dist/internal.d.ts +6 -6
  95. package/dist/internal.d.ts.map +1 -1
  96. package/dist/internal.js +23 -15
  97. package/dist/internal.mjs +9 -4
  98. package/dist/middleware.d.ts +3 -3
  99. package/dist/middleware.d.ts.map +1 -1
  100. package/dist/middleware.js +1 -1
  101. package/dist/preload.cjs +1 -1
  102. package/dist/preload.js +1 -1
  103. package/dist/preload.mjs +1 -1
  104. package/dist/router.cjs +1 -1
  105. package/dist/router.d.ts +3 -3
  106. package/dist/router.js +3 -3
  107. package/dist/router.mjs +1 -1
  108. package/dist/server-fn-setup.cjs +1 -1
  109. package/dist/server-fn-setup.d.ts +1 -1
  110. package/dist/server-fn-setup.js +2 -2
  111. package/dist/server-fn-setup.mjs +1 -1
  112. package/dist/server-fn.cjs +1 -1
  113. package/dist/server-fn.d.ts +2 -2
  114. package/dist/server-fn.js +2 -2
  115. package/dist/server-fn.mjs +1 -1
  116. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  117. package/dist/ui.cjs +1 -1
  118. package/dist/ui.js +1 -1
  119. package/dist/ui.mjs +1 -1
  120. package/package.json +25 -7
package/dist/adapter.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/start v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -54,6 +54,8 @@ function resolveConfig(config = {}) {
54
54
  middleware: config.middleware ?? "src/middleware.ts",
55
55
  ssrNoExternal: config.ssrNoExternal ?? [],
56
56
  resolve: config.resolve ?? [],
57
+ vitePlugin: config.vitePlugin ?? {},
58
+ plugins: config.plugins ?? [],
57
59
  adapter: config.adapter,
58
60
  i18n: resolveI18n(config.i18n),
59
61
  prerender: resolvePrerender(config.prerender)
@@ -407,7 +409,7 @@ export default {
407
409
  // Static first, but only for what is static. ASSETS answers "/" with index.html
408
410
  // whether that is a prerendered page or the shell, so asking about every path
409
411
  // costs an SSR app its home page. Extension means a file, prerendered means a
410
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
412
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
411
413
  const { pathname } = new URL(request.url);
412
414
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
413
415
  const asset = await env.ASSETS.fetch(request.clone());
@@ -687,14 +689,14 @@ var webAdapter = {
687
689
  };
688
690
  var GENERATED_SUBPATHS = /* @__PURE__ */ new Set(["./routes", "./server-fns", "./api-routes"]);
689
691
  function ssrBuildOptions(cfg) {
690
- const noExternal = cfg.ssrNoExternal.length ? cfg.ssrNoExternal : void 0;
692
+ const noExternal = [.../* @__PURE__ */ new Set(["@fluixi/core", ...cfg.ssrNoExternal])];
691
693
  const mode = cfg.adapter?.bundle;
692
694
  if (mode === "inline") return { noExternal: true };
693
695
  if (mode !== "external") return { noExternal };
694
696
  const external = frameworkDeps(cfg.root).filter((name) => !cfg.ssrNoExternal.includes(name)).flatMap((name) => withSubpaths(cfg.root, name));
695
697
  if (!external.length) {
696
698
  console.warn(
697
- ` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no fluixi or @fluixi/* dependency was found in ${(0, import_node_path4.join)(cfg.root, "package.json")} bundling everything.`
699
+ ` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no fluixi or @fluixi/* dependency was found in ${(0, import_node_path4.join)(cfg.root, "package.json")}, bundling everything.`
698
700
  );
699
701
  }
700
702
  return { noExternal, external: external.length ? external : void 0 };
package/dist/adapter.d.ts CHANGED
@@ -10,7 +10,7 @@ export declare function createProdHandler(config?: FluixiConfig): Promise<FetchH
10
10
  /**
11
11
  * The shell the server renders into.
12
12
  *
13
- * `dist/client/index.html` is it, until the app prerenders `/` then that path holds a
13
+ * `dist/client/index.html` is it, until the app prerenders `/`, then that path holds a
14
14
  * rendered page and the build stashes the shell in `dist/server/template.html` first.
15
15
  * Rendering into the page instead puts the home page's markup and head around every
16
16
  * SSR response, and leaves hydration two mount elements to choose between.
@@ -35,7 +35,7 @@ export interface AdapterBuildContext {
35
35
  hasServer: boolean;
36
36
  /**
37
37
  * Bundle a generated entry into one self-contained file. Adapters emit a small
38
- * platform entry the worker's `fetch` export, the function's handler and this
38
+ * platform entry: the worker's `fetch` export, the function's handler, and this
39
39
  * pulls the server bundle and the template into it, because none of these
40
40
  * platforms can resolve a module or read a file at runtime.
41
41
  */
@@ -45,7 +45,7 @@ export interface AdapterBuildContext {
45
45
  * A deploy target.
46
46
  *
47
47
  * The runtime-neutral fetch handler is the portable core; an adapter packages it for a
48
- * platform how the server is bundled (`bundle`), how it is served in development or
48
+ * platform: how the server is bundled (`bundle`), how it is served in development or
49
49
  * on a long-running host (`serve`), and what a deploy actually needs on disk
50
50
  * (`build`): a worker entry, a function manifest, a routing config.
51
51
  */
@@ -55,10 +55,10 @@ export interface Adapter {
55
55
  * How `fluixi build` bundles the framework into the server output. The choice is a
56
56
  * property of the deploy target, not of the app:
57
57
  *
58
- * - `'external'` `@fluixi/*` stays as bare imports, resolved from `node_modules` at
58
+ * - `'external'`: `@fluixi/*` stays as bare imports, resolved from `node_modules` at
59
59
  * runtime. Smaller output, faster build; requires the dependencies to be installed
60
60
  * next to it. Right for a long-running Node/Bun/Deno process.
61
- * - `'inline'` everything is bundled into one self-contained file that resolves
61
+ * - `'inline'`: everything is bundled into one self-contained file that resolves
62
62
  * nothing at runtime. Right for edge/serverless, where there is no `node_modules`.
63
63
  *
64
64
  * Unset leaves Vite's own heuristic alone (installed deps external, linked ones bundled).
@@ -73,10 +73,10 @@ export interface Adapter {
73
73
  */
74
74
  build?(ctx: AdapterBuildContext): Promise<void> | void;
75
75
  }
76
- /** Reference filesystem adapter Node `http` + static files from dist/client. */
76
+ /** Reference filesystem adapter: Node `http` + static files from dist/client. */
77
77
  export declare const nodeAdapter: Adapter;
78
78
  export { cloudflareAdapter, netlifyAdapter, vercelAdapter } from './adapters/platforms.js';
79
- /** Reference edge/web adapter export `{ fetch }`; the platform serves assets. */
79
+ /** Reference edge/web adapter: export `{ fetch }`; the platform serves assets. */
80
80
  export declare const webAdapter: Adapter;
81
81
  /**
82
82
  * The Vite `ssr` options for a build, given the configured adapter's `bundle` mode.
@@ -91,9 +91,9 @@ export declare const webAdapter: Adapter;
91
91
  * only honours an *exact* id in `ssr.external`. A bare package name falls through to a
92
92
  * resolvability probe that does not externalize deep imports here, and the result is the
93
93
  * worst of both worlds: `@fluixi/core` an import, `@fluixi/core/router` copied into
94
- * the bundle two routers, two sets of module state, in one server.
94
+ * the bundle: two routers, two sets of module state, in one server.
95
95
  *
96
- * `ssrNoExternal` always wins it is the app saying "this one must be bundled".
96
+ * `ssrNoExternal` always wins: it is the app saying "this one must be bundled".
97
97
  */
98
98
  export declare function ssrBuildOptions(cfg: ResolvedConfig): {
99
99
  noExternal?: string[] | true;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAI7E;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiBxF;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxF;AAoBD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,GAAG,EAAE,cAAc,CAAC;IACpB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,cAAc,CAAC;IACpB,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC/B,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;IACpE;;;OAGG;IACH,KAAK,CAAC,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxD;AAED,kFAAkF;AAClF,eAAO,MAAM,WAAW,EAAE,OAWzB,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE3F,mFAAmF;AACnF,eAAO,MAAM,UAAU,EAAE,OAQxB,CAAC;AAUF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG;IACpD,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,CAoBA"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAI7E;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiBxF;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxF;AAoBD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,GAAG,EAAE,cAAc,CAAC;IACpB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,cAAc,CAAC;IACpB,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC/B,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;IACpE;;;OAGG;IACH,KAAK,CAAC,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxD;AAED,iFAAiF;AACjF,eAAO,MAAM,WAAW,EAAE,OAWzB,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE3F,kFAAkF;AAClF,eAAO,MAAM,UAAU,EAAE,OAQxB,CAAC;AAUF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG;IACpD,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,CAsBA"}
package/dist/adapter.js CHANGED
@@ -18,7 +18,7 @@ export async function createProdHandler(config = {}) {
18
18
  const clientDir = resolve(cfg.root, 'dist/client');
19
19
  const template = await readTemplate(clientDir, resolve(cfg.root, 'dist/server'));
20
20
  const serverEntry = resolve(cfg.root, 'dist/server', 'entry-server.js');
21
- // SPA apps may ship no server entry (or one only for server functions) import if present.
21
+ // SPA apps may ship no server entry (or one only for server functions), import if present.
22
22
  const mod = existsSync(serverEntry)
23
23
  ? await import(/* @vite-ignore */ pathToFileURL(serverEntry).href)
24
24
  : {};
@@ -32,7 +32,7 @@ export async function createProdHandler(config = {}) {
32
32
  /**
33
33
  * The shell the server renders into.
34
34
  *
35
- * `dist/client/index.html` is it, until the app prerenders `/` then that path holds a
35
+ * `dist/client/index.html` is it, until the app prerenders `/`, then that path holds a
36
36
  * rendered page and the build stashes the shell in `dist/server/template.html` first.
37
37
  * Rendering into the page instead puts the home page's markup and head around every
38
38
  * SSR response, and leaves hydration two mount elements to choose between.
@@ -59,7 +59,7 @@ async function loadPreloader(cfg) {
59
59
  return undefined;
60
60
  }
61
61
  }
62
- /** Reference filesystem adapter Node `http` + static files from dist/client. */
62
+ /** Reference filesystem adapter: Node `http` + static files from dist/client. */
63
63
  export const nodeAdapter = {
64
64
  name: 'node',
65
65
  // A Node server runs from the app directory, so node_modules is right there: keep the
@@ -73,7 +73,7 @@ export const nodeAdapter = {
73
73
  },
74
74
  };
75
75
  export { cloudflareAdapter, netlifyAdapter, vercelAdapter } from './adapters/platforms.js';
76
- /** Reference edge/web adapter export `{ fetch }`; the platform serves assets. */
76
+ /** Reference edge/web adapter: export `{ fetch }`; the platform serves assets. */
77
77
  export const webAdapter = {
78
78
  name: 'web',
79
79
  // An edge/serverless runtime uploads a file, not an install: nothing may be left to
@@ -87,7 +87,7 @@ export const webAdapter = {
87
87
  * Subpaths that only look like package entries: a Vite plugin replaces them with the
88
88
  * app's generated route/server-fn/API tables, and the real file in the package is a stub
89
89
  * that throws. Externalizing one would ship the stub. The plugins run with
90
- * `enforce: 'pre'` so they win anyway this list is the second lock on that door.
90
+ * `enforce: 'pre'` so they win anyway: this list is the second lock on that door.
91
91
  */
92
92
  const GENERATED_SUBPATHS = new Set(['./routes', './server-fns', './api-routes']);
93
93
  /**
@@ -103,12 +103,14 @@ const GENERATED_SUBPATHS = new Set(['./routes', './server-fns', './api-routes'])
103
103
  * only honours an *exact* id in `ssr.external`. A bare package name falls through to a
104
104
  * resolvability probe that does not externalize deep imports here, and the result is the
105
105
  * worst of both worlds: `@fluixi/core` an import, `@fluixi/core/router` copied into
106
- * the bundle two routers, two sets of module state, in one server.
106
+ * the bundle: two routers, two sets of module state, in one server.
107
107
  *
108
- * `ssrNoExternal` always wins it is the app saying "this one must be bundled".
108
+ * `ssrNoExternal` always wins: it is the app saying "this one must be bundled".
109
109
  */
110
110
  export function ssrBuildOptions(cfg) {
111
- const noExternal = cfg.ssrNoExternal.length ? cfg.ssrNoExternal : undefined;
111
+ // Always bundled, for the reason in commands/dev.ts: the routes module is a plugin
112
+ // virtual and an externalized package never reaches the plugin.
113
+ const noExternal = [...new Set(['@fluixi/core', ...cfg.ssrNoExternal])];
112
114
  const mode = cfg.adapter?.bundle;
113
115
  if (mode === 'inline')
114
116
  return { noExternal: true };
@@ -121,7 +123,7 @@ export function ssrBuildOptions(cfg) {
121
123
  // Silently building an inlined bundle here would look identical to a working one
122
124
  // until someone measures it, so say why nothing was externalized.
123
125
  console.warn(` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no ` +
124
- `fluixi or @fluixi/* dependency was found in ${join(cfg.root, 'package.json')} bundling everything.`);
126
+ `fluixi or @fluixi/* dependency was found in ${join(cfg.root, 'package.json')}, bundling everything.`);
125
127
  }
126
128
  return { noExternal, external: external.length ? external : undefined };
127
129
  }
@@ -136,7 +138,7 @@ function frameworkDeps(root) {
136
138
  return Object.keys(declared).filter((id) => id === '@fluixi/core' || id.startsWith('@fluixi/'));
137
139
  }
138
140
  /**
139
- * `['@fluixi/core', '@fluixi/core/router', …]` the package plus every static subpath it
141
+ * `['@fluixi/core', '@fluixi/core/router', …]`: the package plus every static subpath it
140
142
  * exports. Wildcard entries (`./lib/*`) cannot be enumerated and are left to Vite; an
141
143
  * app importing through one gets it bundled, which is the safe direction.
142
144
  */
@@ -164,7 +166,7 @@ function resolvePackage(root, name) {
164
166
  return readPackage(createRequire(join(root, 'index.js')).resolve(`${name}/package.json`));
165
167
  }
166
168
  catch {
167
- /* not exported fall through */
169
+ /* not exported: fall through */
168
170
  }
169
171
  for (let dir = root;; dir = dirname(dir)) {
170
172
  const pkg = readPackage(join(dir, 'node_modules', name, 'package.json'));
package/dist/adapter.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/start v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/adapter.ts
4
4
  import { readFile as readFile2 } from "node:fs/promises";
@@ -24,6 +24,8 @@ function resolveConfig(config = {}) {
24
24
  middleware: config.middleware ?? "src/middleware.ts",
25
25
  ssrNoExternal: config.ssrNoExternal ?? [],
26
26
  resolve: config.resolve ?? [],
27
+ vitePlugin: config.vitePlugin ?? {},
28
+ plugins: config.plugins ?? [],
27
29
  adapter: config.adapter,
28
30
  i18n: resolveI18n(config.i18n),
29
31
  prerender: resolvePrerender(config.prerender)
@@ -377,7 +379,7 @@ export default {
377
379
  // Static first, but only for what is static. ASSETS answers "/" with index.html
378
380
  // whether that is a prerendered page or the shell, so asking about every path
379
381
  // costs an SSR app its home page. Extension means a file, prerendered means a
380
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
382
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
381
383
  const { pathname } = new URL(request.url);
382
384
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
383
385
  const asset = await env.ASSETS.fetch(request.clone());
@@ -657,14 +659,14 @@ var webAdapter = {
657
659
  };
658
660
  var GENERATED_SUBPATHS = /* @__PURE__ */ new Set(["./routes", "./server-fns", "./api-routes"]);
659
661
  function ssrBuildOptions(cfg) {
660
- const noExternal = cfg.ssrNoExternal.length ? cfg.ssrNoExternal : void 0;
662
+ const noExternal = [.../* @__PURE__ */ new Set(["@fluixi/core", ...cfg.ssrNoExternal])];
661
663
  const mode = cfg.adapter?.bundle;
662
664
  if (mode === "inline") return { noExternal: true };
663
665
  if (mode !== "external") return { noExternal };
664
666
  const external = frameworkDeps(cfg.root).filter((name) => !cfg.ssrNoExternal.includes(name)).flatMap((name) => withSubpaths(cfg.root, name));
665
667
  if (!external.length) {
666
668
  console.warn(
667
- ` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no fluixi or @fluixi/* dependency was found in ${join3(cfg.root, "package.json")} bundling everything.`
669
+ ` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no fluixi or @fluixi/* dependency was found in ${join3(cfg.root, "package.json")}, bundling everything.`
668
670
  );
669
671
  }
670
672
  return { noExternal, external: external.length ? external : void 0 };
@@ -55,7 +55,7 @@ export default {
55
55
  // Static first, but only for what is static. ASSETS answers "/" with index.html
56
56
  // whether that is a prerendered page or the shell, so asking about every path
57
57
  // costs an SSR app its home page. Extension means a file, prerendered means a
58
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
58
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
59
59
  const { pathname } = new URL(request.url);
60
60
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
61
61
  const asset = await env.ASSETS.fetch(request.clone());
@@ -49,7 +49,7 @@ export default {
49
49
  // Static first, but only for what is static. ASSETS answers "/" with index.html
50
50
  // whether that is a prerendered page or the shell, so asking about every path
51
51
  // costs an SSR app its home page. Extension means a file, prerendered means a
52
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
52
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
53
53
  const { pathname } = new URL(request.url);
54
54
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
55
55
  const asset = await env.ASSETS.fetch(request.clone());
@@ -29,7 +29,7 @@ export default {
29
29
  // Static first, but only for what is static. ASSETS answers "/" with index.html
30
30
  // whether that is a prerendered page or the shell, so asking about every path
31
31
  // costs an SSR app its home page. Extension means a file, prerendered means a
32
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
32
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
33
33
  const { pathname } = new URL(request.url);
34
34
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
35
35
  const asset = await env.ASSETS.fetch(request.clone());
@@ -77,7 +77,7 @@ export default {
77
77
  // Static first, but only for what is static. ASSETS answers "/" with index.html
78
78
  // whether that is a prerendered page or the shell, so asking about every path
79
79
  // costs an SSR app its home page. Extension means a file, prerendered means a
80
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
80
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
81
81
  const { pathname } = new URL(request.url);
82
82
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
83
83
  const asset = await env.ASSETS.fetch(request.clone());
@@ -3,7 +3,7 @@ import { type Adapter } from '../adapter.js';
3
3
  * Cloudflare Pages. `_worker.js` at the root of the published directory takes every
4
4
  * request; `_routes.json` is what decides whether a request costs an invocation.
5
5
  *
6
- * In advanced mode the worker sees everything not excluded so a prerendered page
6
+ * In advanced mode the worker sees everything not excluded, so a prerendered page
7
7
  * would wake it just to proxy the file back through the ASSETS binding. On a plan
8
8
  * metered by request that is the whole page view budget spent on static files, so
9
9
  * every prerendered path is excluded by name.
@@ -13,7 +13,7 @@ import { type Adapter } from '../adapter.js';
13
13
  export declare const cloudflareAdapter: Adapter;
14
14
  /**
15
15
  * Netlify. The function is a v2 fetch handler under `.netlify/functions-internal/`,
16
- * which is where a framework as opposed to the user puts one, so it cannot
16
+ * which is where a framework: as opposed to the user, puts one, so it cannot
17
17
  * collide with the app's own `netlify/functions`.
18
18
  *
19
19
  * Publish `dist/client`.
@@ -2,7 +2,7 @@
2
2
  * Deploy adapters for the three hosts that expect a specific output layout.
3
3
  *
4
4
  * Each one bundles the same generated entry and then writes whatever the platform
5
- * reads to route a request. What differs is only that layout the handler, the
5
+ * reads to route a request. What differs is only that layout, the handler, the
6
6
  * dispatch order and the render are shared.
7
7
  *
8
8
  * All three inline the framework: a worker or a serverless function is a file that
@@ -40,7 +40,7 @@ async function entrySource(ctx, from, prerendered) {
40
40
  * Is `dist/client/index.html` a page, or the shell the server renders into?
41
41
  *
42
42
  * Vite writes the shell at the path a prerendered `/` would occupy, and every one of
43
- * these platforms serves a matching file before invoking anything so `/` is the one
43
+ * these platforms serves a matching file before invoking anything, so `/` is the one
44
44
  * route an SSR app cannot render, and the CDN answers it with an empty mount element.
45
45
  * No other route is affected: nothing exists at `/about` unless it was prerendered.
46
46
  */
@@ -59,7 +59,7 @@ function skipWhenStatic(ctx, name) {
59
59
  }
60
60
  /**
61
61
  * Add a rule to `_redirects` without taking the file over. Apps ship their own (the
62
- * docs site redirects `/` to its default locale), so ours goes last first match
62
+ * docs site redirects `/` to its default locale), so ours goes last, first match
63
63
  * wins, so the app's rules are reached first.
64
64
  */
65
65
  async function appendRedirect(clientDir, rule) {
@@ -112,7 +112,7 @@ async function prerenderedRoutes(dir, mountId) {
112
112
  * Cloudflare Pages. `_worker.js` at the root of the published directory takes every
113
113
  * request; `_routes.json` is what decides whether a request costs an invocation.
114
114
  *
115
- * In advanced mode the worker sees everything not excluded so a prerendered page
115
+ * In advanced mode the worker sees everything not excluded, so a prerendered page
116
116
  * would wake it just to proxy the file back through the ASSETS binding. On a plan
117
117
  * metered by request that is the whole page view budget spent on static files, so
118
118
  * every prerendered path is excluded by name.
@@ -133,13 +133,13 @@ export const cloudflareAdapter = {
133
133
  await ctx.bundleEntry(cloudflareEntry(await entrySource(ctx, out, prerendered)), out);
134
134
  // Everything under /assets is content-hashed and immutable, so it never needs the
135
135
  // worker. `_worker.js` itself must be excluded or Pages would route it to itself.
136
- // `/` is excluded only when it was prerendered otherwise the worker is the only
136
+ // `/` is excluded only when it was prerendered, otherwise the worker is the only
137
137
  // thing that can answer it, and excluding it would serve the shell instead.
138
138
  const base = ['/assets/*', '/_worker.js'];
139
139
  const room = CF_MAX_RULES - base.length;
140
140
  const exclude = [...base, ...prerendered.slice(0, room)];
141
141
  if (prerendered.length > room) {
142
- // Past the cap the remainder still works it just wakes the worker to hand
142
+ // Past the cap the remainder still works: it just wakes the worker to hand
143
143
  // back a file. Worth saying, because the symptom is a bill, not an error.
144
144
  console.warn(` fluixi: ${prerendered.length} prerendered routes exceed Cloudflare's ${CF_MAX_RULES}-rule ` +
145
145
  `limit for _routes.json; ${prerendered.length - room} will invoke the worker to serve a static file.`);
@@ -149,7 +149,7 @@ export const cloudflareAdapter = {
149
149
  };
150
150
  /**
151
151
  * Netlify. The function is a v2 fetch handler under `.netlify/functions-internal/`,
152
- * which is where a framework as opposed to the user puts one, so it cannot
152
+ * which is where a framework: as opposed to the user, puts one, so it cannot
153
153
  * collide with the app's own `netlify/functions`.
154
154
  *
155
155
  * Publish `dist/client`.
@@ -173,7 +173,7 @@ export const netlifyAdapter = {
173
173
  // load an internal function at all.
174
174
  await writeFile(join(dir, 'fluixi-server.json'), JSON.stringify({ config: { path: '/*', preferStatic: true }, version: 1 }, null, 2) + '\n');
175
175
  // `preferStatic` is what keeps assets, prerendered pages and files like
176
- // `favicon.ico` off the function and it is also what would hand back the shell
176
+ // `favicon.ico` off the function: and it is also what would hand back the shell
177
177
  // for `/`. A forced redirect is the one exception the CDN honours over a file, so
178
178
  // it claims exactly that path and nothing else. Appended, so an app's own rules in
179
179
  // `public/_redirects` still match first.
@@ -51,7 +51,7 @@ export default {
51
51
  // Static first, but only for what is static. ASSETS answers "/" with index.html
52
52
  // whether that is a prerendered page or the shell, so asking about every path
53
53
  // costs an SSR app its home page. Extension means a file, prerendered means a
54
- // page, the rest is the handler's the rule \`withStaticFiles\` already uses.
54
+ // page, the rest is the handler's: the rule \`withStaticFiles\` already uses.
55
55
  const { pathname } = new URL(request.url);
56
56
  if (env && env.ASSETS && (prerendered.has(pathname) || /\\.[^/]+$/.test(pathname))) {
57
57
  const asset = await env.ASSETS.fetch(request.clone());
@@ -73,7 +73,7 @@ function apiRoutesVitePlugin(opts) {
73
73
  return {
74
74
  name: "fluixi-api",
75
75
  // Must beat node resolution: '@fluixi/start/api-routes' is a real file in this package,
76
- // so without `pre` Vite resolves the typed stub and the generated table never loads
76
+ // so without `pre` Vite resolves the typed stub and the generated table never loads ,
77
77
  // the app builds and every API route 404s.
78
78
  enforce: "pre",
79
79
  configResolved(config) {
package/dist/api.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/start v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -103,7 +103,7 @@ function apiRoutesVitePlugin(opts) {
103
103
  return {
104
104
  name: "fluixi-api",
105
105
  // Must beat node resolution: '@fluixi/start/api-routes' is a real file in this package,
106
- // so without `pre` Vite resolves the typed stub and the generated table never loads
106
+ // so without `pre` Vite resolves the typed stub and the generated table never loads ,
107
107
  // the app builds and every API route 404s.
108
108
  enforce: "pre",
109
109
  configResolved(config) {
package/dist/api.js CHANGED
@@ -91,7 +91,7 @@ export function apiRoutesVitePlugin(opts) {
91
91
  return {
92
92
  name: 'fluixi-api',
93
93
  // Must beat node resolution: '@fluixi/start/api-routes' is a real file in this package,
94
- // so without `pre` Vite resolves the typed stub and the generated table never loads
94
+ // so without `pre` Vite resolves the typed stub and the generated table never loads ,
95
95
  // the app builds and every API route 404s.
96
96
  enforce: 'pre',
97
97
  configResolved(config) {
package/dist/api.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/start v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/api.ts
4
4
  import { readdirSync, statSync } from "node:fs";
@@ -75,7 +75,7 @@ function apiRoutesVitePlugin(opts) {
75
75
  return {
76
76
  name: "fluixi-api",
77
77
  // Must beat node resolution: '@fluixi/start/api-routes' is a real file in this package,
78
- // so without `pre` Vite resolves the typed stub and the generated table never loads
78
+ // so without `pre` Vite resolves the typed stub and the generated table never loads ,
79
79
  // the app builds and every API route 404s.
80
80
  enforce: "pre",
81
81
  configResolved(config) {
@@ -73,7 +73,7 @@ function apiRoutesVitePlugin(opts) {
73
73
  return {
74
74
  name: "fluixi-api",
75
75
  // Must beat node resolution: '@fluixi/start/api-routes' is a real file in this package,
76
- // so without `pre` Vite resolves the typed stub and the generated table never loads
76
+ // so without `pre` Vite resolves the typed stub and the generated table never loads ,
77
77
  // the app builds and every API route 404s.
78
78
  enforce: "pre",
79
79
  configResolved(config) {
@@ -1,4 +1,4 @@
1
- /*! @fluixi/start v0.1.0-alpha.74 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/start v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  import {
3
3
  API_VIRTUAL_MODULE,
4
4
  apiRoutesVitePlugin,
@@ -6,7 +6,7 @@ import {
6
6
  handleApi,
7
7
  isApiPath,
8
8
  matchApiRoutes
9
- } from "./chunk-OCPCK4ZJ.mjs";
9
+ } from "./chunk-JACRXSN7.mjs";
10
10
  export {
11
11
  API_VIRTUAL_MODULE,
12
12
  apiRoutesVitePlugin,
@@ -5,7 +5,7 @@ import {
5
5
  handleApi,
6
6
  isApiPath,
7
7
  matchApiRoutes
8
- } from "./chunk-NS5GR2GX.mjs";
8
+ } from "./chunk-MTM6M3TC.mjs";
9
9
  export {
10
10
  API_VIRTUAL_MODULE,
11
11
  apiRoutesVitePlugin,
@@ -110,7 +110,7 @@ function apiRoutesVitePlugin(opts) {
110
110
  return {
111
111
  name: "fluixi-api",
112
112
  // Must beat node resolution: '@fluixi/start/api-routes' is a real file in this package,
113
- // so without `pre` Vite resolves the typed stub and the generated table never loads
113
+ // so without `pre` Vite resolves the typed stub and the generated table never loads ,
114
114
  // the app builds and every API route 404s.
115
115
  enforce: "pre",
116
116
  configResolved(config) {
@@ -179,6 +179,8 @@ function resolveConfig(config = {}) {
179
179
  middleware: config.middleware ?? "src/middleware.ts",
180
180
  ssrNoExternal: config.ssrNoExternal ?? [],
181
181
  resolve: config.resolve ?? [],
182
+ vitePlugin: config.vitePlugin ?? {},
183
+ plugins: config.plugins ?? [],
182
184
  adapter: config.adapter,
183
185
  i18n: resolveI18n(config.i18n),
184
186
  prerender: resolvePrerender(config.prerender)
@@ -374,7 +376,7 @@ function startTypesPlugin(cfg) {
374
376
  const blocks = [];
375
377
  if (cfg.i18n) blocks.push(...i18nTypeBlock(root, cfg.i18n));
376
378
  if (blocks.length === 0) return;
377
- const content = `// Auto-generated by @fluixi/start do not edit.
379
+ const content = `// Auto-generated by @fluixi/start, do not edit.
378
380
  ${blocks.join("\n")}
379
381
  `;
380
382
  const file = (0, import_node_path3.resolve)(root, "src/fluixi-start-env.d.ts");
@@ -395,10 +397,15 @@ async function fluixiPlugins(cfg) {
395
397
  // app has no way to say where an unimported tag comes from.
396
398
  //
397
399
  // `fluixi()` and not `createVitePlugin()`: the latter is the bare compiler integration,
398
- // and the reactive graph agent, source marks, /__fluixi/graph is composed on top of
400
+ // and the reactive graph: agent, source marks, /__fluixi/graph, is composed on top of
399
401
  // it by the former. A start app got no graph at all until this changed.
400
- fluixi({ resolve: cfg.resolve })
402
+ // Everything the app declared for the compiler, with `resolve` still usable on its
403
+ // own because it is the one most apps set. A start app never writes
404
+ // `fluixi()` itself, so without this passthrough the plugin's other options
405
+ // (propsDestructure and the rest) had nowhere to be declared.
406
+ fluixi({ ...cfg.vitePlugin ?? {}, ...cfg.resolve ? { resolve: cfg.resolve } : {} })
401
407
  ];
408
+ if (cfg.plugins?.length) plugins.push(...cfg.plugins);
402
409
  if (cfg.i18n) plugins.push(i18nVitePlugin(cfg.i18n));
403
410
  const { apiRoutesVitePlugin: apiRoutesVitePlugin2 } = await Promise.resolve().then(() => (init_api(), api_exports));
404
411
  plugins.push(apiRoutesVitePlugin2({ dir: cfg.apiDir }));
@@ -560,14 +567,14 @@ async function loadPreloader(cfg) {
560
567
  }
561
568
  var GENERATED_SUBPATHS = /* @__PURE__ */ new Set(["./routes", "./server-fns", "./api-routes"]);
562
569
  function ssrBuildOptions(cfg) {
563
- const noExternal = cfg.ssrNoExternal.length ? cfg.ssrNoExternal : void 0;
570
+ const noExternal = [.../* @__PURE__ */ new Set(["@fluixi/core", ...cfg.ssrNoExternal])];
564
571
  const mode = cfg.adapter?.bundle;
565
572
  if (mode === "inline") return { noExternal: true };
566
573
  if (mode !== "external") return { noExternal };
567
574
  const external = frameworkDeps(cfg.root).filter((name) => !cfg.ssrNoExternal.includes(name)).flatMap((name) => withSubpaths(cfg.root, name));
568
575
  if (!external.length) {
569
576
  console.warn(
570
- ` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no fluixi or @fluixi/* dependency was found in ${(0, import_node_path4.join)(cfg.root, "package.json")} bundling everything.`
577
+ ` fluixi: adapter "${cfg.adapter?.name}" builds an externalized server, but no fluixi or @fluixi/* dependency was found in ${(0, import_node_path4.join)(cfg.root, "package.json")}, bundling everything.`
571
578
  );
572
579
  }
573
580
  return { noExternal, external: external.length ? external : void 0 };
@@ -848,7 +855,7 @@ async function bundleEntry(cfg, plugins, source, outFile) {
848
855
  output: {
849
856
  entryFileNames: (0, import_node_path6.basename)(outFile),
850
857
  // One file, no chunks. A lazy route would otherwise be split out beside
851
- // the entry and for Cloudflare that directory is the published one, so
858
+ // the entry: and for Cloudflare that directory is the published one, so
852
859
  // every server chunk would be a public download.
853
860
  inlineDynamicImports: true
854
861
  }
@@ -27,8 +27,8 @@ export async function build(config = {}) {
27
27
  logLevel: 'warn',
28
28
  build: { outDir: 'dist/client', ssrManifest: true, emptyOutDir: true },
29
29
  });
30
- // SSR builds a server bundle that renders HTML. A SPA may still ship one only for server
31
- // functions / middleware so build it when the entry exists; a pure static SPA skips it.
30
+ // SSR builds a server bundle that renders HTML. A SPA may still ship one, only for server
31
+ // functions / middleware: so build it when the entry exists; a pure static SPA skips it.
32
32
  const serverEntrySrc = resolve(cfg.root, cfg.serverEntry);
33
33
  if (cfg.ssr || existsSync(serverEntrySrc)) {
34
34
  step(`server bundle${bundleNote(cfg)}`);
@@ -71,7 +71,7 @@ export async function build(config = {}) {
71
71
  process.stdout.write('\n');
72
72
  await prerender(config);
73
73
  }
74
- // The deploy target's own output layout a worker entry, a function manifest, a
74
+ // The deploy target's own output layout: a worker entry, a function manifest, a
75
75
  // routing config. Last, so everything it wraps or copies already exists.
76
76
  if (cfg.adapter?.build) {
77
77
  step(`${cfg.adapter.name} output`);
@@ -132,7 +132,7 @@ async function collectRouteAssets(cfg) {
132
132
  * Bundle a generated platform entry into one self-contained file.
133
133
  *
134
134
  * The entry is written next to its output so a relative import of the server bundle
135
- * resolves, then removed a stray `.fluixi-entry.js` in dist would be served as a
135
+ * resolves, then removed: a stray `.fluixi-entry.js` in dist would be served as a
136
136
  * static asset on every one of these platforms.
137
137
  */
138
138
  async function bundleEntry(cfg, plugins, source, outFile) {
@@ -156,7 +156,7 @@ async function bundleEntry(cfg, plugins, source, outFile) {
156
156
  output: {
157
157
  entryFileNames: basename(outFile),
158
158
  // One file, no chunks. A lazy route would otherwise be split out beside
159
- // the entry and for Cloudflare that directory is the published one, so
159
+ // the entry: and for Cloudflare that directory is the published one, so
160
160
  // every server chunk would be a public download.
161
161
  inlineDynamicImports: true,
162
162
  },
@@ -168,7 +168,7 @@ async function bundleEntry(cfg, plugins, source, outFile) {
168
168
  await rm(temp, { force: true });
169
169
  }
170
170
  }
171
- /** `server bundle (node · external)` the output shape is not obvious from the file. */
171
+ /** `server bundle (node · external)`: the output shape is not obvious from the file. */
172
172
  function bundleNote(cfg) {
173
173
  const adapter = cfg.adapter;
174
174
  if (!adapter?.bundle)