@askrjs/askr 0.0.64 → 0.0.66

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.
@@ -5,224 +5,12 @@ import { r as executeComponent } from "./component-internal-CbALfPGD.js";
5
5
  import { d as getCurrentAppRenderRuntime, f as getCurrentComponentInstance } from "./component-scope-CC3cojX9.js";
6
6
  import { g as cleanupComponentGeneration, h as cleanupComponent, i as beginLifecycleCommitBatch, l as flushLifecycleCommitBatch, m as isPromiseLike, o as discardLifecycleCommitBatch, s as drainLifecycleCommitErrors } from "./component-lifecycle-DEMPihoZ.js";
7
7
  import { _ as teardownNodeSubtree } from "./cleanup-B6KovDZZ.js";
8
+ import { d as getRouteRenderContext, f as getRouteRenderData, m as resolveRouteRequest, p as hasRouteRenderData } from "./deferred-Eh9bCVGH.js";
8
9
  import { n as getActiveRenderContext } from "./render-context-Clw3rFiO.js";
9
10
  import { n as syncRouteActivitySnapshot } from "./route-activity-CNJfpwx-.js";
10
11
  import { r as clearDefaultPortalForInstance, t as DefaultPortal } from "./portal-D2tPWNrC.js";
11
12
  import { t as CspNonceScope } from "./csp-nonce-C-8E85El.js";
