@tanstack/router-core 1.171.15 → 1.171.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +3 -12
  3. package/dist/cjs/await-signal.cjs +21 -0
  4. package/dist/cjs/await-signal.cjs.map +1 -0
  5. package/dist/cjs/await-signal.d.cts +1 -0
  6. package/dist/cjs/index.cjs +3 -1
  7. package/dist/cjs/index.d.cts +3 -2
  8. package/dist/cjs/isServer/client.cjs +2 -0
  9. package/dist/cjs/isServer/client.cjs.map +1 -1
  10. package/dist/cjs/isServer/client.d.cts +1 -0
  11. package/dist/cjs/isServer/development.cjs +2 -0
  12. package/dist/cjs/isServer/development.cjs.map +1 -1
  13. package/dist/cjs/isServer/development.d.cts +1 -0
  14. package/dist/cjs/isServer/server.cjs +2 -0
  15. package/dist/cjs/isServer/server.cjs.map +1 -1
  16. package/dist/cjs/isServer/server.d.cts +1 -0
  17. package/dist/cjs/link.cjs.map +1 -1
  18. package/dist/cjs/link.d.cts +5 -3
  19. package/dist/cjs/load-client.cjs +1393 -0
  20. package/dist/cjs/load-client.cjs.map +1 -0
  21. package/dist/cjs/load-client.d.cts +118 -0
  22. package/dist/cjs/load-server.cjs +565 -0
  23. package/dist/cjs/load-server.cjs.map +1 -0
  24. package/dist/cjs/load-server.d.cts +16 -0
  25. package/dist/cjs/redirect.cjs.map +1 -1
  26. package/dist/cjs/redirect.d.cts +0 -1
  27. package/dist/cjs/route.cjs.map +1 -1
  28. package/dist/cjs/router.cjs +204 -439
  29. package/dist/cjs/router.cjs.map +1 -1
  30. package/dist/cjs/router.d.cts +68 -54
  31. package/dist/cjs/ssr/client.cjs +2 -2
  32. package/dist/cjs/ssr/createRequestHandler.cjs +60 -9
  33. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  34. package/dist/cjs/ssr/createRequestHandler.d.cts +1 -0
  35. package/dist/cjs/ssr/handlerCallback.cjs +49 -4
  36. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -1
  37. package/dist/cjs/ssr/handlerCallback.d.cts +3 -0
  38. package/dist/cjs/ssr/server.cjs +4 -0
  39. package/dist/cjs/ssr/server.d.cts +2 -2
  40. package/dist/cjs/ssr/ssr-client.d.cts +1 -10
  41. package/dist/cjs/ssr/ssr-match-id.cjs +2 -2
  42. package/dist/cjs/ssr/ssr-match-id.cjs.map +1 -1
  43. package/dist/cjs/ssr/ssr-server.cjs +6 -6
  44. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  45. package/dist/cjs/ssr/transformStreamWithRouter.cjs +27 -1
  46. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  47. package/dist/cjs/ssr/transformStreamWithRouter.d.cts +2 -0
  48. package/dist/cjs/ssr/types.d.cts +0 -1
  49. package/dist/cjs/stores.cjs +30 -104
  50. package/dist/cjs/stores.cjs.map +1 -1
  51. package/dist/cjs/stores.d.cts +7 -32
  52. package/dist/cjs/utils.cjs +0 -4
  53. package/dist/cjs/utils.cjs.map +1 -1
  54. package/dist/esm/Matches.d.ts +3 -12
  55. package/dist/esm/Matches.js.map +1 -1
  56. package/dist/esm/await-signal.d.ts +1 -0
  57. package/dist/esm/await-signal.js +21 -0
  58. package/dist/esm/await-signal.js.map +1 -0
  59. package/dist/esm/index.d.ts +3 -2
  60. package/dist/esm/index.js +3 -2
  61. package/dist/esm/isServer/client.d.ts +1 -0
  62. package/dist/esm/isServer/client.js +2 -1
  63. package/dist/esm/isServer/client.js.map +1 -1
  64. package/dist/esm/isServer/development.d.ts +1 -0
  65. package/dist/esm/isServer/development.js +2 -1
  66. package/dist/esm/isServer/development.js.map +1 -1
  67. package/dist/esm/isServer/server.d.ts +1 -0
  68. package/dist/esm/isServer/server.js +2 -1
  69. package/dist/esm/isServer/server.js.map +1 -1
  70. package/dist/esm/link.d.ts +5 -3
  71. package/dist/esm/link.js.map +1 -1
  72. package/dist/esm/load-client.d.ts +118 -0
  73. package/dist/esm/load-client.js +1386 -0
  74. package/dist/esm/load-client.js.map +1 -0
  75. package/dist/esm/load-server.d.ts +16 -0
  76. package/dist/esm/load-server.js +565 -0
  77. package/dist/esm/load-server.js.map +1 -0
  78. package/dist/esm/redirect.d.ts +0 -1
  79. package/dist/esm/redirect.js.map +1 -1
  80. package/dist/esm/route.js.map +1 -1
  81. package/dist/esm/router.d.ts +68 -54
  82. package/dist/esm/router.js +207 -442
  83. package/dist/esm/router.js.map +1 -1
  84. package/dist/esm/ssr/client.js +1 -1
  85. package/dist/esm/ssr/createRequestHandler.d.ts +1 -0
  86. package/dist/esm/ssr/createRequestHandler.js +61 -11
  87. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  88. package/dist/esm/ssr/handlerCallback.d.ts +3 -0
  89. package/dist/esm/ssr/handlerCallback.js +47 -5
  90. package/dist/esm/ssr/handlerCallback.js.map +1 -1
  91. package/dist/esm/ssr/server.d.ts +2 -2
  92. package/dist/esm/ssr/server.js +3 -3
  93. package/dist/esm/ssr/ssr-client.d.ts +1 -10
  94. package/dist/esm/ssr/ssr-match-id.js +2 -2
  95. package/dist/esm/ssr/ssr-match-id.js.map +1 -1
  96. package/dist/esm/ssr/ssr-server.js +6 -6
  97. package/dist/esm/ssr/ssr-server.js.map +1 -1
  98. package/dist/esm/ssr/transformStreamWithRouter.d.ts +2 -0
  99. package/dist/esm/ssr/transformStreamWithRouter.js +27 -1
  100. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  101. package/dist/esm/ssr/types.d.ts +0 -1
  102. package/dist/esm/stores.d.ts +7 -32
  103. package/dist/esm/stores.js +30 -104
  104. package/dist/esm/stores.js.map +1 -1
  105. package/dist/esm/utils.js +1 -4
  106. package/dist/esm/utils.js.map +1 -1
  107. package/package.json +3 -3
  108. package/skills/router-core/SKILL.md +23 -4
  109. package/skills/router-core/auth-and-guards/SKILL.md +10 -10
  110. package/skills/router-core/code-splitting/SKILL.md +5 -4
  111. package/skills/router-core/data-loading/SKILL.md +30 -18
  112. package/skills/router-core/navigation/SKILL.md +5 -4
  113. package/skills/router-core/not-found-and-errors/SKILL.md +5 -4
  114. package/skills/router-core/path-params/SKILL.md +5 -4
  115. package/skills/router-core/search-params/SKILL.md +5 -4
  116. package/skills/router-core/ssr/SKILL.md +5 -4
  117. package/skills/router-core/type-safety/SKILL.md +11 -4
  118. package/src/Matches.ts +6 -21
  119. package/src/await-signal.ts +27 -0
  120. package/src/index.ts +1 -3
  121. package/src/isServer/client.ts +1 -0
  122. package/src/isServer/development.ts +1 -0
  123. package/src/isServer/server.ts +1 -0
  124. package/src/link.ts +5 -3
  125. package/src/load-client.ts +2651 -0
  126. package/src/load-server.ts +849 -0
  127. package/src/redirect.ts +0 -1
  128. package/src/route.ts +2 -11
  129. package/src/router.ts +426 -773
  130. package/src/ssr/createRequestHandler.ts +109 -16
  131. package/src/ssr/handlerCallback.ts +76 -10
  132. package/src/ssr/server.ts +4 -1
  133. package/src/ssr/ssr-client.ts +1 -310
  134. package/src/ssr/ssr-match-id.ts +11 -2
  135. package/src/ssr/ssr-server.ts +9 -8
  136. package/src/ssr/transformStreamWithRouter.ts +37 -1
  137. package/src/ssr/types.ts +0 -1
  138. package/src/stores.ts +46 -208
  139. package/dist/cjs/load-matches.cjs +0 -658
  140. package/dist/cjs/load-matches.cjs.map +0 -1
  141. package/dist/cjs/load-matches.d.cts +0 -18
  142. package/dist/cjs/ssr/ssr-client.cjs +0 -183
  143. package/dist/cjs/ssr/ssr-client.cjs.map +0 -1
  144. package/dist/esm/load-matches.d.ts +0 -18
  145. package/dist/esm/load-matches.js +0 -656
  146. package/dist/esm/load-matches.js.map +0 -1
  147. package/dist/esm/ssr/ssr-client.js +0 -183
  148. package/dist/esm/ssr/ssr-client.js.map +0 -1
  149. package/src/load-matches.ts +0 -1278
