@askrjs/askr 0.0.84 → 0.0.86

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 (71) hide show
  1. package/dist/{access-ePqdQqkV.js → access-Dpfoi4cA.js} +7 -1
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.js +3 -3
  4. package/dist/{activity-pySy9t7Y.d.ts → activity-B1I5HJQI.d.ts} +1 -1
  5. package/dist/{activity-CZiPgZy0.js → activity-BvgvaMZA.js} +53 -16
  6. package/dist/benchmark.js +8 -8
  7. package/dist/boot/index.d.ts +3 -3
  8. package/dist/boot/index.js +1 -1
  9. package/dist/{boot-D28lesMw.js → boot-CViTpUiB.js} +22 -20
  10. package/dist/{cleanup-ARiXproi.js → cleanup-c837KVij.js} +16 -6
  11. package/dist/{component-cleanup-Bug5tSiG.js → component-cleanup-BUfUleGZ.js} +2 -2
  12. package/dist/{component-internal-Bw4Mf9fd.js → component-internal-DcrLymUJ.js} +5 -5
  13. package/dist/components/index.d.ts +1 -1
  14. package/dist/components/index.js +1 -1
  15. package/dist/control/index.d.ts +1 -1
  16. package/dist/control/index.js +1 -1
  17. package/dist/{control-Y8F73Uln.d.ts → control-DhUZU4_V.d.ts} +2 -1
  18. package/dist/{control-nrS65oG3.js → control-oLADku43.js} +4 -4
  19. package/dist/{csp-nonce-ZTlD_EnK.js → csp-nonce-Bc52OIVc.js} +19 -2
  20. package/dist/data/index.js +3 -3
  21. package/dist/{data-BRS5woEh.js → data-DGrD3-qA.js} +5 -5
  22. package/dist/{data-runtime-D68YOo9L.js → data-runtime-Ck3tJDDQ.js} +1 -1
  23. package/dist/default-portal-runtime-DvMvWJVp.js +20 -0
  24. package/dist/{authoring-DQPG0VAm.js → deferred-nleQtdfY.js} +85 -5
  25. package/dist/{effect-B487asyz.js → effect-lnxQIpJG.js} +2 -2
  26. package/dist/{fastlane-BOr4lSLl.js → fastlane-CrfB3QG0.js} +2 -2
  27. package/dist/{for-internal-DjpV8ioj.js → for-internal-B_mnQhan.js} +18 -6
  28. package/dist/foundations/index.d.ts +1 -1
  29. package/dist/foundations/index.js +1 -2
  30. package/dist/foundations/state/index.d.ts +1 -1
  31. package/dist/foundations/state/index.js +1 -1
  32. package/dist/foundations/structures/index.d.ts +2 -2
  33. package/dist/foundations/structures/index.js +2 -3
  34. package/dist/fx/index.js +1 -1
  35. package/dist/{index-BApH3laU.d.ts → index-DflhL1h8.d.ts} +20 -16
  36. package/dist/{index-_UN08Pg1.d.ts → index-pIgGaXvS.d.ts} +19 -3
  37. package/dist/{index-DUXXZ31H.d.ts → index-r-nt13FE.d.ts} +1 -1
  38. package/dist/index.d.ts +3 -3
  39. package/dist/index.js +12 -12
  40. package/dist/{lifecycle-batch-CFI4NKpJ.js → lifecycle-batch-Dfpid9-A.js} +39 -20
  41. package/dist/{lifecycle-operations-KYOIcM5R.js → lifecycle-operations-BrYrBsXY.js} +1 -1
  42. package/dist/manifest-D1P9uTlz.js +53 -0
  43. package/dist/{navigate-Dr3cjOSz.js → navigate-BwAPbpCb.js} +17 -16
  44. package/dist/{navigate-CgVIrrSs.d.ts → navigate-NyIjQUwI.d.ts} +1 -1
  45. package/dist/{query-registry-BL6rjGsO.js → query-registry-CPW_6nwF.js} +1 -1
  46. package/dist/{readable-_GQGe_St.js → readable-B5NtV7V0.js} +1 -1
  47. package/dist/render-context-D0Hoj9dW.js +161 -0
  48. package/dist/{renderer-B9j5IV1q.js → renderer-D9DL9R2D.js} +58 -17
  49. package/dist/{deferred-oqtAJ4iH.js → resolution-YHwi4Bav.js} +234 -222
  50. package/dist/resource-operation-ys6eDoRJ.js +304 -0
  51. package/dist/resources/index.d.ts +2 -2
  52. package/dist/resources/index.js +5 -5
  53. package/dist/{route-matching-IfQZmqkN.js → route-matching-DqULzZtC.js} +46 -277
  54. package/dist/router/index.d.ts +12 -10
  55. package/dist/router/index.js +10 -7
  56. package/dist/{selector-DJ1-N1K-.js → selector-Ck_Pp9av.js} +2 -2
  57. package/dist/ssg/index.d.ts +9 -3
  58. package/dist/ssg/index.js +31 -15
  59. package/dist/ssr/index.d.ts +7 -3
  60. package/dist/ssr/index.js +2 -2
  61. package/dist/{ssr-CtC4lChT.js → ssr-B98593qJ.js} +53 -27
  62. package/dist/ssr-DSHd_Q9K.js +25 -0
  63. package/dist/{state-BzIMC6-i.js → state-DCjONcHK.js} +4 -3
  64. package/dist/{portal-pHBoqwYd.js → structures-DsOm-clq.js} +236 -7
  65. package/dist/testing/index.d.ts +2 -2
  66. package/dist/testing/index.js +4 -4
  67. package/dist/{verify-hydration-BguOSco9.js → verify-hydration-ww1dgwea.js} +5 -4
  68. package/package.json +2 -2
  69. package/dist/render-context-D-DFk2WN.js +0 -73
  70. package/dist/ssr-CbQO5xd3.js +0 -12
  71. package/dist/structures-D3vO-WMN.js +0 -221
