@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.
- package/lib/adapters/cloudflare-pages/vite/index.mjs +2 -2
- package/lib/adapters/shared/vite/index.d.ts +3 -4
- package/lib/adapters/shared/vite/index.mjs +158 -143
- package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
- package/lib/chunks/fs.mjs +6 -2
- package/lib/chunks/head.qwik.mjs +814 -93
- package/lib/chunks/request-body-limit.mjs +37 -0
- package/lib/chunks/request-path.mjs +2 -2
- package/lib/chunks/routes.mjs +47 -0
- package/lib/chunks/server-error.mjs +19 -0
- package/lib/chunks/system.mjs +2 -1
- package/lib/chunks/use-functions.qwik.mjs +1 -1
- package/lib/chunks/{worker-thread.qwik.mjs → user-response.mjs} +1053 -1749
- package/lib/chunks/worker-thread.mjs +317 -0
- package/lib/index.d.ts +89 -55
- package/lib/index.qwik.mjs +178 -100
- package/lib/middleware/azure-swa/index.mjs +13 -9
- package/lib/middleware/cloudflare-pages/index.mjs +2 -2
- package/lib/middleware/deno/index.d.ts +2 -0
- package/lib/middleware/deno/index.mjs +2 -1
- package/lib/middleware/netlify-edge/index.mjs +2 -2
- package/lib/middleware/node/index.d.ts +9 -1
- package/lib/middleware/node/index.mjs +28 -3
- package/lib/middleware/request-handler/index.d.ts +9 -10
- package/lib/middleware/request-handler/index.mjs +26 -1105
- package/lib/middleware/vercel-edge/index.mjs +2 -2
- package/lib/ssg/index.d.ts +2 -10
- package/lib/ssg/index.mjs +10 -50
- package/lib/vite/index.d.ts +8 -0
- package/lib/vite/index.mjs +406 -117
- package/package.json +5 -4
- package/lib/chunks/action-handler.mjs +0 -782
- package/lib/chunks/deepFreeze.qwik.mjs +0 -608
- package/lib/chunks/error-handler.mjs +0 -57
- package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
package/lib/chunks/head.qwik.mjs
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
import { e as ensureSlash } from './pathname.mjs';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { createContextId, isServer as isServer$1, implicit$FirstArg, isDev, createComputedQrl, inlinedQrl, _captures, withLocale } from '@qwik.dev/core';
|
|
3
|
+
import * as qwikRouterConfig from '@qwik-router-config';
|
|
4
|
+
import { _getAsyncLocalStorage, _getContextEvent, _resolveContextWithoutSequentialScope, _injectAsyncSignalValue, _UNINITIALIZED, _deserialize, _markSignalAsExternallyOwned, SerializerSymbol, _verifySerializable } from '@qwik.dev/core/internal';
|
|
5
|
+
import { isServer } from '@qwik.dev/core/build';
|
|
6
|
+
import { g as getLoaderName } from './request-path.mjs';
|
|
7
|
+
import { R as RedirectMessage, S as ServerError, t as throwIfControlFlowSignal } from './server-error.mjs';
|
|
8
|
+
|
|
9
|
+
let _asyncRequestStore;
|
|
10
|
+
if (isServer) {
|
|
11
|
+
const AsyncLocalStorage = _getAsyncLocalStorage();
|
|
12
|
+
if (AsyncLocalStorage) {
|
|
13
|
+
_asyncRequestStore = new AsyncLocalStorage();
|
|
14
|
+
} else {
|
|
15
|
+
console.warn("\n=====================\n Qwik Router Warning:\n AsyncLocalStorage is not available, continuing without it.\n This impacts concurrent async server calls, where they lose access to the ServerRequestEv object.\n=====================\n\n");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const deepFreeze = (obj) => {
|
|
20
|
+
if (obj == null) {
|
|
21
|
+
return obj;
|
|
22
|
+
}
|
|
23
|
+
Object.getOwnPropertyNames(obj).forEach((prop) => {
|
|
24
|
+
const value = obj[prop];
|
|
25
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
26
|
+
try {
|
|
27
|
+
deepFreeze(value);
|
|
28
|
+
} catch {
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return Object.freeze(obj);
|
|
34
|
+
};
|
|
4
35
|
|
|
5
36
|
const MODULE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
6
37
|
const httpErrorLoader = () => import('./http-error.qwik.mjs');
|
|
@@ -38,6 +69,10 @@ function walkTrieKeys(root, keys) {
|
|
|
38
69
|
layouts
|
|
39
70
|
};
|
|
40
71
|
}
|
|
72
|
+
const boundaryChain = (ref) => ref.v ? Array.isArray(ref.v) ? ref.v : [
|
|
73
|
+
...ref.layouts,
|
|
74
|
+
ref.v
|
|
75
|
+
] : void 0;
|
|
41
76
|
function collectNodeMeta(node, groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef, loaderHashes, loaderPathsByHash, matchedPathname = "/") {
|
|
42
77
|
for (let j = 0; j < groups.length; j++) {
|
|
43
78
|
const g = groups[j];
|
|
@@ -55,9 +90,15 @@ function collectNodeMeta(node, groups, layouts, errorLoaderRef, notFoundLoaderRe
|
|
|
55
90
|
}
|
|
56
91
|
if (g._E) {
|
|
57
92
|
errorLoaderRef.v = g._E;
|
|
93
|
+
errorLoaderRef.layouts = [
|
|
94
|
+
...layouts
|
|
95
|
+
];
|
|
58
96
|
}
|
|
59
97
|
if (g._4) {
|
|
60
98
|
notFoundLoaderRef.v = g._4;
|
|
99
|
+
notFoundLoaderRef.layouts = [
|
|
100
|
+
...layouts
|
|
101
|
+
];
|
|
61
102
|
}
|
|
62
103
|
if (g._N) {
|
|
63
104
|
menuLoaderRef.v = g._N;
|
|
@@ -77,9 +118,15 @@ function collectNodeMeta(node, groups, layouts, errorLoaderRef, notFoundLoaderRe
|
|
|
77
118
|
}
|
|
78
119
|
if (node._E) {
|
|
79
120
|
errorLoaderRef.v = node._E;
|
|
121
|
+
errorLoaderRef.layouts = [
|
|
122
|
+
...layouts
|
|
123
|
+
];
|
|
80
124
|
}
|
|
81
125
|
if (node._4) {
|
|
82
126
|
notFoundLoaderRef.v = node._4;
|
|
127
|
+
notFoundLoaderRef.layouts = [
|
|
128
|
+
...layouts
|
|
129
|
+
];
|
|
83
130
|
}
|
|
84
131
|
if (node._N) {
|
|
85
132
|
menuLoaderRef.v = node._N;
|
|
@@ -162,27 +209,34 @@ function findChild(node, part, partLower, parts, partIndex) {
|
|
|
162
209
|
}
|
|
163
210
|
return void 0;
|
|
164
211
|
}
|
|
165
|
-
function
|
|
166
|
-
|
|
212
|
+
function descendGroups(node, hit) {
|
|
213
|
+
const value = hit(node);
|
|
214
|
+
if (value !== void 0) {
|
|
167
215
|
return {
|
|
168
|
-
|
|
216
|
+
value,
|
|
217
|
+
node,
|
|
169
218
|
groups: []
|
|
170
219
|
};
|
|
171
220
|
}
|
|
172
221
|
if (node._M) {
|
|
173
222
|
for (let j = 0; j < node._M.length; j++) {
|
|
174
223
|
const group = node._M[j];
|
|
175
|
-
const result =
|
|
224
|
+
const result = descendGroups(group, hit);
|
|
176
225
|
if (result) {
|
|
177
|
-
|
|
178
|
-
result.groups.unshift(group);
|
|
179
|
-
}
|
|
226
|
+
result.groups.unshift(group);
|
|
180
227
|
return result;
|
|
181
228
|
}
|
|
182
229
|
}
|
|
183
230
|
}
|
|
184
231
|
return void 0;
|
|
185
232
|
}
|
|
233
|
+
function findIndexNode(node) {
|
|
234
|
+
const r = descendGroups(node, (n) => n._I || n._G != null ? n : void 0);
|
|
235
|
+
return r ? {
|
|
236
|
+
target: r.node,
|
|
237
|
+
groups: r.groups.filter((g) => g !== r.node)
|
|
238
|
+
} : void 0;
|
|
239
|
+
}
|
|
186
240
|
function resolveLoaders(root, node, gatheredLayouts) {
|
|
187
241
|
if (node._G != null) {
|
|
188
242
|
const keys = node._G.split("/").filter((p) => p.length > 0);
|
|
@@ -222,23 +276,29 @@ function resolveLoaders(root, node, gatheredLayouts) {
|
|
|
222
276
|
];
|
|
223
277
|
}
|
|
224
278
|
function findRestNode(node) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
279
|
+
const r = descendGroups(node, (n) => n._A);
|
|
280
|
+
return r ? {
|
|
281
|
+
next: r.value,
|
|
282
|
+
groups: r.groups
|
|
283
|
+
} : void 0;
|
|
284
|
+
}
|
|
285
|
+
function findGroupBoundary(node, layouts, kind) {
|
|
286
|
+
const r = descendGroups(node, (n) => n[kind]);
|
|
287
|
+
if (!r) {
|
|
288
|
+
return void 0;
|
|
230
289
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return result;
|
|
238
|
-
}
|
|
290
|
+
const groupLayouts = [
|
|
291
|
+
...layouts
|
|
292
|
+
];
|
|
293
|
+
for (const g of r.groups) {
|
|
294
|
+
if (g._L) {
|
|
295
|
+
groupLayouts.push(g._L);
|
|
239
296
|
}
|
|
240
297
|
}
|
|
241
|
-
return
|
|
298
|
+
return {
|
|
299
|
+
v: r.value,
|
|
300
|
+
layouts: groupLayouts
|
|
301
|
+
};
|
|
242
302
|
}
|
|
243
303
|
function matchRouteTree(root = {}, pathname) {
|
|
244
304
|
let node = root;
|
|
@@ -248,32 +308,23 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
248
308
|
const loaderHashes = [];
|
|
249
309
|
const loaderPathsByHash = {};
|
|
250
310
|
const errorLoaderRef = {
|
|
251
|
-
v: void 0
|
|
311
|
+
v: void 0,
|
|
312
|
+
layouts: []
|
|
252
313
|
};
|
|
253
314
|
const notFoundLoaderRef = {
|
|
254
|
-
v: void 0
|
|
315
|
+
v: void 0,
|
|
316
|
+
layouts: []
|
|
255
317
|
};
|
|
256
318
|
const menuLoaderRef = {
|
|
257
319
|
v: void 0
|
|
258
320
|
};
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
loaderPathsByHash[hash] = "/";
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
if (root._E) {
|
|
270
|
-
errorLoaderRef.v = root._E;
|
|
271
|
-
}
|
|
272
|
-
if (root._4) {
|
|
273
|
-
notFoundLoaderRef.v = root._4;
|
|
274
|
-
}
|
|
275
|
-
if (root._N) {
|
|
276
|
-
menuLoaderRef.v = root._N;
|
|
321
|
+
const groupNodes = [];
|
|
322
|
+
collectNodeMeta(root, [], layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef, loaderHashes, loaderPathsByHash);
|
|
323
|
+
if (root._M) {
|
|
324
|
+
groupNodes.push({
|
|
325
|
+
node: root,
|
|
326
|
+
depth: layouts.length
|
|
327
|
+
});
|
|
277
328
|
}
|
|
278
329
|
let done = false;
|
|
279
330
|
let matched = true;
|
|
@@ -309,7 +360,9 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
309
360
|
...loaderPathsByHash
|
|
310
361
|
},
|
|
311
362
|
errorLoader: errorLoaderRef.v,
|
|
363
|
+
errorLayouts: errorLoaderRef.layouts,
|
|
312
364
|
notFoundLoader: notFoundLoaderRef.v,
|
|
365
|
+
notFoundLayouts: notFoundLoaderRef.layouts,
|
|
313
366
|
menuLoader: menuLoaderRef.v
|
|
314
367
|
};
|
|
315
368
|
}
|
|
@@ -321,6 +374,12 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
321
374
|
node = found.next;
|
|
322
375
|
const matchedPathname = `/${parts.slice(0, found.done ? len : i + 1).join("/")}/`;
|
|
323
376
|
collectNodeMeta(node, found.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef, loaderHashes, loaderPathsByHash, matchedPathname);
|
|
377
|
+
if (node._M) {
|
|
378
|
+
groupNodes.push({
|
|
379
|
+
node,
|
|
380
|
+
depth: layouts.length
|
|
381
|
+
});
|
|
382
|
+
}
|
|
324
383
|
}
|
|
325
384
|
if (matched && !done && i === len) {
|
|
326
385
|
if (!node._I && node._G == null) {
|
|
@@ -330,19 +389,6 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
330
389
|
node = indexResult.target;
|
|
331
390
|
}
|
|
332
391
|
}
|
|
333
|
-
if (!node._I && node._G == null && node._A) {
|
|
334
|
-
const next = node._A;
|
|
335
|
-
const paramName = next._P;
|
|
336
|
-
params[paramName] = "";
|
|
337
|
-
routeParts.push(`[...${paramName}]`);
|
|
338
|
-
node = next;
|
|
339
|
-
if (node._L) {
|
|
340
|
-
layouts.push(node._L);
|
|
341
|
-
}
|
|
342
|
-
if (node._N) {
|
|
343
|
-
menuLoaderRef.v = node._N;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
392
|
if (!node._I && node._G == null) {
|
|
347
393
|
const restInfo = findRestNode(node);
|
|
348
394
|
if (restInfo) {
|
|
@@ -373,10 +419,12 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
373
419
|
...fb.loaderPathsByHash
|
|
374
420
|
};
|
|
375
421
|
const fbErrorRef = {
|
|
376
|
-
v: fb.errorLoader
|
|
422
|
+
v: fb.errorLoader,
|
|
423
|
+
layouts: fb.errorLayouts
|
|
377
424
|
};
|
|
378
425
|
const fbNotFoundRef = {
|
|
379
|
-
v: fb.notFoundLoader
|
|
426
|
+
v: fb.notFoundLoader,
|
|
427
|
+
layouts: fb.notFoundLayouts
|
|
380
428
|
};
|
|
381
429
|
const fbMenuRef = {
|
|
382
430
|
v: fb.menuLoader
|
|
@@ -394,19 +442,46 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
394
442
|
loaderHashes: fbLoaderHashes.length > 0 ? fbLoaderHashes : void 0,
|
|
395
443
|
loaderPathsByHash: Object.keys(fbLoaderPathsByHash).length > 0 ? fbLoaderPathsByHash : void 0,
|
|
396
444
|
menuLoader: fbMenuRef.v,
|
|
397
|
-
errorLoader: fbErrorRef
|
|
398
|
-
notFoundLoader: fbNotFoundRef.v
|
|
445
|
+
errorLoader: boundaryChain(fbErrorRef)
|
|
399
446
|
};
|
|
400
447
|
}
|
|
401
448
|
errorLoaderRef.v = fbErrorRef.v;
|
|
449
|
+
errorLoaderRef.layouts = fbErrorRef.layouts;
|
|
402
450
|
notFoundLoaderRef.v = fbNotFoundRef.v;
|
|
451
|
+
notFoundLoaderRef.layouts = fbNotFoundRef.layouts;
|
|
403
452
|
menuLoaderRef.v = fbMenuRef.v;
|
|
404
453
|
}
|
|
405
454
|
if (!loaders) {
|
|
406
|
-
const
|
|
455
|
+
const recover = (kind) => {
|
|
456
|
+
for (let k = groupNodes.length - 1; k >= 0; k--) {
|
|
457
|
+
const found = findGroupBoundary(groupNodes[k].node, layouts.slice(0, groupNodes[k].depth), kind);
|
|
458
|
+
if (found) {
|
|
459
|
+
return found;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return void 0;
|
|
463
|
+
};
|
|
464
|
+
if (!notFoundLoaderRef.v) {
|
|
465
|
+
const g = recover("_4");
|
|
466
|
+
if (g) {
|
|
467
|
+
notFoundLoaderRef.v = g.v;
|
|
468
|
+
notFoundLoaderRef.layouts = g.layouts;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (!errorLoaderRef.v) {
|
|
472
|
+
const g = recover("_E");
|
|
473
|
+
if (g) {
|
|
474
|
+
errorLoaderRef.v = g.v;
|
|
475
|
+
errorLoaderRef.layouts = g.layouts;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const ref = notFoundLoaderRef.v ? notFoundLoaderRef : errorLoaderRef.v ? errorLoaderRef : null;
|
|
479
|
+
const boundary = ref?.v ?? httpErrorLoader;
|
|
480
|
+
const boundaryLayouts = ref ? ref.layouts : layouts;
|
|
407
481
|
return {
|
|
408
|
-
loaders: [
|
|
409
|
-
|
|
482
|
+
loaders: Array.isArray(boundary) ? boundary : [
|
|
483
|
+
...boundaryLayouts,
|
|
484
|
+
boundary
|
|
410
485
|
],
|
|
411
486
|
params,
|
|
412
487
|
routeParts,
|
|
@@ -415,8 +490,7 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
415
490
|
loaderHashes: void 0,
|
|
416
491
|
loaderPathsByHash: void 0,
|
|
417
492
|
menuLoader: menuLoaderRef.v,
|
|
418
|
-
errorLoader: errorLoaderRef
|
|
419
|
-
notFoundLoader: notFoundLoaderRef.v
|
|
493
|
+
errorLoader: boundaryChain(errorLoaderRef)
|
|
420
494
|
};
|
|
421
495
|
}
|
|
422
496
|
if (node._R) {
|
|
@@ -436,8 +510,7 @@ function matchRouteTree(root = {}, pathname) {
|
|
|
436
510
|
loaderHashes: loaderHashes.length > 0 ? loaderHashes : void 0,
|
|
437
511
|
loaderPathsByHash: Object.keys(loaderPathsByHash).length > 0 ? loaderPathsByHash : void 0,
|
|
438
512
|
menuLoader: menuLoaderRef.v,
|
|
439
|
-
errorLoader: errorLoaderRef
|
|
440
|
-
notFoundLoader: notFoundLoaderRef.v
|
|
513
|
+
errorLoader: boundaryChain(errorLoaderRef)
|
|
441
514
|
};
|
|
442
515
|
}
|
|
443
516
|
const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
|
|
@@ -462,7 +535,7 @@ const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
|
|
|
462
535
|
};
|
|
463
536
|
const loadRoute = async (routes, cacheModules, pathname) => {
|
|
464
537
|
const result = matchRouteTree(routes, pathname);
|
|
465
|
-
const { loaders, params, routeParts, notFound, routeBundleNames, loaderHashes, loaderPathsByHash, menuLoader, errorLoader
|
|
538
|
+
const { loaders, params, routeParts, notFound, routeBundleNames, loaderHashes, loaderPathsByHash, menuLoader, errorLoader } = result;
|
|
466
539
|
const routeName = "/" + routeParts.join("/");
|
|
467
540
|
const modules = new Array(loaders.length);
|
|
468
541
|
const pendingLoads = [];
|
|
@@ -472,30 +545,6 @@ const loadRoute = async (routes, cacheModules, pathname) => {
|
|
|
472
545
|
}
|
|
473
546
|
let menu = void 0;
|
|
474
547
|
loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
|
|
475
|
-
if (notFound && notFoundLoader) {
|
|
476
|
-
let notFoundMod;
|
|
477
|
-
let errorMod;
|
|
478
|
-
loadModule(notFoundLoader, pendingLoads, (mod) => notFoundMod = mod, cacheModules);
|
|
479
|
-
loadModule(errorLoader || httpErrorLoader, pendingLoads, (mod) => errorMod = mod, cacheModules);
|
|
480
|
-
if (pendingLoads.length > 0) {
|
|
481
|
-
await Promise.all(pendingLoads);
|
|
482
|
-
}
|
|
483
|
-
const { createNotFoundWrapper } = await import('./not-found-wrapper.qwik.mjs');
|
|
484
|
-
const wrapperModule = createNotFoundWrapper(notFoundMod, errorMod);
|
|
485
|
-
return {
|
|
486
|
-
$routeName$: routeName,
|
|
487
|
-
$params$: params,
|
|
488
|
-
$mods$: [
|
|
489
|
-
wrapperModule
|
|
490
|
-
],
|
|
491
|
-
$menu$: deepFreeze(menu),
|
|
492
|
-
$routeBundleNames$: routeBundleNames,
|
|
493
|
-
$notFound$: notFound,
|
|
494
|
-
$errorLoader$: errorLoader,
|
|
495
|
-
$loaders$: loaderHashes,
|
|
496
|
-
$loaderPaths$: loaderPathsByHash
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
548
|
if (pendingLoads.length > 0) {
|
|
500
549
|
await Promise.all(pendingLoads);
|
|
501
550
|
}
|
|
@@ -512,6 +561,678 @@ const loadRoute = async (routes, cacheModules, pathname) => {
|
|
|
512
561
|
};
|
|
513
562
|
};
|
|
514
563
|
|
|
564
|
+
const QACTION_KEY = "qaction";
|
|
565
|
+
const QFN_KEY = "qfunc";
|
|
566
|
+
const QDATA_KEY = "qdata";
|
|
567
|
+
const Q_ROUTE = "q:route";
|
|
568
|
+
const DEFAULT_LOADERS_SERIALIZATION_STRATEGY = globalThis.__DEFAULT_LOADERS_SERIALIZATION_STRATEGY__ || "never";
|
|
569
|
+
|
|
570
|
+
const RouteStateContext = /* @__PURE__ */ createContextId("qr-s");
|
|
571
|
+
const RouteLoaderCtxContext = /* @__PURE__ */ createContextId("qr-lc");
|
|
572
|
+
const ContentContext = /* @__PURE__ */ createContextId("qr-c");
|
|
573
|
+
const ContentInternalContext = /* @__PURE__ */ createContextId("qr-ic");
|
|
574
|
+
const DocumentHeadContext = /* @__PURE__ */ createContextId("qr-h");
|
|
575
|
+
const RouteLocationContext = /* @__PURE__ */ createContextId("qr-l");
|
|
576
|
+
const RouteNavigateContext = /* @__PURE__ */ createContextId("qr-n");
|
|
577
|
+
const RouteActionContext = /* @__PURE__ */ createContextId("qr-a");
|
|
578
|
+
const RoutePreventNavigateContext = /* @__PURE__ */ createContextId("qr-p");
|
|
579
|
+
const HttpStatusContext = /* @__PURE__ */ createContextId("qr-hs");
|
|
580
|
+
|
|
581
|
+
const REQUEST_ROUTE_LOADER_STATE = "@routeLoaderState";
|
|
582
|
+
const REQUEST_LOADER_PATHS_STORE = "@loaderPathsStore";
|
|
583
|
+
const REQUEST_ROUTE_LOADERS = "@routeLoaders";
|
|
584
|
+
const REQUEST_ROUTE_LOADER_PROMISES = "@routeLoaderPromises";
|
|
585
|
+
const REQUEST_ROUTE_LOADER_EVENTS = "@routeLoaderEvents";
|
|
586
|
+
const REQUEST_ROUTE_LOADER_ROOT_EVENT = "@routeLoaderRootEvent";
|
|
587
|
+
const ROUTE_LOADER_VALUE_PREFIX = "__qwik_route_loader_value__";
|
|
588
|
+
const FULLPATH_HEADER = "X-Qwik-fullpath";
|
|
589
|
+
const ROUTE_PATH_HEADER = "X-Qwik-route-path";
|
|
590
|
+
const navFetchCache = /* @__PURE__ */ new Map();
|
|
591
|
+
const clearNavFetchCache = () => navFetchCache.clear();
|
|
592
|
+
const isRedirectStatus = (status) => status >= 300 && status < 400;
|
|
593
|
+
const wrapWithAbort = (promise, signal) => {
|
|
594
|
+
if (signal.aborted) {
|
|
595
|
+
return Promise.reject(signal.reason);
|
|
596
|
+
}
|
|
597
|
+
return new Promise((resolve, reject) => {
|
|
598
|
+
const abort = () => reject(signal.reason);
|
|
599
|
+
signal.addEventListener("abort", abort, {
|
|
600
|
+
once: true
|
|
601
|
+
});
|
|
602
|
+
promise.finally(() => signal.removeEventListener("abort", abort)).then(resolve, reject);
|
|
603
|
+
});
|
|
604
|
+
};
|
|
605
|
+
const getRouteLoaderValueStateKey = (loaderId) => `${ROUTE_LOADER_VALUE_PREFIX}${loaderId}`;
|
|
606
|
+
const isRequestEvent = (value) => !!value && typeof value === "object" && Object.prototype.hasOwnProperty.call(value, "sharedMap") && Object.prototype.hasOwnProperty.call(value, "cookie");
|
|
607
|
+
const isLoaderInternal = (value) => typeof value === "function" && value.__brand === "server_loader";
|
|
608
|
+
const fetchRouteLoaderData = async (loaderId, routePath, manifestHash, opts) => {
|
|
609
|
+
if (!routePath) {
|
|
610
|
+
return void 0;
|
|
611
|
+
}
|
|
612
|
+
let resolvedPath = routePath;
|
|
613
|
+
const basePath = opts?.basePath ?? "/";
|
|
614
|
+
if (basePath !== "/" && !resolvedPath.startsWith(basePath)) {
|
|
615
|
+
resolvedPath = basePath + resolvedPath.slice(1);
|
|
616
|
+
}
|
|
617
|
+
const pathBase = ensureSlash(resolvedPath);
|
|
618
|
+
const pageUrl = opts?.pageUrl;
|
|
619
|
+
const search = pageUrl?.search ?? "";
|
|
620
|
+
const url = `${pathBase}${getLoaderName(loaderId, manifestHash)}${search}`;
|
|
621
|
+
const headers = {};
|
|
622
|
+
if (pageUrl && pageUrl.pathname !== pathBase) {
|
|
623
|
+
if (!globalThis.__STRICT_LOADERS__) {
|
|
624
|
+
headers[FULLPATH_HEADER] = pageUrl.pathname;
|
|
625
|
+
} else if (isDev) {
|
|
626
|
+
headers[ROUTE_PATH_HEADER] = pageUrl.pathname;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
const cacheKey = `${url}
|
|
630
|
+
${headers[FULLPATH_HEADER] ?? ""}`;
|
|
631
|
+
if (!opts?.ignoreCache) {
|
|
632
|
+
const entry = navFetchCache.get(cacheKey);
|
|
633
|
+
if (entry) {
|
|
634
|
+
return opts?.signal ? wrapWithAbort(entry, opts.signal) : entry;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
const request = async () => {
|
|
638
|
+
const response = await fetch(url, {
|
|
639
|
+
signal: opts?.signal,
|
|
640
|
+
cache: opts?.ignoreCache ? "reload" : "default",
|
|
641
|
+
headers
|
|
642
|
+
});
|
|
643
|
+
if (response.redirected) {
|
|
644
|
+
return {
|
|
645
|
+
r: response.url
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
if (isRedirectStatus(response.status)) {
|
|
649
|
+
const location1 = response.headers.get("Location");
|
|
650
|
+
if (location1) {
|
|
651
|
+
return {
|
|
652
|
+
r: location1
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (!response.ok) {
|
|
657
|
+
return void 0;
|
|
658
|
+
}
|
|
659
|
+
return {
|
|
660
|
+
raw: await response.text()
|
|
661
|
+
};
|
|
662
|
+
};
|
|
663
|
+
if (opts?.ignoreCache) {
|
|
664
|
+
return request();
|
|
665
|
+
}
|
|
666
|
+
if (opts?.signal) {
|
|
667
|
+
return request().then((value) => {
|
|
668
|
+
if (value !== void 0 && !navFetchCache.has(cacheKey)) {
|
|
669
|
+
navFetchCache.set(cacheKey, Promise.resolve(value));
|
|
670
|
+
}
|
|
671
|
+
return value;
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
const promise = request().then((value) => {
|
|
675
|
+
if (value === void 0) {
|
|
676
|
+
navFetchCache.delete(cacheKey);
|
|
677
|
+
}
|
|
678
|
+
return value;
|
|
679
|
+
}, (err) => {
|
|
680
|
+
navFetchCache.delete(cacheKey);
|
|
681
|
+
throw err;
|
|
682
|
+
});
|
|
683
|
+
navFetchCache.set(cacheKey, promise);
|
|
684
|
+
return promise;
|
|
685
|
+
};
|
|
686
|
+
const filterSearchParams = (params, allowed) => {
|
|
687
|
+
const filtered = new URLSearchParams();
|
|
688
|
+
for (let i = 0; i < allowed.length; i++) {
|
|
689
|
+
const name = allowed[i];
|
|
690
|
+
const values = params.getAll(name);
|
|
691
|
+
for (let j = 0; j < values.length; j++) {
|
|
692
|
+
filtered.append(name, values[j]);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
filtered.sort();
|
|
696
|
+
return filtered.toString() ? `?${filtered.toString()}` : "";
|
|
697
|
+
};
|
|
698
|
+
const getLoaderOptions = (rest) => {
|
|
699
|
+
let id;
|
|
700
|
+
let serializationStrategy = DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
|
|
701
|
+
let cacheControl;
|
|
702
|
+
let eTag;
|
|
703
|
+
let cacheKey;
|
|
704
|
+
let search;
|
|
705
|
+
let blockSSR = true;
|
|
706
|
+
const validators = [];
|
|
707
|
+
if (rest.length === 1) {
|
|
708
|
+
const options = rest[0];
|
|
709
|
+
if (options && typeof options === "object") {
|
|
710
|
+
if ("validate" in options) {
|
|
711
|
+
validators.push(options);
|
|
712
|
+
} else {
|
|
713
|
+
if (options.id) {
|
|
714
|
+
id = options.id;
|
|
715
|
+
}
|
|
716
|
+
if (options.serializationStrategy) {
|
|
717
|
+
serializationStrategy = options.serializationStrategy;
|
|
718
|
+
}
|
|
719
|
+
if (options.validation) {
|
|
720
|
+
validators.push(...options.validation);
|
|
721
|
+
}
|
|
722
|
+
if ("cacheControl" in options) {
|
|
723
|
+
cacheControl = options.cacheControl;
|
|
724
|
+
}
|
|
725
|
+
if ("eTag" in options) {
|
|
726
|
+
eTag = options.eTag;
|
|
727
|
+
}
|
|
728
|
+
if ("cacheKey" in options) {
|
|
729
|
+
cacheKey = options.cacheKey;
|
|
730
|
+
}
|
|
731
|
+
if (options.search) {
|
|
732
|
+
search = options.search;
|
|
733
|
+
} else if (globalThis.__STRICT_LOADERS__) {
|
|
734
|
+
search = [];
|
|
735
|
+
}
|
|
736
|
+
if (options.blockSSR === false) {
|
|
737
|
+
if (!__EXPERIMENTAL__.blockSSR) {
|
|
738
|
+
throw new Error('`blockSSR: false` is an experimental feature and is not enabled. Please enable the feature flag by adding `experimental: ["blockSSR"]` to your qwikVite plugin options.');
|
|
739
|
+
}
|
|
740
|
+
blockSSR = false;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
} else if (rest.length > 1) {
|
|
745
|
+
validators.push(...rest.filter(Boolean));
|
|
746
|
+
}
|
|
747
|
+
return {
|
|
748
|
+
id,
|
|
749
|
+
validators: validators.reverse(),
|
|
750
|
+
serializationStrategy,
|
|
751
|
+
cacheControl,
|
|
752
|
+
eTag,
|
|
753
|
+
cacheKey,
|
|
754
|
+
search,
|
|
755
|
+
blockSSR
|
|
756
|
+
};
|
|
757
|
+
};
|
|
758
|
+
const getRequestEvent = (thisArg) => {
|
|
759
|
+
if (!isServer$1) {
|
|
760
|
+
throw new Error("getRequestEvent() can only be used on the server.");
|
|
761
|
+
}
|
|
762
|
+
return _asyncRequestStore?.getStore() || [
|
|
763
|
+
thisArg,
|
|
764
|
+
_getContextEvent()
|
|
765
|
+
].find(isRequestEvent);
|
|
766
|
+
};
|
|
767
|
+
const REQUEST_ROUTE_LOADER_VALUES = "@routeLoaderValues";
|
|
768
|
+
function getRouteLoaderValues(requestEv) {
|
|
769
|
+
let values = requestEv.sharedMap.get(REQUEST_ROUTE_LOADER_VALUES);
|
|
770
|
+
if (!values) {
|
|
771
|
+
values = {};
|
|
772
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADER_VALUES, values);
|
|
773
|
+
}
|
|
774
|
+
return values;
|
|
775
|
+
}
|
|
776
|
+
function getRouteLoaderPromises(requestEv) {
|
|
777
|
+
let promises = requestEv.sharedMap.get(REQUEST_ROUTE_LOADER_PROMISES);
|
|
778
|
+
if (!promises) {
|
|
779
|
+
promises = {};
|
|
780
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADER_PROMISES, promises);
|
|
781
|
+
}
|
|
782
|
+
return promises;
|
|
783
|
+
}
|
|
784
|
+
function clearRouteLoaderData(requestEv) {
|
|
785
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_STATE);
|
|
786
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_VALUES);
|
|
787
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_PROMISES);
|
|
788
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_EVENTS);
|
|
789
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADER_ROOT_EVENT);
|
|
790
|
+
requestEv.sharedMap.delete(REQUEST_ROUTE_LOADERS);
|
|
791
|
+
}
|
|
792
|
+
function setRouteLoaders(requestEv, loaders) {
|
|
793
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADERS, loaders);
|
|
794
|
+
}
|
|
795
|
+
function getRouteLoaders(requestEv) {
|
|
796
|
+
return requestEv.sharedMap.get(REQUEST_ROUTE_LOADERS) ?? [];
|
|
797
|
+
}
|
|
798
|
+
function getRouteLoaderCtx(requestEv) {
|
|
799
|
+
let ctx = requestEv.sharedMap.get(REQUEST_LOADER_PATHS_STORE);
|
|
800
|
+
if (!ctx) {
|
|
801
|
+
ctx = {
|
|
802
|
+
loaderPaths: {}
|
|
803
|
+
};
|
|
804
|
+
requestEv.sharedMap.set(REQUEST_LOADER_PATHS_STORE, ctx);
|
|
805
|
+
}
|
|
806
|
+
return ctx;
|
|
807
|
+
}
|
|
808
|
+
const updateRouteLoaderPaths = (ctx, loaderPaths, pageUrl) => {
|
|
809
|
+
if (!isServer$1) {
|
|
810
|
+
ctx.pagePathname = pageUrl.pathname;
|
|
811
|
+
ctx.pageSearch = pageUrl.search;
|
|
812
|
+
if (isDev) {
|
|
813
|
+
ctx.devRouteLoaderPaths = {};
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
if (loaderPaths) {
|
|
817
|
+
for (const key in loaderPaths) {
|
|
818
|
+
ctx.loaderPaths[key] = loaderPaths[key];
|
|
819
|
+
if (!isServer$1 && isDev) {
|
|
820
|
+
ctx.devRouteLoaderPaths[key] = true;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
const getModuleRouteLoaders = (mods) => {
|
|
826
|
+
const routeLoaders = [];
|
|
827
|
+
const seen = /* @__PURE__ */ new Map();
|
|
828
|
+
for (let i = 0; i < mods.length; i++) {
|
|
829
|
+
const mod = mods[i];
|
|
830
|
+
if (!mod) {
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
for (const key in mod) {
|
|
834
|
+
const value = mod[key];
|
|
835
|
+
if (isLoaderInternal(value)) {
|
|
836
|
+
const existing = seen.get(value.__id);
|
|
837
|
+
if (existing) {
|
|
838
|
+
if (isDev && existing !== value) {
|
|
839
|
+
console.warn(`Two route loaders share the same id "${value.__id}". Only the first will run; the others are ignored. If they are created by a shared wrapper around routeLoader$, give each loader a distinct \`id\` option.`);
|
|
840
|
+
}
|
|
841
|
+
continue;
|
|
842
|
+
}
|
|
843
|
+
seen.set(value.__id, value);
|
|
844
|
+
routeLoaders.push(value);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return routeLoaders;
|
|
849
|
+
};
|
|
850
|
+
const immutableLoaderIds = /* @__PURE__ */ new Set();
|
|
851
|
+
const isImmutableLoader = (loaderId) => immutableLoaderIds.has(loaderId);
|
|
852
|
+
const invalidateNavRouteLoaders = (state) => {
|
|
853
|
+
for (const id in state) {
|
|
854
|
+
if (!id.startsWith(ROUTE_LOADER_VALUE_PREFIX) && !immutableLoaderIds.has(id)) {
|
|
855
|
+
state[id].invalidate();
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
const setLoaderSignalValue = (signal, value) => {
|
|
860
|
+
_injectAsyncSignalValue(signal, value);
|
|
861
|
+
};
|
|
862
|
+
const matchesRouteLoaderId = (loader, loaderId) => {
|
|
863
|
+
return typeof loaderId === "string" && (loader.__id === loaderId || isDev && loader.__qrl.getHash() === loaderId);
|
|
864
|
+
};
|
|
865
|
+
const resolveRouteLoaderByHash = (routeLoaders, loaderId) => {
|
|
866
|
+
return routeLoaders.find((loader) => matchesRouteLoaderId(loader, loaderId));
|
|
867
|
+
};
|
|
868
|
+
const getLoaderRequestEvent = (loader, requestEv) => {
|
|
869
|
+
let rootRequestEv = requestEv.sharedMap.get(REQUEST_ROUTE_LOADER_ROOT_EVENT);
|
|
870
|
+
if (!rootRequestEv) {
|
|
871
|
+
rootRequestEv = requestEv;
|
|
872
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADER_ROOT_EVENT, rootRequestEv);
|
|
873
|
+
}
|
|
874
|
+
const url = new URL(rootRequestEv.url);
|
|
875
|
+
const pathname = globalThis.__STRICT_LOADERS__ ? getRouteLoaderCtx(rootRequestEv).loaderPaths[loader.__id] || rootRequestEv.url.pathname : rootRequestEv.url.pathname;
|
|
876
|
+
const filteredSearch = loader.__search ? filterSearchParams(url.searchParams, loader.__search) : rootRequestEv.url.search;
|
|
877
|
+
if (pathname === rootRequestEv.url.pathname && filteredSearch === rootRequestEv.url.search) {
|
|
878
|
+
return rootRequestEv;
|
|
879
|
+
}
|
|
880
|
+
let events = rootRequestEv.sharedMap.get(REQUEST_ROUTE_LOADER_EVENTS);
|
|
881
|
+
if (!events) {
|
|
882
|
+
events = /* @__PURE__ */ new Map();
|
|
883
|
+
rootRequestEv.sharedMap.set(REQUEST_ROUTE_LOADER_EVENTS, events);
|
|
884
|
+
}
|
|
885
|
+
const eventKey = `${pathname}
|
|
886
|
+
${filteredSearch}`;
|
|
887
|
+
let loaderRequestEv = events.get(eventKey);
|
|
888
|
+
if (!loaderRequestEv) {
|
|
889
|
+
url.pathname = pathname;
|
|
890
|
+
url.search = filteredSearch;
|
|
891
|
+
const request = new Request(url, rootRequestEv.request);
|
|
892
|
+
loaderRequestEv = Object.create(rootRequestEv, {
|
|
893
|
+
originalUrl: {
|
|
894
|
+
value: new URL(url),
|
|
895
|
+
enumerable: true
|
|
896
|
+
},
|
|
897
|
+
params: {
|
|
898
|
+
value: {},
|
|
899
|
+
enumerable: true
|
|
900
|
+
},
|
|
901
|
+
pathname: {
|
|
902
|
+
get: () => url.pathname,
|
|
903
|
+
enumerable: true
|
|
904
|
+
},
|
|
905
|
+
query: {
|
|
906
|
+
get: () => url.searchParams,
|
|
907
|
+
enumerable: true
|
|
908
|
+
},
|
|
909
|
+
request: {
|
|
910
|
+
value: request,
|
|
911
|
+
enumerable: true
|
|
912
|
+
},
|
|
913
|
+
url: {
|
|
914
|
+
value: url,
|
|
915
|
+
enumerable: true
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
events.set(eventKey, loaderRequestEv);
|
|
919
|
+
}
|
|
920
|
+
return loaderRequestEv;
|
|
921
|
+
};
|
|
922
|
+
const detachResponseFromEvent = (requestEv) => {
|
|
923
|
+
let status = 200;
|
|
924
|
+
const headers = new Headers();
|
|
925
|
+
return Object.create(requestEv, {
|
|
926
|
+
headers: {
|
|
927
|
+
value: headers,
|
|
928
|
+
enumerable: true
|
|
929
|
+
},
|
|
930
|
+
status: {
|
|
931
|
+
value: (statusCode) => {
|
|
932
|
+
if (typeof statusCode === "number") {
|
|
933
|
+
status = statusCode;
|
|
934
|
+
}
|
|
935
|
+
return status;
|
|
936
|
+
},
|
|
937
|
+
enumerable: true
|
|
938
|
+
},
|
|
939
|
+
error: {
|
|
940
|
+
value: (statusCode, message) => {
|
|
941
|
+
status = statusCode;
|
|
942
|
+
return new ServerError(statusCode, message);
|
|
943
|
+
},
|
|
944
|
+
enumerable: true
|
|
945
|
+
},
|
|
946
|
+
redirect: {
|
|
947
|
+
value: (statusCode, url) => {
|
|
948
|
+
status = statusCode;
|
|
949
|
+
if (url) {
|
|
950
|
+
headers.set("Location", url);
|
|
951
|
+
}
|
|
952
|
+
return new RedirectMessage();
|
|
953
|
+
},
|
|
954
|
+
enumerable: true
|
|
955
|
+
},
|
|
956
|
+
fail: {
|
|
957
|
+
value: (statusCode, data) => {
|
|
958
|
+
status = statusCode;
|
|
959
|
+
return {
|
|
960
|
+
failed: true,
|
|
961
|
+
...data
|
|
962
|
+
};
|
|
963
|
+
},
|
|
964
|
+
enumerable: true
|
|
965
|
+
},
|
|
966
|
+
// A background loader cannot set the page's cache headers.
|
|
967
|
+
cacheControl: {
|
|
968
|
+
value: () => {
|
|
969
|
+
},
|
|
970
|
+
enumerable: true
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
};
|
|
974
|
+
async function runValidators(requestEv, validators, data) {
|
|
975
|
+
let lastResult = {
|
|
976
|
+
success: true,
|
|
977
|
+
data
|
|
978
|
+
};
|
|
979
|
+
if (validators) {
|
|
980
|
+
for (let i = 0; i < validators.length; i++) {
|
|
981
|
+
const validator = validators[i];
|
|
982
|
+
lastResult = await validator.validate(requestEv, data);
|
|
983
|
+
if (!lastResult.success) {
|
|
984
|
+
return lastResult;
|
|
985
|
+
}
|
|
986
|
+
data = lastResult.data;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
return lastResult;
|
|
990
|
+
}
|
|
991
|
+
function verifySerializable(data, qrl) {
|
|
992
|
+
try {
|
|
993
|
+
_verifySerializable(data, void 0);
|
|
994
|
+
} catch (error) {
|
|
995
|
+
if (error instanceof Error && qrl.dev) {
|
|
996
|
+
error.loc = qrl.dev;
|
|
997
|
+
}
|
|
998
|
+
throw error;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
const getRouteLoaderData = async (loaderQrl, validators, requestEv) => {
|
|
1002
|
+
const loaderRequestEv = requestEv;
|
|
1003
|
+
const result = await runValidators(requestEv, validators, void 0);
|
|
1004
|
+
if (!result.success) {
|
|
1005
|
+
return loaderRequestEv.fail(result.status ?? 500, result.error);
|
|
1006
|
+
}
|
|
1007
|
+
const resolved = await loaderQrl.call(loaderRequestEv, loaderRequestEv);
|
|
1008
|
+
const value = typeof resolved === "function" ? resolved() : resolved;
|
|
1009
|
+
throwIfControlFlowSignal(value);
|
|
1010
|
+
if (isDev) {
|
|
1011
|
+
verifySerializable(value, loaderQrl);
|
|
1012
|
+
}
|
|
1013
|
+
return value;
|
|
1014
|
+
};
|
|
1015
|
+
const loadRouteLoaderByQrl = (loaderId, loaderQrl, validators, requestEv) => {
|
|
1016
|
+
const values = getRouteLoaderValues(requestEv);
|
|
1017
|
+
if (loaderId in values) {
|
|
1018
|
+
return Promise.resolve(values[loaderId]);
|
|
1019
|
+
}
|
|
1020
|
+
const promises = getRouteLoaderPromises(requestEv);
|
|
1021
|
+
let promise = promises[loaderId];
|
|
1022
|
+
if (!promise) {
|
|
1023
|
+
promise = getRouteLoaderData(loaderQrl, validators, requestEv).then((value) => {
|
|
1024
|
+
values[loaderId] = value;
|
|
1025
|
+
return value;
|
|
1026
|
+
}, (err) => {
|
|
1027
|
+
delete promises[loaderId];
|
|
1028
|
+
throw err;
|
|
1029
|
+
});
|
|
1030
|
+
promises[loaderId] = promise;
|
|
1031
|
+
}
|
|
1032
|
+
return promise;
|
|
1033
|
+
};
|
|
1034
|
+
class ServerRouteLoaderCapture {
|
|
1035
|
+
hash;
|
|
1036
|
+
qrl;
|
|
1037
|
+
validators;
|
|
1038
|
+
blockSSR;
|
|
1039
|
+
constructor(hash, qrl, validators, blockSSR) {
|
|
1040
|
+
this.hash = hash;
|
|
1041
|
+
this.qrl = qrl;
|
|
1042
|
+
this.validators = validators;
|
|
1043
|
+
this.blockSSR = blockSSR;
|
|
1044
|
+
}
|
|
1045
|
+
load() {
|
|
1046
|
+
const requestEv = getRequestEvent();
|
|
1047
|
+
if (!requestEv) {
|
|
1048
|
+
throw new Error("Unable to determine the current RequestEvent.");
|
|
1049
|
+
}
|
|
1050
|
+
const values = getRouteLoaderValues(requestEv);
|
|
1051
|
+
if (this.hash in values) {
|
|
1052
|
+
return values[this.hash];
|
|
1053
|
+
}
|
|
1054
|
+
const ev = this.blockSSR ? requestEv : detachResponseFromEvent(requestEv);
|
|
1055
|
+
return loadRouteLoaderByQrl(this.hash, this.qrl, this.validators, ev);
|
|
1056
|
+
}
|
|
1057
|
+
[SerializerSymbol]() {
|
|
1058
|
+
return this.hash;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
const createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
1062
|
+
const id = loader.__id;
|
|
1063
|
+
const stateValues = state;
|
|
1064
|
+
const resumeValueKey = getRouteLoaderValueStateKey(id);
|
|
1065
|
+
const capture = isServer$1 ? new ServerRouteLoaderCapture(id, loader.__qrl, loader.__validators, loader.__blockSSR) : id;
|
|
1066
|
+
const searchFilter = loader.__search;
|
|
1067
|
+
const lastFetch = {};
|
|
1068
|
+
const signal = createComputedQrl(/* @__PURE__ */ inlinedQrl(async (ctx) => {
|
|
1069
|
+
const capture2 = _captures[0], id2 = _captures[1], lastFetch2 = _captures[2], resumeValueKey2 = _captures[3], routeLoaderCtx2 = _captures[4], searchFilter2 = _captures[5], stateValues2 = _captures[6];
|
|
1070
|
+
const hasInjectedValue = !!ctx.info && typeof ctx.info === "object" && "__v" in ctx.info;
|
|
1071
|
+
const trackedRoutePath = ctx.track(routeLoaderCtx2.loaderPaths, id2);
|
|
1072
|
+
const trackedPagePathname = ctx.track(routeLoaderCtx2, "pagePathname");
|
|
1073
|
+
const trackedPageSearch = ctx.track(routeLoaderCtx2, "pageSearch");
|
|
1074
|
+
if (hasInjectedValue) {
|
|
1075
|
+
const value = ctx.info.__v;
|
|
1076
|
+
if (!isServer$1 && resumeValueKey2 in stateValues2) {
|
|
1077
|
+
stateValues2[resumeValueKey2] = value;
|
|
1078
|
+
}
|
|
1079
|
+
lastFetch2.raw = void 0;
|
|
1080
|
+
return value;
|
|
1081
|
+
}
|
|
1082
|
+
if (isServer$1) {
|
|
1083
|
+
return capture2.load();
|
|
1084
|
+
}
|
|
1085
|
+
const pagePathname = trackedPagePathname || location.pathname;
|
|
1086
|
+
const pageSearch = trackedPageSearch || location.search;
|
|
1087
|
+
const pageUrl = new URL(pagePathname + pageSearch, location.href);
|
|
1088
|
+
const mHash = routeLoaderCtx2.manifestHash || "dev";
|
|
1089
|
+
const basePath = qwikRouterConfig.basePathname ?? "/";
|
|
1090
|
+
const needsResumeFetch = stateValues2[resumeValueKey2] === _UNINITIALIZED;
|
|
1091
|
+
const fetchRoutePath = trackedRoutePath || (needsResumeFetch ? pageUrl.pathname : void 0);
|
|
1092
|
+
if (!fetchRoutePath) {
|
|
1093
|
+
return ctx.previous;
|
|
1094
|
+
}
|
|
1095
|
+
let fetchUrl = pageUrl;
|
|
1096
|
+
if (searchFilter2) {
|
|
1097
|
+
fetchUrl = new URL(pageUrl.href);
|
|
1098
|
+
fetchUrl.search = filterSearchParams(pageUrl.searchParams, searchFilter2);
|
|
1099
|
+
}
|
|
1100
|
+
const result = await fetchRouteLoaderData(id2, fetchRoutePath, mHash, {
|
|
1101
|
+
pageUrl: fetchUrl,
|
|
1102
|
+
basePath,
|
|
1103
|
+
ignoreCache: ctx.info === true,
|
|
1104
|
+
signal: ctx.abortSignal
|
|
1105
|
+
});
|
|
1106
|
+
if (!result) {
|
|
1107
|
+
throw new Error(`Loader ${id2} returned empty response`);
|
|
1108
|
+
}
|
|
1109
|
+
let response;
|
|
1110
|
+
if (result.raw === void 0) {
|
|
1111
|
+
response = result;
|
|
1112
|
+
} else {
|
|
1113
|
+
if (result.raw === lastFetch2.raw && ctx.previous !== void 0) {
|
|
1114
|
+
return ctx.previous;
|
|
1115
|
+
}
|
|
1116
|
+
response = await _deserialize(result.raw);
|
|
1117
|
+
if (!response) {
|
|
1118
|
+
throw new Error(`Loader ${id2} returned empty response`);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
if (response.r) {
|
|
1122
|
+
const goto = routeLoaderCtx2.goto;
|
|
1123
|
+
if (goto) {
|
|
1124
|
+
goto(response.r, {
|
|
1125
|
+
replaceState: true
|
|
1126
|
+
});
|
|
1127
|
+
} else {
|
|
1128
|
+
location.href = response.r;
|
|
1129
|
+
}
|
|
1130
|
+
return ctx.previous;
|
|
1131
|
+
}
|
|
1132
|
+
if (response.e) {
|
|
1133
|
+
throw response.e;
|
|
1134
|
+
}
|
|
1135
|
+
lastFetch2.raw = result.raw;
|
|
1136
|
+
if (needsResumeFetch) {
|
|
1137
|
+
stateValues2[resumeValueKey2] = response.d;
|
|
1138
|
+
}
|
|
1139
|
+
return response.d;
|
|
1140
|
+
}, "createRouteLoaderSignal_signal_createComputed_4s4ZDCYhDOA", [
|
|
1141
|
+
capture,
|
|
1142
|
+
id,
|
|
1143
|
+
lastFetch,
|
|
1144
|
+
resumeValueKey,
|
|
1145
|
+
routeLoaderCtx,
|
|
1146
|
+
searchFilter,
|
|
1147
|
+
stateValues
|
|
1148
|
+
]), {
|
|
1149
|
+
serializationStrategy: loader.__serializationStrategy
|
|
1150
|
+
});
|
|
1151
|
+
_markSignalAsExternallyOwned(signal);
|
|
1152
|
+
return signal;
|
|
1153
|
+
};
|
|
1154
|
+
const ensureRouteLoaderSignal = (loader, state, routeLoaderCtx) => {
|
|
1155
|
+
if (loader.__cacheControl === "immutable") {
|
|
1156
|
+
immutableLoaderIds.add(loader.__id);
|
|
1157
|
+
}
|
|
1158
|
+
if (isServer$1 && loader.__serializationStrategy === "never") {
|
|
1159
|
+
state[getRouteLoaderValueStateKey(loader.__id)] = _UNINITIALIZED;
|
|
1160
|
+
}
|
|
1161
|
+
return state[loader.__id] ||= createRouteLoaderSignal(loader, routeLoaderCtx, state);
|
|
1162
|
+
};
|
|
1163
|
+
const ensureRouteLoaderSignals = (mods, state, routeLoaderCtx) => {
|
|
1164
|
+
const loaders = getModuleRouteLoaders(mods);
|
|
1165
|
+
for (let i = 0; i < loaders.length; i++) {
|
|
1166
|
+
const loader = loaders[i];
|
|
1167
|
+
if (isDev && !isServer$1) {
|
|
1168
|
+
const devCtx = routeLoaderCtx;
|
|
1169
|
+
if (devCtx.pagePathname && !devCtx.devRouteLoaderPaths?.[loader.__id]) {
|
|
1170
|
+
devCtx.loaderPaths[loader.__id] = devCtx.pagePathname;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
ensureRouteLoaderSignal(loader, state, routeLoaderCtx);
|
|
1174
|
+
}
|
|
1175
|
+
return loaders;
|
|
1176
|
+
};
|
|
1177
|
+
const loadRouteLoader = (loader, requestEv) => {
|
|
1178
|
+
const loaderEv = getLoaderRequestEvent(loader, requestEv);
|
|
1179
|
+
return loadRouteLoaderByQrl(
|
|
1180
|
+
loader.__id,
|
|
1181
|
+
loader.__qrl,
|
|
1182
|
+
loader.__validators,
|
|
1183
|
+
// A background (blockSSR:false) loader must not touch the page response.
|
|
1184
|
+
loader.__blockSSR ? loaderEv : detachResponseFromEvent(loaderEv)
|
|
1185
|
+
);
|
|
1186
|
+
};
|
|
1187
|
+
const getRouteLoaderResponse = async (loaderQrl, validators, requestEv) => {
|
|
1188
|
+
try {
|
|
1189
|
+
const value = await getRouteLoaderData(loaderQrl, validators, requestEv);
|
|
1190
|
+
return {
|
|
1191
|
+
d: value
|
|
1192
|
+
};
|
|
1193
|
+
} catch (err) {
|
|
1194
|
+
if (err instanceof RedirectMessage) {
|
|
1195
|
+
const location1 = requestEv.headers.get("Location") || "/";
|
|
1196
|
+
requestEv.headers.delete("Location");
|
|
1197
|
+
return {
|
|
1198
|
+
r: location1
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
if (err instanceof ServerError) {
|
|
1202
|
+
return {
|
|
1203
|
+
e: err
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
throw err;
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
const routeLoaderQrl = (loaderQrl, ...rest) => {
|
|
1210
|
+
const { id, validators, serializationStrategy, cacheControl, eTag, cacheKey, search, blockSSR } = getLoaderOptions(rest);
|
|
1211
|
+
function loader() {
|
|
1212
|
+
const state = _resolveContextWithoutSequentialScope(RouteStateContext);
|
|
1213
|
+
let signal = state[loader.__id];
|
|
1214
|
+
if (!signal) {
|
|
1215
|
+
const routeLoaderCtx = _resolveContextWithoutSequentialScope(RouteLoaderCtxContext);
|
|
1216
|
+
signal = ensureRouteLoaderSignal(loader, state, routeLoaderCtx);
|
|
1217
|
+
}
|
|
1218
|
+
void signal.promise();
|
|
1219
|
+
return signal;
|
|
1220
|
+
}
|
|
1221
|
+
loader.__brand = "server_loader";
|
|
1222
|
+
loader.__qrl = loaderQrl;
|
|
1223
|
+
loader.__validators = validators;
|
|
1224
|
+
loader.__id = id ?? loaderQrl.getHash();
|
|
1225
|
+
loader.__serializationStrategy = serializationStrategy;
|
|
1226
|
+
loader.__cacheControl = cacheControl;
|
|
1227
|
+
loader.__eTag = eTag;
|
|
1228
|
+
loader.__cacheKey = cacheKey;
|
|
1229
|
+
loader.__search = search;
|
|
1230
|
+
loader.__blockSSR = blockSSR;
|
|
1231
|
+
Object.freeze(loader);
|
|
1232
|
+
return loader;
|
|
1233
|
+
};
|
|
1234
|
+
const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl);
|
|
1235
|
+
|
|
515
1236
|
const toPath = (url) => url.pathname + url.search + url.hash;
|
|
516
1237
|
const toUrl = (url, baseUrl) => new URL(url, baseUrl.href);
|
|
517
1238
|
const isSameOrigin = (a, b) => a.origin === b.origin;
|
|
@@ -701,4 +1422,4 @@ const resolveHead = (actionData, loaderState, routeLocation, contentModules, loc
|
|
|
701
1422
|
return resolveRouteConfig(getData, routeLocation, contentModules, locale, actionData?.status ?? 200, defaults).head;
|
|
702
1423
|
};
|
|
703
1424
|
|
|
704
|
-
export {
|
|
1425
|
+
export { QFN_KEY as A, QDATA_KEY as B, ContentContext as C, DocumentHeadContext as D, routeLoader$ as E, FULLPATH_HEADER as F, routeLoaderQrl as G, HttpStatusContext as H, getRouteLoaders as I, getRouteLoaderValues as J, loadRouteLoader as K, isPromise as L, getLoaderRequestEvent as M, resolveRouteLoaderByHash as N, getRouteLoaderResponse as O, getRouteLoaderCtx as P, QACTION_KEY as Q, ROUTE_PATH_HEADER as R, setRouteLoaders as S, resolveRouteConfig as T, clearRouteLoaderData as U, matchesRouteLoaderId as V, _asyncRequestStore as _, getClientNavPath as a, isSameOrigin as b, setLoaderSignalValue as c, createDocumentHead as d, ensureRouteLoaderSignals as e, fetchRouteLoaderData as f, getModuleRouteLoaders as g, ContentInternalContext as h, isSamePath as i, RouteLocationContext as j, RouteNavigateContext as k, loadRoute as l, RouteStateContext as m, RouteLoaderCtxContext as n, RouteActionContext as o, RoutePreventNavigateContext as p, invalidateNavRouteLoaders as q, isImmutableLoader as r, shouldPreload as s, toPath as t, updateRouteLoaderPaths as u, clearNavFetchCache as v, resolveHead as w, Q_ROUTE as x, toUrl as y, getRequestEvent as z };
|