@@ -0,0 +1,1393 @@
1
+ const require_not_found = require("./not-found.cjs");
2
+ const require_redirect = require("./redirect.cjs");
3
+ const require_ssr_match_id = require("./ssr/ssr-match-id.cjs");
4
+ const require_router = require("./router.cjs");
5
+ //#region src/load-client.ts
6
+ function replaceRouteChunk(route, lazyFn) {
7
+ route.lazyFn = lazyFn ?? route.lazyFn;
8
+ route._lazy = void 0;
9
+ }
10
+ function preloadComponent(route, type) {
11
+ return route.options[type]?.preload?.();
12
+ }
13
+ function loadComponents(route, onPendingReady) {
14
+ const component = preloadComponent(route, "component");
15
+ const pending = preloadComponent(route, "pendingComponent");
16
+ const pendingReady = onPendingReady && pending ? pending.then(onPendingReady) : pending;
17
+ if (onPendingReady && !pending) onPendingReady();
18
+ if (component && pendingReady) return Promise.all([component, pendingReady]).then(() => {});
19
+ return component ?? pendingReady;
20
+ }
21
+ function loadRouteChunk(route, componentType, onPendingReady) {
22
+ const afterLazy = () => componentType === false ? void 0 : componentType ? preloadComponent(route, componentType) : loadComponents(route, onPendingReady);
23
+ const current = route._lazy;
24
+ if (current) return current === true ? afterLazy() : current.then(afterLazy);
25
+ if (!route.lazyFn) return afterLazy();
26
+ const promise = route.lazyFn().then((lazyRoute) => {
27
+ if (process.env.NODE_ENV === "production" || route._lazy === promise) {
28
+ const { id: _id, ...options } = lazyRoute.options;
29
+ Object.assign(route.options, options);
30
+ route._lazy = true;
31
+ }
32
+ }, (error) => {
33
+ if (process.env.NODE_ENV === "production" || route._lazy === promise) route._lazy = void 0;
34
+ throw error;
35
+ });
36
+ route._lazy = promise;
37
+ return promise.then(afterLazy);
38
+ }
39
+ /** Return the structural lane through the first terminal render boundary. */
40
+ function _getRenderedMatches(matches) {
41
+ const end = matches.findIndex((match) => match.status !== "success" || match._notFound) + 1;
42
+ return end && end < matches.length ? matches.slice(0, end) : matches;
43
+ }
44
+ /** Return the lane whose document assets belong to the current presentation. */
45
+ function _getAssetMatches(matches) {
46
+ let end = matches.length;
47
+ for (let index = 0; index < end; index++) {
48
+ const match = matches[index];
49
+ if (match._assetEnd !== void 0) {
50
+ end = Math.min(end, Math.max(index + 1, match._assetEnd));
51
+ continue;
52
+ }
53
+ if (match.status !== "success" || match._notFound) {
54
+ end = index + 1;
55
+ break;
56
+ }
57
+ }
58
+ return end < matches.length ? matches.slice(0, end) : matches;
59
+ }
60
+ const SUCCESS = 0;
61
+ const ERROR = 1;
62
+ const NOT_FOUND = 2;
63
+ const REDIRECTED = 3;
64
+ const CANCELED = 4;
65
+ function isControl(result) {
66
+ return typeof result[0] === "number";
67
+ }
68
+ function waitFor(value, signal) {
69
+ if (signal.aborted) return Promise.race([Promise.reject(signal), value]);
70
+ return new Promise((resolve, reject) => {
71
+ const abort = () => reject(signal);
72
+ signal.addEventListener("abort", abort, { once: true });
73
+ Promise.resolve(value).then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
74
+ });
75
+ }
76
+ function getRoute(router, match) {
77
+ return router.routesById[match.routeId];
78
+ }
79
+ function normalize(value, rejected, routeId) {
80
+ if (require_redirect.isRedirect(value)) return [REDIRECTED, value];
81
+ if (require_not_found.isNotFound(value)) {
82
+ value.routeId ||= routeId;
83
+ return [NOT_FOUND, value];
84
+ }
85
+ if (rejected && typeof value?.then === "function") value = new Error("A Promise was thrown", { cause: value });
86
+ return rejected ? [ERROR, value] : [SUCCESS, value];
87
+ }
88
+ function normalizeError(route, cause) {
89
+ let outcome = normalize(cause, true, route.id);
90
+ if (outcome[0] !== ERROR) return outcome;
91
+ try {
92
+ route.options.onError?.(outcome[1]);
93
+ } catch (onErrorCause) {
94
+ outcome = normalize(onErrorCause, true, route.id);
95
+ }
96
+ return outcome;
97
+ }
98
+ function normalizeLaneError(route, cause, options) {
99
+ if (options[0].signal.aborted || !options[2]()) {
100
+ options[0].abort();
101
+ return [CANCELED];
102
+ }
103
+ return normalizeError(route, cause);
104
+ }
105
+ function navigateFrom(router, location) {
106
+ return (opts) => router.navigate({
107
+ ...opts,
108
+ _fromLocation: location
109
+ });
110
+ }
111
+ async function contextualize(router, lane, options, end, planSuccessfulLane) {
112
+ const [location, matches] = lane;
113
+ const signal = options[0].signal;
114
+ const preload = !!options[4];
115
+ for (let index = options[7] ?? 0; index < end; index++) {
116
+ const match = matches[index];
117
+ const route = getRoute(router, match);
118
+ match.abortController = options[0];
119
+ const parentContext = matches[index - 1]?.context ?? router.options.context ?? {};
120
+ const common = {
121
+ params: match.params,
122
+ location,
123
+ navigate: navigateFrom(router, location),
124
+ buildLocation: router.buildLocation,
125
+ cause: preload ? "preload" : match.cause,
126
+ abortController: options[0],
127
+ preload,
128
+ matches,
129
+ routeId: route.id
130
+ };
131
+ let context = parentContext;
132
+ try {
133
+ let routeContext = match._ctx;
134
+ if (!routeContext && route.options.context) routeContext = match._ctx = route.options.context({
135
+ ...common,
136
+ deps: match.loaderDeps,
137
+ context: parentContext
138
+ }) || {};
139
+ context = {
140
+ ...parentContext,
141
+ ...routeContext
142
+ };
143
+ match.context = context;
144
+ } catch (cause) {
145
+ releaseFlight(router, match);
146
+ return [index, normalizeLaneError(route, cause, options)];
147
+ }
148
+ if (signal.aborted || !options[2]()) {
149
+ options[0].abort();
150
+ return [index, [CANCELED]];
151
+ }
152
+ const validationError = match.paramsError ?? match.searchError;
153
+ if (validationError !== void 0) {
154
+ releaseFlight(router, match);
155
+ return [index, normalizeLaneError(route, validationError, options)];
156
+ }
157
+ const beforeLoad = route.options.beforeLoad;
158
+ if (!beforeLoad) continue;
159
+ const beforeLoadContext = {
160
+ ...common,
161
+ search: match.search,
162
+ context,
163
+ ...router.options.additionalContext
164
+ };
165
+ const previousStatus = match.status;
166
+ if (previousStatus === "success") match.status = "pending";
167
+ options[8]?.();
168
+ try {
169
+ setFetching(router, match, "beforeLoad", options[0]);
170
+ const result = await waitFor(beforeLoad(beforeLoadContext), signal);
171
+ if (!options[2]()) {
172
+ options[0].abort();
173
+ return [index, [CANCELED]];
174
+ }
175
+ const outcome = normalize(result, false, route.id);
176
+ if (outcome[0] !== SUCCESS) {
177
+ releaseFlight(router, match);
178
+ return [index, outcome];
179
+ }
180
+ match.context = {
181
+ ...context,
182
+ ...result
183
+ };
184
+ } catch (cause) {
185
+ releaseFlight(router, match);
186
+ return [index, normalizeLaneError(route, cause, options)];
187
+ } finally {
188
+ if (previousStatus === "success" && match.status === "pending") match.status = "success";
189
+ setFetching(router, match, false, options[0]);
190
+ }
191
+ }
192
+ planSuccessfulLane();
193
+ }
194
+ function releaseOwnedFlight(router, match, flight) {
195
+ if (!flight || --flight[2]) return;
196
+ if (router._flights?.get(match.id) === flight) {
197
+ const current = router._tx;
198
+ if (current && !current[0].signal.aborted && !(process.env.NODE_ENV !== "production" && current[6]) && !current[3].includes(match) && current[3].some((candidate) => candidate.id === match.id) && current[3].some((candidate) => candidate.isFetching === "beforeLoad")) return;
199
+ router._flights.delete(match.id);
200
+ }
201
+ return flight[1];
202
+ }
203
+ function releaseFlight(router, match) {
204
+ const flight = match._flight;
205
+ match._flight = void 0;
206
+ releaseOwnedFlight(router, match, flight)?.abort();
207
+ }
208
+ /**
209
+ * Not passing in a `next` ownership recipient
210
+ * is equivalent to discarding the match resources
211
+ */
212
+ function transferMatchResources(router, previous, next) {
213
+ const abort = [];
214
+ for (const match of previous) if (!next?.includes(match)) {
215
+ const flight = match._flight;
216
+ match._flight = void 0;
217
+ const controller = releaseOwnedFlight(router, match, flight);
218
+ if (controller) abort.push(controller);
219
+ }
220
+ for (const controller of abort) controller.abort();
221
+ }
222
+ function transferPredecessorResources(router, previous, next) {
223
+ const abort = [];
224
+ for (const match of previous) if (!next.includes(match)) {
225
+ const flight = match._flight;
226
+ match._flight = void 0;
227
+ if (flight?.[2] === 1 && router._flights?.get(match.id) === flight && !(process.env.NODE_ENV !== "production" && router._tx?.[6]) && next.some((candidate) => candidate.id === match.id)) flight[2] = 0;
228
+ else {
229
+ const controller = releaseOwnedFlight(router, match, flight);
230
+ if (controller) abort.push(controller);
231
+ }
232
+ }
233
+ for (const controller of abort) controller.abort();
234
+ }
235
+ function releaseUnownedFlights(router) {
236
+ const abort = [];
237
+ for (const [id, flight] of router._flights ?? []) if (!flight[2]) {
238
+ router._flights.delete(id);
239
+ abort.push(flight[1]);
240
+ }
241
+ for (const controller of abort) controller.abort();
242
+ }
243
+ function acquireMatchResources(matches) {
244
+ for (const match of matches) {
245
+ const flight = match._flight;
246
+ if (flight) flight[2]++;
247
+ }
248
+ }
249
+ function setFetching(router, match, value, owner) {
250
+ match.isFetching = value;
251
+ if (owner && router._tx?.[0] !== owner) return;
252
+ const store = router.stores.byRoute.get(match.routeId);
253
+ const presented = store?.get();
254
+ if (presented?.id === match.id) store.set({
255
+ ...presented,
256
+ isFetching: value
257
+ });
258
+ }
259
+ function getLoaderContext(router, lane, match, route, controller, parentMatchPromise, preload) {
260
+ const location = lane[0];
261
+ return {
262
+ params: match.params,
263
+ location,
264
+ navigate: navigateFrom(router, location),
265
+ cause: preload ? "preload" : match.cause,
266
+ abortController: controller,
267
+ preload,
268
+ deps: match.loaderDeps,
269
+ parentMatchPromise,
270
+ context: match.context,
271
+ route,
272
+ ...router.options.additionalContext
273
+ };
274
+ }
275
+ async function loadResource(router, lane, match, route, loader, parentMatchPromise, preload, owner) {
276
+ const signal = owner.signal;
277
+ if (signal.aborted) return [CANCELED];
278
+ if (!loader) return [SUCCESS, void 0];
279
+ let flight = match._flight;
280
+ setFetching(router, match, "loader", owner);
281
+ try {
282
+ if (!flight) {
283
+ const controller = new AbortController();
284
+ flight = [
285
+ Promise.resolve().then(() => loader(getLoaderContext(router, lane, match, route, controller, parentMatchPromise, preload))).then((value) => normalize(value, false, route.id), (cause) => normalize(cause, true, route.id)).then((result) => {
286
+ if (result[0] !== SUCCESS && router._flights?.get(match.id) === flight) {
287
+ router._flights.delete(match.id);
288
+ if (!flight[2]) controller.abort();
289
+ }
290
+ return result[0] === ERROR && flight[2] ? normalizeError(route, result[1]) : result;
291
+ }),
292
+ controller,
293
+ 1
294
+ ];
295
+ (router._flights ??= /* @__PURE__ */ new Map()).set(match.id, flight);
296
+ }
297
+ match._flight = flight;
298
+ match.abortController = flight[1];
299
+ return await waitFor(flight[0], signal);
300
+ } catch (cause) {
301
+ if (cause !== signal) throw cause;
302
+ releaseFlight(router, match);
303
+ return [CANCELED];
304
+ } finally {
305
+ setFetching(router, match, false, owner);
306
+ }
307
+ }
308
+ function settleInto(match, result, preload) {
309
+ if (result[0] === SUCCESS) {
310
+ match.loaderData = result[1];
311
+ match.error = void 0;
312
+ match.status = "success";
313
+ match.invalid = false;
314
+ match.updatedAt = Date.now();
315
+ match.preload = preload;
316
+ } else if (result[0] !== REDIRECTED) {
317
+ match.status = "success";
318
+ match.error = void 0;
319
+ match.invalid = true;
320
+ }
321
+ }
322
+ function cacheLoaderMatch(router, match, planned) {
323
+ const current = router._cache.get(match.id);
324
+ if (current !== planned || router._committed.some((candidate) => candidate.id === match.id && candidate._flight === match._flight)) return;
325
+ const cached = {
326
+ ...match,
327
+ _notFound: void 0,
328
+ context: {}
329
+ };
330
+ if (cached._flight) cached._flight[2]++;
331
+ router._cache.set(match.id, cached);
332
+ if (current) releaseFlight(router, current);
333
+ }
334
+ function getParentSnapshot(match, outcome) {
335
+ if (outcome[0] === ERROR || outcome[0] === NOT_FOUND) return {
336
+ ...match,
337
+ status: outcome[0] === ERROR ? "error" : "notFound",
338
+ error: outcome[1],
339
+ _flight: void 0
340
+ };
341
+ return match;
342
+ }
343
+ function createLoaderTask(router, lane, index, tasks, semanticParent, options) {
344
+ const match = lane[1][index];
345
+ const route = getRoute(router, match);
346
+ const preload = !!options[4];
347
+ const plannedCacheMatch = preload ? router._cache.get(match.id) : void 0;
348
+ let configured;
349
+ let reload = false;
350
+ let reloadFailure;
351
+ try {
352
+ if (match.status === "success") {
353
+ configured = route.options.shouldReload;
354
+ if (typeof configured === "function") configured = configured(getLoaderContext(router, lane, match, route, options[0], semanticParent, preload));
355
+ if (!options[2]()) {
356
+ options[0].abort();
357
+ reloadFailure = [CANCELED];
358
+ }
359
+ }
360
+ if (!reloadFailure) if (match.status !== "success") reload = true;
361
+ else {
362
+ const staleAge = options[4] || match.preload ? route.options.preloadStaleTime ?? router.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? router.options.defaultStaleTime ?? 0;
363
+ reload = !!(match.invalid || configured || configured === void 0 && Date.now() - match.updatedAt >= staleAge && (options[6] || match.cause === "enter" || options[3].some((candidate) => candidate.routeId === match.routeId && candidate.id !== match.id)));
364
+ }
365
+ } catch (cause) {
366
+ match.invalid = true;
367
+ releaseFlight(router, match);
368
+ reloadFailure = normalizeLaneError(route, cause, options);
369
+ }
370
+ const routeLoader = route.options.loader;
371
+ const loader = typeof routeLoader === "function" ? routeLoader : routeLoader?.handler;
372
+ let donor = (!preload || route.options.preload !== false) && routeLoader && !(process.env.NODE_ENV !== "production" && router._tx?.[6]) ? router._flights?.get(match.id) : void 0;
373
+ if (donor === match._flight || reloadFailure) donor = void 0;
374
+ else if (donor && !reload && !preload && configured === void 0) reload = true;
375
+ else if (!reload) donor = void 0;
376
+ const background = !!(routeLoader && reload && match.status === "success" && !preload && !options[5] && ((typeof routeLoader === "function" ? void 0 : routeLoader?.staleReloadMode) ?? router.options.defaultStaleReloadMode) !== "blocking");
377
+ const loaded = reload && (!preload || route.options.preload !== false);
378
+ const blocking = loaded && !background && (match.status !== "success" || !!routeLoader);
379
+ const onLazyReady = route.lazyFn && route._lazy !== true ? options[8] : void 0;
380
+ if (loaded && !routeLoader) {
381
+ match.invalid = false;
382
+ match.updatedAt = Date.now();
383
+ }
384
+ if (donor) donor[2]++;
385
+ if (blocking) {
386
+ const acceptedFlight = match._flight;
387
+ match._flight = donor;
388
+ releaseOwnedFlight(router, match, acceptedFlight)?.abort();
389
+ if (match.status === "success") match.status = "pending";
390
+ options[8]?.();
391
+ }
392
+ if (!loaded) match.isFetching = false;
393
+ const outcome = (reloadFailure ? Promise.resolve(reloadFailure) : !blocking ? Promise.resolve([SUCCESS, match.loaderData]) : loadResource(router, lane, match, route, loader, semanticParent, preload, options[0])).then((result) => {
394
+ if (blocking) {
395
+ settleInto(match, result, preload);
396
+ if (result[0] === SUCCESS) {
397
+ if (preload && routeLoader && !options[0].signal.aborted) cacheLoaderMatch(router, match, plannedCacheMatch);
398
+ match.status = "pending";
399
+ }
400
+ }
401
+ return result;
402
+ });
403
+ const chunkFailure = waitFor(Promise.resolve().then(() => loadRouteChunk(route, void 0, onLazyReady)), options[0].signal).then(() => void 0, (cause) => [index, normalizeLaneError(route, cause, options)]).then((failure) => outcome.then((result) => {
404
+ if (blocking && !failure && result[0] === SUCCESS && match.status === "pending" && options[2]()) {
405
+ match.status = "success";
406
+ options[8]?.();
407
+ }
408
+ return failure;
409
+ }));
410
+ tasks.push([
411
+ index,
412
+ outcome,
413
+ chunkFailure
414
+ ]);
415
+ if (!background) return outcome.then((result) => getParentSnapshot(match, result));
416
+ const candidate = {
417
+ ...match,
418
+ status: "pending",
419
+ preload: false,
420
+ _flight: donor
421
+ };
422
+ match.invalid = false;
423
+ match.isFetching = "loader";
424
+ const backgroundOutcome = loadResource(router, lane, candidate, route, loader, semanticParent, false, options[0]).then((result) => {
425
+ match.isFetching = false;
426
+ settleInto(candidate, result, false);
427
+ return result;
428
+ });
429
+ (lane[2] ??= []).push([
430
+ index,
431
+ backgroundOutcome,
432
+ chunkFailure,
433
+ candidate
434
+ ]);
435
+ return backgroundOutcome.then((result) => getParentSnapshot(candidate, result));
436
+ }
437
+ async function getNotFoundBoundary(router, matches, indexed, signal, fallback = 0) {
438
+ const cause = indexed?.[1][1];
439
+ let index = cause?.routeId ? matches.findIndex((match) => match.routeId === cause.routeId) : indexed?.[0] ?? matches.length - 1;
440
+ if (index < 0) index = 0;
441
+ for (let i = index; i >= 0; i--) {
442
+ const route = getRoute(router, matches[i]);
443
+ const loading = loadRouteChunk(route, false);
444
+ if (loading) try {
445
+ await waitFor(loading, signal);
446
+ } catch (cause) {
447
+ if (cause === signal) throw cause;
448
+ }
449
+ if (route.options.notFoundComponent) return i;
450
+ }
451
+ return cause?.routeId ? index : fallback;
452
+ }
453
+ function discardBackground(router, lane) {
454
+ if (lane[2]) {
455
+ transferMatchResources(router, lane[2].map((task) => task[3]));
456
+ lane[2] = void 0;
457
+ }
458
+ }
459
+ async function settleTasks(tasks, serialFailure, redirectTasks, gate) {
460
+ let loaderFailure;
461
+ try {
462
+ await Promise.all(tasks.map((task) => task[1].then(async (outcome) => {
463
+ const taskIndex = task[0];
464
+ if (gate && taskIndex >= await gate) return;
465
+ if (outcome[0] >= REDIRECTED) throw [taskIndex, outcome];
466
+ if (!loaderFailure && outcome[0] !== SUCCESS) {
467
+ loaderFailure = [taskIndex, outcome];
468
+ await Promise.all((redirectTasks ?? []).map((nextTask) => {
469
+ if (nextTask[0] <= taskIndex) return;
470
+ return nextTask[1].then((nextOutcome) => {
471
+ if (nextOutcome[0] === REDIRECTED) throw [nextTask[0], nextOutcome];
472
+ });
473
+ }));
474
+ }
475
+ })));
476
+ } catch (cause) {
477
+ return cause;
478
+ }
479
+ return serialFailure ?? loaderFailure;
480
+ }
481
+ async function reduceLane(router, lane, tasks, controller, redirects, settlement, onReady) {
482
+ const matches = lane[1];
483
+ let failure = await settlement;
484
+ let redirectLimitExceeded = false;
485
+ const plannedBoundary = matches.findIndex((match) => match._notFound);
486
+ const boundaryOf = (found) => found[1][0] === NOT_FOUND ? getNotFoundBoundary(router, matches, found, controller.signal) : found[0];
487
+ let readinessEnd = plannedBoundary < 0 ? matches.length : plannedBoundary;
488
+ if ((failure?.[1][0] ?? 0) >= REDIRECTED) readinessEnd = 0;
489
+ else if (failure) {
490
+ readinessEnd = failure[2] ??= await boundaryOf(failure);
491
+ for (const task of tasks) {
492
+ if (task[0] >= readinessEnd) break;
493
+ const outcome = await task[1];
494
+ if (outcome[0] !== SUCCESS && outcome[0] < REDIRECTED && !("loaderData" in matches[task[0]])) {
495
+ failure = [task[0], outcome];
496
+ readinessEnd = failure[2] = await boundaryOf(failure);
497
+ break;
498
+ }
499
+ }
500
+ }
501
+ for (const task of tasks) {
502
+ if (task[0] >= readinessEnd) break;
503
+ const chunkFailure = await task[2];
504
+ if (!chunkFailure) continue;
505
+ failure = chunkFailure;
506
+ break;
507
+ }
508
+ if ((failure?.[1][0] ?? 0) >= REDIRECTED) {
509
+ const outcome = failure[1];
510
+ if (outcome[0] !== REDIRECTED || outcome[1].options.reloadDocument || redirects < 20) {
511
+ discardBackground(router, lane);
512
+ return outcome;
513
+ }
514
+ redirectLimitExceeded = true;
515
+ failure = [0, [ERROR, /* @__PURE__ */ new Error("Too many redirects")]];
516
+ }
517
+ const boundary = failure ? failure[2] ?? await boundaryOf(failure) : plannedBoundary;
518
+ if (boundary >= 0) {
519
+ const outcome = failure?.[1];
520
+ const kind = outcome?.[0];
521
+ const match = matches[boundary];
522
+ const cause = outcome?.[1];
523
+ const install = () => {
524
+ if (outcome) {
525
+ match._notFound = void 0;
526
+ if (kind === ERROR) match.status = "error";
527
+ else {
528
+ cause.routeId = match.routeId;
529
+ if (match.routeId === router.routeTree.id) {
530
+ match.status = "success";
531
+ match._notFound = true;
532
+ } else match.status = "notFound";
533
+ }
534
+ match.error = cause;
535
+ match.isFetching = false;
536
+ }
537
+ };
538
+ install();
539
+ try {
540
+ await waitFor(outcome ? Promise.resolve().then(() => loadRouteChunk(getRoute(router, match), kind === ERROR ? "errorComponent" : "notFoundComponent")) : Promise.all([loadRouteChunk(getRoute(router, match)), loadRouteChunk(getRoute(router, match), "notFoundComponent")]), controller.signal);
541
+ } catch (cause) {
542
+ if (cause === controller.signal) {
543
+ discardBackground(router, lane);
544
+ return [CANCELED];
545
+ }
546
+ }
547
+ if (!outcome) {
548
+ match.status = "success";
549
+ onReady?.();
550
+ } else if (redirectLimitExceeded) {
551
+ controller.abort();
552
+ await Promise.all([
553
+ ...tasks.map((task) => task[1]),
554
+ ...tasks.map((task) => task[2]),
555
+ ...(lane[2] ?? []).map((task) => task[1])
556
+ ]);
557
+ discardBackground(router, lane);
558
+ transferMatchResources(router, matches);
559
+ install();
560
+ }
561
+ }
562
+ return lane;
563
+ }
564
+ async function projectLane(router, lane, signal, start = 0, end = lane[1].length) {
565
+ const matches = lane[1];
566
+ for (let index = start; index < end; index++) {
567
+ const match = matches[index];
568
+ const routeOptions = getRoute(router, match).options;
569
+ if (routeOptions.head || routeOptions.scripts) try {
570
+ const context = {
571
+ ssr: router.options.ssr,
572
+ matches,
573
+ match,
574
+ params: match.params,
575
+ loaderData: match.loaderData
576
+ };
577
+ const [head, scripts] = await waitFor(Promise.all([routeOptions.head?.(context), routeOptions.scripts?.(context)]), signal);
578
+ match.meta = head?.meta;
579
+ match.links = head?.links;
580
+ match.headScripts = head?.scripts;
581
+ match.styles = head?.styles;
582
+ match.scripts = scripts;
583
+ } catch (cause) {
584
+ if (cause === signal) break;
585
+ console.error(cause);
586
+ }
587
+ if (match.status !== "success" || match._notFound) break;
588
+ }
589
+ return lane;
590
+ }
591
+ async function executeClientLane(router, location, matches, options) {
592
+ const matched = [location, matches];
593
+ let plannedBoundary = matches.findIndex((match) => match._notFound);
594
+ if (router.options.notFoundMode !== "root" && plannedBoundary >= 0) {
595
+ const boundary = await getNotFoundBoundary(router, matched[1], void 0, options[0].signal, plannedBoundary);
596
+ if (boundary !== plannedBoundary) {
597
+ matches[plannedBoundary]._notFound = void 0;
598
+ matches[boundary]._notFound = true;
599
+ }
600
+ plannedBoundary = boundary;
601
+ }
602
+ let end = plannedBoundary < 0 ? matches.length : plannedBoundary + 1;
603
+ const tasks = [];
604
+ const start = options[7] ?? 0;
605
+ let semanticParent = start ? Promise.resolve(matched[1][start - 1]) : void 0;
606
+ const planSuccessfulLane = () => {
607
+ for (let index = start; index < end; index++) {
608
+ if (options[0].signal.aborted) break;
609
+ semanticParent = createLoaderTask(router, matched, index, tasks, semanticParent, options);
610
+ }
611
+ };
612
+ const failure = await contextualize(router, matched, options, end, planSuccessfulLane);
613
+ if (failure) {
614
+ options[5] = true;
615
+ end = failure[0];
616
+ if (failure[1][0] === NOT_FOUND) {
617
+ failure[2] = await getNotFoundBoundary(router, matched[1], failure, options[0].signal);
618
+ end = Math.min(end, failure[2] + 1);
619
+ } else if (failure[1][0] >= REDIRECTED) end = 0;
620
+ planSuccessfulLane();
621
+ }
622
+ if (options[2]() && !options[4]) releaseUnownedFlights(router);
623
+ let reduced;
624
+ try {
625
+ const reduction = reduceLane(router, matched, tasks, options[0], options[1], settleTasks(tasks, failure, matched[2]), options[8]);
626
+ if (matched[2]?.length) matched[3] = settleTasks(matched[2], void 0, void 0, reduction.then((foreground) => isControl(foreground) ? 0 : _getRenderedMatches(foreground[1]).length, () => 0));
627
+ reduced = await reduction;
628
+ } catch (cause) {
629
+ discardBackground(router, matched);
630
+ throw cause;
631
+ }
632
+ if (isControl(reduced)) return reduced;
633
+ return projectLane(router, reduced, options[0].signal, options[7] === reduced[1].length ? options[7] : 0);
634
+ }
635
+ /**
636
+ * Finds the first route that should show pending UI and its two timing values.
637
+ * A fallback already on screen remains selected after its route loads, so we
638
+ * do not jump to a child fallback. Matches put back into pending by invalidation
639
+ * skip pendingMs, and a route without a usable fallback blocks pending UI for deeper routes.
640
+ */
641
+ function pendingConfig(router, matches) {
642
+ const presented = router.stores.matches.get();
643
+ for (let index = 0; index < matches.length; index++) {
644
+ const match = matches[index];
645
+ const success = match.status === "success";
646
+ const visible = success && presented[index]?.id === match.id && presented[index]?.status === "pending";
647
+ if (success && !visible) continue;
648
+ const route = getRoute(router, match);
649
+ const delay = visible || match.invalid ? 0 : route.options.pendingMs ?? router.options.defaultPendingMs;
650
+ const component = route.options.pendingComponent ?? router.options.defaultPendingComponent;
651
+ return component && typeof delay === "number" && delay !== Infinity ? [
652
+ delay,
653
+ index,
654
+ route.options.pendingMinMs ?? router.options.defaultPendingMinMs ?? 0,
655
+ component
656
+ ] : void 0;
657
+ }
658
+ }
659
+ /**
660
+ * Waits for `pendingMs`, then presents the complete lane. Rendering applies the
661
+ * selected boundary cutoff while retaining every match's structural state.
662
+ * A replacement load for the same match keeps the timer; choosing a different
663
+ * match resets it. `pendingMinMs` starts after the fallback renders.
664
+ */
665
+ function offerPending(router, tx) {
666
+ if (router._tx !== tx) return;
667
+ let session = router._pending;
668
+ let tookOver = false;
669
+ const sessionMatchId = session?.[0][3][session[1]]?.id;
670
+ if (session?.[0] !== tx) if (session && tx[3][session[1]]?.id === sessionMatchId) {
671
+ session[0] = tx;
672
+ tookOver = true;
673
+ } else {
674
+ clearTimeout(session?.[3]);
675
+ router._pending = session = void 0;
676
+ }
677
+ const config = pendingConfig(router, tx[3]);
678
+ if (!config) return;
679
+ const [delay, boundary, min, component] = config;
680
+ const matchId = tx[3][boundary].id;
681
+ if (!session || session[1] !== boundary || sessionMatchId !== matchId) {
682
+ clearTimeout(session?.[3]);
683
+ const presented = router.stores.matches.get()[boundary];
684
+ const visible = presented?.id === matchId && presented.status === "pending";
685
+ router._pending = session = [
686
+ tx,
687
+ boundary,
688
+ visible ? Date.now() + min : tx[4] + delay,
689
+ void 0,
690
+ visible ? Promise.resolve(true) : void 0,
691
+ component
692
+ ];
693
+ }
694
+ if (session[4] && !tookOver && session[5] === component) return;
695
+ session[5] = component;
696
+ if (!session[4]) {
697
+ clearTimeout(session[3]);
698
+ const remaining = session[2] - Date.now();
699
+ if (remaining > 0) {
700
+ session[3] = setTimeout(() => {
701
+ offerPending(router, tx);
702
+ }, remaining);
703
+ return;
704
+ }
705
+ session[2] = 0;
706
+ }
707
+ const offered = tx[3].map((match) => ({
708
+ ...match,
709
+ _flight: void 0
710
+ }));
711
+ offered[boundary].status = "pending";
712
+ const ack = router.startTransition(() => router.stores.setMatches(offered), offered).then((rendered) => {
713
+ if (rendered && router._pending === session && session[4] === ack && !session[2]) session[2] = Date.now() + min;
714
+ return rendered;
715
+ });
716
+ session[4] = ack;
717
+ }
718
+ /**
719
+ * Cancels pending UI timing when its load ends. The ownership check prevents
720
+ * an older, superseded load from clearing pending UI that a newer load took over.
721
+ */
722
+ function finishPending(router, tx) {
723
+ const session = router._pending;
724
+ if (session?.[0] === tx) {
725
+ clearTimeout(session[3]);
726
+ router._pending = void 0;
727
+ }
728
+ }
729
+ function publishMatches(router, matches) {
730
+ router._committed = matches;
731
+ router.stores.setMatches(matches);
732
+ }
733
+ function discardLane(router, lane) {
734
+ transferMatchResources(router, lane[1]);
735
+ discardBackground(router, lane);
736
+ }
737
+ function commitMatches(router, tx, matches, resolvedPrefix) {
738
+ const previous = router._committed;
739
+ const previousCached = router._cache;
740
+ for (const match of matches) {
741
+ match.preload = false;
742
+ if (resolvedPrefix) match._assetEnd = void 0;
743
+ }
744
+ const cut = _getRenderedMatches(matches).length;
745
+ const cached = /* @__PURE__ */ new Map();
746
+ const now = Date.now();
747
+ for (const match of [...previous, ...previousCached.values()]) {
748
+ if (match.status !== "success" || matches.some((candidate, index) => candidate.id === match.id && (index < cut || candidate.status === "success"))) continue;
749
+ const route = getRoute(router, match);
750
+ if (!route.options.loader || now - match.updatedAt >= (match.preload ? route.options.preloadGcTime ?? router.options.defaultPreloadGcTime ?? 3e5 : route.options.gcTime ?? router.options.defaultGcTime ?? 3e5)) continue;
751
+ cached.set(match.id, previousCached.get(match.id) === match ? match : {
752
+ ...match,
753
+ _flight: void 0,
754
+ isFetching: false,
755
+ context: {}
756
+ });
757
+ }
758
+ tx[3] = [];
759
+ router._cache = cached;
760
+ publishMatches(router, matches);
761
+ transferMatchResources(router, [...previousCached.values(), ...previous], [...matches, ...cached.values()]);
762
+ require_router.runRouteLifecycle(router, previous, matches, () => router._tx === tx);
763
+ }
764
+ function commitRefreshMatches(router, tx, matches, checkpoint) {
765
+ const previous = router._committed;
766
+ const previousCached = router._cache;
767
+ for (const match of matches) match.preload = false;
768
+ const cached = /* @__PURE__ */ new Map();
769
+ tx[3] = [];
770
+ router._cache = cached;
771
+ checkpoint.previousMatches = previous;
772
+ checkpoint.previousCache = previousCached;
773
+ checkpoint.published = true;
774
+ publishMatches(router, matches);
775
+ if (!checkpoint.published || router._tx !== tx) return;
776
+ require_router.runRouteLifecycle(router, previous, matches, () => router._tx === tx);
777
+ }
778
+ function settlePublication(router, checkpoint) {
779
+ if (!checkpoint.published) return;
780
+ checkpoint.published = false;
781
+ transferMatchResources(router, [...checkpoint.previousCache.values(), ...checkpoint.previousMatches], [...router._cache.values(), ...router._committed]);
782
+ }
783
+ function rollbackPublication(router, tx, lane, checkpoint) {
784
+ if (!checkpoint.published || router._tx !== tx || router._committed !== lane[1]) {
785
+ settlePublication(router, checkpoint);
786
+ return false;
787
+ }
788
+ const discarded = [...router._cache.values(), ...router._committed];
789
+ const restored = [...checkpoint.previousCache.values(), ...checkpoint.previousMatches];
790
+ router._cache = checkpoint.previousCache;
791
+ router._committed = checkpoint.previousMatches;
792
+ checkpoint.published = false;
793
+ for (const match of discarded) if (!restored.includes(match) && match._flight && router._flights?.get(match.id) === match._flight) router._flights.delete(match.id);
794
+ finishPending(router, tx);
795
+ router.batch(() => {
796
+ router.stores.status.set("idle");
797
+ router.stores.setMatches(checkpoint.previousPresentation);
798
+ });
799
+ tx[0].abort();
800
+ transferMatchResources(router, discarded, restored);
801
+ discardBackground(router, lane);
802
+ if (router._tx === tx && router._commitPromise === checkpoint.commitPromise) {
803
+ router._commitPromise?.resolve();
804
+ router._commitPromise = void 0;
805
+ }
806
+ return true;
807
+ }
808
+ async function transitionRefresh(router, tx, lane, changeInfo) {
809
+ const refresh = tx[6];
810
+ const checkpoint = {
811
+ previousMatches: router._committed,
812
+ previousPresentation: refresh[0],
813
+ previousCache: router._cache,
814
+ commitPromise: router._commitPromise,
815
+ published: false
816
+ };
817
+ const commit = () => {
818
+ finishPending(router, tx);
819
+ refresh[2] = rollback;
820
+ commitRefreshMatches(router, tx, lane[1], checkpoint);
821
+ if (!checkpoint.published || router._tx !== tx) return;
822
+ router.emit({
823
+ type: "onLoad",
824
+ ...changeInfo
825
+ });
826
+ if (router._tx === tx) router.emit({
827
+ type: "onBeforeRouteMount",
828
+ ...changeInfo
829
+ });
830
+ };
831
+ const rollback = () => {
832
+ if (refresh[2] === rollback) refresh[2] = void 0;
833
+ const restored = rollbackPublication(router, tx, lane, checkpoint);
834
+ router._cancelTransition?.();
835
+ return restored;
836
+ };
837
+ try {
838
+ const rendered = await router.startTransition(commit, lane[1]);
839
+ if (refresh[2] === rollback) refresh[2] = void 0;
840
+ if (checkpoint.published) {
841
+ const handoff = refresh[1];
842
+ if (handoff && router._handoff === handoff) handoff[1]();
843
+ if (router._tx === tx) tx[6] = void 0;
844
+ }
845
+ settlePublication(router, checkpoint);
846
+ return rendered;
847
+ } catch (cause) {
848
+ if (rollback()) return;
849
+ throw cause;
850
+ }
851
+ }
852
+ async function awaitCurrent(router, owner) {
853
+ let current = router._tx;
854
+ while (current && current !== owner) {
855
+ await current[5];
856
+ if (router._tx === current) return;
857
+ current = router._tx;
858
+ }
859
+ }
860
+ async function followRedirect(router, tx, redirect) {
861
+ await router.navigate({
862
+ ...redirect.options,
863
+ replace: true,
864
+ ignoreBlocker: true,
865
+ _redirects: tx[1] + 1
866
+ });
867
+ }
868
+ function restoreCommitted(router, tx) {
869
+ finishPending(router, tx);
870
+ tx[0].abort();
871
+ transferMatchResources(router, tx[3]);
872
+ tx[3] = [];
873
+ if (router._tx !== tx) return;
874
+ router.batch(() => {
875
+ router.stores.status.set("idle");
876
+ router.stores.setMatches(router._committed);
877
+ });
878
+ if (router._tx === tx) {
879
+ router._commitPromise?.resolve();
880
+ router._commitPromise = void 0;
881
+ }
882
+ }
883
+ async function runBackground(router, tx, base, tasks, settlement) {
884
+ const next = base.map((match) => ({ ...match }));
885
+ acquireMatchResources(next);
886
+ for (const task of tasks) {
887
+ releaseFlight(router, next[task[0]]);
888
+ next[task[0]] = task[3];
889
+ }
890
+ const lane = [tx[2], next];
891
+ let reduced;
892
+ try {
893
+ reduced = await reduceLane(router, lane, tasks, tx[0], tx[1], settlement);
894
+ } catch (cause) {
895
+ transferMatchResources(router, next);
896
+ throw cause;
897
+ }
898
+ if (isControl(reduced)) {
899
+ transferMatchResources(router, next);
900
+ if (reduced[0] === REDIRECTED && router._tx === tx && router._committed === base) await followRedirect(router, tx, reduced[1]);
901
+ return;
902
+ }
903
+ const projected = await projectLane(router, reduced, tx[0].signal);
904
+ if (router._tx !== tx || router._committed !== base) {
905
+ transferMatchResources(router, projected[1]);
906
+ return;
907
+ }
908
+ for (const match of projected[1]) {
909
+ const cached = router._cache.get(match.id);
910
+ if (cached?._flight && cached._flight === match._flight) {
911
+ router._cache.delete(match.id);
912
+ releaseFlight(router, cached);
913
+ }
914
+ }
915
+ publishMatches(router, projected[1]);
916
+ transferMatchResources(router, base, projected[1]);
917
+ }
918
+ async function runClientTransaction(router, tx, forceStaleReload, onReady, sync, resolvedPrefix) {
919
+ const options = [
920
+ tx[0],
921
+ tx[1],
922
+ () => router._tx === tx && !!tx[3].length,
923
+ router._committed,
924
+ void 0,
925
+ sync,
926
+ forceStaleReload,
927
+ resolvedPrefix,
928
+ onReady
929
+ ];
930
+ const result = await executeClientLane(router, tx[2], tx[3], options);
931
+ if (isControl(result)) {
932
+ if (result[0] === REDIRECTED && router._tx === tx) {
933
+ finishPending(router, tx);
934
+ transferMatchResources(router, tx[3]);
935
+ tx[3] = [];
936
+ if (router._tx === tx) {
937
+ if (process.env.NODE_ENV !== "production" && tx[6]) router._refreshNextLoad = true;
938
+ await followRedirect(router, tx, result[1]);
939
+ }
940
+ } else restoreCommitted(router, tx);
941
+ return;
942
+ }
943
+ const pending = router._pending;
944
+ if (pending?.[0] === tx) {
945
+ /**
946
+ * Loading finished, so cancel any pending reveal. If the fallback rendered,
947
+ * wait out the rest of `pendingMinMs` before replacing it. If it never
948
+ * rendered, there is no minimum wait; if another load took it over, that
949
+ * load owns the deadline.
950
+ */
951
+ clearTimeout(pending[3]);
952
+ if (pending[4]) {
953
+ const signal = tx[0].signal;
954
+ let rendered = false;
955
+ try {
956
+ rendered = await waitFor(pending[4], signal);
957
+ } catch (cause) {
958
+ if (cause !== signal) throw cause;
959
+ }
960
+ if (rendered && router._pending === pending && pending[0] === tx) {
961
+ const remaining = pending[2] - Date.now();
962
+ if (remaining > 0) {
963
+ try {
964
+ await waitFor(new Promise((resolve) => {
965
+ pending[3] = setTimeout(resolve, remaining);
966
+ }), signal);
967
+ } catch {}
968
+ clearTimeout(pending[3]);
969
+ }
970
+ }
971
+ }
972
+ }
973
+ if (router._tx !== tx) {
974
+ finishPending(router, tx);
975
+ discardLane(router, result);
976
+ return;
977
+ }
978
+ const toLocation = tx[2];
979
+ const changeInfo = require_router.getLocationChangeInfo(toLocation, router.stores.resolvedLocation.get());
980
+ const background = result[2];
981
+ await router.startViewTransition(async () => {
982
+ if (router._tx !== tx) {
983
+ discardLane(router, result);
984
+ return;
985
+ }
986
+ const commit = () => {
987
+ finishPending(router, tx);
988
+ commitMatches(router, tx, result[1], resolvedPrefix);
989
+ if (router._tx !== tx) return;
990
+ router.emit({
991
+ type: "onLoad",
992
+ ...changeInfo
993
+ });
994
+ if (router._tx === tx) router.emit({
995
+ type: "onBeforeRouteMount",
996
+ ...changeInfo
997
+ });
998
+ };
999
+ const rendered = process.env.NODE_ENV !== "production" && tx[6] ? await transitionRefresh(router, tx, result, changeInfo) : await router.startTransition(commit, result[1]);
1000
+ if (process.env.NODE_ENV !== "production" && tx[6] && rendered === void 0) return;
1001
+ if (router._tx !== tx) {
1002
+ discardBackground(router, result);
1003
+ return;
1004
+ }
1005
+ if (background?.length) runBackground(router, tx, result[1], background, result[3]).catch(console.error);
1006
+ router.batch(() => {
1007
+ router.stores.resolvedLocation.set(toLocation);
1008
+ router.stores.status.set("idle");
1009
+ if (router._tx === tx) router.emit({
1010
+ type: "onResolved",
1011
+ ...changeInfo
1012
+ });
1013
+ if (rendered && router._tx === tx) router.emit({
1014
+ type: "onRendered",
1015
+ ...changeInfo
1016
+ });
1017
+ });
1018
+ if (router._tx !== tx) return;
1019
+ router._commitPromise?.resolve();
1020
+ router._commitPromise = void 0;
1021
+ });
1022
+ }
1023
+ async function loadClientRoute(router, opts) {
1024
+ let rematerialize = false;
1025
+ if (process.env.NODE_ENV !== "production") {
1026
+ router._tx?.[6]?.[2]?.();
1027
+ rematerialize = !!router._refreshNextLoad || !!router._tx?.[6];
1028
+ }
1029
+ const refreshPresentation = rematerialize ? router.stores.matches.get() : void 0;
1030
+ const previousOwner = router._tx;
1031
+ const resolvedLocation = router.stores.resolvedLocation.get();
1032
+ const previousLocation = resolvedLocation ?? router.stores.location.get();
1033
+ const location = router.latestLocation;
1034
+ const pendingLocation = router._pendingLocation;
1035
+ const redirects = pendingLocation?.href === location.href ? pendingLocation._redirects ?? 0 : 0;
1036
+ const handoff = router._handoff;
1037
+ const hydrationController = rematerialize ? void 0 : handoff?.[0]();
1038
+ const preflight = new AbortController();
1039
+ const previousPreflight = router._preflight;
1040
+ router._preflight = preflight;
1041
+ if (!rematerialize && !hydrationController) handoff?.[1]();
1042
+ previousPreflight?.abort();
1043
+ if (preflight.signal.aborted) {
1044
+ await awaitCurrent(router, previousOwner);
1045
+ return;
1046
+ }
1047
+ const changeInfo = require_router.getLocationChangeInfo(location, resolvedLocation);
1048
+ router.emit({
1049
+ type: "onBeforeNavigate",
1050
+ ...changeInfo
1051
+ });
1052
+ if (!preflight.signal.aborted) router.emit({
1053
+ type: "onBeforeLoad",
1054
+ ...changeInfo
1055
+ });
1056
+ if (preflight.signal.aborted) {
1057
+ await awaitCurrent(router, previousOwner);
1058
+ return;
1059
+ }
1060
+ const sameHref = previousLocation.href === location.href;
1061
+ let matches;
1062
+ let controller = preflight;
1063
+ try {
1064
+ matches = process.env.NODE_ENV !== "production" && rematerialize ? router.matchRoutes(location, {
1065
+ _controller: preflight,
1066
+ _rematerialize: true
1067
+ }) : router.matchRoutes(location, { _controller: preflight });
1068
+ acquireMatchResources(matches);
1069
+ } catch (cause) {
1070
+ preflight.abort();
1071
+ if (!require_redirect.isRedirect(cause)) {
1072
+ if (process.env.NODE_ENV !== "production" && rematerialize) router._refreshNextLoad = void 0;
1073
+ await awaitCurrent(router);
1074
+ router._commitPromise?.resolve();
1075
+ router._commitPromise = void 0;
1076
+ return;
1077
+ }
1078
+ await router.navigate({
1079
+ ...cause.options,
1080
+ replace: true,
1081
+ ignoreBlocker: true
1082
+ });
1083
+ await awaitCurrent(router, previousOwner);
1084
+ return;
1085
+ }
1086
+ const resolvedPrefix = hydrationController ? handoff[1](matches) : void 0;
1087
+ if (resolvedPrefix) controller = hydrationController;
1088
+ else hydrationController?.abort();
1089
+ if (preflight.signal.aborted) {
1090
+ transferMatchResources(router, matches);
1091
+ await awaitCurrent(router, previousOwner);
1092
+ return;
1093
+ }
1094
+ router._preflight = void 0;
1095
+ const tx = [
1096
+ controller,
1097
+ redirects,
1098
+ location,
1099
+ matches,
1100
+ Date.now(),
1101
+ Promise.resolve().then(() => runClientTransaction(router, tx, sameHref, () => offerPending(router, tx), opts?.sync, resolvedPrefix)).catch(() => {
1102
+ if (router._tx === tx) restoreCommitted(router, tx);
1103
+ })
1104
+ ];
1105
+ if (process.env.NODE_ENV !== "production" && rematerialize) {
1106
+ tx[6] = [refreshPresentation, handoff];
1107
+ router._refreshNextLoad = void 0;
1108
+ }
1109
+ router._tx = tx;
1110
+ if (previousOwner) {
1111
+ for (const match of router.stores.matches.get()) {
1112
+ if (router._tx !== tx) break;
1113
+ if (match.isFetching) setFetching(router, match, false);
1114
+ }
1115
+ previousOwner[0].abort();
1116
+ transferPredecessorResources(router, previousOwner[3], tx[3]);
1117
+ }
1118
+ if (router._tx !== tx) {
1119
+ transferMatchResources(router, tx[3]);
1120
+ tx[3] = [];
1121
+ await awaitCurrent(router, tx);
1122
+ return;
1123
+ }
1124
+ router.batch(() => {
1125
+ router.stores.status.set("pending");
1126
+ router.stores.location.set(location);
1127
+ });
1128
+ offerPending(router, tx);
1129
+ try {
1130
+ await tx[5];
1131
+ } finally {
1132
+ await awaitCurrent(router, tx);
1133
+ }
1134
+ }
1135
+ async function refreshClientRoute(router) {
1136
+ router._tx?.[6]?.[2]?.();
1137
+ const pending = router._tx;
1138
+ if (pending && !pending[6] && router.stores.status.get() === "pending") {
1139
+ await pending[5];
1140
+ if (router._tx !== pending) await awaitCurrent(router, pending);
1141
+ }
1142
+ router._flights?.clear();
1143
+ router.clearCache();
1144
+ router._refreshNextLoad = true;
1145
+ await loadClientRoute(router, { sync: true });
1146
+ }
1147
+ async function preloadClientRoute(router, opts, redirects = 0) {
1148
+ if (redirects > 20) return;
1149
+ if (process.env.NODE_ENV !== "production" && (router._refreshNextLoad || router._tx?.[6])) return;
1150
+ const location = opts._builtLocation ?? router.buildLocation(opts);
1151
+ const base = router._committed;
1152
+ const controller = new AbortController();
1153
+ let matches;
1154
+ try {
1155
+ matches = router.matchRoutes(location, { _controller: controller });
1156
+ acquireMatchResources(matches);
1157
+ } catch (cause) {
1158
+ controller.abort();
1159
+ if (!require_not_found.isNotFound(cause)) console.error(cause);
1160
+ return;
1161
+ }
1162
+ (router._preloads ??= /* @__PURE__ */ new Map()).set(controller, matches);
1163
+ let active;
1164
+ try {
1165
+ let result;
1166
+ try {
1167
+ result = await executeClientLane(router, location, matches, [
1168
+ controller,
1169
+ redirects,
1170
+ () => true,
1171
+ base,
1172
+ true
1173
+ ]);
1174
+ } finally {
1175
+ active = router._preloads.delete(controller);
1176
+ transferMatchResources(router, matches);
1177
+ controller.abort();
1178
+ }
1179
+ if (!isControl(result)) return result[1];
1180
+ if (active && result[0] === REDIRECTED && !result[1].options.reloadDocument) return preloadClientRoute(router, {
1181
+ ...result[1].options,
1182
+ _fromLocation: location
1183
+ }, redirects + 1);
1184
+ } catch (cause) {
1185
+ if (!require_not_found.isNotFound(cause)) console.error(cause);
1186
+ }
1187
+ }
1188
+ async function hydrate(router) {
1189
+ if (process.env.NODE_ENV !== "production" && !window.$_TSR) throw new Error("Invariant failed: Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!");
1190
+ const tsr = window.$_TSR;
1191
+ const adapters = router.options.serializationAdapters;
1192
+ if (adapters?.length) {
1193
+ tsr.t = new Map(adapters.map((adapter) => [adapter.key, adapter.fromSerializable]));
1194
+ tsr.buffer.forEach((script) => script());
1195
+ }
1196
+ tsr.initialized = true;
1197
+ const dehydratedRouter = tsr.router;
1198
+ if (process.env.NODE_ENV !== "production" && !dehydratedRouter) throw new Error("Invariant failed: Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!");
1199
+ router.ssr = { manifest: dehydratedRouter.manifest };
1200
+ router.options.ssr = { nonce: document.querySelector("meta[property=\"csp-nonce\"]")?.content };
1201
+ const dehydratedMatches = dehydratedRouter.matches;
1202
+ const controller = new AbortController();
1203
+ const previousPreflight = router._preflight;
1204
+ router._preflight = controller;
1205
+ previousPreflight?.abort();
1206
+ const isCurrent = () => router._preflight === controller;
1207
+ let location;
1208
+ let candidates;
1209
+ let handoffHistoryHref;
1210
+ let handoffHistoryState;
1211
+ try {
1212
+ await waitFor(router.options.hydrate?.(dehydratedRouter.dehydratedData), controller.signal);
1213
+ if (!isCurrent()) return;
1214
+ const historyLocation = router.history.location;
1215
+ handoffHistoryHref = historyLocation.href;
1216
+ handoffHistoryState = historyLocation.state;
1217
+ router.updateLatestLocation();
1218
+ location = router.latestLocation;
1219
+ router.stores.location.set(location);
1220
+ candidates = router.matchRoutes(location, { _controller: controller });
1221
+ } catch (cause) {
1222
+ if (isCurrent()) router._preflight = void 0;
1223
+ controller.abort(cause);
1224
+ if (cause !== controller.signal) throw cause;
1225
+ }
1226
+ if (!isCurrent()) return;
1227
+ const committed = [];
1228
+ let pendingBoundary;
1229
+ let verifiedAssetEnd = 0;
1230
+ const retryFrom = (index) => {
1231
+ verifiedAssetEnd = Math.min(verifiedAssetEnd, index + 1);
1232
+ const removed = committed.splice(index);
1233
+ for (const match of removed) if (getRoute(router, match).options.loader && (match.status === "success" || !match.invalid && "loaderData" in match)) cacheLoaderMatch(router, {
1234
+ ...match,
1235
+ status: "success",
1236
+ error: void 0,
1237
+ preload: true
1238
+ }, router._cache.get(match.id));
1239
+ transferMatchResources(router, removed);
1240
+ };
1241
+ const shared = dehydratedMatches.length > candidates.length ? candidates.findIndex((match) => match._notFound) + 1 : dehydratedMatches.length;
1242
+ let isTerminal = false;
1243
+ for (let index = 0; index < shared; index++) {
1244
+ const candidate = candidates[index];
1245
+ const dehydrated = dehydratedMatches[index];
1246
+ if (typeof dehydrated.i !== "string" || require_ssr_match_id.hydrateSsrMatchId(dehydrated.i) !== candidate.id) {
1247
+ pendingBoundary ??= index;
1248
+ break;
1249
+ }
1250
+ verifiedAssetEnd = index + 1;
1251
+ const route = getRoute(router, candidate);
1252
+ if ("l" in dehydrated || dehydrated.s === "success" && dehydrated.e === void 0 && route.options.loader) candidate.loaderData = dehydrated.l;
1253
+ candidate.status = dehydrated.s;
1254
+ candidate.ssr = dehydrated.ssr;
1255
+ route.options.ssr = candidate.ssr;
1256
+ candidate.updatedAt = dehydrated.u;
1257
+ candidate.error = dehydrated.e;
1258
+ candidate._notFound ||= dehydrated.g;
1259
+ if (candidate.status === "error" || candidate.status === "notFound" || candidate._notFound) {
1260
+ isTerminal = true;
1261
+ committed.push(candidate);
1262
+ if (candidate.ssr === false || candidate.ssr === "data-only") pendingBoundary ??= index;
1263
+ break;
1264
+ }
1265
+ if (candidate.status === "pending") {
1266
+ pendingBoundary ??= index;
1267
+ break;
1268
+ }
1269
+ committed.push(candidate);
1270
+ if (candidate.ssr === "data-only") pendingBoundary ??= index;
1271
+ }
1272
+ if (!isTerminal && committed.length === shared && shared < candidates.length) pendingBoundary = shared;
1273
+ const chunks = committed.map(async (match) => {
1274
+ try {
1275
+ const route = getRoute(router, match);
1276
+ if (match._notFound) await Promise.all([loadRouteChunk(route), loadRouteChunk(route, "notFoundComponent")]);
1277
+ else await loadRouteChunk(route, match.status === "error" ? "errorComponent" : match.status === "notFound" ? "notFoundComponent" : void 0);
1278
+ return true;
1279
+ } catch {
1280
+ return false;
1281
+ }
1282
+ });
1283
+ let chunkFailure = 0;
1284
+ try {
1285
+ while (chunkFailure < chunks.length && await waitFor(chunks[chunkFailure], controller.signal)) chunkFailure++;
1286
+ } catch {
1287
+ return;
1288
+ }
1289
+ if (!isCurrent()) return;
1290
+ if (chunkFailure < committed.length) retryFrom(chunkFailure);
1291
+ const contextEnd = Math.max(pendingBoundary === committed.length ? committed.length + 1 : committed.length, chunkFailure < chunks.length ? chunkFailure : verifiedAssetEnd);
1292
+ for (let index = 0; index < contextEnd; index++) {
1293
+ const match = candidates[index];
1294
+ const route = getRoute(router, match);
1295
+ const parentContext = candidates[index - 1]?.context ?? router.options.context ?? {};
1296
+ let routeContext;
1297
+ if (route.options.context) {
1298
+ try {
1299
+ routeContext = match._ctx = route.options.context({
1300
+ deps: match.loaderDeps,
1301
+ params: match.params,
1302
+ context: parentContext,
1303
+ location,
1304
+ navigate: navigateFrom(router, location),
1305
+ buildLocation: router.buildLocation,
1306
+ cause: match.cause,
1307
+ abortController: controller,
1308
+ preload: false,
1309
+ matches: candidates,
1310
+ routeId: route.id
1311
+ }) || {};
1312
+ } catch {
1313
+ if (!isCurrent()) return;
1314
+ if (match.status !== "error" && match.status !== "notFound" && !match._notFound) {
1315
+ retryFrom(index);
1316
+ break;
1317
+ }
1318
+ }
1319
+ if (!isCurrent()) return;
1320
+ }
1321
+ match.context = {
1322
+ ...parentContext,
1323
+ ...routeContext,
1324
+ ...committed[index] && dehydratedMatches[index].b
1325
+ };
1326
+ }
1327
+ await projectLane(router, [location, candidates], controller.signal, 0, verifiedAssetEnd);
1328
+ if (!isCurrent()) return;
1329
+ const needsClientLoad = pendingBoundary !== void 0 || committed.length < shared;
1330
+ const committedMatches = isTerminal && committed.length === shared ? candidates : committed;
1331
+ let presented = needsClientLoad ? candidates : committedMatches;
1332
+ let dataOnlyAssetEnd;
1333
+ if (needsClientLoad && pendingBoundary !== void 0) {
1334
+ const boundary = presented[pendingBoundary];
1335
+ dataOnlyAssetEnd = boundary.ssr === "data-only" && verifiedAssetEnd > pendingBoundary + 1 ? verifiedAssetEnd : void 0;
1336
+ presented = presented.slice();
1337
+ presented[pendingBoundary] = {
1338
+ ...boundary,
1339
+ status: "pending",
1340
+ ssr: boundary.ssr === "data-only" ? "data-only" : false,
1341
+ _assetEnd: dataOnlyAssetEnd
1342
+ };
1343
+ }
1344
+ const claim = () => {
1345
+ const historyLocation = router.history.location;
1346
+ return needsClientLoad && !router._tx && historyLocation.href === handoffHistoryHref && historyLocation.state === handoffHistoryState && router._committed === committedMatches && committedMatches.length && !controller.signal.aborted ? controller : void 0;
1347
+ };
1348
+ const handoff = [claim, (matches) => {
1349
+ if (router._handoff !== handoff) return;
1350
+ router._handoff = void 0;
1351
+ const prefix = committedMatches.length;
1352
+ if (!matches || !claim() || committedMatches.some((match, index) => match.id !== matches[index]?.id)) {
1353
+ controller.abort();
1354
+ return;
1355
+ }
1356
+ let handoffAssetEnd = dataOnlyAssetEnd;
1357
+ if (handoffAssetEnd !== void 0) {
1358
+ for (let index = prefix; index < handoffAssetEnd; index++) if (candidates[index]?.id !== matches[index]?.id) {
1359
+ handoffAssetEnd = index > pendingBoundary + 1 ? index : void 0;
1360
+ break;
1361
+ }
1362
+ }
1363
+ const clones = committedMatches.map((match) => ({ ...match }));
1364
+ if (handoffAssetEnd !== void 0) clones[pendingBoundary]._assetEnd = handoffAssetEnd;
1365
+ transferMatchResources(router, matches.splice(0, prefix, ...clones));
1366
+ for (let index = prefix; index < matches.length; index++) {
1367
+ const match = matches[index];
1368
+ const hydrated = candidates[index];
1369
+ if (hydrated?.id === match.id && hydrated._ctx) match._ctx = hydrated._ctx;
1370
+ match.abortController = controller;
1371
+ }
1372
+ return prefix;
1373
+ }];
1374
+ router._committed = committedMatches;
1375
+ router._handoff = handoff;
1376
+ router._preflight = void 0;
1377
+ router.batch(() => {
1378
+ router.stores.setMatches(presented);
1379
+ router.stores.status.set("idle");
1380
+ if (!needsClientLoad) router.stores.resolvedLocation.set(router.stores.location.get());
1381
+ });
1382
+ }
1383
+ //#endregion
1384
+ exports._getAssetMatches = _getAssetMatches;
1385
+ exports._getRenderedMatches = _getRenderedMatches;
1386
+ exports.hydrate = hydrate;
1387
+ exports.loadClientRoute = loadClientRoute;
1388
+ exports.loadRouteChunk = loadRouteChunk;
1389
+ exports.preloadClientRoute = preloadClientRoute;
1390
+ exports.refreshClientRoute = refreshClientRoute;
1391
+ exports.replaceRouteChunk = replaceRouteChunk;
1392
+
1393
+ //# sourceMappingURL=load-client.cjs.map