@@ -1,23 +1,10 @@
1
1
  import { n as Fragment, t as ELEMENT_TYPE } from "./jsx-C3IECePB.js";
2
- import { g as readScope, u as defineScope } from "./component-internal-Bw4Mf9fd.js";
3
- import { d as getCurrentAppRenderRuntime } from "./component-scope-DzJEbYGE.js";
4
- import { p as isPromiseLike } from "./lifecycle-batch-CFI4NKpJ.js";
5
- import { n as getActiveRenderContext, r as getCurrentRenderData } from "./render-context-D-DFk2WN.js";
6
- import { A as insertRecordSorted, D as getRouteRecords, E as getRouteList, F as snapshotRouteState, N as restoreRouteState, P as setDefaultRouteAuthOptions, T as getDefaultRouteAuthOptions, f as addRouteToStores, h as getActiveRouteAuthOptions, i as getMatchingRouteRecord, m as clearRouteState, o as buildRouteContext, s as buildRouteContextBase, z as resource } from "./route-matching-IfQZmqkN.js";
7
- import { i as ROUTE_ROOT_COMPONENT } from "./csp-nonce-ZTlD_EnK.js";
8
- import { c as withTelemetry, t as createQueryPrefetchContext } from "./query-registry-BL6rjGsO.js";
9
- //#region src/runtime/execution-model.ts
10
- const EXECUTION_MODEL_KEY = Symbol.for("__ASKR_EXECUTION_MODEL__");
11
- function getExecutionModel() {
12
- return globalThis[EXECUTION_MODEL_KEY];
13
- }
14
- function assertExecutionModel(model) {
15
- const g = globalThis;
16
- const cur = g[EXECUTION_MODEL_KEY];
17
- if (cur && cur !== model) throw new Error(`[Askr] mixing execution models is not allowed (current: ${cur}, attempted: ${model}). Choose exactly one: createSPA, createSSR, or createIslands.`);
18
- if (!cur) g[EXECUTION_MODEL_KEY] = model;
19
- }
20
- //#endregion
2
+ import { g as readScope, u as defineScope } from "./component-internal-DcrLymUJ.js";
3
+ import { p as isPromiseLike } from "./lifecycle-batch-Dfpid9-A.js";
4
+ import { b as withPageFramework, n as getActiveRenderContext, y as replacePageRoute } from "./render-context-D0Hoj9dW.js";
5
+ import { i as ROUTE_ROOT_COMPONENT } from "./csp-nonce-Bc52OIVc.js";
6
+ import { c as withTelemetry, t as createQueryPrefetchContext } from "./query-registry-CPW_6nwF.js";
7
+ import { c as removeRouteBasePath, i as getMatchingRouteRecord, l as buildRouteContext, o as addRouteBasePath, s as normalizeRouteBasePath, u as buildRouteContextBase, v as getActiveRouteAuthOptions } from "./route-matching-DqULzZtC.js";
21
8
  //#region src/router/lazy.ts
