@qwik.dev/router 2.0.0-beta.37 → 2.0.0-beta.39

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 (35) hide show
  1. package/lib/adapters/cloudflare-pages/vite/index.mjs +2 -2
  2. package/lib/adapters/shared/vite/index.d.ts +3 -4
  3. package/lib/adapters/shared/vite/index.mjs +158 -143
  4. package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
  5. package/lib/chunks/fs.mjs +6 -2
  6. package/lib/chunks/head.qwik.mjs +814 -93
  7. package/lib/chunks/request-body-limit.mjs +37 -0
  8. package/lib/chunks/request-path.mjs +2 -2
  9. package/lib/chunks/routes.mjs +47 -0
  10. package/lib/chunks/server-error.mjs +19 -0
  11. package/lib/chunks/system.mjs +2 -1
  12. package/lib/chunks/use-functions.qwik.mjs +1 -1
  13. package/lib/chunks/{worker-thread.qwik.mjs → user-response.mjs} +1053 -1749
  14. package/lib/chunks/worker-thread.mjs +317 -0
  15. package/lib/index.d.ts +89 -55
  16. package/lib/index.qwik.mjs +178 -100
  17. package/lib/middleware/azure-swa/index.mjs +13 -9
  18. package/lib/middleware/cloudflare-pages/index.mjs +2 -2
  19. package/lib/middleware/deno/index.d.ts +2 -0
  20. package/lib/middleware/deno/index.mjs +2 -1
  21. package/lib/middleware/netlify-edge/index.mjs +2 -2
  22. package/lib/middleware/node/index.d.ts +9 -1
  23. package/lib/middleware/node/index.mjs +28 -3
  24. package/lib/middleware/request-handler/index.d.ts +9 -10
  25. package/lib/middleware/request-handler/index.mjs +26 -1105
  26. package/lib/middleware/vercel-edge/index.mjs +2 -2
  27. package/lib/ssg/index.d.ts +2 -10
  28. package/lib/ssg/index.mjs +10 -50
  29. package/lib/vite/index.d.ts +8 -0
  30. package/lib/vite/index.mjs +406 -117
  31. package/package.json +5 -4
  32. package/lib/chunks/action-handler.mjs +0 -782
  33. package/lib/chunks/deepFreeze.qwik.mjs +0 -608
  34. package/lib/chunks/error-handler.mjs +0 -57
  35. package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
@@ -39,11 +39,11 @@ function cloudflarePagesAdapter(opts = {}) {
39
39
  publicDir: false
40
40
  };
41
41
  },
