@qwik.dev/router 2.0.0-beta.28 → 2.0.0-beta.29

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 (42) hide show
  1. package/lib/adapters/azure-swa/vite/index.mjs +31 -36
  2. package/lib/adapters/bun-server/vite/index.mjs +0 -3
  3. package/lib/adapters/cloud-run/vite/index.mjs +0 -3
  4. package/lib/adapters/cloudflare-pages/vite/index.mjs +15 -9
  5. package/lib/adapters/deno-server/vite/index.mjs +7 -5
  6. package/lib/adapters/netlify-edge/vite/index.mjs +13 -23
  7. package/lib/adapters/node-server/vite/index.mjs +0 -3
  8. package/lib/adapters/shared/vite/index.d.ts +1 -7
  9. package/lib/adapters/shared/vite/index.mjs +164 -136
  10. package/lib/adapters/ssg/vite/index.mjs +3 -4
  11. package/lib/adapters/vercel-edge/vite/index.mjs +25 -9
  12. package/lib/chunks/error-handler.mjs +26 -26
  13. package/lib/chunks/fs.mjs +28 -138
  14. package/lib/chunks/http-error.qwik.mjs +27 -0
  15. package/lib/chunks/not-found-wrapper.qwik.mjs +25 -0
  16. package/lib/chunks/pathname.mjs +105 -0
  17. package/lib/chunks/routing.qwik.mjs +592 -216
  18. package/lib/chunks/system.mjs +328 -0
  19. package/lib/chunks/use-functions.qwik.mjs +35 -0
  20. package/lib/chunks/worker-thread.mjs +271 -0
  21. package/lib/index.d.ts +136 -102
  22. package/lib/index.qwik.mjs +699 -751
  23. package/lib/middleware/aws-lambda/index.mjs +7 -1
  24. package/lib/middleware/azure-swa/index.mjs +7 -2
  25. package/lib/middleware/bun/index.mjs +20 -5
  26. package/lib/middleware/cloudflare-pages/index.mjs +8 -2
  27. package/lib/middleware/deno/index.mjs +19 -5
  28. package/lib/middleware/netlify-edge/index.mjs +8 -2
  29. package/lib/middleware/node/index.mjs +10 -14
  30. package/lib/middleware/request-handler/index.d.ts +82 -12
  31. package/lib/middleware/request-handler/index.mjs +661 -524
  32. package/lib/middleware/vercel-edge/index.mjs +8 -2
  33. package/lib/modules.d.ts +7 -4
  34. package/lib/ssg/index.d.ts +48 -16
  35. package/lib/ssg/index.mjs +320 -7
  36. package/lib/vite/index.d.ts +6 -0
  37. package/lib/vite/index.mjs +1098 -641
  38. package/modules.d.ts +7 -4
  39. package/package.json +4 -4
  40. package/lib/chunks/format-error.mjs +0 -137
  41. package/lib/chunks/index.mjs +0 -896
  42. package/lib/chunks/types.qwik.mjs +0 -22
@@ -1,7 +1,6 @@
1
- import { createAsync$, isBrowser } from '@qwik.dev/core';
2
- import { p } from '@qwik.dev/core/preloader';
1
+ import { createAsyncQrl, inlinedQrl, _captures, isBrowser, withLocale } from '@qwik.dev/core';
3
2
  import { _deserialize, _UNINITIALIZED } from '@qwik.dev/core/internal';
4
- import { R as RouteDataProp, M as MenuDataProp } from './types.qwik.mjs';
3
+ import { p } from '@qwik.dev/core/preloader';
5
4
 
6
5
  const MODULE_CACHE = /* @__PURE__ */ new WeakMap();
7
6
  const CLIENT_DATA_CACHE = /* @__PURE__ */ new Map();
@@ -13,6 +12,35 @@ const Q_ROUTE = "q:route";
13
12
  const DEFAULT_LOADERS_SERIALIZATION_STRATEGY = globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__ || "never";
14
13
 
15
14
  const MAX_Q_DATA_RETRY_COUNT = 3;
