@qwik.dev/router 2.0.0-beta.36 → 2.0.0-beta.38
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 +3 -5
- package/lib/adapters/shared/vite/index.d.ts +3 -4
- package/lib/adapters/shared/vite/index.mjs +167 -155
- package/lib/chunks/dev-preloaded-route-loader.mjs +3 -0
- package/lib/chunks/format.mjs +31 -0
- package/lib/chunks/fs.mjs +10 -8
- package/lib/chunks/head.qwik.mjs +1425 -0
- package/lib/chunks/http-error.qwik.mjs +2 -2
- package/lib/chunks/pathname.mjs +3 -32
- package/lib/chunks/request-body-limit.mjs +37 -0
- package/lib/chunks/request-path.mjs +60 -0
- package/lib/chunks/routes.mjs +47 -0
- package/lib/chunks/server-error.mjs +19 -0
- package/lib/chunks/system.mjs +8 -8
- package/lib/chunks/use-functions.qwik.mjs +3 -12
- package/lib/chunks/user-response.mjs +1875 -0
- package/lib/chunks/worker-thread.mjs +317 -0
- package/lib/index.d.ts +251 -44
- package/lib/index.qwik.mjs +734 -485
- package/lib/middleware/aws-lambda/index.mjs +2 -1
- 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 +65 -26
- package/lib/middleware/request-handler/index.mjs +38 -1679
- package/lib/middleware/vercel-edge/index.mjs +2 -2
- package/lib/ssg/index.d.ts +5 -13
- package/lib/ssg/index.mjs +14 -53
- package/lib/vite/index.d.ts +23 -0
- package/lib/vite/index.mjs +533 -122
- package/package.json +4 -3
- package/lib/chunks/deepFreeze.qwik.mjs +0 -18
- package/lib/chunks/error-handler.mjs +0 -57
- package/lib/chunks/not-found-wrapper.qwik.mjs +0 -25
- package/lib/chunks/redirect-handler.mjs +0 -6
- package/lib/chunks/routing.qwik.mjs +0 -821
- package/lib/chunks/worker-thread.qwik.mjs +0 -2585
|
@@ -0,0 +1,1425 @@
|
|
|
1
|
+
import { e as ensureSlash } from './pathname.mjs';
|
|
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, _markSignalAsExternallyOwned, _deserialize, 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
|
+
};
|
|
35
|
+
|
|
36
|
+
const MODULE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
37
|
+
const httpErrorLoader = () => import('./http-error.qwik.mjs');
|
|
38
|
+
function walkTrieKeys(root, keys) {
|
|
39
|
+
let node = root;
|
|
40
|
+
const layouts = [];
|
|
41
|
+
if (node._L) {
|
|
42
|
+
layouts.push(node._L);
|
|
43
|
+
}
|
|
44
|
+
for (let i = 0; i < keys.length; i++) {
|
|
45
|
+
const key = keys[i];
|
|
46
|
+
let next = node[key];
|
|
47
|
+
if (!next && node._M) {
|
|
48
|
+
for (let j = 0; j < node._M.length; j++) {
|
|
49
|
+
const group = node._M[j];
|
|
50
|
+
next = group[key];
|
|
51
|
+
if (next) {
|
|
52
|
+
if (group._L) {
|
|
53
|
+
layouts.push(group._L);
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (!next) {
|
|
60
|
+
return void 0;
|
|
61
|
+
}
|
|
62
|
+
node = next;
|
|
63
|
+
if (node._L) {
|
|
64
|
+
layouts.push(node._L);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
node,
|
|
69
|
+
layouts
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const boundaryChain = (ref) => ref.v ? Array.isArray(ref.v) ? ref.v : [
|
|
73
|
+
...ref.layouts,
|
|
74
|
+
ref.v
|
|
75
|
+
] : void 0;
|
|
76
|
+
function collectNodeMeta(node, groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef, loaderHashes, loaderPathsByHash, matchedPathname = "/") {
|
|
77
|
+
for (let j = 0; j < groups.length; j++) {
|
|
78
|
+
const g = groups[j];
|
|
79
|
+
if (g._L) {
|
|
80
|
+
layouts.push(g._L);
|
|
81
|
+
}
|
|
82
|
+
if (g._R && loaderHashes) {
|
|
83
|
+
loaderHashes.push(...g._R);
|
|
84
|
+
if (loaderPathsByHash) {
|
|
85
|
+
for (let i = 0; i < g._R.length; i++) {
|
|
86
|
+
const hash = g._R[i];
|
|
87
|
+
loaderPathsByHash[hash] = matchedPathname;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (g._E) {
|
|
92
|
+
errorLoaderRef.v = g._E;
|
|
93
|
+
errorLoaderRef.layouts = [
|
|
94
|
+
...layouts
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
if (g._4) {
|
|
98
|
+
notFoundLoaderRef.v = g._4;
|
|
99
|
+
notFoundLoaderRef.layouts = [
|
|
100
|
+
...layouts
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
if (g._N) {
|
|
104
|
+
menuLoaderRef.v = g._N;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (node._L) {
|
|
108
|
+
layouts.push(node._L);
|
|
109
|
+
}
|
|
110
|
+
if (node._R && loaderHashes) {
|
|
111
|
+
loaderHashes.push(...node._R);
|
|
112
|
+
if (loaderPathsByHash) {
|
|
113
|
+
for (let i = 0; i < node._R.length; i++) {
|
|
114
|
+
const hash = node._R[i];
|
|
115
|
+
loaderPathsByHash[hash] = matchedPathname;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (node._E) {
|
|
120
|
+
errorLoaderRef.v = node._E;
|
|
121
|
+
errorLoaderRef.layouts = [
|
|
122
|
+
...layouts
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
if (node._4) {
|
|
126
|
+
notFoundLoaderRef.v = node._4;
|
|
127
|
+
notFoundLoaderRef.layouts = [
|
|
128
|
+
...layouts
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
if (node._N) {
|
|
132
|
+
menuLoaderRef.v = node._N;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function tryWildcardMatch(node, part, partLower, parts, partIndex) {
|
|
136
|
+
let next = node._W;
|
|
137
|
+
if (next) {
|
|
138
|
+
const prefix = next._0;
|
|
139
|
+
const suffix = next._9;
|
|
140
|
+
if (prefix || suffix) {
|
|
141
|
+
const pre = prefix || "";
|
|
142
|
+
const suf = suffix || "";
|
|
143
|
+
if (partLower.length > pre.length + suf.length && (!pre || partLower.startsWith(pre.toLowerCase())) && (!suf || partLower.endsWith(suf.toLowerCase()))) {
|
|
144
|
+
const paramName = next._P;
|
|
145
|
+
const value = part.slice(pre.length, suf ? part.length - suf.length : void 0);
|
|
146
|
+
return {
|
|
147
|
+
next,
|
|
148
|
+
routePart: `${pre}[${paramName}]${suf}`,
|
|
149
|
+
done: false,
|
|
150
|
+
kind: 1,
|
|
151
|
+
paramName,
|
|
152
|
+
paramValue: value
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
const paramName = next._P;
|
|
157
|
+
return {
|
|
158
|
+
next,
|
|
159
|
+
routePart: `[${paramName}]`,
|
|
160
|
+
done: false,
|
|
161
|
+
kind: 1,
|
|
162
|
+
paramName,
|
|
163
|
+
paramValue: part
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
next = node._A;
|
|
168
|
+
if (next) {
|
|
169
|
+
const paramName = next._P;
|
|
170
|
+
const restValue = parts.slice(partIndex).join("/");
|
|
171
|
+
return {
|
|
172
|
+
next,
|
|
173
|
+
routePart: `[...${paramName}]`,
|
|
174
|
+
done: true,
|
|
175
|
+
kind: 2,
|
|
176
|
+
paramName,
|
|
177
|
+
paramValue: restValue
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return void 0;
|
|
181
|
+
}
|
|
182
|
+
function findChild(node, part, partLower, parts, partIndex) {
|
|
183
|
+
const exact = node[partLower];
|
|
184
|
+
if (exact) {
|
|
185
|
+
return {
|
|
186
|
+
next: exact,
|
|
187
|
+
groups: [],
|
|
188
|
+
routePart: part,
|
|
189
|
+
done: false,
|
|
190
|
+
kind: 0
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (node._M) {
|
|
194
|
+
for (let j = 0; j < node._M.length; j++) {
|
|
195
|
+
const group = node._M[j];
|
|
196
|
+
const groupResult = findChild(group, part, partLower, parts, partIndex);
|
|
197
|
+
if (groupResult) {
|
|
198
|
+
groupResult.groups.unshift(group);
|
|
199
|
+
return groupResult;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const wildcard = tryWildcardMatch(node, part, partLower, parts, partIndex);
|
|
204
|
+
if (wildcard) {
|
|
205
|
+
return {
|
|
206
|
+
...wildcard,
|
|
207
|
+
groups: []
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return void 0;
|
|
211
|
+
}
|
|
212
|
+
function descendGroups(node, hit) {
|
|
213
|
+
const value = hit(node);
|
|
214
|
+
if (value !== void 0) {
|
|
215
|
+
return {
|
|
216
|
+
value,
|
|
217
|
+
node,
|
|
218
|
+
groups: []
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (node._M) {
|
|
222
|
+
for (let j = 0; j < node._M.length; j++) {
|
|
223
|
+
const group = node._M[j];
|
|
224
|
+
const result = descendGroups(group, hit);
|
|
225
|
+
if (result) {
|
|
226
|
+
result.groups.unshift(group);
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return void 0;
|
|
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
|
+
}
|
|
240
|
+
function resolveLoaders(root, node, gatheredLayouts) {
|
|
241
|
+
if (node._G != null) {
|
|
242
|
+
const keys = node._G.split("/").filter((p) => p.length > 0);
|
|
243
|
+
const target = walkTrieKeys(root, keys);
|
|
244
|
+
if (!target) {
|
|
245
|
+
return void 0;
|
|
246
|
+
}
|
|
247
|
+
let targetNode = target.node;
|
|
248
|
+
const targetLayouts = target.layouts;
|
|
249
|
+
if (!targetNode._I && targetNode._G == null) {
|
|
250
|
+
const indexResult = findIndexNode(targetNode);
|
|
251
|
+
if (indexResult) {
|
|
252
|
+
for (let j = 0; j < indexResult.groups.length; j++) {
|
|
253
|
+
const g = indexResult.groups[j];
|
|
254
|
+
if (g._L) {
|
|
255
|
+
targetLayouts.push(g._L);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
targetNode = indexResult.target;
|
|
259
|
+
if (targetNode._L) {
|
|
260
|
+
targetLayouts.push(targetNode._L);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return resolveLoaders(root, targetNode, targetLayouts);
|
|
265
|
+
}
|
|
266
|
+
const index = node._I;
|
|
267
|
+
if (!index) {
|
|
268
|
+
return void 0;
|
|
269
|
+
}
|
|
270
|
+
if (Array.isArray(index)) {
|
|
271
|
+
return index;
|
|
272
|
+
}
|
|
273
|
+
return [
|
|
274
|
+
...gatheredLayouts,
|
|
275
|
+
index
|
|
276
|
+
];
|
|
277
|
+
}
|
|
278
|
+
function findRestNode(node) {
|
|
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;
|
|
289
|
+
}
|
|
290
|
+
const groupLayouts = [
|
|
291
|
+
...layouts
|
|
292
|
+
];
|
|
293
|
+
for (const g of r.groups) {
|
|
294
|
+
if (g._L) {
|
|
295
|
+
groupLayouts.push(g._L);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
v: r.value,
|
|
300
|
+
layouts: groupLayouts
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function matchRouteTree(root = {}, pathname) {
|
|
304
|
+
let node = root;
|
|
305
|
+
const params = {};
|
|
306
|
+
const routeParts = [];
|
|
307
|
+
const layouts = [];
|
|
308
|
+
const loaderHashes = [];
|
|
309
|
+
const loaderPathsByHash = {};
|
|
310
|
+
const errorLoaderRef = {
|
|
311
|
+
v: void 0,
|
|
312
|
+
layouts: []
|
|
313
|
+
};
|
|
314
|
+
const notFoundLoaderRef = {
|
|
315
|
+
v: void 0,
|
|
316
|
+
layouts: []
|
|
317
|
+
};
|
|
318
|
+
const menuLoaderRef = {
|
|
319
|
+
v: void 0
|
|
320
|
+
};
|
|
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
|
+
});
|
|
328
|
+
}
|
|
329
|
+
let done = false;
|
|
330
|
+
let matched = true;
|
|
331
|
+
const parts = pathname.split("/").filter((p) => p.length > 0).map(decodeURIComponent);
|
|
332
|
+
let restFallback;
|
|
333
|
+
let i = 0;
|
|
334
|
+
const len = parts.length;
|
|
335
|
+
for (; !done && i < len; i++) {
|
|
336
|
+
const part = parts[i];
|
|
337
|
+
const partLower = part.toLowerCase();
|
|
338
|
+
const found = findChild(node, part, partLower, parts, i);
|
|
339
|
+
if (!found) {
|
|
340
|
+
matched = false;
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
const restInfo = found.kind === 1 ? findRestNode(node) : void 0;
|
|
344
|
+
if (restInfo) {
|
|
345
|
+
restFallback = {
|
|
346
|
+
aNode: restInfo.next,
|
|
347
|
+
groups: restInfo.groups,
|
|
348
|
+
paramName: restInfo.next._P,
|
|
349
|
+
restValue: parts.slice(i).join("/"),
|
|
350
|
+
routeParts: [
|
|
351
|
+
...routeParts
|
|
352
|
+
],
|
|
353
|
+
params: {
|
|
354
|
+
...params
|
|
355
|
+
},
|
|
356
|
+
layouts: [
|
|
357
|
+
...layouts
|
|
358
|
+
],
|
|
359
|
+
loaderPathsByHash: {
|
|
360
|
+
...loaderPathsByHash
|
|
361
|
+
},
|
|
362
|
+
errorLoader: errorLoaderRef.v,
|
|
363
|
+
errorLayouts: errorLoaderRef.layouts,
|
|
364
|
+
notFoundLoader: notFoundLoaderRef.v,
|
|
365
|
+
notFoundLayouts: notFoundLoaderRef.layouts,
|
|
366
|
+
menuLoader: menuLoaderRef.v
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
if (found.paramName) {
|
|
370
|
+
params[found.paramName] = found.paramValue;
|
|
371
|
+
}
|
|
372
|
+
routeParts.push(found.routePart);
|
|
373
|
+
done = found.done;
|
|
374
|
+
node = found.next;
|
|
375
|
+
const matchedPathname = `/${parts.slice(0, found.done ? len : i + 1).join("/")}/`;
|
|
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
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (matched && !done && i === len) {
|
|
385
|
+
if (!node._I && node._G == null) {
|
|
386
|
+
const indexResult = findIndexNode(node);
|
|
387
|
+
if (indexResult) {
|
|
388
|
+
collectNodeMeta(indexResult.target, indexResult.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef, loaderHashes, loaderPathsByHash, pathname);
|
|
389
|
+
node = indexResult.target;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (!node._I && node._G == null) {
|
|
393
|
+
const restInfo = findRestNode(node);
|
|
394
|
+
if (restInfo) {
|
|
395
|
+
const next = restInfo.next;
|
|
396
|
+
const paramName = next._P;
|
|
397
|
+
params[paramName] = "";
|
|
398
|
+
routeParts.push(`[...${paramName}]`);
|
|
399
|
+
collectNodeMeta(next, restInfo.groups, layouts, errorLoaderRef, notFoundLoaderRef, menuLoaderRef, loaderHashes, loaderPathsByHash, pathname);
|
|
400
|
+
node = next;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const loaders = matched && (done || i >= len) ? resolveLoaders(root, node, layouts) : void 0;
|
|
405
|
+
if (!loaders && restFallback) {
|
|
406
|
+
const fb = restFallback;
|
|
407
|
+
const fbParams = {
|
|
408
|
+
...fb.params,
|
|
409
|
+
[fb.paramName]: fb.restValue
|
|
410
|
+
};
|
|
411
|
+
const fbRouteParts = [
|
|
412
|
+
...fb.routeParts,
|
|
413
|
+
`[...${fb.paramName}]`
|
|
414
|
+
];
|
|
415
|
+
const fbLayouts = [
|
|
416
|
+
...fb.layouts
|
|
417
|
+
];
|
|
418
|
+
const fbLoaderPathsByHash = {
|
|
419
|
+
...fb.loaderPathsByHash
|
|
420
|
+
};
|
|
421
|
+
const fbErrorRef = {
|
|
422
|
+
v: fb.errorLoader,
|
|
423
|
+
layouts: fb.errorLayouts
|
|
424
|
+
};
|
|
425
|
+
const fbNotFoundRef = {
|
|
426
|
+
v: fb.notFoundLoader,
|
|
427
|
+
layouts: fb.notFoundLayouts
|
|
428
|
+
};
|
|
429
|
+
const fbMenuRef = {
|
|
430
|
+
v: fb.menuLoader
|
|
431
|
+
};
|
|
432
|
+
const fbLoaderHashes = [];
|
|
433
|
+
collectNodeMeta(fb.aNode, fb.groups, fbLayouts, fbErrorRef, fbNotFoundRef, fbMenuRef, fbLoaderHashes, fbLoaderPathsByHash, pathname);
|
|
434
|
+
const fbLoaders = resolveLoaders(root, fb.aNode, fbLayouts);
|
|
435
|
+
if (fbLoaders) {
|
|
436
|
+
return {
|
|
437
|
+
loaders: fbLoaders,
|
|
438
|
+
params: fbParams,
|
|
439
|
+
routeParts: fbRouteParts,
|
|
440
|
+
notFound: false,
|
|
441
|
+
routeBundleNames: fb.aNode._B,
|
|
442
|
+
loaderHashes: fbLoaderHashes.length > 0 ? fbLoaderHashes : void 0,
|
|
443
|
+
loaderPathsByHash: Object.keys(fbLoaderPathsByHash).length > 0 ? fbLoaderPathsByHash : void 0,
|
|
444
|
+
menuLoader: fbMenuRef.v,
|
|
445
|
+
errorLoader: boundaryChain(fbErrorRef)
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
errorLoaderRef.v = fbErrorRef.v;
|
|
449
|
+
errorLoaderRef.layouts = fbErrorRef.layouts;
|
|
450
|
+
notFoundLoaderRef.v = fbNotFoundRef.v;
|
|
451
|
+
notFoundLoaderRef.layouts = fbNotFoundRef.layouts;
|
|
452
|
+
menuLoaderRef.v = fbMenuRef.v;
|
|
453
|
+
}
|
|
454
|
+
if (!loaders) {
|
|
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;
|
|
481
|
+
return {
|
|
482
|
+
loaders: Array.isArray(boundary) ? boundary : [
|
|
483
|
+
...boundaryLayouts,
|
|
484
|
+
boundary
|
|
485
|
+
],
|
|
486
|
+
params,
|
|
487
|
+
routeParts,
|
|
488
|
+
notFound: true,
|
|
489
|
+
routeBundleNames: void 0,
|
|
490
|
+
loaderHashes: void 0,
|
|
491
|
+
loaderPathsByHash: void 0,
|
|
492
|
+
menuLoader: menuLoaderRef.v,
|
|
493
|
+
errorLoader: boundaryChain(errorLoaderRef)
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
if (node._R) {
|
|
497
|
+
loaderHashes.push(...node._R);
|
|
498
|
+
const matchedPathname = ensureSlash(pathname);
|
|
499
|
+
for (let i2 = 0; i2 < node._R.length; i2++) {
|
|
500
|
+
const hash = node._R[i2];
|
|
501
|
+
loaderPathsByHash[hash] = matchedPathname;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
loaders,
|
|
506
|
+
params,
|
|
507
|
+
routeParts,
|
|
508
|
+
notFound: false,
|
|
509
|
+
routeBundleNames: node._B,
|
|
510
|
+
loaderHashes: loaderHashes.length > 0 ? loaderHashes : void 0,
|
|
511
|
+
loaderPathsByHash: Object.keys(loaderPathsByHash).length > 0 ? loaderPathsByHash : void 0,
|
|
512
|
+
menuLoader: menuLoaderRef.v,
|
|
513
|
+
errorLoader: boundaryChain(errorLoaderRef)
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => {
|
|
517
|
+
if (typeof moduleLoader === "function") {
|
|
518
|
+
const loadedModule = MODULE_CACHE.get(moduleLoader);
|
|
519
|
+
if (loadedModule) {
|
|
520
|
+
moduleSetter(loadedModule);
|
|
521
|
+
} else {
|
|
522
|
+
const moduleOrPromise = moduleLoader();
|
|
523
|
+
if (typeof moduleOrPromise.then === "function") {
|
|
524
|
+
pendingLoads.push(moduleOrPromise.then((loadedModule2) => {
|
|
525
|
+
if (cacheModules !== false) {
|
|
526
|
+
MODULE_CACHE.set(moduleLoader, loadedModule2);
|
|
527
|
+
}
|
|
528
|
+
moduleSetter(loadedModule2);
|
|
529
|
+
}));
|
|
530
|
+
} else if (moduleOrPromise) {
|
|
531
|
+
moduleSetter(moduleOrPromise);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
const loadRoute = async (routes, cacheModules, pathname) => {
|
|
537
|
+
const result = matchRouteTree(routes, pathname);
|
|
538
|
+
const { loaders, params, routeParts, notFound, routeBundleNames, loaderHashes, loaderPathsByHash, menuLoader, errorLoader } = result;
|
|
539
|
+
const routeName = "/" + routeParts.join("/");
|
|
540
|
+
const modules = new Array(loaders.length);
|
|
541
|
+
const pendingLoads = [];
|
|
542
|
+
for (let i = 0; i < loaders.length; i++) {
|
|
543
|
+
const moduleLoader = loaders[i];
|
|
544
|
+
loadModule(moduleLoader, pendingLoads, (routeModule) => modules[i] = routeModule, cacheModules);
|
|
545
|
+
}
|
|
546
|
+
let menu = void 0;
|
|
547
|
+
loadModule(menuLoader, pendingLoads, (menuModule) => menu = menuModule?.default, cacheModules);
|
|
548
|
+
if (pendingLoads.length > 0) {
|
|
549
|
+
await Promise.all(pendingLoads);
|
|
550
|
+
}
|
|
551
|
+
return {
|
|
552
|
+
$routeName$: routeName,
|
|
553
|
+
$params$: params,
|
|
554
|
+
$mods$: modules,
|
|
555
|
+
$menu$: deepFreeze(menu),
|
|
556
|
+
$routeBundleNames$: routeBundleNames,
|
|
557
|
+
$notFound$: notFound,
|
|
558
|
+
$errorLoader$: errorLoader,
|
|
559
|
+
$loaders$: loaderHashes,
|
|
560
|
+
$loaderPaths$: loaderPathsByHash
|
|
561
|
+
};
|
|
562
|
+
};
|
|
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_LOADER_PATHS_STORE = "@loaderPathsStore";
|
|
582
|
+
const REQUEST_ROUTE_LOADERS = "@routeLoaders";
|
|
583
|
+
const REQUEST_ROUTE_LOADER_PROMISES = "@routeLoaderPromises";
|
|
584
|
+
const REQUEST_ROUTE_LOADER_EVENTS = "@routeLoaderEvents";
|
|
585
|
+
const REQUEST_ROUTE_LOADER_ROOT_EVENT = "@routeLoaderRootEvent";
|
|
586
|
+
const ROUTE_LOADER_VALUE_PREFIX = "__qwik_route_loader_value__";
|
|
587
|
+
const FULLPATH_HEADER = "X-Qwik-fullpath";
|
|
588
|
+
const ROUTE_PATH_HEADER = "X-Qwik-route-path";
|
|
589
|
+
const LOADER_FETCH_CACHE_TTL = 5e3;
|
|
590
|
+
const LOADER_FETCH_CACHE_MAX = 128;
|
|
591
|
+
const fetchCache = /* @__PURE__ */ new Map();
|
|
592
|
+
const perfNow = () => globalThis.performance?.now() ?? Date.now();
|
|
593
|
+
const isRedirectStatus = (status) => status >= 300 && status < 400;
|
|
594
|
+
const setCache = (key, entry) => {
|
|
595
|
+
fetchCache.set(key, entry);
|
|
596
|
+
if (fetchCache.size > LOADER_FETCH_CACHE_MAX) {
|
|
597
|
+
const oldestKey = fetchCache.keys().next().value;
|
|
598
|
+
if (oldestKey !== void 0) {
|
|
599
|
+
fetchCache.delete(oldestKey);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
const wrapWithAbort = (promise, signal) => {
|
|
604
|
+
if (signal.aborted) {
|
|
605
|
+
return Promise.reject(signal.reason);
|
|
606
|
+
}
|
|
607
|
+
return new Promise((resolve, reject) => {
|
|
608
|
+
const abort = () => reject(signal.reason);
|
|
609
|
+
signal.addEventListener("abort", abort, {
|
|
610
|
+
once: true
|
|
611
|
+
});
|
|
612
|
+
promise.finally(() => signal.removeEventListener("abort", abort)).then(resolve, reject);
|
|
613
|
+
});
|
|
614
|
+
};
|
|
615
|
+
const getRouteLoaderValueStateKey = (loaderId) => `${ROUTE_LOADER_VALUE_PREFIX}${loaderId}`;
|
|
616
|
+
const isRequestEvent = (value) => !!value && typeof value === "object" && Object.prototype.hasOwnProperty.call(value, "sharedMap") && Object.prototype.hasOwnProperty.call(value, "cookie");
|
|
617
|
+
const isLoaderInternal = (value) => typeof value === "function" && value.__brand === "server_loader";
|
|
618
|
+
const fetchRouteLoaderData = async (loaderId, routePath, manifestHash, opts) => {
|
|
619
|
+
if (!routePath) {
|
|
620
|
+
return void 0;
|
|
621
|
+
}
|
|
622
|
+
let resolvedPath = routePath;
|
|
623
|
+
const basePath = opts?.basePath ?? "/";
|
|
624
|
+
if (basePath !== "/" && !resolvedPath.startsWith(basePath)) {
|
|
625
|
+
resolvedPath = basePath + resolvedPath.slice(1);
|
|
626
|
+
}
|
|
627
|
+
const pathBase = ensureSlash(resolvedPath);
|
|
628
|
+
const pageUrl = opts?.pageUrl;
|
|
629
|
+
const search = pageUrl?.search ?? "";
|
|
630
|
+
const url = `${pathBase}${getLoaderName(loaderId, manifestHash)}${search}`;
|
|
631
|
+
const headers = {};
|
|
632
|
+
if (pageUrl && pageUrl.pathname !== pathBase) {
|
|
633
|
+
if (!globalThis.__STRICT_LOADERS__) {
|
|
634
|
+
headers[FULLPATH_HEADER] = pageUrl.pathname;
|
|
635
|
+
} else if (isDev) {
|
|
636
|
+
headers[ROUTE_PATH_HEADER] = pageUrl.pathname;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
const cacheKey = `${url}
|
|
640
|
+
${headers[FULLPATH_HEADER] ?? ""}`;
|
|
641
|
+
if (!opts?.ignoreCache) {
|
|
642
|
+
const entry = fetchCache.get(cacheKey);
|
|
643
|
+
if (entry) {
|
|
644
|
+
if (entry.promise) {
|
|
645
|
+
return opts?.signal ? wrapWithAbort(entry.promise, opts.signal) : entry.promise;
|
|
646
|
+
}
|
|
647
|
+
if (entry.expires > perfNow()) {
|
|
648
|
+
return entry.value;
|
|
649
|
+
}
|
|
650
|
+
fetchCache.delete(cacheKey);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
const request = async () => {
|
|
654
|
+
const response = await fetch(url, {
|
|
655
|
+
signal: opts?.signal,
|
|
656
|
+
cache: opts?.ignoreCache ? "reload" : "default",
|
|
657
|
+
headers
|
|
658
|
+
});
|
|
659
|
+
if (response.redirected) {
|
|
660
|
+
return {
|
|
661
|
+
r: response.url
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
if (isRedirectStatus(response.status)) {
|
|
665
|
+
const location1 = response.headers.get("Location");
|
|
666
|
+
if (location1) {
|
|
667
|
+
return {
|
|
668
|
+
r: location1
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
if (!response.ok) {
|
|
673
|
+
return void 0;
|
|
674
|
+
}
|
|
675
|
+
const text = await response.text();
|
|
676
|
+
return await _deserialize(text) ?? void 0;
|
|
677
|
+
};
|
|
678
|
+
if (opts?.ignoreCache) {
|
|
679
|
+
return request();
|
|
680
|
+
}
|
|
681
|
+
if (opts?.signal) {
|
|
682
|
+
return request().then((value) => {
|
|
683
|
+
if (value !== void 0 && !fetchCache.has(cacheKey)) {
|
|
684
|
+
setCache(cacheKey, {
|
|
685
|
+
value,
|
|
686
|
+
expires: perfNow() + LOADER_FETCH_CACHE_TTL
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
return value;
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
const promise = request().then((value) => {
|
|
693
|
+
if (value === void 0) {
|
|
694
|
+
fetchCache.delete(cacheKey);
|
|
695
|
+
} else {
|
|
696
|
+
setCache(cacheKey, {
|
|
697
|
+
value,
|
|
698
|
+
expires: perfNow() + LOADER_FETCH_CACHE_TTL
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
return value;
|
|
702
|
+
}, (err) => {
|
|
703
|
+
fetchCache.delete(cacheKey);
|
|
704
|
+
throw err;
|
|
705
|
+
});
|
|
706
|
+
setCache(cacheKey, {
|
|
707
|
+
promise,
|
|
708
|
+
expires: perfNow() + LOADER_FETCH_CACHE_TTL
|
|
709
|
+
});
|
|
710
|
+
return promise;
|
|
711
|
+
};
|
|
712
|
+
const filterSearchParams = (params, allowed) => {
|
|
713
|
+
const filtered = new URLSearchParams();
|
|
714
|
+
for (let i = 0; i < allowed.length; i++) {
|
|
715
|
+
const name = allowed[i];
|
|
716
|
+
const values = params.getAll(name);
|
|
717
|
+
for (let j = 0; j < values.length; j++) {
|
|
718
|
+
filtered.append(name, values[j]);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
filtered.sort();
|
|
722
|
+
return filtered.toString() ? `?${filtered.toString()}` : "";
|
|
723
|
+
};
|
|
724
|
+
const getLoaderOptions = (rest) => {
|
|
725
|
+
let id;
|
|
726
|
+
let serializationStrategy = DEFAULT_LOADERS_SERIALIZATION_STRATEGY;
|
|
727
|
+
let expires;
|
|
728
|
+
let poll;
|
|
729
|
+
let eTag;
|
|
730
|
+
let cacheKey;
|
|
731
|
+
let search;
|
|
732
|
+
let allowStale = true;
|
|
733
|
+
let blockSSR = true;
|
|
734
|
+
const validators = [];
|
|
735
|
+
if (rest.length === 1) {
|
|
736
|
+
const options = rest[0];
|
|
737
|
+
if (options && typeof options === "object") {
|
|
738
|
+
if ("validate" in options) {
|
|
739
|
+
validators.push(options);
|
|
740
|
+
} else {
|
|
741
|
+
if (options.id) {
|
|
742
|
+
id = options.id;
|
|
743
|
+
}
|
|
744
|
+
if (options.serializationStrategy) {
|
|
745
|
+
serializationStrategy = options.serializationStrategy;
|
|
746
|
+
}
|
|
747
|
+
if (options.validation) {
|
|
748
|
+
validators.push(...options.validation);
|
|
749
|
+
}
|
|
750
|
+
if ("expires" in options) {
|
|
751
|
+
expires = options.expires;
|
|
752
|
+
}
|
|
753
|
+
if ("poll" in options) {
|
|
754
|
+
poll = options.poll;
|
|
755
|
+
}
|
|
756
|
+
if ("eTag" in options) {
|
|
757
|
+
eTag = options.eTag;
|
|
758
|
+
}
|
|
759
|
+
if ("cacheKey" in options) {
|
|
760
|
+
cacheKey = options.cacheKey;
|
|
761
|
+
}
|
|
762
|
+
if (options.search) {
|
|
763
|
+
search = options.search;
|
|
764
|
+
} else if (globalThis.__STRICT_LOADERS__) {
|
|
765
|
+
search = [];
|
|
766
|
+
}
|
|
767
|
+
if (options.allowStale === false) {
|
|
768
|
+
allowStale = false;
|
|
769
|
+
}
|
|
770
|
+
if (options.blockSSR === false) {
|
|
771
|
+
if (!__EXPERIMENTAL__.blockSSR) {
|
|
772
|
+
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.');
|
|
773
|
+
}
|
|
774
|
+
blockSSR = false;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
} else if (rest.length > 1) {
|
|
779
|
+
validators.push(...rest.filter(Boolean));
|
|
780
|
+
}
|
|
781
|
+
return {
|
|
782
|
+
id,
|
|
783
|
+
validators: validators.reverse(),
|
|
784
|
+
serializationStrategy,
|
|
785
|
+
expires,
|
|
786
|
+
poll,
|
|
787
|
+
eTag,
|
|
788
|
+
cacheKey,
|
|
789
|
+
search,
|
|
790
|
+
allowStale,
|
|
791
|
+
blockSSR
|
|
792
|
+
};
|
|
793
|
+
};
|
|
794
|
+
const getRequestEvent = (thisArg) => {
|
|
795
|
+
if (!isServer$1) {
|
|
796
|
+
throw new Error("getRequestEvent() can only be used on the server.");
|
|
797
|
+
}
|
|
798
|
+
return _asyncRequestStore?.getStore() || [
|
|
799
|
+
thisArg,
|
|
800
|
+
_getContextEvent()
|
|
801
|
+
].find(isRequestEvent);
|
|
802
|
+
};
|
|
803
|
+
const REQUEST_ROUTE_LOADER_VALUES = "@routeLoaderValues";
|
|
804
|
+
function getRouteLoaderValues(requestEv) {
|
|
805
|
+
let values = requestEv.sharedMap.get(REQUEST_ROUTE_LOADER_VALUES);
|
|
806
|
+
if (!values) {
|
|
807
|
+
values = {};
|
|
808
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADER_VALUES, values);
|
|
809
|
+
}
|
|
810
|
+
return values;
|
|
811
|
+
}
|
|
812
|
+
function getRouteLoaderPromises(requestEv) {
|
|
813
|
+
let promises = requestEv.sharedMap.get(REQUEST_ROUTE_LOADER_PROMISES);
|
|
814
|
+
if (!promises) {
|
|
815
|
+
promises = {};
|
|
816
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADER_PROMISES, promises);
|
|
817
|
+
}
|
|
818
|
+
return promises;
|
|
819
|
+
}
|
|
820
|
+
function setRouteLoaders(requestEv, loaders) {
|
|
821
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADERS, loaders);
|
|
822
|
+
}
|
|
823
|
+
function getRouteLoaders(requestEv) {
|
|
824
|
+
return requestEv.sharedMap.get(REQUEST_ROUTE_LOADERS) ?? [];
|
|
825
|
+
}
|
|
826
|
+
function getRouteLoaderCtx(requestEv) {
|
|
827
|
+
let ctx = requestEv.sharedMap.get(REQUEST_LOADER_PATHS_STORE);
|
|
828
|
+
if (!ctx) {
|
|
829
|
+
ctx = {
|
|
830
|
+
loaderPaths: {}
|
|
831
|
+
};
|
|
832
|
+
requestEv.sharedMap.set(REQUEST_LOADER_PATHS_STORE, ctx);
|
|
833
|
+
}
|
|
834
|
+
return ctx;
|
|
835
|
+
}
|
|
836
|
+
const updateRouteLoaderPaths = (ctx, loaderPaths, pageUrl) => {
|
|
837
|
+
if (!isServer$1) {
|
|
838
|
+
ctx.pagePathname = pageUrl.pathname;
|
|
839
|
+
ctx.pageSearch = pageUrl.search;
|
|
840
|
+
if (isDev) {
|
|
841
|
+
ctx.devRouteLoaderPaths = {};
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
if (loaderPaths) {
|
|
845
|
+
for (const key in loaderPaths) {
|
|
846
|
+
ctx.loaderPaths[key] = loaderPaths[key];
|
|
847
|
+
if (!isServer$1 && isDev) {
|
|
848
|
+
ctx.devRouteLoaderPaths[key] = true;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
const getModuleRouteLoaders = (mods) => {
|
|
854
|
+
const routeLoaders = [];
|
|
855
|
+
const seen = /* @__PURE__ */ new Map();
|
|
856
|
+
for (let i = 0; i < mods.length; i++) {
|
|
857
|
+
const mod = mods[i];
|
|
858
|
+
if (!mod) {
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
for (const key in mod) {
|
|
862
|
+
const value = mod[key];
|
|
863
|
+
if (isLoaderInternal(value)) {
|
|
864
|
+
const existing = seen.get(value.__id);
|
|
865
|
+
if (existing) {
|
|
866
|
+
if (isDev && existing !== value) {
|
|
867
|
+
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.`);
|
|
868
|
+
}
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
871
|
+
seen.set(value.__id, value);
|
|
872
|
+
routeLoaders.push(value);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return routeLoaders;
|
|
877
|
+
};
|
|
878
|
+
const setLoaderSignalValue = (signal, value) => {
|
|
879
|
+
_injectAsyncSignalValue(signal, value);
|
|
880
|
+
};
|
|
881
|
+
const matchesRouteLoaderId = (loader, loaderId) => {
|
|
882
|
+
return typeof loaderId === "string" && (loader.__id === loaderId || isDev && loader.__qrl.getHash() === loaderId);
|
|
883
|
+
};
|
|
884
|
+
const resolveRouteLoaderByHash = (routeLoaders, loaderId) => {
|
|
885
|
+
return routeLoaders.find((loader) => matchesRouteLoaderId(loader, loaderId));
|
|
886
|
+
};
|
|
887
|
+
const getLoaderRequestEvent = (loader, requestEv) => {
|
|
888
|
+
let rootRequestEv = requestEv.sharedMap.get(REQUEST_ROUTE_LOADER_ROOT_EVENT);
|
|
889
|
+
if (!rootRequestEv) {
|
|
890
|
+
rootRequestEv = requestEv;
|
|
891
|
+
requestEv.sharedMap.set(REQUEST_ROUTE_LOADER_ROOT_EVENT, rootRequestEv);
|
|
892
|
+
}
|
|
893
|
+
const url = new URL(rootRequestEv.url);
|
|
894
|
+
const pathname = globalThis.__STRICT_LOADERS__ ? getRouteLoaderCtx(rootRequestEv).loaderPaths[loader.__id] || rootRequestEv.url.pathname : rootRequestEv.url.pathname;
|
|
895
|
+
const filteredSearch = loader.__search ? filterSearchParams(url.searchParams, loader.__search) : rootRequestEv.url.search;
|
|
896
|
+
if (pathname === rootRequestEv.url.pathname && filteredSearch === rootRequestEv.url.search) {
|
|
897
|
+
return rootRequestEv;
|
|
898
|
+
}
|
|
899
|
+
let events = rootRequestEv.sharedMap.get(REQUEST_ROUTE_LOADER_EVENTS);
|
|
900
|
+
if (!events) {
|
|
901
|
+
events = /* @__PURE__ */ new Map();
|
|
902
|
+
rootRequestEv.sharedMap.set(REQUEST_ROUTE_LOADER_EVENTS, events);
|
|
903
|
+
}
|
|
904
|
+
const eventKey = `${pathname}
|
|
905
|
+
${filteredSearch}`;
|
|
906
|
+
let loaderRequestEv = events.get(eventKey);
|
|
907
|
+
if (!loaderRequestEv) {
|
|
908
|
+
url.pathname = pathname;
|
|
909
|
+
url.search = filteredSearch;
|
|
910
|
+
loaderRequestEv = Object.create(rootRequestEv, {
|
|
911
|
+
pathname: {
|
|
912
|
+
get: () => url.pathname,
|
|
913
|
+
enumerable: true
|
|
914
|
+
},
|
|
915
|
+
query: {
|
|
916
|
+
get: () => url.searchParams,
|
|
917
|
+
enumerable: true
|
|
918
|
+
},
|
|
919
|
+
url: {
|
|
920
|
+
value: url,
|
|
921
|
+
enumerable: true
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
events.set(eventKey, loaderRequestEv);
|
|
925
|
+
}
|
|
926
|
+
return loaderRequestEv;
|
|
927
|
+
};
|
|
928
|
+
const detachResponseFromEvent = (requestEv) => {
|
|
929
|
+
let status = 200;
|
|
930
|
+
const headers = new Headers();
|
|
931
|
+
return Object.create(requestEv, {
|
|
932
|
+
headers: {
|
|
933
|
+
value: headers,
|
|
934
|
+
enumerable: true
|
|
935
|
+
},
|
|
936
|
+
status: {
|
|
937
|
+
value: (statusCode) => {
|
|
938
|
+
if (typeof statusCode === "number") {
|
|
939
|
+
status = statusCode;
|
|
940
|
+
}
|
|
941
|
+
return status;
|
|
942
|
+
},
|
|
943
|
+
enumerable: true
|
|
944
|
+
},
|
|
945
|
+
error: {
|
|
946
|
+
value: (statusCode, message) => {
|
|
947
|
+
status = statusCode;
|
|
948
|
+
return new ServerError(statusCode, message);
|
|
949
|
+
},
|
|
950
|
+
enumerable: true
|
|
951
|
+
},
|
|
952
|
+
redirect: {
|
|
953
|
+
value: (statusCode, url) => {
|
|
954
|
+
status = statusCode;
|
|
955
|
+
if (url) {
|
|
956
|
+
headers.set("Location", url);
|
|
957
|
+
}
|
|
958
|
+
return new RedirectMessage();
|
|
959
|
+
},
|
|
960
|
+
enumerable: true
|
|
961
|
+
},
|
|
962
|
+
fail: {
|
|
963
|
+
value: (statusCode, data) => {
|
|
964
|
+
status = statusCode;
|
|
965
|
+
return {
|
|
966
|
+
failed: true,
|
|
967
|
+
...data
|
|
968
|
+
};
|
|
969
|
+
},
|
|
970
|
+
enumerable: true
|
|
971
|
+
},
|
|
972
|
+
// A background loader cannot set the page's cache headers.
|
|
973
|
+
cacheControl: {
|
|
974
|
+
value: () => {
|
|
975
|
+
},
|
|
976
|
+
enumerable: true
|
|
977
|
+
}
|
|
978
|
+
});
|
|
979
|
+
};
|
|
980
|
+
async function runValidators(requestEv, validators, data) {
|
|
981
|
+
let lastResult = {
|
|
982
|
+
success: true,
|
|
983
|
+
data
|
|
984
|
+
};
|
|
985
|
+
if (validators) {
|
|
986
|
+
for (let i = 0; i < validators.length; i++) {
|
|
987
|
+
const validator = validators[i];
|
|
988
|
+
lastResult = await validator.validate(requestEv, data);
|
|
989
|
+
if (!lastResult.success) {
|
|
990
|
+
return lastResult;
|
|
991
|
+
}
|
|
992
|
+
data = lastResult.data;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
return lastResult;
|
|
996
|
+
}
|
|
997
|
+
function verifySerializable(data, qrl) {
|
|
998
|
+
try {
|
|
999
|
+
_verifySerializable(data, void 0);
|
|
1000
|
+
} catch (error) {
|
|
1001
|
+
if (error instanceof Error && qrl.dev) {
|
|
1002
|
+
error.loc = qrl.dev;
|
|
1003
|
+
}
|
|
1004
|
+
throw error;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
const getRouteLoaderData = async (loaderQrl, validators, requestEv) => {
|
|
1008
|
+
const loaderRequestEv = requestEv;
|
|
1009
|
+
const result = await runValidators(requestEv, validators, void 0);
|
|
1010
|
+
if (!result.success) {
|
|
1011
|
+
return loaderRequestEv.fail(result.status ?? 500, result.error);
|
|
1012
|
+
}
|
|
1013
|
+
const resolved = await loaderQrl.call(loaderRequestEv, loaderRequestEv);
|
|
1014
|
+
const value = typeof resolved === "function" ? resolved() : resolved;
|
|
1015
|
+
throwIfControlFlowSignal(value);
|
|
1016
|
+
if (isDev) {
|
|
1017
|
+
verifySerializable(value, loaderQrl);
|
|
1018
|
+
}
|
|
1019
|
+
return value;
|
|
1020
|
+
};
|
|
1021
|
+
const loadRouteLoaderByQrl = (loaderId, loaderQrl, validators, requestEv) => {
|
|
1022
|
+
const values = getRouteLoaderValues(requestEv);
|
|
1023
|
+
if (loaderId in values) {
|
|
1024
|
+
return Promise.resolve(values[loaderId]);
|
|
1025
|
+
}
|
|
1026
|
+
const promises = getRouteLoaderPromises(requestEv);
|
|
1027
|
+
let promise = promises[loaderId];
|
|
1028
|
+
if (!promise) {
|
|
1029
|
+
promise = getRouteLoaderData(loaderQrl, validators, requestEv).then((value) => {
|
|
1030
|
+
values[loaderId] = value;
|
|
1031
|
+
return value;
|
|
1032
|
+
}, (err) => {
|
|
1033
|
+
delete promises[loaderId];
|
|
1034
|
+
throw err;
|
|
1035
|
+
});
|
|
1036
|
+
promises[loaderId] = promise;
|
|
1037
|
+
}
|
|
1038
|
+
return promise;
|
|
1039
|
+
};
|
|
1040
|
+
class ServerRouteLoaderCapture {
|
|
1041
|
+
hash;
|
|
1042
|
+
qrl;
|
|
1043
|
+
validators;
|
|
1044
|
+
blockSSR;
|
|
1045
|
+
constructor(hash, qrl, validators, blockSSR) {
|
|
1046
|
+
this.hash = hash;
|
|
1047
|
+
this.qrl = qrl;
|
|
1048
|
+
this.validators = validators;
|
|
1049
|
+
this.blockSSR = blockSSR;
|
|
1050
|
+
}
|
|
1051
|
+
load() {
|
|
1052
|
+
const requestEv = getRequestEvent();
|
|
1053
|
+
if (!requestEv) {
|
|
1054
|
+
throw new Error("Unable to determine the current RequestEvent.");
|
|
1055
|
+
}
|
|
1056
|
+
const values = getRouteLoaderValues(requestEv);
|
|
1057
|
+
if (this.hash in values) {
|
|
1058
|
+
return values[this.hash];
|
|
1059
|
+
}
|
|
1060
|
+
const ev = this.blockSSR ? requestEv : detachResponseFromEvent(requestEv);
|
|
1061
|
+
return loadRouteLoaderByQrl(this.hash, this.qrl, this.validators, ev);
|
|
1062
|
+
}
|
|
1063
|
+
[SerializerSymbol]() {
|
|
1064
|
+
return this.hash;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
const createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
1068
|
+
const id = loader.__id;
|
|
1069
|
+
const stateValues = state;
|
|
1070
|
+
const resumeValueKey = getRouteLoaderValueStateKey(id);
|
|
1071
|
+
const capture = isServer$1 ? new ServerRouteLoaderCapture(id, loader.__qrl, loader.__validators, loader.__blockSSR) : id;
|
|
1072
|
+
const searchFilter = loader.__search;
|
|
1073
|
+
const lastFetch = {};
|
|
1074
|
+
const signal = createComputedQrl(/* @__PURE__ */ inlinedQrl(async (ctx) => {
|
|
1075
|
+
const capture2 = _captures[0], id2 = _captures[1], lastFetch2 = _captures[2], resumeValueKey2 = _captures[3], routeLoaderCtx2 = _captures[4], searchFilter2 = _captures[5], stateValues2 = _captures[6];
|
|
1076
|
+
const hasInjectedValue = !!ctx.info && typeof ctx.info === "object" && "__v" in ctx.info;
|
|
1077
|
+
const trackedRoutePath = ctx.track(routeLoaderCtx2.loaderPaths, id2);
|
|
1078
|
+
const trackedPagePathname = ctx.track(routeLoaderCtx2, "pagePathname");
|
|
1079
|
+
const trackedPageSearch = ctx.track(routeLoaderCtx2, "pageSearch");
|
|
1080
|
+
if (hasInjectedValue) {
|
|
1081
|
+
const value = ctx.info.__v;
|
|
1082
|
+
if (!isServer$1 && resumeValueKey2 in stateValues2) {
|
|
1083
|
+
stateValues2[resumeValueKey2] = value;
|
|
1084
|
+
}
|
|
1085
|
+
return value;
|
|
1086
|
+
}
|
|
1087
|
+
if (isServer$1) {
|
|
1088
|
+
return capture2.load();
|
|
1089
|
+
}
|
|
1090
|
+
const pagePathname = trackedPagePathname || location.pathname;
|
|
1091
|
+
const pageSearch = trackedPageSearch || location.search;
|
|
1092
|
+
const pageUrl = new URL(pagePathname + pageSearch, location.href);
|
|
1093
|
+
const mHash = routeLoaderCtx2.manifestHash || "dev";
|
|
1094
|
+
const basePath = qwikRouterConfig.basePathname ?? "/";
|
|
1095
|
+
const needsResumeFetch = stateValues2[resumeValueKey2] === _UNINITIALIZED;
|
|
1096
|
+
const fetchRoutePath = trackedRoutePath || (needsResumeFetch ? pageUrl.pathname : void 0);
|
|
1097
|
+
if (!fetchRoutePath) {
|
|
1098
|
+
return ctx.previous;
|
|
1099
|
+
}
|
|
1100
|
+
let fetchUrl = pageUrl;
|
|
1101
|
+
if (searchFilter2) {
|
|
1102
|
+
const filteredSearch = filterSearchParams(pageUrl.searchParams, searchFilter2);
|
|
1103
|
+
if (ctx.previous !== void 0 && filteredSearch === lastFetch2.filteredSearch && fetchRoutePath === lastFetch2.routePath) {
|
|
1104
|
+
return ctx.previous;
|
|
1105
|
+
}
|
|
1106
|
+
lastFetch2.filteredSearch = filteredSearch;
|
|
1107
|
+
lastFetch2.routePath = fetchRoutePath;
|
|
1108
|
+
fetchUrl = new URL(pageUrl.href);
|
|
1109
|
+
fetchUrl.search = filteredSearch;
|
|
1110
|
+
}
|
|
1111
|
+
const response = await fetchRouteLoaderData(id2, fetchRoutePath, mHash, {
|
|
1112
|
+
pageUrl: fetchUrl,
|
|
1113
|
+
basePath,
|
|
1114
|
+
ignoreCache: ctx.info === true,
|
|
1115
|
+
signal: ctx.abortSignal
|
|
1116
|
+
});
|
|
1117
|
+
if (!response) {
|
|
1118
|
+
throw new Error(`Loader ${id2} returned empty response`);
|
|
1119
|
+
}
|
|
1120
|
+
if (response.r) {
|
|
1121
|
+
const goto = routeLoaderCtx2.goto;
|
|
1122
|
+
if (goto) {
|
|
1123
|
+
goto(response.r, {
|
|
1124
|
+
replaceState: true
|
|
1125
|
+
});
|
|
1126
|
+
} else {
|
|
1127
|
+
location.href = response.r;
|
|
1128
|
+
}
|
|
1129
|
+
return ctx.previous;
|
|
1130
|
+
}
|
|
1131
|
+
if (response.e) {
|
|
1132
|
+
throw response.e;
|
|
1133
|
+
}
|
|
1134
|
+
if (needsResumeFetch) {
|
|
1135
|
+
stateValues2[resumeValueKey2] = response.d;
|
|
1136
|
+
}
|
|
1137
|
+
return response.d;
|
|
1138
|
+
}, "createRouteLoaderSignal_signal_createComputed_4s4ZDCYhDOA", [
|
|
1139
|
+
capture,
|
|
1140
|
+
id,
|
|
1141
|
+
lastFetch,
|
|
1142
|
+
resumeValueKey,
|
|
1143
|
+
routeLoaderCtx,
|
|
1144
|
+
searchFilter,
|
|
1145
|
+
stateValues
|
|
1146
|
+
]), {
|
|
1147
|
+
serializationStrategy: loader.__serializationStrategy,
|
|
1148
|
+
expires: loader.__expires,
|
|
1149
|
+
poll: loader.__poll,
|
|
1150
|
+
allowStale: loader.__allowStale
|
|
1151
|
+
});
|
|
1152
|
+
_markSignalAsExternallyOwned(signal);
|
|
1153
|
+
return signal;
|
|
1154
|
+
};
|
|
1155
|
+
const ensureRouteLoaderSignal = (loader, state, routeLoaderCtx) => {
|
|
1156
|
+
if (isServer$1 && loader.__serializationStrategy === "never") {
|
|
1157
|
+
state[getRouteLoaderValueStateKey(loader.__id)] = _UNINITIALIZED;
|
|
1158
|
+
}
|
|
1159
|
+
return state[loader.__id] ||= createRouteLoaderSignal(loader, routeLoaderCtx, state);
|
|
1160
|
+
};
|
|
1161
|
+
const ensureRouteLoaderSignals = (mods, state, routeLoaderCtx) => {
|
|
1162
|
+
const loaders = getModuleRouteLoaders(mods);
|
|
1163
|
+
for (let i = 0; i < loaders.length; i++) {
|
|
1164
|
+
const loader = loaders[i];
|
|
1165
|
+
if (isDev && !isServer$1) {
|
|
1166
|
+
const devCtx = routeLoaderCtx;
|
|
1167
|
+
if (devCtx.pagePathname && !devCtx.devRouteLoaderPaths?.[loader.__id]) {
|
|
1168
|
+
devCtx.loaderPaths[loader.__id] = devCtx.pagePathname;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
ensureRouteLoaderSignal(loader, state, routeLoaderCtx);
|
|
1172
|
+
}
|
|
1173
|
+
return loaders;
|
|
1174
|
+
};
|
|
1175
|
+
const loadRouteLoader = (loader, requestEv) => {
|
|
1176
|
+
const loaderEv = getLoaderRequestEvent(loader, requestEv);
|
|
1177
|
+
return loadRouteLoaderByQrl(
|
|
1178
|
+
loader.__id,
|
|
1179
|
+
loader.__qrl,
|
|
1180
|
+
loader.__validators,
|
|
1181
|
+
// A background (blockSSR:false) loader must not touch the page response.
|
|
1182
|
+
loader.__blockSSR ? loaderEv : detachResponseFromEvent(loaderEv)
|
|
1183
|
+
);
|
|
1184
|
+
};
|
|
1185
|
+
const getRouteLoaderResponse = async (loaderQrl, validators, requestEv) => {
|
|
1186
|
+
try {
|
|
1187
|
+
const value = await getRouteLoaderData(loaderQrl, validators, requestEv);
|
|
1188
|
+
return {
|
|
1189
|
+
d: value
|
|
1190
|
+
};
|
|
1191
|
+
} catch (err) {
|
|
1192
|
+
if (err instanceof RedirectMessage) {
|
|
1193
|
+
const location1 = requestEv.headers.get("Location") || "/";
|
|
1194
|
+
requestEv.headers.delete("Location");
|
|
1195
|
+
return {
|
|
1196
|
+
r: location1
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1199
|
+
if (err instanceof ServerError) {
|
|
1200
|
+
return {
|
|
1201
|
+
e: err
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
throw err;
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
const routeLoaderQrl = (loaderQrl, ...rest) => {
|
|
1208
|
+
const { id, validators, serializationStrategy, expires, poll, eTag, cacheKey, search, allowStale, blockSSR } = getLoaderOptions(rest);
|
|
1209
|
+
function loader() {
|
|
1210
|
+
const state = _resolveContextWithoutSequentialScope(RouteStateContext);
|
|
1211
|
+
let signal = state[loader.__id];
|
|
1212
|
+
if (!signal) {
|
|
1213
|
+
const routeLoaderCtx = _resolveContextWithoutSequentialScope(RouteLoaderCtxContext);
|
|
1214
|
+
signal = ensureRouteLoaderSignal(loader, state, routeLoaderCtx);
|
|
1215
|
+
}
|
|
1216
|
+
void signal.promise();
|
|
1217
|
+
return signal;
|
|
1218
|
+
}
|
|
1219
|
+
loader.__brand = "server_loader";
|
|
1220
|
+
loader.__qrl = loaderQrl;
|
|
1221
|
+
loader.__validators = validators;
|
|
1222
|
+
loader.__id = id ?? loaderQrl.getHash();
|
|
1223
|
+
loader.__serializationStrategy = serializationStrategy;
|
|
1224
|
+
loader.__expires = expires ?? 12e4;
|
|
1225
|
+
loader.__poll = poll ?? false;
|
|
1226
|
+
loader.__eTag = eTag;
|
|
1227
|
+
loader.__cacheKey = cacheKey;
|
|
1228
|
+
loader.__search = search;
|
|
1229
|
+
loader.__allowStale = allowStale;
|
|
1230
|
+
loader.__blockSSR = blockSSR;
|
|
1231
|
+
Object.freeze(loader);
|
|
1232
|
+
return loader;
|
|
1233
|
+
};
|
|
1234
|
+
const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl);
|
|
1235
|
+
|
|
1236
|
+
const toPath = (url) => url.pathname + url.search + url.hash;
|
|
1237
|
+
const toUrl = (url, baseUrl) => new URL(url, baseUrl.href);
|
|
1238
|
+
const isSameOrigin = (a, b) => a.origin === b.origin;
|
|
1239
|
+
const isSamePathname = ({ pathname: a }, { pathname: b }) => {
|
|
1240
|
+
const lDiff = Math.abs(a.length - b.length);
|
|
1241
|
+
return lDiff === 0 ? a === b : lDiff === 1 && ensureSlash(a) === ensureSlash(b);
|
|
1242
|
+
};
|
|
1243
|
+
const isSameSearchQuery = (a, b) => a.search === b.search;
|
|
1244
|
+
const isSamePath = (a, b) => isSameSearchQuery(a, b) && isSamePathname(a, b);
|
|
1245
|
+
const getClientNavPath = (props, baseUrl) => {
|
|
1246
|
+
const href = props.href;
|
|
1247
|
+
if (typeof href === "string" && typeof props.target !== "string" && !props.reload) {
|
|
1248
|
+
try {
|
|
1249
|
+
const linkUrl = toUrl(href.trim(), baseUrl.url);
|
|
1250
|
+
const currentUrl = toUrl("", baseUrl.url);
|
|
1251
|
+
if (isSameOrigin(linkUrl, currentUrl)) {
|
|
1252
|
+
return toPath(linkUrl);
|
|
1253
|
+
}
|
|
1254
|
+
} catch (e) {
|
|
1255
|
+
console.error(e);
|
|
1256
|
+
}
|
|
1257
|
+
} else if (props.reload) {
|
|
1258
|
+
return toPath(toUrl("", baseUrl.url));
|
|
1259
|
+
}
|
|
1260
|
+
return null;
|
|
1261
|
+
};
|
|
1262
|
+
const shouldPreload = (clientNavPath, currentLoc) => {
|
|
1263
|
+
if (clientNavPath) {
|
|
1264
|
+
const prefetchUrl = toUrl(clientNavPath, currentLoc.url);
|
|
1265
|
+
const currentUrl = toUrl("", currentLoc.url);
|
|
1266
|
+
return !isSamePathname(prefetchUrl, currentUrl);
|
|
1267
|
+
}
|
|
1268
|
+
return false;
|
|
1269
|
+
};
|
|
1270
|
+
const isPromise = (value) => {
|
|
1271
|
+
return value && typeof value.then === "function";
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
const mergeArray = (existingArr, newArr) => {
|
|
1275
|
+
if (Array.isArray(newArr)) {
|
|
1276
|
+
for (const newItem of newArr) {
|
|
1277
|
+
if (typeof newItem.key === "string") {
|
|
1278
|
+
const existingIndex = existingArr.findIndex((i) => i.key === newItem.key);
|
|
1279
|
+
if (existingIndex > -1) {
|
|
1280
|
+
existingArr[existingIndex] = newItem;
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
existingArr.push(newItem);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
};
|
|
1288
|
+
const resolveDocumentHead = (resolvedHead, updatedHead) => {
|
|
1289
|
+
if (typeof updatedHead.title === "string") {
|
|
1290
|
+
resolvedHead.title = updatedHead.title;
|
|
1291
|
+
}
|
|
1292
|
+
mergeArray(resolvedHead.meta, updatedHead.meta);
|
|
1293
|
+
mergeArray(resolvedHead.links, updatedHead.links);
|
|
1294
|
+
mergeArray(resolvedHead.styles, updatedHead.styles);
|
|
1295
|
+
mergeArray(resolvedHead.scripts, updatedHead.scripts);
|
|
1296
|
+
Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter);
|
|
1297
|
+
};
|
|
1298
|
+
const createDocumentHead = (defaults, manifestHash) => ({
|
|
1299
|
+
title: defaults?.title || "",
|
|
1300
|
+
meta: [
|
|
1301
|
+
...defaults?.meta || []
|
|
1302
|
+
],
|
|
1303
|
+
links: [
|
|
1304
|
+
...defaults?.links || []
|
|
1305
|
+
],
|
|
1306
|
+
styles: [
|
|
1307
|
+
...defaults?.styles || []
|
|
1308
|
+
],
|
|
1309
|
+
scripts: [
|
|
1310
|
+
...defaults?.scripts || []
|
|
1311
|
+
],
|
|
1312
|
+
frontmatter: {
|
|
1313
|
+
...defaults?.frontmatter
|
|
1314
|
+
},
|
|
1315
|
+
manifestHash: manifestHash || "dev"
|
|
1316
|
+
});
|
|
1317
|
+
const resolveRouteConfig = (resolveValue, routeLocation, contentModules, locale, status, defaults) => withLocale(locale, () => {
|
|
1318
|
+
const head = createDocumentHead(defaults);
|
|
1319
|
+
let eTag;
|
|
1320
|
+
let cacheKey;
|
|
1321
|
+
const fns = [];
|
|
1322
|
+
for (let i = 0; i < contentModules.length; i++) {
|
|
1323
|
+
const contentModule = contentModules[i];
|
|
1324
|
+
if (!contentModule) {
|
|
1325
|
+
continue;
|
|
1326
|
+
}
|
|
1327
|
+
const isLast = i === contentModules.length - 1;
|
|
1328
|
+
let config;
|
|
1329
|
+
if (contentModule.routeConfig) {
|
|
1330
|
+
config = contentModule.routeConfig;
|
|
1331
|
+
} else if (contentModule.head) {
|
|
1332
|
+
const synthetic = {
|
|
1333
|
+
head: void 0
|
|
1334
|
+
};
|
|
1335
|
+
const headExport = contentModule.head;
|
|
1336
|
+
if (typeof headExport === "function") {
|
|
1337
|
+
const mod = contentModule;
|
|
1338
|
+
config = (props) => ({
|
|
1339
|
+
head: headExport(props),
|
|
1340
|
+
eTag: mod.eTag,
|
|
1341
|
+
cacheKey: mod.cacheKey
|
|
1342
|
+
});
|
|
1343
|
+
} else {
|
|
1344
|
+
synthetic.head = headExport;
|
|
1345
|
+
const mod = contentModule;
|
|
1346
|
+
if (mod.eTag !== void 0) {
|
|
1347
|
+
synthetic.eTag = mod.eTag;
|
|
1348
|
+
}
|
|
1349
|
+
if (mod.cacheKey !== void 0) {
|
|
1350
|
+
synthetic.cacheKey = mod.cacheKey;
|
|
1351
|
+
}
|
|
1352
|
+
config = synthetic;
|
|
1353
|
+
}
|
|
1354
|
+
} else {
|
|
1355
|
+
const mod = contentModule;
|
|
1356
|
+
if (mod.eTag !== void 0 || mod.cacheKey !== void 0) {
|
|
1357
|
+
config = {
|
|
1358
|
+
eTag: mod.eTag,
|
|
1359
|
+
cacheKey: mod.cacheKey
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
if (!config) {
|
|
1364
|
+
continue;
|
|
1365
|
+
}
|
|
1366
|
+
if (typeof config === "function") {
|
|
1367
|
+
fns.unshift({
|
|
1368
|
+
fn: config,
|
|
1369
|
+
isLast
|
|
1370
|
+
});
|
|
1371
|
+
} else {
|
|
1372
|
+
if (config.head) {
|
|
1373
|
+
resolveDocumentHead(head, config.head);
|
|
1374
|
+
}
|
|
1375
|
+
if (config.eTag !== void 0) {
|
|
1376
|
+
eTag = config.eTag;
|
|
1377
|
+
}
|
|
1378
|
+
if (config.cacheKey !== void 0) {
|
|
1379
|
+
cacheKey = config.cacheKey;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
if (fns.length) {
|
|
1384
|
+
const headProps = {
|
|
1385
|
+
head,
|
|
1386
|
+
status,
|
|
1387
|
+
withLocale: (fn) => fn(),
|
|
1388
|
+
resolveValue,
|
|
1389
|
+
...routeLocation
|
|
1390
|
+
};
|
|
1391
|
+
for (const { fn } of fns) {
|
|
1392
|
+
const result = fn(headProps);
|
|
1393
|
+
if (result.head) {
|
|
1394
|
+
resolveDocumentHead(head, result.head);
|
|
1395
|
+
}
|
|
1396
|
+
if (result.eTag !== void 0) {
|
|
1397
|
+
eTag = result.eTag;
|
|
1398
|
+
}
|
|
1399
|
+
if (result.cacheKey !== void 0) {
|
|
1400
|
+
cacheKey = result.cacheKey;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
return {
|
|
1405
|
+
head,
|
|
1406
|
+
eTag,
|
|
1407
|
+
cacheKey
|
|
1408
|
+
};
|
|
1409
|
+
});
|
|
1410
|
+
const resolveHead = (actionData, loaderState, routeLocation, contentModules, locale, defaults) => {
|
|
1411
|
+
const getData = (loaderOrAction) => {
|
|
1412
|
+
const id = loaderOrAction.__id;
|
|
1413
|
+
const signal = loaderState?.[id];
|
|
1414
|
+
if (signal) {
|
|
1415
|
+
return signal.value;
|
|
1416
|
+
}
|
|
1417
|
+
if (actionData?.action === id) {
|
|
1418
|
+
return actionData.actionResult;
|
|
1419
|
+
}
|
|
1420
|
+
return void 0;
|
|
1421
|
+
};
|
|
1422
|
+
return resolveRouteConfig(getData, routeLocation, contentModules, locale, actionData?.status ?? 200, defaults).head;
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
export { getRouteLoaders as A, getRouteLoaderValues as B, ContentContext as C, DocumentHeadContext as D, loadRouteLoader as E, FULLPATH_HEADER as F, isPromise as G, HttpStatusContext as H, getLoaderRequestEvent as I, resolveRouteLoaderByHash as J, getRouteLoaderResponse as K, getRouteLoaderCtx as L, setRouteLoaders as M, resolveRouteConfig as N, matchesRouteLoaderId as O, QACTION_KEY as Q, ROUTE_PATH_HEADER as R, _asyncRequestStore as _, isSameOrigin as a, setLoaderSignalValue as b, createDocumentHead as c, ContentInternalContext as d, ensureRouteLoaderSignals as e, fetchRouteLoaderData as f, getClientNavPath as g, RouteLocationContext as h, isSamePath as i, RouteNavigateContext as j, RouteStateContext as k, loadRoute as l, RouteLoaderCtxContext as m, RouteActionContext as n, RoutePreventNavigateContext as o, Q_ROUTE as p, toUrl as q, resolveHead as r, shouldPreload as s, toPath as t, updateRouteLoaderPaths as u, getRequestEvent as v, QFN_KEY as w, QDATA_KEY as x, routeLoader$ as y, routeLoaderQrl as z };
|