42
- async generate({ clientOutDir, serverOutDir, basePathname, assetsDir }) {
42
+ async generate({ clientOutDir, serverOutDir, basePathname }) {
43
43
  const routesJsonPath = join(clientOutDir, "_routes.json");
44
44
  const hasRoutesJson = fs.existsSync(routesJsonPath);
45
45
  if (!hasRoutesJson && opts.functionRoutes !== false) {
46
- const pathName = ensureSlash(assetsDir ? join(basePathname, assetsDir) : basePathname);
46
+ const pathName = ensureSlash(basePathname);
47
47
  const routesJson = {
48
48
  version: 1,
49
49
  include: [
@@ -1,6 +1,6 @@
1
- import type { Plugin as Plugin_2 } from 'vite';
1
+ import { Plugin as Plugin_2 } from 'vite';
2
2
  import type { SsgRenderOptions } from 'packages/qwik-router/src/ssg';
3
- import type { UserConfig } from 'vite';
3
+ import { UserConfig } from 'vite';
4
4
 
5
5
  /** @public */
6
6
  export declare interface AdapterSSGOptions extends Omit<SsgRenderOptions, 'outDir' | 'origin'> {
@@ -75,7 +75,7 @@ export declare interface ServerAdapterOptions {
75
75
  }
76
76
 
77
77
  /** @public */
78
- export declare function viteAdapter(opts: ViteAdapterPluginOptions): Plugin_2<any>[];
78
+ export declare function viteAdapter(opts: ViteAdapterPluginOptions): Plugin_2<never>[];
79
79
 
80
80
  /** @public */
81
81
  declare interface ViteAdapterPluginOptions {
@@ -93,7 +93,6 @@ declare interface ViteAdapterPluginOptions {
93
93
  serverOutDir: string;
94
94
  basePathname: string;
95
95
  routes: BuiltRoute[];
96
- assetsDir?: string;
97
96
  warn: (message: string) => void;
98
97
  error: (message: string) => void;
99
98
  }) => Promise<void>;
@@ -1,67 +1,21 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { readFile, unlink, rm } from 'node:fs/promises';
1
3
  import { join, resolve, dirname, basename } from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
4
  import fs from 'node:fs';
4
- import { g as getErrorHtml } from '../../../chunks/error-handler.mjs';
5
5
  import { L as LOADER_REGEX } from '../../../chunks/request-path.mjs';
6
6
  import { e as ensureSlash } from '../../../chunks/pathname.mjs';
7
7
 
8
- const SSG_WORKER_IMPORT_PREFIX = "@qwik-router-ssg-worker/";
9
- function ssgWorkerImportPlugin() {
10
- return {
11
- name: "qwik-router-ssg-worker-imports",
12
- enforce: "pre",
13
- async resolveId(id, importer) {
14
- if (!id.startsWith(SSG_WORKER_IMPORT_PREFIX)) {
15
- return null;
16
- }
17
- const subpath = id.slice(SSG_WORKER_IMPORT_PREFIX.length);
18
- const sourceId = fileURLToPath(new URL(`../../${subpath}`, import.meta.url));
19
- const resolved = await this.resolve(sourceId, importer, {
20
- skipSelf: true
21
- });
22
- return `${(resolved ?? {
23
- id: sourceId
24
- }).id}?ssg-worker`;
25
- }
26
- };
27
- }
28
-
29
- function createNotFoundPathsCode(basePathname, notFounds) {
30
- notFounds.sort((a, b) => {
31
- if (a[0].length > b[0].length) {
32
- return -1;
33
- }
34
- if (a[0].length < b[0].length) {
35
- return 1;
36
- }
37
- if (a[0] < b[0]) {
38
- return -1;
39
- }
40
- if (a[0] > b[0]) {
41
- return 1;
42
- }
43
- return 0;
44
- });
45
- if (!notFounds.some((r) => r[0] === basePathname)) {
46
- const html = getErrorHtml(404, "Resource Not Found");
47
- notFounds.push([
48
- basePathname,
49
- html
50
- ]);
51
- }
52
- return JSON.stringify(notFounds, null, 2).slice(1, -1);
53
- }
54
8
  function createStaticPathsCode(staticPaths) {
55
9
  return JSON.stringify(Array.from(new Set(staticPaths)).sort()).slice(1, -1);
56
10
  }
57
- const injectStatics = async (staticPathsCode, notFoundPathsCode, outDir) => {
11
+ const injectStatics = async (staticPathsCode, outDir) => {
58
12
  const promises = /* @__PURE__ */ new Set();
59
13
  const doReplace = async (path) => {
60
14
  const code = await fs.promises.readFile(path, "utf-8");
61
15
  let replaced = false;
62
- const newCode = code.replace(/(['"])__QWIK_ROUTER_(STATIC_PATHS|NOT_FOUND)_ARRAY__\1/g, (_, _quote, type) => {
16
+ const newCode = code.replace(/(['"])__QWIK_ROUTER_STATIC_PATHS_ARRAY__\1/g, () => {
63
17
  replaced = true;
64
- return type === "STATIC_PATHS" ? staticPathsCode : notFoundPathsCode;
18
+ return staticPathsCode;
65
19
  });
66
20
  if (replaced) {
67
21
  await fs.promises.writeFile(path, newCode);
@@ -95,25 +49,24 @@ async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths,
95
49
  pathNameBase + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/"
96
50
  ]);
97
51
  const staticPaths = new Set(userStaticPaths.map(ensureSlash));
98
- const notFounds = [];
99
52
  const loadItem = async (fsDir, fsName, pathname) => {
100
53
  pathname = ensureSlash(pathname);
101
54
  if (ignorePathnames.has(pathname)) {
102
55
  return;
103
56
  }
104
57
  const fsPath = join(fsDir, fsName);
105
- if (fsName === "index.html" || LOADER_REGEX.test("/" + fsName)) {
58
+ if (fsName === "index.html") {
106
59
  if (!staticPaths.has(pathname) && cleanStatic) {
107
60
  await fs.promises.unlink(fsPath);
108
61
  }
109
62
  return;
110
63
  }
111
- if (fsName === "404.html") {
112
- const notFoundHtml = await fs.promises.readFile(fsPath, "utf-8");
113
- notFounds.push([
114
- pathname,
115
- notFoundHtml
116
- ]);
64
+ if (LOADER_REGEX.test("/" + fsName)) {
65
+ if (staticPaths.has(pathname)) {
66
+ staticPaths.add(pathname + fsName);
67
+ } else if (cleanStatic) {
68
+ await fs.promises.unlink(fsPath);
69
+ }
117
70
  return;
118
71
  }
119
72
  const stat = await fs.promises.stat(fsPath);
@@ -130,19 +83,21 @@ async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths,
130
83
  if (fs.existsSync(clientOutDir)) {
131
84
  await loadDir(clientOutDir, pathName);
132
85
  }
133
- const notFoundPathsCode = createNotFoundPathsCode(pathName, notFounds);
134
86
  const staticPathsCode = createStaticPathsCode(staticPaths);
135
- await injectStatics(staticPathsCode, notFoundPathsCode, serverOutDir);
87
+ await injectStatics(staticPathsCode, serverOutDir);
136
88
  }
137
89
 
138
90
  const QWIK_SSG_ENTRY_ID = "@qwik-ssg-entry";
139
91
  const QWIK_SSG_ENTRY_RESOLVED = "\0@qwik-ssg-entry";
92
+ const QWIK_SSG_WORKER_ENTRY_ID = "@qwik-ssg-worker-entry";
93
+ const QWIK_SSG_WORKER_ENTRY_RESOLVED = "\0@qwik-ssg-worker-entry";
140
94
  function viteAdapter(opts) {
141
95
  let qwikRouterPlugin = null;
142
96
  let qwikVitePlugin = null;
143
- let serverOutDir = null;
144
97
  let viteCommand;
98
+ let buildAppRan = false;
145
99
  const outputEntries = [];
100
+ const ssgOutDirFor = (root) => join(resolve(root), "node_modules", ".cache", `qwik-router-ssg-${process.pid}`);
146
101
  const plugin = {
147
102
  name: `vite-plugin-qwik-router-ssg-${opts.name}`,
148
103
  enforce: "post",
@@ -155,30 +110,78 @@ function viteAdapter(opts) {
155
110
  "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "production"),
156
111
  ...config.define
157
112
  };
113
+ config.builder ??= {};
114
+ if (opts.ssg !== null) {
115
+ config.environments = {
116
+ ...config.environments,
117
+ // Same server externalization as `ssr` (via the router/qwik `configEnvironment` hooks);
118
+ // only the build graph and outDir differ. run-ssg externalizes node_modules deps and
119
+ // resolves them at render time, so native/CJS packages (e.g. a database client) are not
120
+ // force-bundled.
121
+ ssg: {
122
+ consumer: "server",
123
+ build: {
124
+ ssr: true,
125
+ outDir: ssgOutDirFor(config.root ?? process.cwd()),
126
+ emptyOutDir: true,
127
+ // Throwaway output, executed once and deleted — skip minify/sourcemap work.
128
+ minify: false,
129
+ sourcemap: false
130
+ }
131
+ }
132
+ };
133
+ }
158
134
  return config;
159
135
  },
136
+ configEnvironment(name, environmentOptions) {
137
+ if (name === "ssg") {
138
+ environmentOptions.build = {
139
+ ...environmentOptions.build,
140
+ rollupOptions: {
141
+ ...environmentOptions.build?.rollupOptions,
142
+ input: {}
143
+ }
144
+ };
145
+ }
146
+ },
160
147
  configResolved(config) {
161
148
  viteCommand = config.command;
162
149
  qwikRouterPlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik-router");
163
150
  if (!qwikRouterPlugin) {
164
151
  throw new Error("Missing vite-plugin-qwik-router");
165
152
  }
153
+ qwikRouterPlugin.api?._setSsgRoutes?.(opts.ssg?.include, opts.ssg?.exclude);
166
154
  qwikVitePlugin = config.plugins.find((p) => p.name === "vite-plugin-qwik");
167
155
  if (!qwikVitePlugin) {
168
156
  throw new Error("Missing vite-plugin-qwik");
169
157
  }
170
- serverOutDir = config.build.outDir;
171
158
  },
172
159
  resolveId(id) {
173
160
  if (id === QWIK_SSG_ENTRY_ID) {
174
161
  return QWIK_SSG_ENTRY_RESOLVED;
175
162
  }
163
+ if (id === QWIK_SSG_WORKER_ENTRY_ID) {
164
+ return QWIK_SSG_WORKER_ENTRY_RESOLVED;
165
+ }
176
166
  },
177
167
  load(id) {
168
+ if (id === QWIK_SSG_WORKER_ENTRY_RESOLVED) {
169
+ const { srcDir } = qwikVitePlugin.api.getOptions();
170
+ return [
171
+ `import render from '${srcDir}/entry.ssr';`,
172
+ `import qwikRouterConfig from '@qwik-router-config';`,
173
+ `import { startWorker } from '@qwik.dev/router/ssg';`,
174
+ // Fire-and-forget (no top-level await): avoids a Rollup inlined-dynamic-import init-order
175
+ // bug on the SSR target. See rollup/rollup#4166.
176
+ `startWorker({ render, qwikRouterConfig }).catch((err) => {`,
177
+ ` console.error(err);`,
178
+ ` process.exit(1);`,
179
+ `});`
180
+ ].join("\n");
181
+ }
178
182
  if (id !== QWIK_SSG_ENTRY_RESOLVED) {
179
183
  return;
180
184
  }
181
- const { srcDir } = qwikVitePlugin.api.getOptions();
182
185
  const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
183
186
  const basePathname = qwikRouterPlugin.api.getBasePathname();
184
187
  const rootDir = qwikVitePlugin.api.getRootDir() ?? void 0;
@@ -212,47 +215,43 @@ function viteAdapter(opts) {
212
215
  }
213
216
  }
214
217
  return [
215
- `import { isMainThread } from 'node:worker_threads';`,
216
- `import render from '${srcDir}/entry.ssr';`,
217
218
  `import qwikRouterConfig from '@qwik-router-config';`,
218
- `import { runSsg, startWorker } from '@qwik.dev/router/ssg';`,
219
+ `import { runSsg } from '@qwik.dev/router/ssg';`,
219
220
  ``,
220
221
  `const ssgOpts = ${JSON.stringify(ssgOpts)};`,
221
222
  ``,
222
223
  `// Parse --quiet / --debug CLI flags`,
223
- `const args = isMainThread ? process.argv.slice(2) : [];`,
224
+ `const args = process.argv.slice(2);`,
224
225
  `if (args.includes('--quiet')) ssgOpts.log = 'quiet';`,
225
226
  `if (args.includes('--debug')) ssgOpts.log = 'debug';`,
226
227
  ``,
227
- // Fire-and-forget instead of top-level await. On the worker/edge SSR target Vite
228
- // inlines dynamic imports, and Rollup then reads the inlined `./system` namespace
229
- // before it is initialized across a top-level await. See rollup/rollup#4166.
230
- // runSsg/startWorker keep the process alive (worker handles) and call process.exit.
231
- `const ssgRun = isMainThread`,
232
- ` ? runSsg({`,
233
- ` render,`,
234
- ` qwikRouterConfig,`,
235
- ` workerFilePath: new URL(import.meta.url).href,`,
236
- ` ...ssgOpts,`,
237
- ` })`,
238
- ` : startWorker({ render, qwikRouterConfig });`,
239
- `ssgRun.catch((err) => {`,
228
+ // Fire-and-forget; see rollup/rollup#4166 above. The worker entry is a sibling file.
229
+ `runSsg({`,
230
+ ` qwikRouterConfig,`,
231
+ ` workerFilePath: new URL('./run-ssg-worker.js', import.meta.url).href,`,
232
+ ` ...ssgOpts,`,
233
+ `}).catch((err) => {`,
240
234
  ` console.error(err);`,
241
235
  ` process.exit(1);`,
242
236
  `});`
243
237
  ].join("\n");
244
238
  },
245
239
  buildStart() {
246
- if (this.environment.config.consumer === "server" && opts.ssg !== null && viteCommand === "build" && serverOutDir) {
240
+ if (this.environment.name === "ssg" && viteCommand === "build") {
247
241
  this.emitFile({
248
242
  id: QWIK_SSG_ENTRY_ID,
249
243
  type: "chunk",
250
244
  fileName: "run-ssg.js"
251
245
  });
246
+ this.emitFile({
247
+ id: QWIK_SSG_WORKER_ENTRY_ID,
248
+ type: "chunk",
249
+ fileName: "run-ssg-worker.js"
250
+ });
252
251
  }
253
252
  },
254
253
  generateBundle(_, bundles) {
255
- if (this.environment.config.consumer === "server") {
254
+ if (this.environment.name === "ssr") {
256
255
  outputEntries.length = 0;
257
256
  for (const fileName in bundles) {
258
257
  const chunk = bundles[fileName];
@@ -260,77 +259,93 @@ function viteAdapter(opts) {
260
259
  outputEntries.push(fileName);
261
260
  }
262
261
  }
262
+ if (opts.ssg !== null && viteCommand === "build" && !buildAppRan) {
263
+ this.warn("Qwik Router SSG was skipped: the `ssr` environment was built directly instead of through the Vite app builder, so no pages were prerendered. Build with the Qwik CLI or `createBuilder(config).buildApp()` (a plain `vite build` does this automatically).");
264
+ }
263
265
  }
264
266
  },
265
- closeBundle: {
266
- sequential: true,
267
- async handler() {
268
- if (this.environment.config.consumer === "server" && serverOutDir && qwikRouterPlugin?.api && qwikVitePlugin?.api) {
269
- const staticPaths = opts.staticPaths || [];
270
- const routes = qwikRouterPlugin.api.getRoutes();
271
- const basePathname = qwikRouterPlugin.api.getBasePathname();
272
- const clientOutDir = qwikVitePlugin.api.getClientOutDir();
273
- const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
274
- const assetsDir = qwikVitePlugin.api.getAssetsDir();
275
- if (opts.ssg !== null && clientOutDir && clientPublicOutDir) {
276
- const runSsgPath = join(serverOutDir, "run-ssg.js");
277
- const { spawn } = await import('node:child_process');
278
- const ssgExitCode = await new Promise((resolve2, reject) => {
279
- const child = spawn(process.execPath, [
280
- runSsgPath
281
- ], {
282
- stdio: [
283
- "ignore",
284
- "inherit",
285
- "inherit"
286
- ],
287
- env: {
288
- ...process.env,
289
- NODE_ENV: process.env.NODE_ENV || "production"
290
- }
291
- });
292
- child.on("close", resolve2);
293
- child.on("error", reject);
294
- });
295
- if (ssgExitCode !== 0) {
296
- const err = new Error(`Error while running SSG from "${opts.name}" adapter. At least one path failed to render.`);
297
- err.stack = void 0;
298
- this.error(err);
299
- }
300
- const fs = await import('node:fs');
301
- const staticPathsFile = join(clientPublicOutDir, "_static-paths.json");
302
- try {
303
- const content = await fs.promises.readFile(staticPathsFile, "utf-8");
304
- staticPaths.push(...JSON.parse(content));
305
- await fs.promises.unlink(staticPathsFile);
306
- } catch {
267
+ // Build the deployed server (`ssr`) and the separate `ssg` graph (run-ssg) — two graphs, so
268
+ // prerendered route code never reaches the `ssr` bundle — then render the pages and post-build.
269
+ // (The client builds in its own `vite build`.)
270
+ async buildApp(builder) {
271
+ buildAppRan = true;
272
+ const ssr = builder.environments.ssr;
273
+ if (ssr) {
274
+ await builder.build(ssr);
275
+ }
276
+ const serverOutDir = ssr?.config.build.outDir;
277
+ if (!serverOutDir || !qwikRouterPlugin?.api || !qwikVitePlugin?.api) {
278
+ return;
279
+ }
280
+ const log = builder.config.logger;
281
+ const staticPaths = opts.staticPaths || [];
282
+ const routes = qwikRouterPlugin.api.getRoutes();
283
+ const basePathname = qwikRouterPlugin.api.getBasePathname();
284
+ const clientOutDir = qwikVitePlugin.api.getClientOutDir();
285
+ const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
286
+ const ssgEnv = builder.environments.ssg;
287
+ const ssgOutDir = ssgOutDirFor(builder.config.root);
288
+ if (ssgEnv && clientOutDir && clientPublicOutDir) {
289
+ await builder.build(ssgEnv);
290
+ const runSsgPath = join(ssgOutDir, "run-ssg.js");
291
+ const ssgExitCode = await new Promise((res, reject) => {
292
+ const child = spawn(process.execPath, [
293
+ runSsgPath
294
+ ], {
295
+ stdio: [
296
+ "ignore",
297
+ "inherit",
298
+ "inherit"
299
+ ],
300
+ env: {
301
+ ...process.env,
302
+ NODE_ENV: process.env.NODE_ENV || "production"
307
303
  }
304
+ });
305
+ child.on("close", res);
306
+ child.on("error", reject);
307
+ });
308
+ if (ssgExitCode !== 0) {
309
+ throw new Error(`Error while running SSG from "${opts.name}" adapter. At least one path failed to render.`);
310
+ }
311
+ const staticPathsFile = join(clientPublicOutDir, "_static-paths.json");
312
+ try {
313
+ staticPaths.push(...JSON.parse(await readFile(staticPathsFile, "utf-8")));
314
+ await unlink(staticPathsFile);
315
+ } catch {
316
+ }
317
+ if (process.env.QWIK_ROUTER_KEEP_SSG_BUILD) {
318
+ log.warn(`SSG build kept at ${ssgOutDir}`);
319
+ } else {
320
+ await rm(ssgOutDir, {
321
+ recursive: true,
322
+ force: true
323
+ });
324
+ }
325
+ }
326
+ await postBuild(clientPublicOutDir, serverOutDir, basePathname, staticPaths, !!opts.cleanStaticGenerated);
327
+ if (typeof opts.generate === "function") {
328
+ await opts.generate({
329
+ outputEntries,
330
+ serverOutDir,
331
+ clientOutDir,
332
+ clientPublicOutDir,
333
+ basePathname,
334
+ routes,
335
+ warn: (message) => log.warn(message),
336
+ error: (message) => {
337
+ throw new Error(message);
308
338
  }
309
- await postBuild(clientPublicOutDir, serverOutDir, assetsDir ? join(basePathname, assetsDir) : basePathname, staticPaths, !!opts.cleanStaticGenerated);
310
- if (typeof opts.generate === "function") {
311
- await opts.generate({
312
- outputEntries,
313
- serverOutDir,
314
- clientOutDir,
315
- clientPublicOutDir,
316
- basePathname,
317
- routes,
318
- assetsDir,
319
- warn: (message) => this.warn(message),
320
- error: (message) => this.error(message)
321
- });
322
- }
323
- this.warn(`
339
+ });
340
+ }
341
+ log.warn(`
324
342
  ==============================================
325
343
  Note: Make sure that you are serving the built files with proper cache headers.
326
344
  See https://qwik.dev/docs/deployments/#cache-headers for more information.
327
345
  ==============================================`);
328
- }
329
- }
330
346
  }
331
347
  };
332
348
  return [
333
- ssgWorkerImportPlugin(),
334
349
  plugin
335
350
  ];
336
351
  }
@@ -0,0 +1,3 @@
1
+ const devPreloadedRouteLoaders = globalThis[/* @__PURE__ */ Symbol.for("devPreloadedRouteLoaders")] ??= /* @__PURE__ */ new WeakMap();
2
+
3
+ export { devPreloadedRouteLoaders as d };
package/lib/chunks/fs.mjs CHANGED
@@ -123,8 +123,12 @@ function isServiceWorkerName(extlessName) {
123
123
  function isEntryName(extlessName) {
124
124
  return extlessName === "entry";
125
125
  }
126
+ function errorBoundaryName(extlessName) {
127
+ const match = /^(error|404)(?:|!|@.+)$/.exec(extlessName);
128
+ return match ? match[1] : void 0;
129
+ }
126
130
  function isErrorName(extlessName) {
127
- return extlessName === "error" || extlessName === "404";
131
+ return errorBoundaryName(extlessName) !== void 0;
128
132
  }
129
133
  function isGroupedLayoutName(dirName, warn = true) {
130
134
  return dirName.startsWith("(") && dirName.endsWith(")");
@@ -139,4 +143,4 @@ function getPathnameFromDirPath(opts, dirPath) {
139
143
  return pathname;
140
144
  }
141
145
 
142
- export { isErrorName as a, isLayoutModule as b, isEntryName as c, isMenuFileName as d, isServiceWorkerName as e, isPageModuleExt as f, getExtension as g, isModuleExt as h, isIndexModule as i, isMarkdownExt as j, normalizePath as k, getPathnameFromDirPath as l, getMenuPathname as m, normalizePathSlash as n, createFileId as o, parseRouteIndexName as p, isPluginModule as q, removeExtension as r, isPageExt as s };
146
+ export { isErrorName as a, isPageModuleExt as b, isModuleExt as c, isMarkdownExt as d, isLayoutModule as e, isEntryName as f, getExtension as g, isMenuFileName as h, isIndexModule as i, isServiceWorkerName as j, normalizePath as k, getPathnameFromDirPath as l, getMenuPathname as m, normalizePathSlash as n, createFileId as o, parseRouteIndexName as p, errorBoundaryName as q, removeExtension as r, isPluginModule as s, isPageExt as t };