15
+ const getFetchOptions = (action, noCache) => {
16
+ const actionData = action?.data;
17
+ if (!actionData) {
18
+ if (noCache) {
19
+ return {
20
+ cache: "no-cache",
21
+ headers: {
22
+ "Cache-Control": "no-cache",
23
+ Pragma: "no-cache"
24
+ }
25
+ };
26
+ }
27
+ return void 0;
28
+ }
29
+ if (actionData instanceof FormData) {
30
+ return {
31
+ method: "POST",
32
+ body: actionData
33
+ };
34
+ } else {
35
+ return {
36
+ method: "POST",
37
+ body: JSON.stringify(actionData),
38
+ headers: {
39
+ "Content-Type": "application/json; charset=UTF-8"
40
+ }
41
+ };
42
+ }
43
+ };
16
44
  const loadClientData = async (url, opts, retryCount = 0) => {
17
45
  const pagePathname = url.pathname;
18
46
  const pageSearch = url.search;
@@ -64,7 +92,10 @@ const loadClientData = async (url, opts, retryCount = 0) => {
64
92
  const { action } = opts;
65
93
  const actionData = clientData.loaders[action.id];
66
94
  resolveFn = () => {
67
- action.resolve({ status: rsp.status, result: actionData });
95
+ action.resolve({
96
+ status: rsp.status,
97
+ result: actionData
98
+ });
68
99
  };
69
100
  }
70
101
  return clientData;
@@ -88,35 +119,6 @@ const loadClientData = async (url, opts, retryCount = 0) => {
88
119
  return v;
89
120
  });
90
121
  };
91
- const getFetchOptions = (action, noCache) => {
92
- const actionData = action?.data;
93
- if (!actionData) {
94
- if (noCache) {
95
- return {
96
- cache: "no-cache",
97
- headers: {
98
- "Cache-Control": "no-cache",
99
- Pragma: "no-cache"
100
- }
101
- };
102
- }
103
- return void 0;
104
- }
105
- if (actionData instanceof FormData) {
106
- return {
107
- method: "POST",
108
- body: actionData
109
- };
110
- } else {
111
- return {
112
- method: "POST",
113
- body: JSON.stringify(actionData),
114
- headers: {
115
- "Content-Type": "application/json; charset=UTF-8"
116
- }
117
- };
118
- }
119
- };
120
122
 
121
123
  const toPath = (url) => url.pathname + url.search + url.hash;
122
124
  const toUrl = (url, baseUrl) => new URL(url, baseUrl.href);
@@ -169,23 +171,35 @@ const isPromise = (value) => {
169
171
  return value && typeof value.then === "function";
170
172
  };
171
173
  const createLoaderSignal = (loadersObject, loaderId, url, serializationStrategy, container) => {
172
- return createAsync$(
173
- async () => {
174
- if (isBrowser && loadersObject[loaderId] === _UNINITIALIZED) {
175
- const data = await loadClientData(url, {
176
- loaderIds: [loaderId]
177
- });
178
- loadersObject[loaderId] = data?.loaders[loaderId] ?? _UNINITIALIZED;
179
- }
180
- return loadersObject[loaderId];
181
- },
182
- {
183
- container,
184
- serializationStrategy
174
+ return createAsyncQrl(/* @__PURE__ */ inlinedQrl(async () => {
175
+ const loaderId2 = _captures[0], loadersObject2 = _captures[1], url2 = _captures[2];
176
+ if (isBrowser && loadersObject2[loaderId2] === _UNINITIALIZED) {
177
+ const data = await loadClientData(url2, {
178
+ loaderIds: [
179
+ loaderId2
180
+ ]
181
+ });
182
+ loadersObject2[loaderId2] = data?.loaders[loaderId2] ?? _UNINITIALIZED;
185
183
  }
186
- );
184
+ return loadersObject2[loaderId2];
185
+ }, "createLoaderSignal_createAsync_CFLMoh8rnzw", [
186
+ loaderId,
187
+ loadersObject,
188
+ url
189
+ ]), {
190
+ container,
191
+ serializationStrategy
192
+ });
187
193
  };
188
194
 
195
+ const newScrollState = () => {
196
+ return {
197
+ x: 0,
198
+ y: 0,
199
+ w: 0,
200
+ h: 0
201
+ };
202
+ };
189
203
  const clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
190
204
  if (navType !== "popstate") {
191
205
  const samePath = isSamePath(fromURL, toURL);
@@ -202,14 +216,6 @@ const clientNavigate = (win, navType, fromURL, toURL, replaceState = false) => {
202
216
  }
203
217
  }
204
218
  };
