@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.
- package/dist/{access-ePqdQqkV.js → access-Dpfoi4cA.js} +7 -1
- package/dist/actions/index.d.ts +1 -1
- package/dist/actions/index.js +3 -3
- package/dist/{activity-pySy9t7Y.d.ts → activity-B1I5HJQI.d.ts} +1 -1
- package/dist/{activity-CZiPgZy0.js → activity-BvgvaMZA.js} +53 -16
- package/dist/benchmark.js +8 -8
- package/dist/boot/index.d.ts +3 -3
- package/dist/boot/index.js +1 -1
- package/dist/{boot-D28lesMw.js → boot-CViTpUiB.js} +22 -20
- package/dist/{cleanup-ARiXproi.js → cleanup-c837KVij.js} +16 -6
- package/dist/{component-cleanup-Bug5tSiG.js → component-cleanup-BUfUleGZ.js} +2 -2
- package/dist/{component-internal-Bw4Mf9fd.js → component-internal-DcrLymUJ.js} +5 -5
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/control/index.d.ts +1 -1
- package/dist/control/index.js +1 -1
- package/dist/{control-Y8F73Uln.d.ts → control-DhUZU4_V.d.ts} +2 -1
- package/dist/{control-nrS65oG3.js → control-oLADku43.js} +4 -4
- package/dist/{csp-nonce-ZTlD_EnK.js → csp-nonce-Bc52OIVc.js} +19 -2
- package/dist/data/index.js +3 -3
- package/dist/{data-BRS5woEh.js → data-DGrD3-qA.js} +5 -5
- package/dist/{data-runtime-D68YOo9L.js → data-runtime-Ck3tJDDQ.js} +1 -1
- package/dist/default-portal-runtime-DvMvWJVp.js +20 -0
- package/dist/{authoring-DQPG0VAm.js → deferred-nleQtdfY.js} +85 -5
- package/dist/{effect-B487asyz.js → effect-lnxQIpJG.js} +2 -2
- package/dist/{fastlane-BOr4lSLl.js → fastlane-CrfB3QG0.js} +2 -2
- package/dist/{for-internal-DjpV8ioj.js → for-internal-B_mnQhan.js} +18 -6
- package/dist/foundations/index.d.ts +1 -1
- package/dist/foundations/index.js +1 -2
- package/dist/foundations/state/index.d.ts +1 -1
- package/dist/foundations/state/index.js +1 -1
- package/dist/foundations/structures/index.d.ts +2 -2
- package/dist/foundations/structures/index.js +2 -3
- package/dist/fx/index.js +1 -1
- package/dist/{index-BApH3laU.d.ts → index-DflhL1h8.d.ts} +20 -16
- package/dist/{index-_UN08Pg1.d.ts → index-pIgGaXvS.d.ts} +19 -3
- package/dist/{index-DUXXZ31H.d.ts → index-r-nt13FE.d.ts} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +12 -12
- package/dist/{lifecycle-batch-CFI4NKpJ.js → lifecycle-batch-Dfpid9-A.js} +39 -20
- package/dist/{lifecycle-operations-KYOIcM5R.js → lifecycle-operations-BrYrBsXY.js} +1 -1
- package/dist/manifest-D1P9uTlz.js +53 -0
- package/dist/{navigate-Dr3cjOSz.js → navigate-BwAPbpCb.js} +17 -16
- package/dist/{navigate-CgVIrrSs.d.ts → navigate-NyIjQUwI.d.ts} +1 -1
- package/dist/{query-registry-BL6rjGsO.js → query-registry-CPW_6nwF.js} +1 -1
- package/dist/{readable-_GQGe_St.js → readable-B5NtV7V0.js} +1 -1
- package/dist/render-context-D0Hoj9dW.js +161 -0
- package/dist/{renderer-B9j5IV1q.js → renderer-D9DL9R2D.js} +58 -17
- package/dist/{deferred-oqtAJ4iH.js → resolution-YHwi4Bav.js} +234 -222
- package/dist/resource-operation-ys6eDoRJ.js +304 -0
- package/dist/resources/index.d.ts +2 -2
- package/dist/resources/index.js +5 -5
- package/dist/{route-matching-IfQZmqkN.js → route-matching-DqULzZtC.js} +46 -277
- package/dist/router/index.d.ts +12 -10
- package/dist/router/index.js +10 -7
- package/dist/{selector-DJ1-N1K-.js → selector-Ck_Pp9av.js} +2 -2
- package/dist/ssg/index.d.ts +9 -3
- package/dist/ssg/index.js +31 -15
- package/dist/ssr/index.d.ts +7 -3
- package/dist/ssr/index.js +2 -2
- package/dist/{ssr-CtC4lChT.js → ssr-B98593qJ.js} +53 -27
- package/dist/ssr-DSHd_Q9K.js +25 -0
- package/dist/{state-BzIMC6-i.js → state-DCjONcHK.js} +4 -3
- package/dist/{portal-pHBoqwYd.js → structures-DsOm-clq.js} +236 -7
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +4 -4
- package/dist/{verify-hydration-BguOSco9.js → verify-hydration-ww1dgwea.js} +5 -4
- package/package.json +2 -2
- package/dist/render-context-D-DFk2WN.js +0 -73
- package/dist/ssr-CbQO5xd3.js +0 -12
- 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-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { i as
|
|
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/
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
|
157
|
-
if (!value || typeof value !== "object"
|
|
158
|
-
const
|
|
159
|
-
return
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
|
177
|
-
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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 };
|