12
- import { A as insertRecordSorted, C as getCurrentPathPrefix, D as getRoutes, E as getRouteRecords, F as snapshotRouteState, I as computeRank, L as normalizeRouteSegmentName, M as pushRegistrationScope, N as restoreRouteState, O as hasActivePageScope, P as setDefaultRouteAuthOptions, R as parseSegments, S as getCurrentPageScope, T as getDefaultRouteAuthOptions, _ as getCurrentInheritedAuthRequirements, a as resolveRouteFromRoutes, b as getCurrentLayoutChain, c as deepFreeze, f as addRouteToStores, g as getActiveRoutes, j as lockRouteRegistration, l as makeQuery, m as clearRouteState, n as computeMatchesFromRoutes, p as assertRouteRegistrationUnlocked, r as computeRouteActivityMatches, u as parseLocation, v as getCurrentInheritedMeta, w as getCurrentScopeKind, x as getCurrentPageChain, y as getCurrentInheritedPolicies } from "./route-matching-vJpvLVbX.js";
13
- import { d as hasRouteRenderData, f as resolveRouteRequest, l as getRouteRenderContext, u as getRouteRenderData, x as _preloadRouteHandler, y as createRouteHandler } from "./deferred-vBQJwHl5.js";
14
- import { allOf } from "@askrjs/auth";
15
- //#region src/runtime/execution-model.ts
16
- const EXECUTION_MODEL_KEY = Symbol.for("__ASKR_EXECUTION_MODEL__");
17
- function getExecutionModel() {
18
- return globalThis[EXECUTION_MODEL_KEY];
19
- }
20
- function assertExecutionModel(model) {
21
- const g = globalThis;
22
- const cur = g[EXECUTION_MODEL_KEY];
23
- 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.`);
24
- if (!cur) g[EXECUTION_MODEL_KEY] = model;
25
- }
26
- //#endregion
27
- //#region src/router/access.ts
28
- function compileNodePolicies(node) {
29
- return node.policies ? [...node.policies] : [];
30
- }
31
- //#endregion
32
- //#region src/router/authoring.ts
33
- function validateRoutePath(path) {
34
- if (!path.startsWith("/")) throw new Error(`Route path must begin with "/". Got: "${path}"`);
35
- if (/\/{2,}/.test(path)) throw new Error("Route path cannot contain consecutive slashes.");
36
- if (/:([^/{}]+)/.test(path)) {
37
- const suggested = path.replace(/:([^/{}]+)/g, "{$1}");
38
- throw new Error(`Route parameter syntax uses {name} interpolation, not :name. Use "${suggested}" instead of "${path}".`);
39
- }
40
- const segments = path.split("/").filter(Boolean);
41
- const seenParamNames = /* @__PURE__ */ new Set();
42
- for (let index = 0; index < segments.length; index++) {
43
- const segment = segments[index];
44
- if (segment === "*") continue;
45
- const hasOpenBrace = segment.includes("{");
46
- const hasCloseBrace = segment.includes("}");
47
- if (!hasOpenBrace && !hasCloseBrace) continue;
48
- if (!(segment.startsWith("{") && segment.endsWith("}"))) throw new Error("Route parameter segments must use complete {name} interpolation.");
49
- const rawParamName = normalizeRouteSegmentName(segment.slice(1, -1));
50
- const isSplat = rawParamName.startsWith("*");
51
- const paramName = isSplat ? normalizeRouteSegmentName(rawParamName.slice(1)) : rawParamName;
52
- if (!paramName) throw new Error(isSplat ? "Route splat parameter name cannot be empty." : "Route parameter name cannot be empty.");
53
- if (isSplat && paramName === "*") throw new Error("Route named splat parameter name cannot be \"*\".");
54
- if (isSplat && index !== segments.length - 1) throw new Error("Route named splat parameters must be the final segment.");
55
- if (seenParamNames.has(paramName)) throw new Error(`Route path cannot reuse duplicate parameter name "${paramName}".`);
56
- seenParamNames.add(paramName);
57
- }
58
- }
59
- function normalizeAbsoluteRoutePath(path) {
60
- if (!path || path === "/") return "/";
61
- return (path.endsWith("/") ? path.slice(0, -1) : path) || "/";
62
- }
63
- function joinRoutePaths(prefix, path) {
64
- const normalizedPrefix = normalizeAbsoluteRoutePath(prefix || "/");
65
- const normalizedPath = path.replace(/^\/+|\/+$/g, "");
66
- if (!normalizedPath) return normalizedPrefix;
67
- return normalizedPrefix === "/" ? `/${normalizedPath}` : `${normalizedPrefix}/${normalizedPath}`;
68
- }
69
- function resolvePageScopePath(path) {
70
- if (!path) throw new Error("page(path, Component, fn) requires a non-empty path.");
71
- if (path.startsWith("/")) {
72
- validateRoutePath(path);
73
- return normalizeAbsoluteRoutePath(path);
74
- }
75
- return joinRoutePaths(getCurrentPathPrefix(), path);
76
- }
77
- function resolveIndexPath() {
78
- return normalizeAbsoluteRoutePath(getCurrentPathPrefix() || "/");
79
- }
80
- function resolveRouteRegistrationPath(path) {
81
- if (path.startsWith("/")) {
82
- if (hasActivePageScope()) throw new Error(`Child route paths inside page() must be relative. Use "${path.slice(1)}" instead of "${path}".`);
83
- validateRoutePath(path);
84
- return normalizeAbsoluteRoutePath(path);
85
- }
86
- const prefix = getCurrentPathPrefix();
87
- if (!prefix) throw new Error(`Route path must begin with "/". Got: "${path}"`);
88
- return joinRoutePaths(prefix, path);
89
- }
90
- function pushGroupScope(options, fn) {
91
- const policies = compileNodePolicies(options);
92
- pushRegistrationScope({
93
- kind: "group",
94
- pathPrefix: getCurrentPathPrefix(),
95
- layout: options.layout,
96
- auth: options.auth,
97
- policies,
98
- meta: options.meta
99
- }, fn);
100
- }
101
- function pushPageScope(path, Component, options, fn) {
102
- if (hasActivePageScope()) throw new Error("page() cannot be nested inside another page(). Use route() for child leaves or group() for inherited behavior inside the existing page scope.");
103
- const policies = compileNodePolicies(options);
104
- pushRegistrationScope({
105
- kind: "page",
106
- pathPrefix: resolvePageScopePath(path),
107
- page: Component,
108
- hasIndex: false,
109
- auth: options.auth,
110
- policies,
111
- meta: options.meta
112
- }, fn);
113
- }
114
- function normalizeRouteOptions(options) {
115
- if (!options) return;
116
- const loader = options.loader;
117
- const preload = options.preload;
118
- const policies = compileNodePolicies(options);
119
- if (!loader && !preload && !options.entries && policies.length === 0 && !options.title && !options.namespace && !options.search && !options.meta && !options.actions && options.auth === void 0) return;
120
- return {
121
- ...loader ? { loader } : {},
122
- ...preload ? { preload } : {},
123
- ...options.entries ? { entries: options.entries } : {},
124
- ...options.auth !== void 0 ? { auth: options.auth } : {},
125
- ...policies.length > 0 ? { policies } : {},
126
- ...options.title ? { title: options.title } : {},
127
- ...options.namespace ? { namespace: options.namespace } : {},
128
- ...options.search ? { search: options.search } : {},
129
- ...options.meta ? { meta: options.meta } : {},
130
- ...options.actions ? { actions: options.actions } : {}
131
- };
132
- }
133
- function registerRouteAtResolvedPath(path, Component, options, metadata) {
134
- validateRoutePath(path);
135
- const chain = getCurrentLayoutChain();
136
- const pageChain = getCurrentPageChain();
137
- const segments = parseSegments(path);
138
- const rank = computeRank(segments);
139
- const isFallback = metadata?.isFallback ?? path === "/*";
140
- const comp = Component;
141
- const normalizedOptions = normalizeRouteOptions(options);
142
- const policies = [...getCurrentInheritedPolicies(), ...normalizedOptions?.policies ?? []];
143
- const authRequirements = [...getCurrentInheritedAuthRequirements(), ...normalizedOptions?.auth ? [normalizedOptions.auth] : []];
144
- const auth = authRequirements.length === 0 ? void 0 : authRequirements.length === 1 ? authRequirements[0] : allOf(...authRequirements);
145
- const metaChain = [...getCurrentInheritedMeta(), ...normalizedOptions?.meta ? [normalizedOptions.meta] : []];
146
- const handler = createRouteHandler(comp, pageChain, chain);
147
- const renderHandler = createRouteHandler(comp, pageChain, chain, true);
148
- insertRecordSorted({
149
- path,
150
- component: comp,
151
- segments,
152
- rank,
153
- layoutChain: chain,
154
- pageChain,
155
- options: normalizedOptions ? {
156
- ...normalizedOptions,
157
- ...auth ? { auth } : {},
158
- ...policies.length > 0 ? { policies } : {}
159
- } : policies.length > 0 ? {
160
- policies,
161
- ...auth ? { auth } : {}
162
- } : auth ? { auth } : {},
163
- ...metaChain.length > 0 ? { metaChain } : {},
164
- isFallback,
165
- handler,
166
- renderHandler,
167
- ...metadata?.fallbackPrefix ? { fallbackPrefix: metadata.fallbackPrefix } : {}
168
- });
169
- addRouteToStores({
170
- path,
171
- handler,
172
- namespace: normalizedOptions?.namespace ?? options?.namespace,
173
- ...metadata?.fallbackPrefix ? { fallbackPrefix: metadata.fallbackPrefix } : {}
174
- });
175
- }
176
- function group(options, fn) {
177
- pushGroupScope(options, fn);
178
- }
179
- function page(path, Component, optionsOrFn, maybeFn) {
180
- const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
181
- const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
182
- if (typeof Component !== "function") throw new Error("page(path, Component, fn) requires a component function as the second argument.");
183
- if (typeof fn !== "function") throw new Error("page(path, Component, fn) requires a route definition callback as the final argument.");
184
- pushPageScope(path, Component, options, fn);
185
- }
186
- function index(Component, options) {
187
- const pageScope = getCurrentPageScope();
188
- if (pageScope?.hasIndex) throw new Error("page() cannot declare multiple index routes.");
189
- if (pageScope) pageScope.hasIndex = true;
190
- registerRouteAtResolvedPath(resolveIndexPath(), Component, options);
191
- }
192
- function fallback(Component) {
193
- if (hasActivePageScope()) {
194
- if (getCurrentScopeKind() !== "page") throw new Error("fallback() inside page() must be declared directly in the page scope, not inside nested group().");
195
- registerRouteAtResolvedPath(`${getCurrentPathPrefix()}/*`, Component, void 0, {
196
- isFallback: true,
197
- fallbackPrefix: getCurrentPathPrefix()
198
- });
199
- return;
200
- }
201
- if (!(getCurrentInheritedPolicies().length === 0 && getCurrentInheritedAuthRequirements().length === 0)) throw new Error("fallback() can only be registered at the root scope. Use route(\"/*\", Component) if you need compatibility behavior.");
202
- registerRouteAtResolvedPath("/*", Component, void 0, {
203
- isFallback: true,
204
- fallbackPrefix: "/"
205
- });
206
- }
207
- function registerRoutes(definition, options = {}) {
208
- setDefaultRouteAuthOptions(options.auth);
209
- definition();
210
- }
211
- function route(path, Component, options) {
212
- if (typeof path === "undefined") throw new Error("route() is only for route registration. Use currentRoute() inside components.");
213
- if (getExecutionModel() === "islands") throw new Error("Routes are not supported with islands. Use createSPA (client) or createSSR (server) instead.");
214
- const currentInst = getCurrentComponentInstance();
215
- if (currentInst && currentInst.ssr) throw new Error("route() cannot be called during SSR rendering. Register routes at module load time instead.");
216
- assertRouteRegistrationUnlocked();
217
- if (typeof Component !== "function") throw new Error("route(path, Component) requires a component function as the second argument. Passing JSX elements or VNodes directly is not supported.");
218
- if (options?.search && options.search.kind !== "object") throw new Error("route search must be an object schema.");
219
- registerRouteAtResolvedPath(resolveRouteRegistrationPath(path), Component, options);
220
- return Object.freeze({
221
- path: resolveRouteRegistrationPath(path),
222
- ...options?.search ? { searchSchema: options.search } : {}
223
- });
224
- }
225
- //#endregion
13
+ import { c as deepFreeze, g as getActiveRoutes, j as lockRouteRegistration, l as makeQuery, n as computeMatchesFromRoutes, r as computeRouteActivityMatches, u as parseLocation } from "./route-matching-DLBWDeXX.js";
226
14
  //#region src/common/app-render-runtime.ts
227
15
  const stagedRouteLocations = /* @__PURE__ */ new WeakMap();
228
16
  function createAppRenderRuntime(input = {}) {
@@ -317,44 +105,6 @@ function syncCurrentRouteSnapshot(pathname, search, hash, activityMatches) {
317
105
  setCurrentRouteSnapshot(pathname, search, hash, activityMatches);
318
106
  }
319
107
  //#endregion
320
- //#region src/router/manifest.ts
321
- function getManifest() {
322
- const auth = getDefaultRouteAuthOptions();
323
- return {
324
- records: [...getRouteRecords()],
325
- ...auth ? { auth } : {}
326
- };
327
- }
328
- function _applyManifest(manifest) {
329
- setDefaultRouteAuthOptions(manifest.auth);
330
- for (const record of manifest.records) {
331
- insertRecordSorted(record);
332
- addRouteToStores({
333
- path: record.path,
334
- handler: record.handler,
335
- namespace: record.options.namespace,
336
- ..."fallbackPrefix" in record && typeof record.fallbackPrefix === "string" ? { fallbackPrefix: record.fallbackPrefix } : {}
337
- });
338
- }
339
- }
340
- function clearRoutes() {
341
- clearRouteState();
342
- }
343
- function createRouteRegistry(definition, options = {}) {
344
- const previous = snapshotRouteState();
345
- clearRoutes();
346
- try {
347
- registerRoutes(definition, options);
348
- const manifest = getManifest();
349
- return Object.freeze({
350
- manifest,
351
- routes: getRoutes()
352
- });
353
- } finally {
354
- restoreRouteState(previous);
355
- }
356
- }
357
- //#endregion
358
108
  //#region src/router/navigation-registry.ts
359
109
  let currentInstance = null;
360
110
  let currentPathname = "/";
@@ -400,10 +150,7 @@ function collectRouteActivityMatches(pathname, apps = registeredApps) {
400
150
  const matches = [];
401
151
  const seenPaths = /* @__PURE__ */ new Set();
402
152
  for (const app of apps) {
403
- const appMatches = computeRouteActivityMatches(pathname, {
404
- manifest: app.manifest,
405
- routes: app.routes
406
- });
153
+ const appMatches = computeRouteActivityMatches(pathname, { registry: app.registry });
407
154
  for (const match of appMatches) {
408
155
  if (seenPaths.has(match.path)) continue;
409
156
  seenPaths.add(match.path);
@@ -417,7 +164,7 @@ function syncRegisteredRouteSnapshot() {
417
164
  const pathname = window.location.pathname || "/";
418
165
  syncCurrentRouteSnapshot(pathname, window.location.search || "", window.location.hash || "", collectRouteActivityMatches(pathname));
419
166
  }
420
- function registerAppInstance(instance, path, source = {}) {
167
+ function registerAppInstance(instance, path, source) {
421
168
  const existingIndex = registeredApps.findIndex((app) => app.instance === instance);
422
169
  const registration = {
423
170
  instance,
@@ -1043,23 +790,8 @@ function rerenderResolvedRoute(instance, pathname, href) {
1043
790
  return true;
1044
791
  }
1045
792
  function resolveAppRouteRequest(app, pathname, href, signal) {
1046
- if (app.manifest) return resolveRouteRequest(href, {
1047
- manifest: app.manifest,
1048
- auth: app.auth,
1049
- signal
1050
- });
1051
- if (app.routes) {
1052
- const resolved = resolveRouteFromRoutes(pathname, app.routes);
1053
- if (!resolved) return null;
1054
- const result = {
1055
- kind: "render",
1056
- handler: resolved.handler,
1057
- params: resolved.params
1058
- };
1059
- const lazyImport = _preloadRouteHandler(resolved.handler);
1060
- return lazyImport ? lazyImport.then(() => result) : result;
1061
- }
1062
793
  return resolveRouteRequest(href, {
794
+ registry: app.registry,
1063
795
  auth: app.auth,
1064
796
  signal
1065
797
  });
@@ -1448,4 +1180,4 @@ function initializeNavigation() {
1448
1180
  window.addEventListener("popstate", handlePopState);
1449
1181
  }
1450
1182
  //#endregion
1451
- export { assertExecutionModel as C, route as S, fallback as _, resolveRouteMeta as a, page as b, registerAppInstance as c, clearRoutes as d, createRouteRegistry as f, createAppRenderRuntime as g, setServerLocation as h, reconcileRouteMeta as i, unregisterAppInstance as l, currentRoute as m, navigate as n, serializeRouteMeta as o, getManifest as p, updateRouteQuery as r, configureScrollRestoration as s, initializeNavigation as t, _applyManifest as u, group as v, registerRoutes as x, index as y };
1183
+ export { resolveRouteMeta as a, registerAppInstance as c, setServerLocation as d, createAppRenderRuntime as f, reconcileRouteMeta as i, unregisterAppInstance as l, navigate as n, serializeRouteMeta as o, updateRouteQuery as r, configureScrollRestoration as s, initializeNavigation as t, currentRoute as u };
@@ -225,7 +225,7 @@ function lockRouteRegistration() {
225
225
  function assertRouteRegistrationUnlocked() {
226
226
  if (registrationLocked) throw new Error("Route registration is locked after app startup. Register routes at module load time before calling createSPA or createSSR.");
227
227
  }
228
- function getRoutes() {
228
+ function getRouteList() {
229
229
  return [...routes];
230
230
  }
231
231
  function hasRegisteredRoutes() {
@@ -477,10 +477,8 @@ function computeMatchesFromRouteRecords(pathname, routeRecords) {
477
477
  namespace: bestMatch.record.options.namespace
478
478
  }];
479
479
  }
480
- function computeRouteActivityMatches(pathname, options = {}) {
481
- if (options.manifest) return computeMatchesFromRouteRecords(pathname, options.manifest.records);
482
- if (options.routes) return computeMatchesFromRoutes(pathname, options.routes);
483
- return computeMatchesFromRoutes(pathname, getActiveRoutes());
480
+ function computeRouteActivityMatches(pathname, options) {
481
+ return computeMatchesFromRouteRecords(pathname, options.registry.manifest.records);
484
482
  }
485
483
  function resolveRoute(pathname) {
486
484
  const normalized = pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname;
@@ -512,4 +510,4 @@ function _resolveRouteMatchFromRoutes(pathname, routeList) {
512
510
  return findBestResolvedRouteFromRoutes(pathname, routeList);
513
511
  }
514
512
  //#endregion
515
- export { insertRecordSorted as A, getCurrentPathPrefix as C, getRoutes as D, getRouteRecords as E, snapshotRouteState as F, computeRank as I, normalizeRouteSegmentName as L, pushRegistrationScope as M, restoreRouteState as N, hasActivePageScope as O, setDefaultRouteAuthOptions as P, parseSegments as R, getCurrentPageScope as S, getDefaultRouteAuthOptions as T, getCurrentInheritedAuthRequirements as _, resolveRouteFromRoutes as a, getCurrentLayoutChain as b, deepFreeze as c, _setActiveRouteAuthOptions as d, addRouteToStores as f, getActiveRoutes as g, getActiveRouteAuthOptions as h, getMatchingRouteRecord as i, lockRouteRegistration as j, hasRegisteredRoutes as k, makeQuery as l, clearRouteState as m, computeMatchesFromRoutes as n, buildRouteContext as o, assertRouteRegistrationUnlocked as p, computeRouteActivityMatches as r, buildRouteContextBase as s, _resolveRouteMatchFromRoutes as t, parseLocation as u, getCurrentInheritedMeta as v, getCurrentScopeKind as w, getCurrentPageChain as x, getCurrentInheritedPolicies as y };
513
+ export { insertRecordSorted as A, getCurrentPathPrefix as C, getRouteRecords as D, getRouteList as E, snapshotRouteState as F, computeRank as I, normalizeRouteSegmentName as L, pushRegistrationScope as M, restoreRouteState as N, hasActivePageScope as O, setDefaultRouteAuthOptions as P, parseSegments as R, getCurrentPageScope as S, getDefaultRouteAuthOptions as T, getCurrentInheritedAuthRequirements as _, resolveRouteFromRoutes as a, getCurrentLayoutChain as b, deepFreeze as c, _setActiveRouteAuthOptions as d, addRouteToStores as f, getActiveRoutes as g, getActiveRouteAuthOptions as h, getMatchingRouteRecord as i, lockRouteRegistration as j, hasRegisteredRoutes as k, makeQuery as l, clearRouteState as m, computeMatchesFromRoutes as n, buildRouteContext as o, assertRouteRegistrationUnlocked as p, computeRouteActivityMatches as r, buildRouteContextBase as s, _resolveRouteMatchFromRoutes as t, parseLocation as u, getCurrentInheritedMeta as v, getCurrentScopeKind as w, getCurrentPageChain as x, getCurrentInheritedPolicies as y };
@@ -1,6 +1,6 @@
1
1
  import { c as RenderableChild } from "../control-CMzFPMjr.js";
2
2
  import { r as JSXElement, s as Props } from "../jsx-Dvr2SGRG.js";
3
- import { A as RouteQuery, B as RouteSnapshot, C as RouteMeta, D as RouteParams, E as RouteOptions, F as RouteRenderResult, I as RouteRequestOptions, L as RouteRequestResult, M as RouteRef, N as RouteRefSearch, O as RoutePathParams, P as RouteRegistry, R as RouteSearch, S as RouteMatch, T as RouteMode, _ as RouteContext, a as AccessRedirectDecision, b as RouteHandler, c as LayoutScopeRecord, d as ParsedSegment, f as RegisterRoutesOptions, g as RouteComponent, h as RouteAuthResolver, i as AccessDenyStatus, j as RouteRecord, k as RoutePolicy, l as PageHelperOptions, m as RouteAuthOptions, n as AccessDecision, o as AccessRedirectStatus, p as Route, r as AccessDenyDecision, s as GroupHelperOptions, t as AccessAllowDecision, u as PageScopeRecord, v as RouteDefinition, w as RouteMetaSource, x as RouteManifest, y as RouteDestination, z as RouteSearchValue } from "../router-Dz7ZoLja.js";
3
+ import { A as RouteRecord, B as RouteSnapshot, C as RouteMetaSource, D as RoutePathParams, E as RouteParams, F as RouteRenderResult, I as RouteRequestOptions, L as RouteRequestResult, M as RouteRefSearch, N as RouteRegistry, O as RoutePolicy, P as RouteRegistryOptions, R as RouteSearch, S as RouteMeta, T as RouteOptions, _ as RouteDefinition, a as AccessRedirectDecision, b as RouteManifest, c as LayoutScopeRecord, d as ParsedSegment, f as Route, g as RouteContext, h as RouteComponent, i as AccessDenyStatus, j as RouteRef, k as RouteQuery, l as PageHelperOptions, m as RouteAuthResolver, n as AccessDecision, o as AccessRedirectStatus, p as RouteAuthOptions, r as AccessDenyDecision, s as GroupHelperOptions, t as AccessAllowDecision, u as PageScopeRecord, v as RouteDestination, w as RouteMode, x as RouteMatch, y as RouteHandler, z as RouteSearchValue } from "../router-4EhVGcma.js";
4
4
  import { a as RouteQueryUpdates, c as NavigateOptions, d as ScrollRestorationOptions, i as RouteQueryUpdater, l as HistoryScrollBehavior, n as RouteQueryParamInput, o as UpdateRouteQueryOptions, r as RouteQueryParamValue, s as updateRouteQuery, t as navigate, u as NavigationScrollBehavior } from "../navigate-BVDCzOuB.js";
5
5
  import { AuthContext, AuthContext as AuthContext$1, AuthRequirement, AuthRequirement as AuthRequirement$1 } from "@askrjs/auth";
6
6
  import { ObjectSchema } from "@askrjs/schema";
@@ -21,7 +21,6 @@ declare function page<const TPath extends string>(path: TPath, Component: RouteC
21
21
  declare function page<const TPath extends string, TComponent extends AnyRouteComponent>(path: TPath, Component: CompatibleRouteComponent<TPath, TComponent>, options: PageHelperOptions, fn: RouteDefinition): void;
22
22
  declare function index(Component: RouteComponent, options?: RouteOptions): void;
23
23
  declare function fallback(Component: RouteComponent): void;
24
- declare function registerRoutes(definition: RouteDefinition, options?: RegisterRoutesOptions): void;
25
24
  declare function route<const TPath extends string, const TSearchSchema extends ObjectSchema<RouteSearch> | undefined = undefined>(path: TPath, Component: RouteComponent<RoutePathParams<TPath>>, options?: RouteOptions<RoutePathParams<TPath>, TSearchSchema>): RouteRef<RoutePathParams<TPath>, RouteRefSearch<TSearchSchema>>;
26
25
  declare function route<const TPath extends string, TComponent extends AnyRouteComponent, const TSearchSchema extends ObjectSchema<RouteSearch> | undefined = undefined>(path: TPath, Component: CompatibleRouteComponent<TPath, TComponent>, options?: RouteOptionsForComponent<TPath, TComponent, TSearchSchema>): RouteRef<RoutePathParams<TPath>, RouteRefSearch<TSearchSchema>>;
27
26
  //#endregion
@@ -33,15 +32,10 @@ declare function currentRoute<TParams extends RouteParams = RouteParams>(): Rout
33
32
  declare function currentAuth(): AuthContext$1;
34
33
  //#endregion
35
34
  //#region src/router/resolution.d.ts
36
- declare function resolveRouteRequest(target: string, options?: RouteRequestOptions): RouteRequestResult | Promise<RouteRequestResult>;
35
+ declare function resolveRouteRequest(target: string, options: RouteRequestOptions): RouteRequestResult | Promise<RouteRequestResult>;
37
36
  //#endregion
38
37
  //#region src/router/manifest.d.ts
39
- declare function getManifest(): RouteManifest;
40
- declare function clearRoutes(): void;
41
- declare function createRouteRegistry(definition: RouteDefinition, options?: RegisterRoutesOptions): RouteRegistry;
42
- //#endregion
43
- //#region src/router/store.d.ts
44
- declare function getRoutes(): Route[];
38
+ declare function createRouteRegistry(definition: RouteDefinition, options?: RouteRegistryOptions): RouteRegistry;
45
39
  //#endregion
46
40
  //#region src/router/lazy.d.ts
47
41
  type LazyRouteComponent<TComponent extends AnyRouteComponent> = TComponent & {
@@ -166,4 +160,4 @@ declare function Link({
166
160
  ...rest
167
161
  }: LinkProps): JSXElement;
168
162
  //#endregion
169
- export { type AccessDecision, type AccessDenyDecision, type AccessRedirectDecision, type AuthContext, type AuthRequirement, type Deferred, type DeferredState, type GroupHelperOptions, type HistoryScrollBehavior, type LayoutScopeRecord, type LazyRouteComponent, Link, type LinkProps, type NavigateOptions, type NavigationScrollBehavior, Outlet, type PageHelperOptions, type PageScopeRecord, type ParsedSegment, type RegisterRoutesOptions, Resolve, type ResolveProps, type Route, type RouteAuthOptions, type RouteAuthResolver, type RouteComponent, type RouteContext, type RouteDefinition, type RouteDestination, type RouteHandler, type RouteManifest, type RouteMatch, type RouteMeta, type RouteMetaSource, type RouteMode, type RouteOptions, type RouteParams, type RoutePathParams, type RoutePolicy, type RouteQuery, type RouteQueryParamInput, type RouteQueryParamValue, type RouteQueryUpdater, type RouteQueryUpdates, type RouteRecord, type RouteRef, type RouteRegistry, type RouteRenderResult, type RouteRequestOptions, type RouteRequestResult, type RouteSearch, type RouteSearchValue, type RouteSnapshot, type ScrollRestorationOptions, type UpdateRouteQueryOptions, allow, clearRoutes, createRouteRegistry, currentAuth, currentRoute, defer, deny, fallback, forbidden, getManifest, getRoutes, group, index, isDeferred, lazy, navigate, notFound, page, reconcileRouteMeta, redirect, registerRoutes, resolveDeferredValues, resolveRouteMeta, resolveRouteRequest, route, routeData, serializeRouteMeta, to$1 as to, unauthorized, updateRouteQuery };
163
+ export { type AccessDecision, type AccessDenyDecision, type AccessRedirectDecision, type AuthContext, type AuthRequirement, type Deferred, type DeferredState, type GroupHelperOptions, type HistoryScrollBehavior, type LayoutScopeRecord, type LazyRouteComponent, Link, type LinkProps, type NavigateOptions, type NavigationScrollBehavior, Outlet, type PageHelperOptions, type PageScopeRecord, type ParsedSegment, Resolve, type ResolveProps, type Route, type RouteAuthOptions, type RouteAuthResolver, type RouteComponent, type RouteContext, type RouteDefinition, type RouteDestination, type RouteHandler, type RouteManifest, type RouteMatch, type RouteMeta, type RouteMetaSource, type RouteMode, type RouteOptions, type RouteParams, type RoutePathParams, type RoutePolicy, type RouteQuery, type RouteQueryParamInput, type RouteQueryParamValue, type RouteQueryUpdater, type RouteQueryUpdates, type RouteRecord, type RouteRef, type RouteRegistry, type RouteRegistryOptions, type RouteRenderResult, type RouteRequestOptions, type RouteRequestResult, type RouteSearch, type RouteSearchValue, type RouteSnapshot, type ScrollRestorationOptions, type UpdateRouteQueryOptions, allow, createRouteRegistry, currentAuth, currentRoute, defer, deny, fallback, forbidden, group, index, isDeferred, lazy, navigate, notFound, page, reconcileRouteMeta, redirect, resolveDeferredValues, resolveRouteMeta, resolveRouteRequest, route, routeData, serializeRouteMeta, to$1 as to, unauthorized, updateRouteQuery };
@@ -1,7 +1,7 @@
1
- import { S as route, _ as fallback, a as resolveRouteMeta, b as page, d as clearRoutes, f as createRouteRegistry, i as reconcileRouteMeta, m as currentRoute, n as navigate, o as serializeRouteMeta, p as getManifest, r as updateRouteQuery, v as group, x as registerRoutes, y as index } from "../navigate-CaFA0DdW.js";
1
+ import { C as lazy, a as resolveDeferredValues, b as Outlet, i as isDeferred, l as createRouteRegistry, m as resolveRouteRequest, n as Resolve, r as defer, s as routeData, y as currentAuth } from "../deferred-Eh9bCVGH.js";
2
2
  import { jsx } from "../jsx-runtime.js";
3
- import { D as getRoutes } from "../route-matching-vJpvLVbX.js";
4
- import { S as lazy, a as resolveDeferredValues, f as resolveRouteRequest, i as isDeferred, n as Resolve, p as currentAuth, r as defer, s as routeData, v as Outlet } from "../deferred-vBQJwHl5.js";
3
+ import { a as route, i as page, n as group, r as index, t as fallback } from "../authoring-Di8MInO-.js";
4
+ import { a as resolveRouteMeta, i as reconcileRouteMeta, n as navigate, o as serializeRouteMeta, r as updateRouteQuery, u as currentRoute } from "../navigate-QMRcR581.js";
5
5
  import { o as mergeProps } from "../compose-ref-Cc_YkUpM.js";
6
6
  import { t as applyInteractionPolicy } from "../interactions-w7gQN4ha.js";
7
7
  //#region src/router/policy.ts
@@ -147,4 +147,4 @@ function Link({ href: suppliedHref, to, class: className, children, rel, target,
147
147
  });
148
148
  }
149
149
  //#endregion
150
- export { Link, Outlet, Resolve, allow, clearRoutes, createRouteRegistry, currentAuth, currentRoute, defer, deny, fallback, forbidden, getManifest, getRoutes, group, index, isDeferred, lazy, navigate, notFound, page, reconcileRouteMeta, redirect, registerRoutes, resolveDeferredValues, resolveRouteMeta, resolveRouteRequest, route, routeData, serializeRouteMeta, to, unauthorized, updateRouteQuery };
150
+ export { Link, Outlet, Resolve, allow, createRouteRegistry, currentAuth, currentRoute, defer, deny, fallback, forbidden, group, index, isDeferred, lazy, navigate, notFound, page, reconcileRouteMeta, redirect, resolveDeferredValues, resolveRouteMeta, resolveRouteRequest, route, routeData, serializeRouteMeta, to, unauthorized, updateRouteQuery };
@@ -79,6 +79,8 @@ interface RouteOptions<TParams extends RouteParams = RouteParams, TSearchSchema
79
79
  data: QueryPrefetchContext;
80
80
  }) => unknown;
81
81
  entries?: () => Array<TParams> | Promise<Array<TParams>>;
82
+ /** Optional invalidation keys used by incremental SSG generation. */
83
+ invalidationKeys?: readonly string[];
82
84
  title?: string;
83
85
  namespace?: string;
84
86
  search?: TSearchSchema;
@@ -147,12 +149,13 @@ interface LayoutScopeRecord {
147
149
  interface PageScopeRecord {
148
150
  component: RouteComponent;
149
151
  }
150
- interface RegisterRoutesOptions {
152
+ interface RouteRegistryOptions {
151
153
  auth?: RouteAuthOptions;
152
154
  }
153
155
  type RouteDefinition = () => void;
154
156
  interface RouteRequestOptions {
155
- manifest?: RouteManifest;
157
+ /** Explicit route source shared by the application renderers. */
158
+ registry: RouteRegistry;
156
159
  mode?: RouteMode;
157
160
  /** @internal Hydration adopts server loader data instead of rerunning it. */
158
161
  load?: boolean;
@@ -215,14 +218,16 @@ interface RouteRecord {
215
218
  * instead of assembling plain `Route[]` arrays.
216
219
  *
217
220
  * ```ts
218
- * import { getManifest } from '@askrjs/askr/router';
219
- * await createSPA({ root: '#app', manifest: getManifest() });
221
+ * import { createRouteRegistry } from '@askrjs/askr/router';
222
+ * const registry = createRouteRegistry(() => { ... });
223
+ * await createSPA({ root: '#app', registry });
220
224
  * ```
221
225
  */
222
226
  interface RouteManifest {
223
227
  records: RouteRecord[];
224
228
  auth?: RouteAuthOptions;
225
229
  }
230
+ declare const routeRegistryBrand: unique symbol;
226
231
  interface RouteHandler<TParams extends RouteParams = RouteParams> {
227
232
  (params: TParams, context?: {
228
233
  signal: AbortSignal;
@@ -234,6 +239,8 @@ interface Route<TParams extends RouteParams = RouteParams> {
234
239
  namespace?: string;
235
240
  }
236
241
  interface RouteRegistry {
242
+ /** Internal brand: registries must come from createRouteRegistry(). */
243
+ readonly [routeRegistryBrand]: true;
237
244
  manifest: RouteManifest;
238
245
  routes: readonly Route[];
239
246
  }
@@ -259,4 +266,4 @@ interface RouteSnapshot<TParams extends RouteParams = RouteParams> {
259
266
  matches: readonly RouteMatch<TParams>[];
260
267
  }
261
268
  //#endregion
262
- export { RouteQuery as A, RouteSnapshot as B, RouteMeta as C, RouteParams as D, RouteOptions as E, RouteRenderResult as F, RouteRequestOptions as I, RouteRequestResult as L, RouteRef as M, RouteRefSearch as N, RoutePathParams as O, RouteRegistry as P, RouteSearch as R, RouteMatch as S, RouteMode as T, RouteContext as _, AccessRedirectDecision as a, RouteHandler as b, LayoutScopeRecord as c, ParsedSegment as d, RegisterRoutesOptions as f, RouteComponent as g, RouteAuthResolver as h, AccessDenyStatus as i, RouteRecord as j, RoutePolicy as k, PageHelperOptions as l, RouteAuthOptions as m, AccessDecision as n, AccessRedirectStatus as o, Route as p, AccessDenyDecision as r, GroupHelperOptions as s, AccessAllowDecision as t, PageScopeRecord as u, RouteDefinition as v, RouteMetaSource as w, RouteManifest as x, RouteDestination as y, RouteSearchValue as z };
269
+ export { RouteRecord as A, RouteSnapshot as B, RouteMetaSource as C, RoutePathParams as D, RouteParams as E, RouteRenderResult as F, RouteRequestOptions as I, RouteRequestResult as L, RouteRefSearch as M, RouteRegistry as N, RoutePolicy as O, RouteRegistryOptions as P, RouteSearch as R, RouteMeta as S, RouteOptions as T, RouteDefinition as _, AccessRedirectDecision as a, RouteManifest as b, LayoutScopeRecord as c, ParsedSegment as d, Route as f, RouteContext as g, RouteComponent as h, AccessDenyStatus as i, RouteRef as j, RouteQuery as k, PageHelperOptions as l, RouteAuthResolver as m, AccessDecision as n, AccessRedirectStatus as o, RouteAuthOptions as p, AccessDenyDecision as r, GroupHelperOptions as s, AccessAllowDecision as t, PageScopeRecord as u, RouteDestination as v, RouteMode as w, RouteMatch as x, RouteHandler as y, RouteSearchValue as z };
@@ -1,26 +1,21 @@
1
- import { c as RenderableChild, d as DocumentRenderContext, f as DocumentRenderer, s as ComponentFunction, u as DocumentRenderArgs } from "../control-CMzFPMjr.js";
2
- import { E as RouteOptions, O as RoutePathParams, P as RouteRegistry, b as RouteHandler, k as RoutePolicy } from "../router-Dz7ZoLja.js";
1
+ import { d as DocumentRenderContext, f as DocumentRenderer, u as DocumentRenderArgs } from "../control-CMzFPMjr.js";
2
+ import { D as RoutePathParams, N as RouteRegistry, O as RoutePolicy, T as RouteOptions, y as RouteHandler } from "../router-4EhVGcma.js";
3
3
  import { AuthRequirement } from "@askrjs/auth";
4
4
  //#region src/ssg/types.d.ts
5
5
  type SSGMode = 'full' | 'incremental';
6
6
  type RouteRenderStatus = 'success' | 'error' | 'skipped' | 'removed';
7
7
  type RouteRenderReason = 'full' | 'changed-key' | 'changed-route' | 'new-route' | 'no-keys' | 'unchanged' | 'deleted' | 'runtime-only';
8
8
  type RouteConfigParams<Path extends string> = string extends Path ? Record<string, string> : RoutePathParams<Path>;
9
- type RouteComponentProps<Path extends string> = RouteConfigParams<Path> & Record<string, unknown>;
10
- type StaticRouteComponent<Path extends string> = (props: RouteComponentProps<Path>, context?: Parameters<ComponentFunction>[1]) => RenderableChild;
11
9
  /**
12
10
  * Route config accepted by SSG.
13
11
  *
14
- * `handler` is preferred and matches router/SSR naming.
15
- * `component` is kept for compatibility and is normalized to `handler`.
12
+ * The handler is defined by the route registry and matches router/SSR naming.
16
13
  */
17
14
  interface RouteConfig<Path extends string = string> {
18
15
  /** URL path to generate (e.g., "/blog/post-1", "/") */
19
16
  path: Path;
20
17
  /** Route handler compatible with router/SSR */
21
- handler?: RouteHandler;
22
- /** Backward-compatible alias for handler */
23
- component?: StaticRouteComponent<Path>;
18
+ handler: RouteHandler;
24
19
  /** Optional base props merged with route params during render */
25
20
  props?: Record<string, unknown>;
26
21
  /** Optional namespace for router compatibility */
@@ -72,13 +67,9 @@ interface SSGAssetSource {
72
67
  to?: string;
73
68
  }
74
69
  /** Options for createStaticGen */
75
- type SSGOptions<TRoutes extends readonly RouteConfig[] = RouteConfig[]> = SSGBaseOptions & ({
76
- /** Routes to generate. Prefer `registry` when routes are already defined through the router DSL. */routes: TRoutes;
77
- registry?: never;
78
- } | {
70
+ type SSGOptions<TRoutes extends readonly RouteConfig[] = RouteConfig[]> = SSGBaseOptions & {
79
71
  /** Explicit route registry captured with `createRouteRegistry()`. */registry: RouteRegistry;
80
- routes?: never;
81
- });
72
+ };
82
73
  /** Options for a single generation run */
83
74
  interface SSGGenerateOptions {
84
75
  /** Generation mode */
@@ -190,29 +181,13 @@ interface DiscoveredResources {
190
181
  }
191
182
  //#endregion
192
183
  //#region src/ssg/create-static-gen.d.ts
193
- type AnyRouteConfig = RouteConfig<string>;
194
- type StrictRouteConfig<TRoute extends AnyRouteConfig> = Omit<TRoute, 'params' | 'entries'> & {
195
- params?: RouteConfig<TRoute['path']>['params'];
196
- entries?: RouteConfig<TRoute['path']>['entries'];
197
- };
198
- type StrictRouteConfigs<TRoutes extends readonly AnyRouteConfig[]> = { [TIndex in keyof TRoutes]: TRoutes[TIndex] extends AnyRouteConfig ? StrictRouteConfig<TRoutes[TIndex]> : never };
199
- type StaticGenRouteSource<TRoutes extends readonly AnyRouteConfig[]> = {
200
- routes: TRoutes & StrictRouteConfigs<TRoutes>;
201
- registry?: never;
202
- } | {
203
- registry: RouteRegistry;
204
- routes?: never;
205
- };
206
184
  /**
207
185
  * Create a Static Site Generator
208
186
  *
209
187
  * Usage:
210
188
  * ```ts
211
189
  * const ssg = createStaticGen({
212
- * routes: [
213
- * { path: '/', component: HomePage },
214
- * { path: '/about', component: AboutPage },
215
- * ],
190
+ * registry,
216
191
  * outputDir: './dist',
217
192
  * dataOverrides: {
218
193
  * '/api/posts': { posts: [...] }
@@ -223,7 +198,7 @@ type StaticGenRouteSource<TRoutes extends readonly AnyRouteConfig[]> = {
223
198
  * console.log(`Generated ${result.successful}/${result.totalRoutes} routes`);
224
199
  * ```
225
200
  */
226
- declare function createStaticGen<const TRoutes extends readonly AnyRouteConfig[]>(options: Omit<SSGOptions<TRoutes>, 'routes' | 'registry'> & StaticGenRouteSource<TRoutes>): {
201
+ declare function createStaticGen(options: SSGOptions): {
227
202
  /**
228
203
  * Generate static HTML for all routes
229
204
  * Writes to outputDir with metadata.json