205
- const newScrollState = () => {
206
- return {
207
- x: 0,
208
- y: 0,
209
- w: 0,
210
- h: 0
211
- };
212
- };
213
219
  const preloadRouteBundles = (path, probability = 0.8) => {
214
220
  if (isBrowser) {
215
221
  path = path.endsWith("/") ? path : path + "/";
@@ -218,127 +224,157 @@ const preloadRouteBundles = (path, probability = 0.8) => {
218
224
  }
219
225
  };
220
226
 
221
- function matchRoute(route, path) {
222
- const routeIdx = startIdxSkipSlash(route);
223
- const routeLength = lengthNoTrailingSlash(route);
224
- const pathIdx = startIdxSkipSlash(path);
225
- const pathLength = lengthNoTrailingSlash(path);
226
- return matchRoutePart(route, routeIdx, routeLength, path, pathIdx, pathLength);
227
- }
228
- function matchRoutePart(route, routeIdx, routeLength, path, pathIdx, pathLength) {
229
- if (path.startsWith("/build/")) {
230
- return null;
231
- }
232
- let params = null;
233
- while (routeIdx < routeLength) {
234
- const routeCh = route.charCodeAt(routeIdx++);
235
- const pathCh = path.charCodeAt(pathIdx++);
236
- if (routeCh === 91 /* OPEN_BRACKET */) {
237
- const isMany = isThreeDots(route, routeIdx);
238
- const paramNameStart = routeIdx + (isMany ? 3 : 0);
239
- const paramNameEnd = scan(route, paramNameStart, routeLength, 93 /* CLOSE_BRACKET */);
240
- const paramName = route.substring(paramNameStart, paramNameEnd);
241
- const paramSuffixEnd = scan(route, paramNameEnd + 1, routeLength, 47 /* SLASH */);
242
- const suffix = route.substring(paramNameEnd + 1, paramSuffixEnd);
243
- routeIdx = paramNameEnd + 1;
244
- const paramValueStart = pathIdx - 1;
245
- if (isMany) {
246
- const match = recursiveScan(
247
- paramName,
248
- suffix,
249
- path,
250
- paramValueStart,
251
- pathLength,
252
- route,
253
- routeIdx + suffix.length + 1,
254
- routeLength
255
- );
256
- if (match) {
257
- return Object.assign(params || (params = {}), match);
227
+ const mergeArray = (existingArr, newArr) => {
228
+ if (Array.isArray(newArr)) {
229
+ for (const newItem of newArr) {
230
+ if (typeof newItem.key === "string") {
231
+ const existingIndex = existingArr.findIndex((i) => i.key === newItem.key);
232
+ if (existingIndex > -1) {
233
+ existingArr[existingIndex] = newItem;
234
+ continue;
258
235
  }
259
236
  }
260
- const paramValueEnd = scan(path, paramValueStart, pathLength, 47 /* SLASH */, suffix);
261
- if (paramValueEnd == -1) {
262
- return null;
263
- }
264
- const paramValue = path.substring(paramValueStart, paramValueEnd);
265
- if (!isMany && !suffix && !paramValue) {
266
- return null;
267
- }
268
- pathIdx = paramValueEnd;
269
- (params || (params = {}))[paramName] = decodeURIComponent(paramValue);
270
- } else if (routeCh !== pathCh) {
271
- if (!(isNaN(pathCh) && isRestParameter(route, routeIdx))) {
272
- return null;
273
- }
237
+ existingArr.push(newItem);
274
238
  }
275
239
  }
276
- if (allConsumed(route, routeIdx) && allConsumed(path, pathIdx)) {
277
- return params || {};
278
- } else {
279
- return null;
240
+ };
241
+ const resolveDocumentHead = (resolvedHead, updatedHead) => {
242
+ if (typeof updatedHead.title === "string") {
243
+ resolvedHead.title = updatedHead.title;
280
244
  }
281
- }
282
- function isRestParameter(text, idx) {
283
- return text.charCodeAt(idx) === 91 /* OPEN_BRACKET */ && isThreeDots(text, idx + 1);
284
- }
285
- function lengthNoTrailingSlash(text) {
286
- const length = text.length;
287
- return length > 1 && text.charCodeAt(length - 1) === 47 /* SLASH */ ? length - 1 : length;
288
- }
289
- function allConsumed(text, idx) {
290
- const length = text.length;
291
- return idx >= length || idx == length - 1 && text.charCodeAt(idx) === 47 /* SLASH */;
292
- }
293
- function startIdxSkipSlash(text) {
294
- return text.charCodeAt(0) === 47 /* SLASH */ ? 1 : 0;
295
- }
296
- function isThreeDots(text, idx) {
297
- return text.charCodeAt(idx) === 46 /* DOT */ && text.charCodeAt(idx + 1) === 46 /* DOT */ && text.charCodeAt(idx + 2) === 46 /* DOT */;
298
- }
299
- function scan(text, idx, end, ch, suffix = "") {
300
- while (idx < end && text.charCodeAt(idx) !== ch) {
301
- idx++;
245
+ mergeArray(resolvedHead.meta, updatedHead.meta);
246
+ mergeArray(resolvedHead.links, updatedHead.links);
247
+ mergeArray(resolvedHead.styles, updatedHead.styles);
248
+ mergeArray(resolvedHead.scripts, updatedHead.scripts);
249
+ Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter);
250
+ };
251
+ const createDocumentHead = (defaults) => ({
252
+ title: defaults?.title || "",
253
+ meta: [
254
+ ...defaults?.meta || []
255
+ ],
256
+ links: [
257
+ ...defaults?.links || []
258
+ ],
259
+ styles: [
260
+ ...defaults?.styles || []
261
+ ],
262
+ scripts: [
263
+ ...defaults?.scripts || []
264
+ ],
265
+ frontmatter: {
266
+ ...defaults?.frontmatter
302
267
  }
303
- const suffixLength = suffix.length;
304
- for (let i = 0; i < suffixLength; i++) {
305
- if (text.charCodeAt(idx - suffixLength + i) !== suffix.charCodeAt(i)) {
306
- return -1;
268
+ });
269
+ const resolveRouteConfig = (resolveValue, routeLocation, contentModules, locale, status, defaults) => withLocale(locale, () => {
270
+ const head = createDocumentHead(defaults);
271
+ let eTag;
272
+ let cacheKey;
273
+ const fns = [];
274
+ for (let i = 0; i < contentModules.length; i++) {
275
+ const contentModule = contentModules[i];
276
+ if (!contentModule) {
277
+ continue;
307
278
  }
308
- }
309
- return idx - suffixLength;
310
- }
311
- function recursiveScan(paramName, suffix, path, pathStart, pathLength, route, routeStart, routeLength) {
312
- if (path.charCodeAt(pathStart) === 47 /* SLASH */) {
313
- pathStart++;
314
- }
315
- let pathIdx = pathLength;
316
- const sep = suffix + "/";
317
- while (pathIdx >= pathStart) {
318
- const match = matchRoutePart(route, routeStart, routeLength, path, pathIdx, pathLength);
319
- if (match) {
320
- let value = path.substring(pathStart, Math.min(pathIdx, pathLength));
321
- if (value.endsWith(sep)) {
322
- value = value.substring(0, value.length - sep.length);
279
+ const isLast = i === contentModules.length - 1;
280
+ let config;
281
+ if (contentModule.routeConfig) {
282
+ config = contentModule.routeConfig;
283
+ } else if (contentModule.head) {
284
+ const synthetic = {
285
+ head: void 0
286
+ };
287
+ const headExport = contentModule.head;
288
+ if (typeof headExport === "function") {
289
+ const mod = contentModule;
290
+ config = (props) => ({
291
+ head: headExport(props),
292
+ eTag: mod.eTag,
293
+ cacheKey: mod.cacheKey
294
+ });
295
+ } else {
296
+ synthetic.head = headExport;
297
+ const mod = contentModule;
298
+ if (mod.eTag !== void 0) {
299
+ synthetic.eTag = mod.eTag;
300
+ }
301
+ if (mod.cacheKey !== void 0) {
302
+ synthetic.cacheKey = mod.cacheKey;
303
+ }
304
+ config = synthetic;
305
+ }
306
+ } else {
307
+ const mod = contentModule;
308
+ if (mod.eTag !== void 0 || mod.cacheKey !== void 0) {
309
+ config = {
310
+ eTag: mod.eTag,
311
+ cacheKey: mod.cacheKey
312
+ };
323
313
  }
324
- match[paramName] = decodeURIComponent(value);
325
- return match;
326
314
  }
327
- const newPathIdx = lastIndexOf(path, pathStart, sep, pathIdx, pathStart - 1) + sep.length;
328
- if (pathIdx === newPathIdx) {
329
- break;
315
+ if (!config) {
316
+ continue;
317
+ }
318
+ if (typeof config === "function") {
319
+ fns.unshift({
320
+ fn: config,
321
+ isLast
322
+ });
323
+ } else {
324
+ if (config.head) {
325
+ resolveDocumentHead(head, config.head);
326
+ }
327
+ if (config.eTag !== void 0) {
328
+ eTag = config.eTag;
329
+ }
330
+ if (config.cacheKey !== void 0) {
331
+ cacheKey = config.cacheKey;
332
+ }
330
333
  }
331
- pathIdx = newPathIdx;
332
334
  }
333
- return null;
334
- }
335
- function lastIndexOf(text, start, match, searchIdx, notFoundIdx) {
336
- let idx = text.lastIndexOf(match, searchIdx);
337
- if (idx == searchIdx - match.length) {
338
- idx = text.lastIndexOf(match, searchIdx - match.length - 1);
335
+ if (fns.length) {
336
+ const headProps = {
337
+ head,
338
+ status,
339
+ withLocale: (fn) => fn(),
340
+ resolveValue,
341
+ ...routeLocation
342
+ };
343
+ for (const { fn } of fns) {
344
+ const result = fn(headProps);
345
+ if (result.head) {
346
+ resolveDocumentHead(head, result.head);
347
+ }
348
+ if (result.eTag !== void 0) {
349
+ eTag = result.eTag;
350
+ }
351
+ if (result.cacheKey !== void 0) {
352
+ cacheKey = result.cacheKey;
353
+ }
354
+ }
339
355
  }
340
- return idx > start ? idx : notFoundIdx;
341
- }
356
+ return {
357
+ head,
358
+ eTag,
359
+ cacheKey
360
+ };
361
+ });
362
+ const resolveHead = (endpoint, routeLocation, contentModules, locale, defaults) => {
363
+ const getData = (loaderOrAction) => {
364
+ const id = loaderOrAction.__id;
365
+ if (loaderOrAction.__brand === "server_loader") {
366
+ if (!(id in endpoint.loaders)) {
367
+ throw new Error("You can not get the returned data of a loader that has not been executed for this request.");
368
+ }
369
+ }
370
+ const data = endpoint.loaders[id];
371
+ if (isPromise(data)) {
372
+ throw new Error("Loaders returning a promise can not be resolved for the head function.");
373
+ }
374
+ return data;
375
+ };
376
+ return resolveRouteConfig(getData, routeLocation, contentModules, locale, endpoint.status, defaults).head;
377
+ };
342
378
 
343
379
  const deepFreeze = (obj) => {
344
380
  if (obj == null) {
@@ -357,45 +393,350 @@ const deepFreeze = (obj) => {
357
393
  return Object.freeze(obj);
358
394
  };
359
395
 
360
- const loadRoute = async (routes, menus, cacheModules, pathname, isInternal) => {
361
- if (!Array.isArray(routes)) {
362
- return null;
363
- }
364
- for (const routeData of routes) {
365
- const routeName = routeData[RouteDataProp.RouteName];
366
- const params = matchRoute(routeName, pathname);
367
- if (!params) {
368
- continue;
396
+ const httpErrorLoader = () => import('./http-error.qwik.mjs');
397
+ function walkTrieKeys(root, keys) {
398
+ let node = root;
399
+ const layouts = [];
400
+ if (node._L) {
401
+ layouts.push(node._L);
402
+ }
403
+ for (const key of keys) {
404
+ const next = node[key];
405
+ if (!next) {
406
+ return void 0;
369
407
  }
370
- const moduleLoaders = routeData[RouteDataProp.ModuleLoaders];
371
- const routeBundleNames = routeData[RouteDataProp.RouteBundleNames];
372
- const modules = new Array(moduleLoaders.length);
373
- const pendingLoads = [];
374
- moduleLoaders.forEach((moduleLoader, i) => {
375
- loadModule(
376
- moduleLoader,
377
- pendingLoads,
378
- (routeModule) => modules[i] = routeModule,
379
- cacheModules
380
- );
381
- });
382
- let menu = void 0;
383
- if (!isInternal) {
384
- const menuLoader = getMenuLoader(menus, pathname);
385
- loadModule(
386
- menuLoader,
387
- pendingLoads,
388
- (menuModule) => menu = menuModule?.default,
389
- cacheModules
390
- );
408
+ node = next;
409
+ if (node._L) {
410
+ layouts.push(node._L);
391
411
  }
392
- if (pendingLoads.length > 0) {
393
- await Promise.all(pendingLoads);
412
+ }
413
+ return {
414
+ node,
415
+ layouts
416
+ };
417
+ }
418
+ function resolveLoaders(root, node, gatheredLayouts) {
419
+ if (node._G) {
420
+ const keys = node._G.split("/").filter((p) => p.length > 0);
421
+ const target = walkTrieKeys(root, keys);
422
+ if (!target) {
423
+ return void 0;
394
424
  }
395
- return [routeName, params, modules, deepFreeze(menu), routeBundleNames];
425
+ return resolveLoaders(root, target.node, target.layouts);
396
426
  }
397
- return null;
398
- };
427
+ const index = node._I;
428
+ if (!index) {
429
+ return void 0;
430
+ }
431
+ if (Array.isArray(index)) {
432
+ return index;
433
+ }
434
+ return [
435
+ ...gatheredLayouts,
436
+ index
437
+ ];
438
+ }
439
+ function collectNodeMeta(node, groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef) {
440
+ for (const g of groups) {
441
+ if (g._L) {
442
+ layouts.push(g._L);
443
+ }
444
+ if (g._E) {
445
+ errorLoaderRef.v = g._E;
446
+ }
447
+ if (g._4) {
448
+ notFoundLoaderRef.v = g._4;
449
+ }
450
+ if (g._N) {
451
+ menuLoaderRef.v = g._N;
452
+ }
453
+ }
454
+ if (node._L) {
455
+ layouts.push(node._L);
456
+ }
457
+ if (node._E) {
458
+ errorLoaderRef.v = node._E;
459
+ }
460
+ if (node._4) {
461
+ notFoundLoaderRef.v = node._4;
462
+ }
463
+ if (node._N) {
464
+ menuLoaderRef.v = node._N;
465
+ }
466
+ }
467
+ function tryWildcardMatch(node, part, partLower, parts, partIndex, params) {
468
+ let next = node._W;
469
+ if (next) {
470
+ const prefix = next._0;
471
+ const suffix = next._9;
472
+ if (prefix || suffix) {
473
+ const pre = prefix || "";
474
+ const suf = suffix || "";
475
+ if (partLower.length > pre.length + suf.length && (!pre || partLower.startsWith(pre.toLowerCase())) && (!suf || partLower.endsWith(suf.toLowerCase()))) {
476
+ const paramName = next._P;
477
+ const value = part.slice(pre.length, suf ? part.length - suf.length : void 0);
478
+ params[paramName] = value;
479
+ return {
480
+ next,
481
+ routePart: `${pre}[${paramName}]${suf}`,
482
+ done: false
483
+ };
484
+ }
485
+ } else {
486
+ const paramName = next._P;
487
+ params[paramName] = part;
488
+ return {
489
+ next,
490
+ routePart: `[${paramName}]`,
491
+ done: false
492
+ };
493
+ }
494
+ }
495
+ next = node._A;
496
+ if (next) {
497
+ const paramName = next._P;
498
+ const restValue = parts.slice(partIndex).join("/");
499
+ params[paramName] = restValue;
500
+ return {
501
+ next,
502
+ routePart: `[...${paramName}]`,
503
+ done: true
504
+ };
505
+ }
506
+ return void 0;
507
+ }
508
+ function findChild(node, part, partLower, parts, partIndex, params) {
509
+ const exact = node[partLower];
510
+ if (exact) {
511
+ return {
512
+ next: exact,
513
+ groups: [],
514
+ routePart: part,
515
+ done: false
516
+ };
517
+ }
518
+ if (node._M) {
519
+ for (const group of node._M) {
520
+ const groupResult = findChild(group, part, partLower, parts, partIndex, params);
521
+ if (groupResult) {
522
+ groupResult.groups.unshift(group);
523
+ return groupResult;
524
+ }
525
+ }
526
+ }
527
+ const wildcard = tryWildcardMatch(node, part, partLower, parts, partIndex, params);
528
+ if (wildcard) {
529
+ return {
530
+ ...wildcard,
531
+ groups: []
532
+ };
533
+ }
534
+ return void 0;
535
+ }
536
+ function findIndexNode(node) {
537
+ if (node._I || node._G) {
538
+ return {
539
+ target: node,
540
+ groups: []
541
+ };
542
+ }
543
+ if (node._M) {
544
+ for (const group of node._M) {
545
+ const result = findIndexNode(group);
546
+ if (result) {
547
+ if (result.target !== group) {
548
+ result.groups.unshift(group);
549
+ }
550
+ return result;
551
+ }
552
+ }
553
+ }
554
+ return void 0;
555
+ }
556
+ function findRestNode(node) {
557
+ if (node._A) {
558
+ return {
559
+ next: node._A,
560
+ groups: []
561
+ };
562
+ }
563
+ if (node._M) {
564
+ for (const group of node._M) {
565
+ const result = findRestNode(group);
566
+ if (result) {
567
+ result.groups.unshift(group);
568
+ return result;
569
+ }
570
+ }
571
+ }
572
+ return void 0;
573
+ }
574
+ function matchRouteTree(root = {}, pathname) {
575
+ let node = root;
576
+ const params = {};
577
+ const routeParts = [];
578
+ const layouts = [];
579
+ const errorLoaderRef = {
580
+ v: void 0
581
+ };
582
+ const notFoundLoaderRef = {
583
+ v: void 0
584
+ };
585
+ const menuLoaderRef = {
586
+ v: void 0
587
+ };
588
+ if (root._L) {
589
+ layouts.push(root._L);
590
+ }
591
+ if (root._E) {
592
+ errorLoaderRef.v = root._E;
593
+ }
594
+ if (root._4) {
595
+ notFoundLoaderRef.v = root._4;
596
+ }
597
+ if (root._N) {
598
+ menuLoaderRef.v = root._N;
599
+ }
600
+ let done = false;
601
+ let matched = true;
602
+ const parts = pathname.split("/").filter((p) => p.length > 0).map(decodeURIComponent);
603
+ let restFallback;
604
+ let i = 0;
605
+ const len = parts.length;
606
+ for (; !done && i < len; i++) {
607
+ const part = parts[i];
608
+ const partLower = part.toLowerCase();
609
+ const restInfo = findRestNode(node);
610
+ if (restInfo) {
611
+ restFallback = {
612
+ aNode: restInfo.next,
613
+ groups: restInfo.groups,
614
+ paramName: restInfo.next._P,
615
+ restValue: parts.slice(i).join("/"),
616
+ routeParts: [
617
+ ...routeParts
618
+ ],
619
+ params: {
620
+ ...params
621
+ },
622
+ layouts: [
623
+ ...layouts
624
+ ],
625
+ errorLoader: errorLoaderRef.v,
626
+ notFoundLoader: notFoundLoaderRef.v,
627
+ menuLoader: menuLoaderRef.v
628
+ };
629
+ }
630
+ const found = findChild(node, part, partLower, parts, i, params);
631
+ if (!found) {
632
+ matched = false;
633
+ break;
634
+ }
635
+ routeParts.push(found.routePart);
636
+ done = found.done;
637
+ node = found.next;
638
+ collectNodeMeta(node, found.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef);
639
+ }
640
+ if (matched && !done && i === len) {
641
+ if (!node._I && !node._G) {
642
+ const indexResult = findIndexNode(node);
643
+ if (indexResult) {
644
+ collectNodeMeta(indexResult.target, indexResult.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef);
645
+ node = indexResult.target;
646
+ }
647
+ }
648
+ if (!node._I && !node._G && node._A) {
649
+ const next = node._A;
650
+ const paramName = next._P;
651
+ params[paramName] = "";
652
+ routeParts.push(`[...${paramName}]`);
653
+ node = next;
654
+ if (node._L) {
655
+ layouts.push(node._L);
656
+ }
657
+ if (node._N) {
658
+ menuLoaderRef.v = node._N;
659
+ }
660
+ }
661
+ if (!node._I && !node._G) {
662
+ const restInfo = findRestNode(node);
663
+ if (restInfo) {
664
+ const next = restInfo.next;
665
+ const paramName = next._P;
666
+ params[paramName] = "";
667
+ routeParts.push(`[...${paramName}]`);
668
+ collectNodeMeta(next, restInfo.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef);
669
+ node = next;
670
+ }
671
+ }
672
+ }
673
+ const loaders = matched && (done || i >= len) ? resolveLoaders(root, node, layouts) : void 0;
674
+ if (!loaders && restFallback) {
675
+ const fb = restFallback;
676
+ const fbParams = {
677
+ ...fb.params,
678
+ [fb.paramName]: fb.restValue
679
+ };
680
+ const fbRouteParts = [
681
+ ...fb.routeParts,
682
+ `[...${fb.paramName}]`
683
+ ];
684
+ const fbLayouts = [
685
+ ...fb.layouts
686
+ ];
687
+ const fbErrorRef = {
688
+ v: fb.errorLoader
689
+ };
690
+ const fbNotFoundRef = {
691
+ v: fb.notFoundLoader
692
+ };
693
+ const fbMenuRef = {
694
+ v: fb.menuLoader
695
+ };
696
+ collectNodeMeta(fb.aNode, fb.groups, fbLayouts, fbErrorRef, fbNotFoundRef, fbMenuRef);
697
+ const fbLoaders = resolveLoaders(root, fb.aNode, fbLayouts);
698
+ if (fbLoaders) {
699
+ return {
700
+ loaders: fbLoaders,
701
+ params: fbParams,
702
+ routeParts: fbRouteParts,
703
+ notFound: false,
704
+ routeBundleNames: fb.aNode._B,
705
+ menuLoader: fbMenuRef.v,
706
+ errorLoader: fbErrorRef.v,
707
+ notFoundLoader: fbNotFoundRef.v
708
+ };
709
+ }
710
+ errorLoaderRef.v = fbErrorRef.v;
711
+ notFoundLoaderRef.v = fbNotFoundRef.v;
712
+ menuLoaderRef.v = fbMenuRef.v;
713
+ }
714
+ if (!loaders) {
715
+ const loader = notFoundLoaderRef.v || errorLoaderRef.v || httpErrorLoader;
716
+ return {
717
+ loaders: [
718
+ loader
719
+ ],
720
+ params,
721
+ routeParts,
722
+ notFound: true,
723
+ routeBundleNames: void 0,
724
+ menuLoader: menuLoaderRef.v,
725
+ errorLoader: errorLoaderRef.v,
726
+ notFoundLoader: notFoundLoaderRef.v
727
+ };
728
+ }
729
+ return {
730
+ loaders,
731
+ params,
732
+ routeParts,
733
+ notFound: false,
734
+ routeBundleNames: node._B,
735
+ menuLoader: menuLoaderRef.v,
736
+ errorLoader: errorLoaderRef.v,
737
+ notFoundLoader: notFoundLoaderRef.v
738
+ };
739
+ }
399
740
  const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
400
741
  if (typeof moduleLoader === "function") {
401
742
  const loadedModule = MODULE_CACHE.get(moduleLoader);
@@ -404,30 +745,65 @@ const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
404
745
  } else {
405
746
  const moduleOrPromise = moduleLoader();
406
747
  if (typeof moduleOrPromise.then === "function") {
407
- pendingLoads.push(
408
- moduleOrPromise.then((loadedModule2) => {
409
- if (cacheModules !== false) {
410
- MODULE_CACHE.set(moduleLoader, loadedModule2);
411
- }
412
- moduleSetter(loadedModule2);
413
- })
414
- );
748
+ pendingLoads.push(moduleOrPromise.then((loadedModule2) => {
749
+ if (cacheModules !== false) {
750
+ MODULE_CACHE.set(moduleLoader, loadedModule2);
751
+ }
752
+ moduleSetter(loadedModule2);
753
+ }));
415
754
  } else if (moduleOrPromise) {
416
755
  moduleSetter(moduleOrPromise);
417
756
  }
418
757
  }
419
758
  }
420
759
  };
421
- const getMenuLoader = (menus, pathname) => {
422
- if (menus) {
423
- pathname = pathname.endsWith("/") ? pathname : pathname + "/";
424
- const menu = menus.find(
425
- (m) => m[MenuDataProp.Pathname] === pathname || pathname.startsWith(m[MenuDataProp.Pathname])
426
- );
427
- if (menu) {
428
- return menu[MenuDataProp.MenuLoader];
760
+ const loadRoute = async (routes, cacheModules, pathname, isInternal) => {
761
+ const result = matchRouteTree(routes, pathname);
762
+ const { loaders, params, routeParts, notFound, routeBundleNames, menuLoader, errorLoader, notFoundLoader } = result;
763
+ const routeName = "/" + routeParts.join("/");
764
+ const modules = new Array(loaders.length);
765
+ const pendingLoads = [];
766
+ loaders.forEach((moduleLoader, i) => {
767
+ loadModule(moduleLoader, pendingLoads, (routeModule) => modules[i] = routeModule, cacheModules);
768
+ });
769
+ let menu = void 0;
770
+ if (!isInternal) {
771
+ loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
772
+ }
773
+ if (notFound && notFoundLoader) {
774
+ let notFoundMod;
775
+ let errorMod;
776
+ loadModule(notFoundLoader, pendingLoads, (mod) => notFoundMod = mod, cacheModules);
777
+ loadModule(errorLoader || httpErrorLoader, pendingLoads, (mod) => errorMod = mod, cacheModules);
778
+ if (pendingLoads.length > 0) {
779
+ await Promise.all(pendingLoads);
429
780
  }
781
+ const { createNotFoundWrapper } = await import('./not-found-wrapper.qwik.mjs');
782
+ const wrapperModule = createNotFoundWrapper(notFoundMod, errorMod);
783
+ return {
784
+ $routeName$: routeName,
785
+ $params$: params,
786
+ $mods$: [
787
+ wrapperModule
788
+ ],
789
+ $menu$: deepFreeze(menu),
790
+ $routeBundleNames$: routeBundleNames,
791
+ $notFound$: notFound,
792
+ $errorLoader$: errorLoader
793
+ };
430
794
  }
795
+ if (pendingLoads.length > 0) {
796
+ await Promise.all(pendingLoads);
797
+ }
798
+ return {
799
+ $routeName$: routeName,
800
+ $params$: params,
801
+ $mods$: modules,
802
+ $menu$: deepFreeze(menu),
803
+ $routeBundleNames$: routeBundleNames,
804
+ $notFound$: notFound,
805
+ $errorLoader$: errorLoader
806
+ };
431
807
  };
432
808
 
433
- export { CLIENT_DATA_CACHE as C, DEFAULT_LOADERS_SERIALIZATION_STRATEGY as D, Q_ROUTE as Q, isSamePath as a, isSameOrigin as b, createLoaderSignal as c, loadRoute as d, clientNavigate as e, QFN_KEY as f, getClientNavPath as g, QACTION_KEY as h, isPromise as i, QDATA_KEY as j, QLOADER_KEY as k, loadClientData as l, preloadRouteBundles as p, shouldPreload as s, toUrl as t };
809
+ export { CLIENT_DATA_CACHE as C, DEFAULT_LOADERS_SERIALIZATION_STRATEGY as D, Q_ROUTE as Q, createDocumentHead as a, isSameOrigin as b, createLoaderSignal as c, loadRoute as d, clientNavigate as e, QFN_KEY as f, getClientNavPath as g, QACTION_KEY as h, isSamePath as i, QDATA_KEY as j, isPromise as k, loadClientData as l, QLOADER_KEY as m, resolveRouteConfig as n, preloadRouteBundles as p, resolveHead as r, shouldPreload as s, toUrl as t };