22
9
  const pendingLazy = /* @__PURE__ */ new Set();
23
10
  const lazyStates = /* @__PURE__ */ new WeakMap();
@@ -140,41 +127,210 @@ function setCurrentAuth(context) {
140
127
  if (render) render.authContext = context;
141
128
  }
142
129
  //#endregion
143
- //#region src/common/page-render-envelope.ts
144
- const PAGE_RENDER_ENVELOPE_VERSION = 1;
145
- function ownedRecord(value) {
146
- return Object.freeze({ ...value });
147
- }
148
- function createPageRenderEnvelope(input = {}) {
149
- return Object.freeze({
150
- version: PAGE_RENDER_ENVELOPE_VERSION,
151
- resources: ownedRecord(input.resources),
152
- route: input.route,
153
- framework: ownedRecord(input.framework)
130
+ //#region src/common/deferred-value.ts
131
+ const DEFERRED_VALUE = Symbol.for("@askrjs/askr/deferred-value");
132
+ const DEFERRED_BOUNDARY = Symbol.for("@askrjs/askr/deferred-boundary");
133
+ function defer(promise) {
134
+ let state = "pending";
135
+ let value;
136
+ let error;
137
+ const normalized = Promise.resolve(promise);
138
+ normalized.then((resolved) => {
139
+ state = "fulfilled";
140
+ value = resolved;
141
+ }, (reason) => {
142
+ state = "rejected";
143
+ error = reason;
154
144
  });
145
+ return Object.freeze(Object.defineProperties({}, {
146
+ state: {
147
+ enumerable: true,
148
+ get: () => state
149
+ },
150
+ value: {
151
+ enumerable: true,
152
+ get: () => value
153
+ },
154
+ error: {
155
+ enumerable: true,
156
+ get: () => error
157
+ },
158
+ promise: { value: normalized },
159
+ [DEFERRED_VALUE]: { value: true }
160
+ }));
155
161
  }
156
- function isPageRenderEnvelope(value) {
157
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
158
- const candidate = value;
159
- return candidate.version === PAGE_RENDER_ENVELOPE_VERSION && Boolean(candidate.resources && typeof candidate.resources === "object" && !Array.isArray(candidate.resources)) && Boolean(candidate.framework && typeof candidate.framework === "object" && !Array.isArray(candidate.framework));
162
+ function isDeferred(value) {
163
+ if (!value || typeof value !== "object") return false;
164
+ const marker = Object.getOwnPropertyDescriptor(value, DEFERRED_VALUE);
165
+ return Boolean(marker && "value" in marker && marker.value === true);
160
166
  }
161
- function pageRenderEnvelope(value, fallback = {}) {
162
- if (isPageRenderEnvelope(value)) return value;
163
- return createPageRenderEnvelope({
164
- ...fallback,
165
- route: value ?? fallback.route
166
- });
167
+ /** @internal Reconstruct settled server data without importing deferred rendering. */
168
+ function reviveDeferredValue(state, value, error) {
169
+ const promise = state === "fulfilled" ? Promise.resolve(value) : Promise.reject(error);
170
+ if (state === "rejected") promise.catch(() => void 0);
171
+ return Object.freeze(Object.defineProperties({}, {
172
+ state: {
173
+ enumerable: true,
174
+ value: state
175
+ },
176
+ value: {
177
+ enumerable: true,
178
+ value
179
+ },
180
+ error: {
181
+ enumerable: true,
182
+ value: error
183
+ },
184
+ promise: { value: promise },
185
+ [DEFERRED_VALUE]: { value: true }
186
+ }));
167
187
  }
168
- function replacePageRoute(value, route) {
169
- const current = pageRenderEnvelope(value);
170
- return createPageRenderEnvelope({
171
- resources: current.resources,
172
- route,
173
- framework: current.framework
174
- });
188
+ //#endregion
189
+ //#region src/router/route-hydration.ts
190
+ function isDeferredHydrationValue(value) {
191
+ return isDeferred(value);
192
+ }
193
+ const omissionGuards = /* @__PURE__ */ new WeakMap();
194
+ function propertyPath(parent, key) {
195
+ if (/^(?:0|[1-9]\d*)$/.test(key)) return `${parent}[${key}]`;
196
+ if (/^[A-Za-z_$][\w$]*$/.test(key)) return `${parent}.${key}`;
197
+ return `${parent}[${JSON.stringify(key)}]`;
198
+ }
199
+ function invalid(route, path, reason) {
200
+ throw new TypeError(`[Askr] Route hydration data for "${route}" at "${path}" is not JSON transport-safe: ${reason}. Return JSON-compatible data or use route(..., { dehydrate(data) { ... } }) to omit server-only values.`);
201
+ }
202
+ function objectLabel(value) {
203
+ if (value instanceof Date) return "Date";
204
+ if (value instanceof Map) return "Map";
205
+ if (value instanceof Set) return "Set";
206
+ const constructor = value.constructor;
207
+ return typeof constructor === "function" && constructor.name ? constructor.name : "class instance";
208
+ }
209
+ /** Validate the exact value that will enter the route hydration envelope. */
210
+ function validateRouteHydrationData(value, route, path = "$", ancestors = /* @__PURE__ */ new Set()) {
211
+ if (value === null || typeof value === "string" || typeof value === "boolean") return;
212
+ if (typeof value === "number") {
213
+ if (!Number.isFinite(value)) invalid(route, path, "non-finite numbers are not supported");
214
+ return;
215
+ }
216
+ if (typeof value === "undefined") invalid(route, path, "undefined is not supported");
217
+ if (typeof value === "bigint") invalid(route, path, "bigint is not supported");
218
+ if (typeof value === "symbol") invalid(route, path, "symbols are not supported");
219
+ if (typeof value === "function") invalid(route, path, "functions are not supported");
220
+ const object = value;
221
+ if (isDeferredHydrationValue(object)) {
222
+ if (object.state === "fulfilled") validateRouteHydrationData(object.value, route, `${path}.value`, ancestors);
223
+ return;
224
+ }
225
+ if (ancestors.has(object)) invalid(route, path, "cyclic references are not supported");
226
+ ancestors.add(object);
227
+ try {
228
+ if (Array.isArray(object)) {
229
+ for (let index = 0; index < object.length; index += 1) if (!Object.prototype.hasOwnProperty.call(object, index)) invalid(route, `${path}[${index}]`, "sparse arrays are not supported");
230
+ for (const key of Reflect.ownKeys(object)) {
231
+ if (key === "length") continue;
232
+ if (typeof key === "symbol") invalid(route, path, "symbol-keyed properties are not supported");
233
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
234
+ if (!descriptor.enumerable) invalid(route, propertyPath(path, key), "non-enumerable properties are not supported");
235
+ if (!("value" in descriptor)) invalid(route, propertyPath(path, key), "accessors are not supported");
236
+ if (!/^(?:0|[1-9]\d*)$/.test(key) || Number(key) >= object.length) invalid(route, propertyPath(path, key), "named array properties are not supported");
237
+ validateRouteHydrationData(descriptor.value, route, propertyPath(path, key), ancestors);
238
+ }
239
+ return;
240
+ }
241
+ const prototype = Object.getPrototypeOf(object);
242
+ if (prototype !== Object.prototype && prototype !== null) invalid(route, path, `${objectLabel(object)} instances are not supported; use a plain object`);
243
+ for (const key of Reflect.ownKeys(object)) {
244
+ if (typeof key === "symbol") invalid(route, path, "symbol-keyed properties are not supported");
245
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
246
+ const childPath = propertyPath(path, key);
247
+ if (!descriptor.enumerable) invalid(route, childPath, "non-enumerable properties are not supported");
248
+ if (!("value" in descriptor)) invalid(route, childPath, "accessors are not supported");
249
+ validateRouteHydrationData(descriptor.value, route, childPath, ancestors);
250
+ }
251
+ } finally {
252
+ ancestors.delete(object);
253
+ }
175
254
  }
176
- function isEmptyPageRenderEnvelope(value) {
177
- return value.route === void 0 && Object.keys(value.resources).length === 0 && Object.keys(value.framework).length === 0;
255
+ function omissionMap(complete, selected, ancestors = /* @__PURE__ */ new Set()) {
256
+ if (!complete || typeof complete !== "object" || isDeferredHydrationValue(complete)) return void 0;
257
+ if (ancestors.has(complete)) return void 0;
258
+ ancestors.add(complete);
259
+ const selectedObject = selected && typeof selected === "object" ? selected : void 0;
260
+ const output = Object.create(null);
261
+ try {
262
+ for (const key of Object.keys(complete)) {
263
+ if (!selectedObject || !Object.prototype.hasOwnProperty.call(selectedObject, key)) {
264
+ output[key] = 1;
265
+ continue;
266
+ }
267
+ const completeDescriptor = Object.getOwnPropertyDescriptor(complete, key);
268
+ const selectedDescriptor = Object.getOwnPropertyDescriptor(selectedObject, key);
269
+ if (!completeDescriptor || !selectedDescriptor) continue;
270
+ if (!("value" in completeDescriptor) || !("value" in selectedDescriptor)) continue;
271
+ const nested = omissionMap(completeDescriptor.value, selectedDescriptor.value, ancestors);
272
+ if (nested) output[key] = nested;
273
+ }
274
+ } finally {
275
+ ancestors.delete(complete);
276
+ }
277
+ return Object.keys(output).length > 0 ? Object.freeze(output) : void 0;
278
+ }
279
+ function prepareRouteHydrationData(complete, dehydrate, context, route = context.href || context.pathname) {
280
+ const selected = dehydrate ? dehydrate(complete, context) : complete;
281
+ if (isPromiseLike(selected)) throw new TypeError(`[Askr] Route dehydrate() for "${route}" returned a Promise. dehydrate(data, context) must be synchronous.`);
282
+ validateRouteHydrationData(selected, route);
283
+ return {
284
+ data: selected,
285
+ metadata: Object.freeze({
286
+ r: route,
287
+ ...dehydrate ? { o: omissionMap(complete, selected) } : {}
288
+ })
289
+ };
290
+ }
291
+ function readMetadata(framework) {
292
+ const value = framework["rh"];
293
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
294
+ const metadata = value;
295
+ return typeof metadata.r === "string" ? metadata : void 0;
296
+ }
297
+ function omittedRead(route, path) {
298
+ throw new Error(`[Askr] routeData() read "${path}" on the initial hydration of "${route}", but that branch was intentionally omitted by dehydrate(). Keep initial hydrated rendering within the selected data, or wait for a client navigation that reruns the loader with the complete result.`);
299
+ }
300
+ function guardOmissions(value, omissions, route, path = "$") {
301
+ if (!omissions || !value || typeof value !== "object" || isDeferredHydrationValue(value)) return value;
302
+ let guards = omissionGuards.get(value);
303
+ if (!guards) {
304
+ guards = /* @__PURE__ */ new WeakMap();
305
+ omissionGuards.set(value, guards);
306
+ }
307
+ const cached = guards.get(omissions);
308
+ if (cached) return cached;
309
+ const guarded = new Proxy(value, { get(target, property, receiver) {
310
+ if (typeof property === "string") {
311
+ const omitted = omissions[property];
312
+ if (omitted && !Object.prototype.hasOwnProperty.call(target, property)) omittedRead(route, propertyPath(path, property));
313
+ const child = Reflect.get(target, property, receiver);
314
+ return omitted === 1 ? child : guardOmissions(child, omitted, route, propertyPath(path, property));
315
+ }
316
+ return Reflect.get(target, property, receiver);
317
+ } });
318
+ guards.set(omissions, guarded);
319
+ return guarded;
320
+ }
321
+ function guardHydratedRouteData(value, framework) {
322
+ const metadata = readMetadata(framework);
323
+ return metadata ? guardOmissions(value, metadata.o, metadata.r) : value;
324
+ }
325
+ function getRouteHydrationMetadata(framework) {
326
+ return readMetadata(framework);
327
+ }
328
+ /** @internal Remove initial-only omission guards after a client loader reruns. */
329
+ function withoutRouteHydrationMetadata(framework) {
330
+ if (!framework || !("rh" in framework)) return framework;
331
+ const next = { ...framework };
332
+ delete next["rh"];
333
+ return next;
178
334
  }
179
335
  //#endregion
180
336
  //#region src/router/resolution.ts
@@ -208,14 +364,21 @@ function createRouteRenderResult(record, params, context, handler) {
208
364
  function getDefaultRouteMode() {
209
365
  return typeof window !== "undefined" ? "spa" : "ssr";
210
366
  }
367
+ function withoutInitialRouteHydrationMetadata(envelope) {
368
+ return withPageFramework(envelope, withoutRouteHydrationMetadata(envelope.framework) ?? {});
369
+ }
211
370
  /** @internal Bind resolved loader output to one route subtree and its hydration envelope. */
212
- function bindResolvedRouteData(handler, data) {
371
+ function bindResolvedRouteData(handler, data, hydration) {
213
372
  return (params, context) => {
214
373
  const renderContext = getActiveRenderContext();
215
374
  if (renderContext) {
216
375
  const envelope = replacePageRoute(renderContext.renderData, data);
217
- renderContext.renderData = envelope;
218
- renderContext.hydrationData = envelope;
376
+ renderContext.renderData = hydration ? envelope : withoutInitialRouteHydrationMetadata(envelope);
377
+ const hydrationEnvelope = replacePageRoute(renderContext.hydrationData, hydration?.data ?? data);
378
+ renderContext.hydrationData = hydration ? withPageFramework(hydrationEnvelope, {
379
+ ...hydrationEnvelope.framework,
380
+ ["rh"]: hydration.metadata
381
+ }) : withoutInitialRouteHydrationMetadata(hydrationEnvelope);
219
382
  }
220
383
  return handler(params, context);
221
384
  };
@@ -254,7 +417,12 @@ function buildLoadedRenderResult(record, params, context, request, telemetry, lo
254
417
  }));
255
418
  const loaded = runPreload ? runPreload.then(load) : load();
256
419
  const finalize = (data) => {
257
- const result = createRouteRenderResult(record, params, context, bindResolvedRouteData(renderHandler, data));
420
+ const hydration = context.mode === "ssr" ? prepareRouteHydrationData(data, record.options?.dehydrate, {
421
+ ...context,
422
+ params,
423
+ request
424
+ }, context.href || context.pathname || record.path) : void 0;
425
+ const result = createRouteRenderResult(record, params, context, bindResolvedRouteData(renderHandler, data, hydration));
258
426
  routeRenderData.set(result, data);
259
427
  return result;
260
428
  };
@@ -308,24 +476,33 @@ function resolveMatchedRoute(record, params, context, authOptions, request, tele
308
476
  }
309
477
  function resolveRouteRequest(target, options) {
310
478
  if (!options?.registry) throw new TypeError("resolveRouteRequest requires options.registry.");
479
+ const basePath = normalizeRouteBasePath(options.registry.manifest.basePath);
480
+ const logicalTarget = removeRouteBasePath(target, basePath);
481
+ if (logicalTarget === void 0) return null;
311
482
  return withTelemetry(options.telemetry?.routeMatch, {}, () => {
312
483
  const records = options.registry.manifest.records;
313
- const match = getMatchingRouteRecord(target, records);
484
+ const match = getMatchingRouteRecord(logicalTarget, records);
314
485
  if (!match) return null;
315
486
  const mode = options.mode ?? getDefaultRouteMode();
316
487
  const signal = options.signal ?? getActiveRenderContext()?.signal ?? new AbortController().signal;
317
488
  const authOptions = getActiveRouteAuthOptions(options.auth ?? options.registry.manifest.auth);
318
- const base = buildRouteContextBase(target, match.params, {
489
+ const base = buildRouteContextBase(logicalTarget, match.params, {
319
490
  mode,
320
491
  signal
321
492
  });
493
+ const exposeRedirect = (result) => result?.kind === "redirect" ? {
494
+ ...result,
495
+ to: addRouteBasePath(result.to, basePath)
496
+ } : result;
322
497
  const finalize = (authContext) => {
323
498
  setCurrentAuth(authContext);
324
- return resolveMatchedRoute(match.record, match.params, buildRouteContext(target, match.params, {
499
+ const result = resolveMatchedRoute(match.record, match.params, buildRouteContext(logicalTarget, match.params, {
325
500
  mode,
326
501
  signal,
327
502
  authContext
328
503
  }), authOptions, options.request, options.telemetry, options.load !== false);
504
+ if (!basePath) return result;
505
+ return isPromiseLike(result) ? Promise.resolve(result).then(exposeRedirect) : exposeRedirect(result);
329
506
  };
330
507
  if (options.authContext) return finalize(options.authContext);
331
508
  if (!authOptions?.resolve) return finalize(anonymous());
@@ -334,169 +511,4 @@ function resolveRouteRequest(target, options) {
334
511
  });
335
512
  }
336
513
  //#endregion
337
- //#region src/router/manifest.ts
338
- function createRouteManifest() {
339
- const auth = getDefaultRouteAuthOptions();
340
- return {
341
- records: [...getRouteRecords()],
342
- ...auth ? { auth } : {}
343
- };
344
- }
345
- function _applyManifest(manifest) {
346
- setDefaultRouteAuthOptions(manifest.auth);
347
- for (const record of manifest.records) {
348
- insertRecordSorted(record);
349
- addRouteToStores({
350
- path: record.path,
351
- handler: record.handler,
352
- namespace: record.options.namespace,
353
- ..."fallbackPrefix" in record && typeof record.fallbackPrefix === "string" ? { fallbackPrefix: record.fallbackPrefix } : {}
354
- });
355
- }
356
- }
357
- function createRouteRegistry(definition, options = {}) {
358
- const previous = snapshotRouteState();
359
- clearRouteState();
360
- try {
361
- setDefaultRouteAuthOptions(options.auth);
362
- definition();
363
- const manifest = createRouteManifest();
364
- return Object.freeze({
365
- manifest,
366
- routes: getRouteList()
367
- });
368
- } finally {
369
- restoreRouteState(previous);
370
- }
371
- }
372
- //#endregion
373
- //#region src/router/deferred.tsx
374
- const DEFERRED_VALUE = Symbol.for("@askrjs/askr/deferred-value");
375
- const DEFERRED_BOUNDARY = Symbol.for("@askrjs/askr/deferred-boundary");
376
- function defer(promise) {
377
- let state = "pending";
378
- let value;
379
- let error;
380
- const normalized = Promise.resolve(promise);
381
- normalized.then((resolved) => {
382
- state = "fulfilled";
383
- value = resolved;
384
- }, (reason) => {
385
- state = "rejected";
386
- error = reason;
387
- });
388
- return Object.freeze(Object.defineProperties({}, {
389
- state: {
390
- enumerable: true,
391
- get: () => state
392
- },
393
- value: {
394
- enumerable: true,
395
- get: () => value
396
- },
397
- error: {
398
- enumerable: true,
399
- get: () => error
400
- },
401
- promise: { value: normalized },
402
- [DEFERRED_VALUE]: { value: true }
403
- }));
404
- }
405
- function isDeferred(value) {
406
- return Boolean(value && typeof value === "object" && value[DEFERRED_VALUE] === true);
407
- }
408
- /** @internal Reconstruct settled server data without starting loader work. */
409
- function reviveDeferredValue(state, value, error) {
410
- const promise = state === "fulfilled" ? Promise.resolve(value) : Promise.reject(error);
411
- if (state === "rejected") promise.catch(() => void 0);
412
- return Object.freeze(Object.defineProperties({}, {
413
- state: {
414
- enumerable: true,
415
- value: state
416
- },
417
- value: {
418
- enumerable: true,
419
- value
420
- },
421
- error: {
422
- enumerable: true,
423
- value: error
424
- },
425
- promise: { value: promise },
426
- [DEFERRED_VALUE]: { value: true }
427
- }));
428
- }
429
- function abortError() {
430
- const error = /* @__PURE__ */ new Error("Deferred route data was aborted.");
431
- error.name = "AbortError";
432
- return error;
433
- }
434
- function awaitWithSignal(promise, signal) {
435
- if (!signal) return promise;
436
- if (signal.aborted) return Promise.reject(abortError());
437
- return new Promise((resolve, reject) => {
438
- const abort = () => reject(abortError());
439
- signal.addEventListener("abort", abort, { once: true });
440
- promise.then((value) => {
441
- signal.removeEventListener("abort", abort);
442
- resolve(value);
443
- }, (error) => {
444
- signal.removeEventListener("abort", abort);
445
- reject(error);
446
- });
447
- });
448
- }
449
- async function resolveDeferredValues(input, signal) {
450
- const seen = /* @__PURE__ */ new Set();
451
- const visit = async (value) => {
452
- if (!value || typeof value !== "object") return;
453
- if (isDeferred(value)) {
454
- const resolved = await awaitWithSignal(value.promise, signal);
455
- await visit(resolved);
456
- return;
457
- }
458
- if (seen.has(value)) return;
459
- seen.add(value);
460
- const children = Array.isArray(value) ? value : Object.values(value);
461
- await Promise.all(children.map(visit));
462
- };
463
- await visit(input);
464
- return input;
465
- }
466
- function routeData() {
467
- const envelope = getCurrentRenderData();
468
- if (envelope) return envelope.route;
469
- const runtime = getCurrentAppRenderRuntime();
470
- if (!runtime?.hasRoute) throw new Error("routeData() can only be read while rendering a route with loader data.");
471
- return runtime.route;
472
- }
473
- function rejectedChild(props, error) {
474
- return typeof props.rejected === "function" ? props.rejected(error) : props.rejected ?? null;
475
- }
476
- function Resolve(props) {
477
- if (props.value.state === "fulfilled") return props.children(props.value.value);
478
- if (props.value.state === "rejected") return rejectedChild(props, props.value.error);
479
- const renderContext = getActiveRenderContext();
480
- if (renderContext) {
481
- const id = `d:${renderContext.deferredBoundaries.length}`;
482
- renderContext.deferredBoundaries.push({
483
- id,
484
- promise: props.value.promise,
485
- fulfilled: (value) => props.children(value),
486
- rejected: (error) => rejectedChild(props, error)
487
- });
488
- return {
489
- type: DEFERRED_BOUNDARY,
490
- props: {
491
- id,
492
- pending: props.pending ?? null
493
- }
494
- };
495
- }
496
- const result = resource(() => props.value.promise, [props.value]);
497
- if (result.error) return rejectedChild(props, result.error);
498
- if (result.pending || result.value === null) return props.pending ?? null;
499
- return props.children(result.value);
500
- }
501
- //#endregion
502
- export { _preloadRouteHandler as C, getExecutionModel as E, getRenderHandler as S, assertExecutionModel as T, isPageRenderEnvelope as _, resolveDeferredValues as a, Outlet as b, _applyManifest as c, getRouteRenderContext as d, getRouteRenderData as f, isEmptyPageRenderEnvelope as g, createPageRenderEnvelope as h, isDeferred as i, createRouteRegistry as l, resolveRouteRequest as m, Resolve as n, reviveDeferredValue as o, hasRouteRenderData as p, defer as r, routeData as s, DEFERRED_BOUNDARY as t, bindResolvedRouteData as u, pageRenderEnvelope as v, lazy as w, createRouteHandler as x, currentAuth as y };
514
+ export { createRouteHandler as _, resolveRouteRequest as a, lazy as b, prepareRouteHydrationData as c, DEFERRED_BOUNDARY as d, defer as f, Outlet as g, currentAuth as h, hasRouteRenderData as i, validateRouteHydrationData as l, reviveDeferredValue as m, getRouteRenderContext as n, getRouteHydrationMetadata as o, isDeferred as p, getRouteRenderData as r, guardHydratedRouteData as s, bindResolvedRouteData as t, withoutRouteHydrationMetadata as u, getRenderHandler as v, _preloadRouteHandler as y };