@funstack/router 1.0.0 → 1.1.0

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.
@@ -2,12 +2,11 @@
2
2
  import { install } from "@funstack/skill-installer";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { dirname, resolve } from "node:path";
5
-
6
5
  //#region src/bin/skill-installer.ts
7
6
  const skillDir = resolve(dirname(fileURLToPath(import.meta.url)), "../../skills/funstack-router-knowledge");
8
7
  console.log("Installing skill from:", skillDir);
9
8
  await install(skillDir);
10
-
11
9
  //#endregion
12
- export { };
10
+ export {};
11
+
13
12
  //# sourceMappingURL=skill-installer.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-installer.mjs","names":[],"sources":["../../src/bin/skill-installer.ts"],"sourcesContent":["#! /usr/bin/env node\n\nimport { install } from \"@funstack/skill-installer\";\nimport { fileURLToPath } from \"node:url\";\nimport { resolve, dirname } from \"node:path\";\n\n// Resolve the skill directory relative to this script's location.\n// This script is at dist/bin/skill-installer.mjs, so go up two levels\n// to reach the package root, then into skills/.\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst skillDir = resolve(__dirname, \"../../skills/funstack-router-knowledge\");\n\nconsole.log(\"Installing skill from:\", skillDir);\n\nawait install(skillDir);\n"],"mappings":";;;;;;AAUA,MAAM,WAAW,QADC,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACrB,yCAAyC;AAE7E,QAAQ,IAAI,0BAA0B,SAAS;AAE/C,MAAM,QAAQ,SAAS"}
1
+ {"version":3,"file":"skill-installer.mjs","names":[],"sources":["../../src/bin/skill-installer.ts"],"sourcesContent":["#! /usr/bin/env node\n\nimport { install } from \"@funstack/skill-installer\";\nimport { fileURLToPath } from \"node:url\";\nimport { resolve, dirname } from \"node:path\";\n\n// Resolve the skill directory relative to this script's location.\n// This script is at dist/bin/skill-installer.mjs, so go up two levels\n// to reach the package root, then into skills/.\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst skillDir = resolve(__dirname, \"../../skills/funstack-router-knowledge\");\n\nconsole.log(\"Installing skill from:\", skillDir);\n\nawait install(skillDir);\n"],"mappings":";;;;;AAUA,MAAM,WAAW,QADC,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACrB,yCAAyC;AAE7E,QAAQ,IAAI,0BAA0B,SAAS;AAE/C,MAAM,QAAQ,SAAS"}
@@ -31,7 +31,6 @@ function routeState() {
31
31
  return definition;
32
32
  });
33
33
  }
34
-
35
34
  //#endregion
36
35
  //#region src/bindRoute.ts
37
36
  function bindRoute(partialRoute, binding) {
@@ -40,7 +39,7 @@ function bindRoute(partialRoute, binding) {
40
39
  ...binding
41
40
  };
42
41
  }
43
-
44
42
  //#endregion
45
43
  export { route as n, routeState as r, bindRoute as t };
46
- //# sourceMappingURL=bindRoute-C7JBYje-.mjs.map
44
+
45
+ //# sourceMappingURL=bindRoute-CQ2-ruTp.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"bindRoute-C7JBYje-.mjs","names":[],"sources":["../src/route.ts","../src/bindRoute.ts"],"sourcesContent":["import type { ComponentType, ReactNode } from \"react\";\n\nconst routeDefinitionSymbol = Symbol();\nconst partialRouteDefinitionSymbol = Symbol();\n\n/**\n * Extracts parameter names from a path pattern.\n * E.g., \"/users/:id/posts/:postId\" -> \"id\" | \"postId\"\n */\ntype ExtractParams<T extends string> =\n T extends `${string}:${infer Param}/${infer Rest}`\n ? Param | ExtractParams<`/${Rest}`>\n : T extends `${string}:${infer Param}`\n ? Param\n : never;\n\n/**\n * Creates a params object type from a path pattern.\n * E.g., \"/users/:id\" -> { id: string }\n */\nexport type PathParams<T extends string> = [ExtractParams<T>] extends [never]\n ? Record<string, never>\n : { [K in ExtractParams<T>]: string };\n\n/**\n * Arguments passed to action functions.\n * The request carries the POST method and FormData body.\n */\nexport type ActionArgs<Params extends Record<string, string>> = {\n /** Extracted path parameters */\n params: Params;\n /** Request object with method POST and FormData body */\n request: Request;\n /** AbortSignal for cancellation */\n signal: AbortSignal;\n};\n\n/**\n * Arguments passed to loader functions.\n */\nexport type LoaderArgs<\n Params extends Record<string, string>,\n ActionResult = undefined,\n> = {\n /** Extracted path parameters */\n params: Params;\n /** Request object with URL and headers */\n request: Request;\n /** AbortSignal for cancellation on navigation */\n signal: AbortSignal;\n /** Result from the action, if this load was triggered by a form submission */\n actionResult: ActionResult | undefined;\n};\n\n/**\n * Props for route components without loader.\n * Includes navigation state management props.\n */\nexport interface RouteComponentProps<\n TParams extends Record<string, string>,\n TState = undefined,\n> {\n /** Extracted path parameters */\n params: TParams;\n /** Current navigation state for this route (undefined on first visit) */\n state: TState | undefined;\n /** Update navigation state for this route asynchronously via replace navigation */\n setState: (\n state: TState | ((prev: TState | undefined) => TState),\n ) => Promise<void>;\n /** Update navigation state for this route synchronously via updateCurrentEntry */\n setStateSync: (\n state: TState | ((prev: TState | undefined) => TState),\n ) => void;\n /** Reset navigation state to undefined asynchronously via replace navigation */\n resetState: () => Promise<void>;\n /** Reset navigation state to undefined synchronously via updateCurrentEntry */\n resetStateSync: () => void;\n /** Ephemeral navigation info (only available during navigation, not persisted) */\n info: unknown;\n /** Whether a navigation transition is pending */\n isPending: boolean;\n}\n\n/**\n * Props for route components with loader.\n * Includes data from loader and navigation state management props.\n */\nexport interface RouteComponentPropsWithData<\n TParams extends Record<string, string>,\n TData,\n TState = undefined,\n> extends RouteComponentProps<TParams, TState> {\n /** Data returned from the loader */\n data: TData;\n}\n\n/**\n * Route definition created by the `route` helper function.\n */\nexport interface OpaqueRouteDefinition {\n [routeDefinitionSymbol]: unknown;\n path?: string;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n}\n\n/**\n * Type-carrying route definition created by the `route` helper function when an `id` is provided.\n * This type carries type information for params, state, and data, enabling type-safe hooks in the future.\n */\nexport interface TypefulOpaqueRouteDefinition<\n Id extends string,\n Params extends Record<string, string>,\n State,\n Data,\n> {\n [routeDefinitionSymbol]: {\n id: Id;\n params: Params;\n state: State;\n data: Data;\n };\n path?: string;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n}\n\n/**\n * Partial route definition created by the `route` helper function when `id` is provided but `component` is not.\n * Used for two-phase route definition in RSC: Phase 1 defines id, path, loader, action;\n * Phase 2 uses `bindRoute()` to attach the component.\n * This type carries type information for params, state, and data, enabling type-safe hooks.\n */\nexport interface PartialRouteDefinition<\n Id extends string,\n Params extends Record<string, string>,\n State,\n Data,\n> {\n [partialRouteDefinitionSymbol]: {\n id: Id;\n params: Params;\n state: State;\n data: Data;\n };\n path?: string;\n}\n\n/** Extract the Id type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteId<T> =\n T extends PartialRouteDefinition<\n infer Id,\n infer _Params,\n infer _State,\n infer _Data\n >\n ? Id\n : T extends TypefulOpaqueRouteDefinition<\n infer Id,\n infer _Params,\n infer _State,\n infer _Data\n >\n ? Id\n : never;\n\n/** Extract the Params type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteParams<T> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer Params,\n infer _State,\n infer _Data\n >\n ? Params\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer Params,\n infer _State,\n infer _Data\n >\n ? Params\n : never;\n\n/** Extract the State type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteState<T> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer _Params,\n infer State,\n infer _Data\n >\n ? State\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer _Params,\n infer State,\n infer _Data\n >\n ? State\n : never;\n\n/** Extract the Data type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteData<T> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer _Params,\n infer _State,\n infer Data\n >\n ? Data\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer _Params,\n infer _State,\n infer Data\n >\n ? Data\n : never;\n\n/** Extract the component props type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type RouteComponentPropsOf<\n T extends\n | TypefulOpaqueRouteDefinition<\n string,\n Record<string, string>,\n unknown,\n unknown\n >\n | PartialRouteDefinition<string, Record<string, string>, unknown, unknown>,\n> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer Params,\n infer State,\n infer Data\n >\n ? Data extends undefined\n ? RouteComponentProps<Params, State>\n : RouteComponentPropsWithData<Params, Data, State>\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer Params,\n infer State,\n infer Data\n >\n ? Data extends undefined\n ? RouteComponentProps<Params, State>\n : RouteComponentPropsWithData<Params, Data, State>\n : never;\n\n/**\n * Any route definition defined by user.\n */\nexport type RouteDefinition =\n | OpaqueRouteDefinition\n | TypefulOpaqueRouteDefinition<\n string,\n Record<string, string>,\n unknown,\n unknown\n >\n | {\n path?: string;\n component?: ComponentType<object> | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n };\n\n/**\n * Route definition with action and loader.\n * Action result flows to loader via actionResult parameter.\n */\ntype RouteWithActionAndLoader<\n TPath extends string,\n TActionResult,\n TData,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => TActionResult;\n loader: (\n args: LoaderArgs<PathParams<TPath>, Awaited<TActionResult>>,\n ) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<PathParams<TPath>, TData, TState>\n >\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Route definition with action only (no loader).\n * Action executes as a pure side effect.\n */\ntype RouteWithActionOnly<\n TPath extends string,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => unknown;\n component?:\n | ComponentType<RouteComponentProps<PathParams<TPath>, TState>>\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Route definition with loader - infers TData from loader return type.\n * TPath is used to infer params type from the path pattern.\n * TState is the type of navigation state for this route.\n * TId is the optional route identifier for type-safe route references.\n */\ntype RouteWithLoader<\n TPath extends string,\n TData,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n loader: (args: LoaderArgs<PathParams<TPath>>) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<PathParams<TPath>, TData, TState>\n >\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Route definition without loader.\n * TPath is used to infer params type from the path pattern.\n * TState is the type of navigation state for this route.\n * TId is the optional route identifier for type-safe route references.\n */\ntype RouteWithoutLoader<\n TPath extends string,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n component?:\n | ComponentType<RouteComponentProps<PathParams<TPath>, TState>>\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Pathless route definition with loader.\n * Pathless routes always match and don't consume any pathname.\n */\ntype PathlessRouteWithLoader<\n TData,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n loader: (args: LoaderArgs<Record<string, never>>) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<Record<string, never>, TData, TState>\n >\n | ReactNode;\n children?: RouteDefinition[];\n requireChildren?: boolean;\n};\n\n/**\n * Pathless route definition without loader.\n * Pathless routes always match and don't consume any pathname.\n */\ntype PathlessRouteWithoutLoader<\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n component?:\n | ComponentType<RouteComponentProps<Record<string, never>, TState>>\n | ReactNode;\n children?: RouteDefinition[];\n requireChildren?: boolean;\n};\n\n/**\n * Partial route definition with action and loader (no component).\n * Used for two-phase route definition.\n */\ntype PartialRouteWithActionAndLoader<\n TPath extends string,\n TActionResult,\n TData,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => TActionResult;\n loader: (\n args: LoaderArgs<PathParams<TPath>, Awaited<TActionResult>>,\n ) => TData;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial route definition with action only (no component, no loader).\n */\ntype PartialRouteWithActionOnly<\n TPath extends string,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => unknown;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial route definition with loader (no component).\n */\ntype PartialRouteWithLoader<\n TPath extends string,\n TData,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n loader: (args: LoaderArgs<PathParams<TPath>>) => TData;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial route definition without loader or component.\n */\ntype PartialRouteWithoutLoader<\n TPath extends string,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial pathless route definition with loader (no component).\n */\ntype PartialPathlessRouteWithLoader<\n TData,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n loader: (args: LoaderArgs<Record<string, never>>) => TData;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial pathless route definition without loader or component.\n */\ntype PartialPathlessRouteWithoutLoader<\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Helper function for creating type-safe route definitions.\n *\n * When a loader is provided, TypeScript infers the return type and ensures\n * the component accepts a `data` prop of that type. Components always receive\n * a `params` prop with types inferred from the path pattern.\n *\n * For routes with navigation state, use `routeState<TState>()({ ... })` instead.\n *\n * @example\n * ```typescript\n * // Route with async loader\n * route({\n * path: \"users/:userId\",\n * loader: async ({ params, signal }) => {\n * const res = await fetch(`/api/users/${params.userId}`, { signal });\n * return res.json() as Promise<User>;\n * },\n * component: UserDetail, // Must accept { data: Promise<User>, params: { userId: string }, state, setState, resetState }\n * });\n *\n * // Route without loader\n * route({\n * path: \"about\",\n * component: AboutPage, // Must accept { params: {}, state, setState, resetState }\n * });\n * ```\n */\n// Partial overload: id + action + loader (no component) → PartialRouteDefinition\nexport function route<\n TId extends string,\n const TPath extends string,\n TActionResult,\n TData,\n>(\n definition: PartialRouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n TId\n > & {\n id: TId;\n },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Partial overload: id + action only (no component) → PartialRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: PartialRouteWithActionOnly<TPath, TId> & { id: TId },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Partial overload: id + pathless + loader (no component) → PartialRouteDefinition\nexport function route<TId extends string, TData>(\n definition: PartialPathlessRouteWithLoader<TData, TId> & { id: TId },\n): PartialRouteDefinition<TId, Record<string, never>, undefined, TData>;\n// Partial overload: id + pathless + no loader (no component) → PartialRouteDefinition\nexport function route<TId extends string>(\n definition: PartialPathlessRouteWithoutLoader<TId> & { id: TId },\n): PartialRouteDefinition<TId, Record<string, never>, undefined, undefined>;\n// Partial overload: id + loader (no component) → PartialRouteDefinition\nexport function route<TId extends string, const TPath extends string, TData>(\n definition: PartialRouteWithLoader<TPath, TData, TId> & { id: TId },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Partial overload: id + no loader (no component) → PartialRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: PartialRouteWithoutLoader<TPath, TId> & { id: TId },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Overload with id + action + loader → TypefulOpaqueRouteDefinition\nexport function route<\n TId extends string,\n const TPath extends string,\n TActionResult,\n TData,\n>(\n definition: RouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n undefined,\n TId\n > & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Overload with id + action only → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: RouteWithActionOnly<TPath, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Overload with action + loader (no id)\nexport function route<const TPath extends string, TActionResult, TData>(\n definition: RouteWithActionAndLoader<TPath, TActionResult, TData, undefined>,\n): OpaqueRouteDefinition;\n// Overload with action only (no id)\nexport function route<const TPath extends string>(\n definition: RouteWithActionOnly<TPath, undefined>,\n): OpaqueRouteDefinition;\n// Pathless overload with id + loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, TData>(\n definition: PathlessRouteWithLoader<TData, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, Record<string, never>, undefined, TData>;\n// Pathless overload with id + no loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string>(\n definition: PathlessRouteWithoutLoader<undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<\n TId,\n Record<string, never>,\n undefined,\n undefined\n>;\n// Pathless overload with loader (no id)\nexport function route<TData>(\n definition: PathlessRouteWithLoader<TData, undefined>,\n): OpaqueRouteDefinition;\n// Pathless overload without loader (no id)\nexport function route(\n definition: PathlessRouteWithoutLoader<undefined>,\n): OpaqueRouteDefinition;\n// Overload with id + loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, const TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Overload with id + no loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: RouteWithoutLoader<TPath, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Overload with loader (no id)\nexport function route<const TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, undefined>,\n): OpaqueRouteDefinition;\n// Overload without loader (no id)\nexport function route<const TPath extends string>(\n definition: RouteWithoutLoader<TPath, undefined>,\n): OpaqueRouteDefinition;\n// Implementation\nexport function route(\n definition: object,\n):\n | OpaqueRouteDefinition\n | PartialRouteDefinition<string, Record<string, string>, unknown, unknown> {\n return definition as unknown as OpaqueRouteDefinition;\n}\n\n/**\n * Helper function for creating type-safe route definitions with navigation state.\n *\n * Use this curried function when your route component needs to manage navigation state.\n * The state is tied to the navigation history entry and persists across back/forward navigation.\n *\n * @example\n * ```typescript\n * // Route with navigation state\n * type MyState = { scrollPosition: number };\n * routeState<MyState>()({\n * path: \"users/:userId\",\n * component: UserPage, // Receives { params, state, setState, resetState }\n * });\n *\n * // Route with both loader and navigation state\n * type FilterState = { filter: string };\n * routeState<FilterState>()({\n * path: \"products\",\n * loader: async () => fetchProducts(),\n * component: ProductList, // Receives { data, params, state, setState, resetState }\n * });\n * ```\n */\nexport function routeState<TState>(): {\n // Partial overload: id + action + loader (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string, TActionResult, TData>(\n definition: PartialRouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n TId\n > & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Partial overload: id + action only (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string>(\n definition: PartialRouteWithActionOnly<TPath, TId> & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Partial overload: id + pathless + loader (no component) → PartialRouteDefinition\n <TId extends string, TData>(\n definition: PartialPathlessRouteWithLoader<TData, TId> & { id: TId },\n ): PartialRouteDefinition<TId, Record<string, never>, TState, TData>;\n // Partial overload: id + pathless + no loader (no component) → PartialRouteDefinition\n <TId extends string>(\n definition: PartialPathlessRouteWithoutLoader<TId> & { id: TId },\n ): PartialRouteDefinition<TId, Record<string, never>, TState, undefined>;\n // Partial overload: id + loader (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string, TData>(\n definition: PartialRouteWithLoader<TPath, TData, TId> & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Partial overload: id + no loader (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string>(\n definition: PartialRouteWithoutLoader<TPath, TId> & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Overload with id + action + loader → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string, TActionResult, TData>(\n definition: RouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n TState,\n TId\n > & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Overload with id + action only → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string>(\n definition: RouteWithActionOnly<TPath, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Overload with action + loader (no id)\n <TPath extends string, TActionResult, TData>(\n definition: RouteWithActionAndLoader<TPath, TActionResult, TData, TState>,\n ): OpaqueRouteDefinition;\n // Overload with action only (no id)\n <TPath extends string>(\n definition: RouteWithActionOnly<TPath, TState>,\n ): OpaqueRouteDefinition;\n // Pathless overload with id + loader → TypefulOpaqueRouteDefinition\n <TId extends string, TData>(\n definition: PathlessRouteWithLoader<TData, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, Record<string, never>, TState, TData>;\n // Pathless overload with id + no loader → TypefulOpaqueRouteDefinition\n <TId extends string>(\n definition: PathlessRouteWithoutLoader<TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<\n TId,\n Record<string, never>,\n TState,\n undefined\n >;\n // Pathless overload with loader (no id)\n <TData>(\n definition: PathlessRouteWithLoader<TData, TState>,\n ): OpaqueRouteDefinition;\n // Pathless overload without loader (no id)\n (definition: PathlessRouteWithoutLoader<TState>): OpaqueRouteDefinition;\n // Overload with id + loader → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Overload with id + no loader → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string>(\n definition: RouteWithoutLoader<TPath, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Overload with loader (no id)\n <TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, TState>,\n ): OpaqueRouteDefinition;\n // Overload without loader (no id)\n <TPath extends string>(\n definition: RouteWithoutLoader<TPath, TState>,\n ): OpaqueRouteDefinition;\n} {\n return ((definition: object) => {\n return definition as unknown as OpaqueRouteDefinition;\n }) as never;\n}\n","import type { ComponentType, ReactNode } from \"react\";\nimport type {\n OpaqueRouteDefinition,\n PartialRouteDefinition,\n RouteDefinition,\n TypefulOpaqueRouteDefinition,\n} from \"./route.js\";\n\ntype BindRouteOptions = {\n component: ComponentType<any> | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Binds a component (and optionally children) to a partial route definition,\n * producing a full route definition for use with `<Router />`.\n *\n * This is the Phase 2 of two-phase route definition for RSC:\n * - Phase 1: `route()` without component → `PartialRouteDefinition` (shared module)\n * - Phase 2: `bindRoute()` with component → full route definition (server module)\n *\n * @example\n * ```tsx\n * // Phase 1 (shared module)\n * export const userRoute = route({\n * id: \"user\",\n * path: \"/:userId\",\n * loader: fetchUser,\n * });\n *\n * // Phase 2 (server module)\n * const routes = [\n * bindRoute(userRoute, { component: <UserProfile /> }),\n * ];\n * ```\n */\nexport function bindRoute<\n TId extends string,\n TParams extends Record<string, string>,\n TState,\n TData,\n>(\n partialRoute: PartialRouteDefinition<TId, TParams, TState, TData>,\n binding: BindRouteOptions,\n): TypefulOpaqueRouteDefinition<TId, TParams, TState, TData>;\nexport function bindRoute(\n partialRoute: OpaqueRouteDefinition,\n binding: BindRouteOptions,\n): OpaqueRouteDefinition;\nexport function bindRoute(\n partialRoute: object,\n binding: BindRouteOptions,\n): object {\n return { ...partialRoute, ...binding };\n}\n"],"mappings":";AAynBA,SAAgB,MACd,YAG2E;AAC3E,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BT,SAAgB,aAuFd;AACA,UAAS,eAAuB;AAC9B,SAAO;;;;;;AC/rBX,SAAgB,UACd,cACA,SACQ;AACR,QAAO;EAAE,GAAG;EAAc,GAAG;EAAS"}
1
+ {"version":3,"file":"bindRoute-CQ2-ruTp.mjs","names":[],"sources":["../src/route.ts","../src/bindRoute.ts"],"sourcesContent":["import type { ComponentType, ReactNode } from \"react\";\n\nconst routeDefinitionSymbol = Symbol();\nconst partialRouteDefinitionSymbol = Symbol();\n\n/**\n * Extracts parameter names from a path pattern.\n * E.g., \"/users/:id/posts/:postId\" -> \"id\" | \"postId\"\n */\ntype ExtractParams<T extends string> =\n T extends `${string}:${infer Param}/${infer Rest}`\n ? Param | ExtractParams<`/${Rest}`>\n : T extends `${string}:${infer Param}`\n ? Param\n : never;\n\n/**\n * Creates a params object type from a path pattern.\n * E.g., \"/users/:id\" -> { id: string }\n */\nexport type PathParams<T extends string> = [ExtractParams<T>] extends [never]\n ? Record<string, never>\n : { [K in ExtractParams<T>]: string };\n\n/**\n * Arguments passed to action functions.\n * The request carries the POST method and FormData body.\n */\nexport type ActionArgs<Params extends Record<string, string>> = {\n /** Extracted path parameters */\n params: Params;\n /** Request object with method POST and FormData body */\n request: Request;\n /** AbortSignal for cancellation */\n signal: AbortSignal;\n};\n\n/**\n * Arguments passed to loader functions.\n */\nexport type LoaderArgs<\n Params extends Record<string, string>,\n ActionResult = undefined,\n> = {\n /** Extracted path parameters */\n params: Params;\n /** Request object with URL and headers */\n request: Request;\n /** AbortSignal for cancellation on navigation */\n signal: AbortSignal;\n /** Result from the action, if this load was triggered by a form submission */\n actionResult: ActionResult | undefined;\n};\n\n/**\n * Props for route components without loader.\n * Includes navigation state management props.\n */\nexport interface RouteComponentProps<\n TParams extends Record<string, string>,\n TState = undefined,\n> {\n /** Extracted path parameters */\n params: TParams;\n /** Current navigation state for this route (undefined on first visit) */\n state: TState | undefined;\n /** Update navigation state for this route asynchronously via replace navigation */\n setState: (\n state: TState | ((prev: TState | undefined) => TState),\n ) => Promise<void>;\n /** Update navigation state for this route synchronously via updateCurrentEntry */\n setStateSync: (\n state: TState | ((prev: TState | undefined) => TState),\n ) => void;\n /** Reset navigation state to undefined asynchronously via replace navigation */\n resetState: () => Promise<void>;\n /** Reset navigation state to undefined synchronously via updateCurrentEntry */\n resetStateSync: () => void;\n /** Ephemeral navigation info (only available during navigation, not persisted) */\n info: unknown;\n /** Whether a navigation transition is pending */\n isPending: boolean;\n}\n\n/**\n * Props for route components with loader.\n * Includes data from loader and navigation state management props.\n */\nexport interface RouteComponentPropsWithData<\n TParams extends Record<string, string>,\n TData,\n TState = undefined,\n> extends RouteComponentProps<TParams, TState> {\n /** Data returned from the loader */\n data: TData;\n}\n\n/**\n * Route definition created by the `route` helper function.\n */\nexport interface OpaqueRouteDefinition {\n [routeDefinitionSymbol]: unknown;\n path?: string;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n}\n\n/**\n * Type-carrying route definition created by the `route` helper function when an `id` is provided.\n * This type carries type information for params, state, and data, enabling type-safe hooks in the future.\n */\nexport interface TypefulOpaqueRouteDefinition<\n Id extends string,\n Params extends Record<string, string>,\n State,\n Data,\n> {\n [routeDefinitionSymbol]: {\n id: Id;\n params: Params;\n state: State;\n data: Data;\n };\n path?: string;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n}\n\n/**\n * Partial route definition created by the `route` helper function when `id` is provided but `component` is not.\n * Used for two-phase route definition in RSC: Phase 1 defines id, path, loader, action;\n * Phase 2 uses `bindRoute()` to attach the component.\n * This type carries type information for params, state, and data, enabling type-safe hooks.\n */\nexport interface PartialRouteDefinition<\n Id extends string,\n Params extends Record<string, string>,\n State,\n Data,\n> {\n [partialRouteDefinitionSymbol]: {\n id: Id;\n params: Params;\n state: State;\n data: Data;\n };\n path?: string;\n}\n\n/** Extract the Id type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteId<T> =\n T extends PartialRouteDefinition<\n infer Id,\n infer _Params,\n infer _State,\n infer _Data\n >\n ? Id\n : T extends TypefulOpaqueRouteDefinition<\n infer Id,\n infer _Params,\n infer _State,\n infer _Data\n >\n ? Id\n : never;\n\n/** Extract the Params type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteParams<T> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer Params,\n infer _State,\n infer _Data\n >\n ? Params\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer Params,\n infer _State,\n infer _Data\n >\n ? Params\n : never;\n\n/** Extract the State type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteState<T> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer _Params,\n infer State,\n infer _Data\n >\n ? State\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer _Params,\n infer State,\n infer _Data\n >\n ? State\n : never;\n\n/** Extract the Data type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type ExtractRouteData<T> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer _Params,\n infer _State,\n infer Data\n >\n ? Data\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer _Params,\n infer _State,\n infer Data\n >\n ? Data\n : never;\n\n/** Extract the component props type from a TypefulOpaqueRouteDefinition or PartialRouteDefinition */\nexport type RouteComponentPropsOf<\n T extends\n | TypefulOpaqueRouteDefinition<\n string,\n Record<string, string>,\n unknown,\n unknown\n >\n | PartialRouteDefinition<string, Record<string, string>, unknown, unknown>,\n> =\n T extends PartialRouteDefinition<\n infer _Id,\n infer Params,\n infer State,\n infer Data\n >\n ? Data extends undefined\n ? RouteComponentProps<Params, State>\n : RouteComponentPropsWithData<Params, Data, State>\n : T extends TypefulOpaqueRouteDefinition<\n infer _Id,\n infer Params,\n infer State,\n infer Data\n >\n ? Data extends undefined\n ? RouteComponentProps<Params, State>\n : RouteComponentPropsWithData<Params, Data, State>\n : never;\n\n/**\n * Any route definition defined by user.\n */\nexport type RouteDefinition =\n | OpaqueRouteDefinition\n | TypefulOpaqueRouteDefinition<\n string,\n Record<string, string>,\n unknown,\n unknown\n >\n | {\n path?: string;\n component?: ComponentType<object> | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n };\n\n/**\n * Route definition with action and loader.\n * Action result flows to loader via actionResult parameter.\n */\ntype RouteWithActionAndLoader<\n TPath extends string,\n TActionResult,\n TData,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => TActionResult;\n loader: (\n args: LoaderArgs<PathParams<TPath>, Awaited<TActionResult>>,\n ) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<PathParams<TPath>, TData, TState>\n >\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Route definition with action only (no loader).\n * Action executes as a pure side effect.\n */\ntype RouteWithActionOnly<\n TPath extends string,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => unknown;\n component?:\n | ComponentType<RouteComponentProps<PathParams<TPath>, TState>>\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Route definition with loader - infers TData from loader return type.\n * TPath is used to infer params type from the path pattern.\n * TState is the type of navigation state for this route.\n * TId is the optional route identifier for type-safe route references.\n */\ntype RouteWithLoader<\n TPath extends string,\n TData,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n loader: (args: LoaderArgs<PathParams<TPath>>) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<PathParams<TPath>, TData, TState>\n >\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Route definition without loader.\n * TPath is used to infer params type from the path pattern.\n * TState is the type of navigation state for this route.\n * TId is the optional route identifier for type-safe route references.\n */\ntype RouteWithoutLoader<\n TPath extends string,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n component?:\n | ComponentType<RouteComponentProps<PathParams<TPath>, TState>>\n | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Pathless route definition with loader.\n * Pathless routes always match and don't consume any pathname.\n */\ntype PathlessRouteWithLoader<\n TData,\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n loader: (args: LoaderArgs<Record<string, never>>) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<Record<string, never>, TData, TState>\n >\n | ReactNode;\n children?: RouteDefinition[];\n requireChildren?: boolean;\n};\n\n/**\n * Pathless route definition without loader.\n * Pathless routes always match and don't consume any pathname.\n */\ntype PathlessRouteWithoutLoader<\n TState,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n component?:\n | ComponentType<RouteComponentProps<Record<string, never>, TState>>\n | ReactNode;\n children?: RouteDefinition[];\n requireChildren?: boolean;\n};\n\n/**\n * Partial route definition with action and loader (no component).\n * Used for two-phase route definition.\n */\ntype PartialRouteWithActionAndLoader<\n TPath extends string,\n TActionResult,\n TData,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => TActionResult;\n loader: (\n args: LoaderArgs<PathParams<TPath>, Awaited<TActionResult>>,\n ) => TData;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial route definition with action only (no component, no loader).\n */\ntype PartialRouteWithActionOnly<\n TPath extends string,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n action: (args: ActionArgs<PathParams<TPath>>) => unknown;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial route definition with loader (no component).\n */\ntype PartialRouteWithLoader<\n TPath extends string,\n TData,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n loader: (args: LoaderArgs<PathParams<TPath>>) => TData;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial route definition without loader or component.\n */\ntype PartialRouteWithoutLoader<\n TPath extends string,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path: TPath;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial pathless route definition with loader (no component).\n */\ntype PartialPathlessRouteWithLoader<\n TData,\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n loader: (args: LoaderArgs<Record<string, never>>) => TData;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Partial pathless route definition without loader or component.\n */\ntype PartialPathlessRouteWithoutLoader<\n TId extends string | undefined = undefined,\n> = {\n id?: TId;\n path?: undefined;\n component?: never;\n children?: never;\n exact?: never;\n requireChildren?: never;\n};\n\n/**\n * Helper function for creating type-safe route definitions.\n *\n * When a loader is provided, TypeScript infers the return type and ensures\n * the component accepts a `data` prop of that type. Components always receive\n * a `params` prop with types inferred from the path pattern.\n *\n * For routes with navigation state, use `routeState<TState>()({ ... })` instead.\n *\n * @example\n * ```typescript\n * // Route with async loader\n * route({\n * path: \"users/:userId\",\n * loader: async ({ params, signal }) => {\n * const res = await fetch(`/api/users/${params.userId}`, { signal });\n * return res.json() as Promise<User>;\n * },\n * component: UserDetail, // Must accept { data: Promise<User>, params: { userId: string }, state, setState, resetState }\n * });\n *\n * // Route without loader\n * route({\n * path: \"about\",\n * component: AboutPage, // Must accept { params: {}, state, setState, resetState }\n * });\n * ```\n */\n// Partial overload: id + action + loader (no component) → PartialRouteDefinition\nexport function route<\n TId extends string,\n const TPath extends string,\n TActionResult,\n TData,\n>(\n definition: PartialRouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n TId\n > & {\n id: TId;\n },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Partial overload: id + action only (no component) → PartialRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: PartialRouteWithActionOnly<TPath, TId> & { id: TId },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Partial overload: id + pathless + loader (no component) → PartialRouteDefinition\nexport function route<TId extends string, TData>(\n definition: PartialPathlessRouteWithLoader<TData, TId> & { id: TId },\n): PartialRouteDefinition<TId, Record<string, never>, undefined, TData>;\n// Partial overload: id + pathless + no loader (no component) → PartialRouteDefinition\nexport function route<TId extends string>(\n definition: PartialPathlessRouteWithoutLoader<TId> & { id: TId },\n): PartialRouteDefinition<TId, Record<string, never>, undefined, undefined>;\n// Partial overload: id + loader (no component) → PartialRouteDefinition\nexport function route<TId extends string, const TPath extends string, TData>(\n definition: PartialRouteWithLoader<TPath, TData, TId> & { id: TId },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Partial overload: id + no loader (no component) → PartialRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: PartialRouteWithoutLoader<TPath, TId> & { id: TId },\n): PartialRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Overload with id + action + loader → TypefulOpaqueRouteDefinition\nexport function route<\n TId extends string,\n const TPath extends string,\n TActionResult,\n TData,\n>(\n definition: RouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n undefined,\n TId\n > & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Overload with id + action only → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: RouteWithActionOnly<TPath, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Overload with action + loader (no id)\nexport function route<const TPath extends string, TActionResult, TData>(\n definition: RouteWithActionAndLoader<TPath, TActionResult, TData, undefined>,\n): OpaqueRouteDefinition;\n// Overload with action only (no id)\nexport function route<const TPath extends string>(\n definition: RouteWithActionOnly<TPath, undefined>,\n): OpaqueRouteDefinition;\n// Pathless overload with id + loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, TData>(\n definition: PathlessRouteWithLoader<TData, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, Record<string, never>, undefined, TData>;\n// Pathless overload with id + no loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string>(\n definition: PathlessRouteWithoutLoader<undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<\n TId,\n Record<string, never>,\n undefined,\n undefined\n>;\n// Pathless overload with loader (no id)\nexport function route<TData>(\n definition: PathlessRouteWithLoader<TData, undefined>,\n): OpaqueRouteDefinition;\n// Pathless overload without loader (no id)\nexport function route(\n definition: PathlessRouteWithoutLoader<undefined>,\n): OpaqueRouteDefinition;\n// Overload with id + loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, const TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, TData>;\n// Overload with id + no loader → TypefulOpaqueRouteDefinition\nexport function route<TId extends string, const TPath extends string>(\n definition: RouteWithoutLoader<TPath, undefined, TId> & { id: TId },\n): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, undefined, undefined>;\n// Overload with loader (no id)\nexport function route<const TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, undefined>,\n): OpaqueRouteDefinition;\n// Overload without loader (no id)\nexport function route<const TPath extends string>(\n definition: RouteWithoutLoader<TPath, undefined>,\n): OpaqueRouteDefinition;\n// Implementation\nexport function route(\n definition: object,\n):\n | OpaqueRouteDefinition\n | PartialRouteDefinition<string, Record<string, string>, unknown, unknown> {\n return definition as unknown as OpaqueRouteDefinition;\n}\n\n/**\n * Helper function for creating type-safe route definitions with navigation state.\n *\n * Use this curried function when your route component needs to manage navigation state.\n * The state is tied to the navigation history entry and persists across back/forward navigation.\n *\n * @example\n * ```typescript\n * // Route with navigation state\n * type MyState = { scrollPosition: number };\n * routeState<MyState>()({\n * path: \"users/:userId\",\n * component: UserPage, // Receives { params, state, setState, resetState }\n * });\n *\n * // Route with both loader and navigation state\n * type FilterState = { filter: string };\n * routeState<FilterState>()({\n * path: \"products\",\n * loader: async () => fetchProducts(),\n * component: ProductList, // Receives { data, params, state, setState, resetState }\n * });\n * ```\n */\nexport function routeState<TState>(): {\n // Partial overload: id + action + loader (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string, TActionResult, TData>(\n definition: PartialRouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n TId\n > & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Partial overload: id + action only (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string>(\n definition: PartialRouteWithActionOnly<TPath, TId> & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Partial overload: id + pathless + loader (no component) → PartialRouteDefinition\n <TId extends string, TData>(\n definition: PartialPathlessRouteWithLoader<TData, TId> & { id: TId },\n ): PartialRouteDefinition<TId, Record<string, never>, TState, TData>;\n // Partial overload: id + pathless + no loader (no component) → PartialRouteDefinition\n <TId extends string>(\n definition: PartialPathlessRouteWithoutLoader<TId> & { id: TId },\n ): PartialRouteDefinition<TId, Record<string, never>, TState, undefined>;\n // Partial overload: id + loader (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string, TData>(\n definition: PartialRouteWithLoader<TPath, TData, TId> & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Partial overload: id + no loader (no component) → PartialRouteDefinition\n <TId extends string, TPath extends string>(\n definition: PartialRouteWithoutLoader<TPath, TId> & { id: TId },\n ): PartialRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Overload with id + action + loader → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string, TActionResult, TData>(\n definition: RouteWithActionAndLoader<\n TPath,\n TActionResult,\n TData,\n TState,\n TId\n > & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Overload with id + action only → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string>(\n definition: RouteWithActionOnly<TPath, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Overload with action + loader (no id)\n <TPath extends string, TActionResult, TData>(\n definition: RouteWithActionAndLoader<TPath, TActionResult, TData, TState>,\n ): OpaqueRouteDefinition;\n // Overload with action only (no id)\n <TPath extends string>(\n definition: RouteWithActionOnly<TPath, TState>,\n ): OpaqueRouteDefinition;\n // Pathless overload with id + loader → TypefulOpaqueRouteDefinition\n <TId extends string, TData>(\n definition: PathlessRouteWithLoader<TData, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, Record<string, never>, TState, TData>;\n // Pathless overload with id + no loader → TypefulOpaqueRouteDefinition\n <TId extends string>(\n definition: PathlessRouteWithoutLoader<TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<\n TId,\n Record<string, never>,\n TState,\n undefined\n >;\n // Pathless overload with loader (no id)\n <TData>(\n definition: PathlessRouteWithLoader<TData, TState>,\n ): OpaqueRouteDefinition;\n // Pathless overload without loader (no id)\n (definition: PathlessRouteWithoutLoader<TState>): OpaqueRouteDefinition;\n // Overload with id + loader → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, TData>;\n // Overload with id + no loader → TypefulOpaqueRouteDefinition\n <TId extends string, TPath extends string>(\n definition: RouteWithoutLoader<TPath, TState, TId> & { id: TId },\n ): TypefulOpaqueRouteDefinition<TId, PathParams<TPath>, TState, undefined>;\n // Overload with loader (no id)\n <TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, TState>,\n ): OpaqueRouteDefinition;\n // Overload without loader (no id)\n <TPath extends string>(\n definition: RouteWithoutLoader<TPath, TState>,\n ): OpaqueRouteDefinition;\n} {\n return ((definition: object) => {\n return definition as unknown as OpaqueRouteDefinition;\n }) as never;\n}\n","import type { ComponentType, ReactNode } from \"react\";\nimport type {\n OpaqueRouteDefinition,\n PartialRouteDefinition,\n RouteDefinition,\n TypefulOpaqueRouteDefinition,\n} from \"./route.js\";\n\ntype BindRouteOptions = {\n component: ComponentType<any> | ReactNode;\n children?: RouteDefinition[];\n exact?: boolean;\n requireChildren?: boolean;\n};\n\n/**\n * Binds a component (and optionally children) to a partial route definition,\n * producing a full route definition for use with `<Router />`.\n *\n * This is the Phase 2 of two-phase route definition for RSC:\n * - Phase 1: `route()` without component → `PartialRouteDefinition` (shared module)\n * - Phase 2: `bindRoute()` with component → full route definition (server module)\n *\n * @example\n * ```tsx\n * // Phase 1 (shared module)\n * export const userRoute = route({\n * id: \"user\",\n * path: \"/:userId\",\n * loader: fetchUser,\n * });\n *\n * // Phase 2 (server module)\n * const routes = [\n * bindRoute(userRoute, { component: <UserProfile /> }),\n * ];\n * ```\n */\nexport function bindRoute<\n TId extends string,\n TParams extends Record<string, string>,\n TState,\n TData,\n>(\n partialRoute: PartialRouteDefinition<TId, TParams, TState, TData>,\n binding: BindRouteOptions,\n): TypefulOpaqueRouteDefinition<TId, TParams, TState, TData>;\nexport function bindRoute(\n partialRoute: OpaqueRouteDefinition,\n binding: BindRouteOptions,\n): OpaqueRouteDefinition;\nexport function bindRoute(\n partialRoute: object,\n binding: BindRouteOptions,\n): object {\n return { ...partialRoute, ...binding };\n}\n"],"mappings":";AAynBA,SAAgB,MACd,YAG2E;AAC3E,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BT,SAAgB,aAuFd;AACA,UAAS,eAAuB;AAC9B,SAAO;;;;;AC/rBX,SAAgB,UACd,cACA,SACQ;AACR,QAAO;EAAE,GAAG;EAAc,GAAG;EAAS"}
@@ -446,4 +446,4 @@ declare function bindRoute<TId extends string, TParams extends Record<string, st
446
446
  declare function bindRoute(partialRoute: OpaqueRouteDefinition, binding: BindRouteOptions): OpaqueRouteDefinition;
447
447
  //#endregion
448
448
  export { routeState as _, ExtractRouteParams as a, OpaqueRouteDefinition as c, RouteComponentProps as d, RouteComponentPropsOf as f, route as g, TypefulOpaqueRouteDefinition as h, ExtractRouteId as i, PartialRouteDefinition as l, RouteDefinition as m, ActionArgs as n, ExtractRouteState as o, RouteComponentPropsWithData as p, ExtractRouteData as r, LoaderArgs as s, bindRoute as t, PathParams as u };
449
- //# sourceMappingURL=bindRoute-BtT4qPKI.d.mts.map
449
+ //# sourceMappingURL=bindRoute-DulMzi5X.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bindRoute-BtT4qPKI.d.mts","names":[],"sources":["../src/route.ts","../src/bindRoute.ts"],"mappings":"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"}
1
+ {"version":3,"file":"bindRoute-DulMzi5X.d.mts","names":[],"sources":["../src/route.ts","../src/bindRoute.ts"],"mappings":"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"}
@@ -21,7 +21,16 @@ function MyComponent() {
21
21
  console.log(location.pathname); // "/users/123"
22
22
  console.log(location.search); // "?tab=profile"
23
23
  console.log(location.hash); // "#section"
24
+ console.log(location.entryId); // NavigationHistoryEntry.id or null
25
+ console.log(location.entryKey); // NavigationHistoryEntry.key or null
24
26
  }`}</CodeBlock>
27
+ <p>
28
+ <code>entryId</code> and <code>entryKey</code> are <code>null</code>{" "}
29
+ when the Navigation API is unavailable. Do not render them directly in
30
+ DOM — they are not available during SSR and will cause a hydration
31
+ mismatch. Use them as a React <code>key</code> or in effects/callbacks
32
+ instead.
33
+ </p>
25
34
  </article>
26
35
 
27
36
  <article className="api-item">
@@ -335,7 +335,24 @@ routeState<{ tab: string }>()({
335
335
  pathname: string;
336
336
  search: string;
337
337
  hash: string;
338
+ entryId: string | null; // NavigationHistoryEntry.id
339
+ entryKey: string | null; // NavigationHistoryEntry.key
338
340
  }`}</CodeBlock>
341
+ <p>
342
+ <code>entryId</code> and <code>entryKey</code> expose the
343
+ corresponding properties from the Navigation API's{" "}
344
+ <code>NavigationHistoryEntry</code>. <code>entryId</code> is a unique
345
+ identifier for the entry — a new id is assigned when the entry is
346
+ replaced. <code>entryKey</code> represents the slot in the entry list
347
+ and is stable across replacements. Both are <code>null</code> when the
348
+ Navigation API is unavailable (e.g., in static fallback mode).
349
+ </p>
350
+ <p>
351
+ <strong>Warning:</strong> Do not render these values directly in DOM,
352
+ as they are not available during SSR and will cause a hydration
353
+ mismatch. They are best suited for use as a React <code>key</code> or
354
+ in effects/callbacks.
355
+ </p>
339
356
  </article>
340
357
 
341
358
  <article className="api-item">
@@ -0,0 +1,320 @@
1
+ import { CodeBlock } from "../components/CodeBlock.js";
2
+
3
+ export function LearnLoadersPage() {
4
+ return (
5
+ <div className="learn-content">
6
+ <h2>How Loaders Run</h2>
7
+
8
+ <p className="page-intro">
9
+ Loaders fetch data for a route before the UI renders. This page explains
10
+ when loaders execute, how results are cached, and how different types of
11
+ navigation affect loader behavior.
12
+ </p>
13
+
14
+ <section>
15
+ <h3>Defining a Loader</h3>
16
+ <p>
17
+ A loader is a function on a route definition that receives the route
18
+ params, a <code>Request</code>, and an <code>AbortSignal</code>. It
19
+ can return any value &mdash; typically a Promise from a fetch call:
20
+ </p>
21
+ <CodeBlock language="tsx">{`import { route } from "@funstack/router";
22
+
23
+ const userRoute = route({
24
+ path: "/users/:id",
25
+ loader: async ({ params, request, signal }) => {
26
+ const res = await fetch(\`/api/users/\${params.id}\`, { signal });
27
+ return res.json();
28
+ },
29
+ component: UserPage,
30
+ });`}</CodeBlock>
31
+ <p>
32
+ The component receives the loader&rsquo;s return value as the{" "}
33
+ <code>data</code> prop. For async loaders this is a{" "}
34
+ <code>Promise</code>, which you unwrap with React&rsquo;s{" "}
35
+ <code>use()</code> hook inside a <code>Suspense</code> boundary:
36
+ </p>
37
+ <CodeBlock language="tsx">{`import { use, Suspense } from "react";
38
+
39
+ function UserPage({ data }: { data: Promise<User> }) {
40
+ return (
41
+ <Suspense fallback={<p>Loading...</p>}>
42
+ <UserDetail data={data} />
43
+ </Suspense>
44
+ );
45
+ }
46
+
47
+ function UserDetail({ data }: { data: Promise<User> }) {
48
+ const user = use(data);
49
+ return <h1>{user.name}</h1>;
50
+ }`}</CodeBlock>
51
+ </section>
52
+
53
+ <section>
54
+ <h3>When Loaders Execute</h3>
55
+ <p>Loaders run at two points in the lifecycle:</p>
56
+ <ol>
57
+ <li>
58
+ <strong>Initial page load</strong> &mdash; When the Router first
59
+ renders, it matches the current URL against the route definitions
60
+ and executes all matching loaders immediately.
61
+ </li>
62
+ <li>
63
+ <strong>Navigation events</strong> &mdash; When the user navigates
64
+ (by clicking a link, submitting a form, or calling{" "}
65
+ <code>navigate()</code>), the Router matches the destination URL and
66
+ executes loaders for the matched routes.
67
+ </li>
68
+ </ol>
69
+ <p>
70
+ In both cases, all loaders in the matched route stack (parent and
71
+ child) run <strong>in parallel</strong>. The navigation completes once
72
+ every loader&rsquo;s Promise has resolved.
73
+ </p>
74
+ </section>
75
+
76
+ <section>
77
+ <h3>Caching by Navigation Entry</h3>
78
+ <p>
79
+ Loader results are cached using the{" "}
80
+ <strong>navigation entry ID</strong> from the Navigation API. Each
81
+ time you navigate to a new URL, the browser creates a new navigation
82
+ entry with a unique ID. The Router uses this ID as the cache key, so:
83
+ </p>
84
+ <ul>
85
+ <li>
86
+ Re-renders of the same page <strong>do not</strong> re-execute
87
+ loaders &mdash; the cached result is returned.
88
+ </li>
89
+ <li>
90
+ Navigating to a new URL always creates a new entry and{" "}
91
+ <strong>always</strong> executes loaders, even if the URL is the
92
+ same as a previous navigation.
93
+ </li>
94
+ </ul>
95
+ <p>
96
+ This design ensures that loaders run exactly once per navigation while
97
+ preventing unnecessary re-fetches during React re-renders.
98
+ </p>
99
+ </section>
100
+
101
+ <section>
102
+ <h3>Navigation Types and Loader Behavior</h3>
103
+ <p>
104
+ Different types of navigation have different effects on whether
105
+ loaders run:
106
+ </p>
107
+
108
+ <h4>Push and Replace</h4>
109
+ <p>
110
+ A <strong>push</strong> navigation (the default when clicking a link
111
+ or calling <code>navigate()</code>) creates a new navigation entry.
112
+ Since the entry is new, loaders always execute. A{" "}
113
+ <strong>replace</strong> navigation behaves the same way &mdash; it
114
+ creates a new entry that replaces the current one, so loaders execute
115
+ fresh.
116
+ </p>
117
+
118
+ <h4>Traverse (Back / Forward)</h4>
119
+ <p>
120
+ When the user goes back or forward in history, the browser revisits an{" "}
121
+ <strong>existing</strong> navigation entry. Because the entry ID is
122
+ the same as when the page was originally visited, the cached loader
123
+ results are returned <strong>without re-executing</strong> the
124
+ loaders. This makes back/forward navigation instant.
125
+ </p>
126
+
127
+ <h4>Reload</h4>
128
+ <p>
129
+ A reload navigation stays on the same navigation entry, but the Router
130
+ generates a <strong>fresh cache key</strong> so that all loaders{" "}
131
+ <strong>re-execute</strong>. This is useful when you want to refresh
132
+ data without navigating away from the current page.
133
+ </p>
134
+ <p>
135
+ You can trigger a reload programmatically using the Navigation
136
+ API&rsquo;s <code>navigation.reload()</code> method:
137
+ </p>
138
+ <CodeBlock language="tsx">{`function RefreshButton() {
139
+ return (
140
+ <button onClick={() => navigation.reload()}>
141
+ Refresh Data
142
+ </button>
143
+ );
144
+ }`}</CodeBlock>
145
+ <p>
146
+ During a reload, the old cached data remains available for the{" "}
147
+ <strong>pending UI</strong>. Because the Router wraps navigations in a
148
+ React transition, the previous UI stays on screen while the new data
149
+ loads. Once the new loaders resolve, the UI updates. This means users
150
+ see the existing content while the refresh is in progress, rather than
151
+ a blank screen or loading spinner.
152
+ </p>
153
+ <p>
154
+ Consecutive reloads work correctly &mdash; each reload increments an
155
+ internal counter to produce a unique cache key, and stale caches are
156
+ pruned automatically.
157
+ </p>
158
+
159
+ <h4>Form Submissions</h4>
160
+ <p>
161
+ When a <code>{'<form method="post">'}</code> is submitted, the Router
162
+ runs the matched route&rsquo;s <code>action</code> first, then clears
163
+ the loader cache for the current entry and re-executes all loaders.
164
+ The action&rsquo;s return value is passed to each loader as{" "}
165
+ <code>actionResult</code>. See the{" "}
166
+ <a href="/learn/actions">Form Actions</a> page for details.
167
+ </p>
168
+ </section>
169
+
170
+ <section>
171
+ <h3>Nested Route Loaders</h3>
172
+ <p>
173
+ When routes are nested, each route in the matched stack can define its
174
+ own loader. All loaders in the stack execute in parallel, and each
175
+ component receives its own loader&rsquo;s result:
176
+ </p>
177
+ <CodeBlock language="tsx">{`const routes = [
178
+ route({
179
+ path: "/dashboard",
180
+ loader: () => fetchDashboardLayout(),
181
+ component: DashboardLayout,
182
+ children: [
183
+ route({
184
+ path: "/stats",
185
+ loader: () => fetchStats(),
186
+ component: StatsPage,
187
+ }),
188
+ ],
189
+ }),
190
+ ];
191
+
192
+ // When navigating to /dashboard/stats:
193
+ // → fetchDashboardLayout() and fetchStats() run in parallel
194
+ // → DashboardLayout receives the layout data
195
+ // → StatsPage receives the stats data`}</CodeBlock>
196
+ <p>
197
+ On reload, <strong>all</strong> loaders in the matched stack
198
+ re-execute, not just the deepest one.
199
+ </p>
200
+ </section>
201
+
202
+ <section>
203
+ <h3>Cache Cleanup</h3>
204
+ <p>
205
+ Cached loader results are automatically cleaned up when a navigation
206
+ entry is <strong>disposed</strong>. The browser disposes entries when
207
+ they are removed from the history stack (for example, when the user
208
+ navigates forward from a point in the middle of the history stack, the
209
+ entries ahead are discarded). The Router listens for these dispose
210
+ events and removes the corresponding cached data.
211
+ </p>
212
+ </section>
213
+
214
+ <section>
215
+ <h3>Error Handling</h3>
216
+ <p>
217
+ When a loader throws an error, the router catches it and re-throws it
218
+ during rendering of that route&rsquo;s component. This means the error
219
+ can be caught by a React{" "}
220
+ <a href="https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary">
221
+ Error Boundary
222
+ </a>{" "}
223
+ placed above the route in the component tree. For async loaders that
224
+ return a rejected promise, the error is surfaced when{" "}
225
+ <code>use(data)</code> is called, which is also caught by Error
226
+ Boundaries.
227
+ </p>
228
+ <p>
229
+ The recommended pattern is to place an error boundary in your{" "}
230
+ <strong>root layout route</strong>, wrapping the{" "}
231
+ <code>{"<Outlet />"}</code>. This catches errors from any loader in
232
+ the route tree while keeping the root layout (header, navigation,
233
+ etc.) intact:
234
+ </p>
235
+ <CodeBlock language="tsx">{`import { Router, route, Outlet } from "@funstack/router";
236
+ import { ErrorBoundary } from "./ErrorBoundary";
237
+
238
+ function RootLayout() {
239
+ return (
240
+ <div>
241
+ <header>My App</header>
242
+ <ErrorBoundary fallback={<div>Something went wrong.</div>}>
243
+ <Outlet />
244
+ </ErrorBoundary>
245
+ </div>
246
+ );
247
+ }
248
+
249
+ const routes = [
250
+ route({
251
+ path: "/",
252
+ component: RootLayout,
253
+ children: [
254
+ route({
255
+ path: "/",
256
+ component: HomePage,
257
+ }),
258
+ route({
259
+ path: "/users/:id",
260
+ component: UserPage,
261
+ loader: async ({ params }) => {
262
+ const res = await fetch(\`/api/users/\${params.id}\`);
263
+ if (!res.ok) throw new Error("Failed to load user");
264
+ return res.json();
265
+ },
266
+ }),
267
+ ],
268
+ }),
269
+ ];`}</CodeBlock>
270
+ <p>
271
+ This works for both synchronous and asynchronous loaders. For sync
272
+ loaders, the router catches the error and re-throws it during route
273
+ rendering. For async loaders, the rejected promise naturally surfaces
274
+ through <code>use()</code>. Either way, Error Boundaries catch the
275
+ error.
276
+ </p>
277
+ <p>
278
+ You can also place error boundaries at more granular levels (e.g.,
279
+ wrapping a specific route&rsquo;s <code>{"<Outlet />"}</code> or{" "}
280
+ <code>{"<Suspense>"}</code> boundary) for fine-grained error handling.
281
+ </p>
282
+ </section>
283
+
284
+ <section>
285
+ <h3>Summary</h3>
286
+ <table className="summary-table">
287
+ <thead>
288
+ <tr>
289
+ <th>Navigation type</th>
290
+ <th>Loaders run?</th>
291
+ <th>Why</th>
292
+ </tr>
293
+ </thead>
294
+ <tbody>
295
+ <tr>
296
+ <td>Push / Replace</td>
297
+ <td>Yes</td>
298
+ <td>New navigation entry, no cache</td>
299
+ </tr>
300
+ <tr>
301
+ <td>Traverse (Back / Forward)</td>
302
+ <td>No</td>
303
+ <td>Existing entry, cached results returned</td>
304
+ </tr>
305
+ <tr>
306
+ <td>Reload</td>
307
+ <td>Yes</td>
308
+ <td>Fresh cache key generated</td>
309
+ </tr>
310
+ <tr>
311
+ <td>Form submission (POST)</td>
312
+ <td>Yes</td>
313
+ <td>Cache cleared after action runs</td>
314
+ </tr>
315
+ </tbody>
316
+ </table>
317
+ </section>
318
+ </div>
319
+ );
320
+ }
@@ -16,6 +16,7 @@
16
16
  ### Learn
17
17
 
18
18
  - [Form Actions](./LearnActionsPage.tsx) - FUNSTACK Router can intercept submissions and run an action function on the client before navigation occurs. This guide explains how actions work, when to use them, and important considerations for progressive enhancement.
19
+ - [How Loaders Run](./LearnLoadersPage.tsx) - Loaders fetch data for a route before the UI renders. This page explains when loaders execute, how results are cached, and how different types of navigation affect loader behavior.
19
20
  - [Navigation API](./LearnNavigationApiPage.tsx) - FUNSTACK Router is built on the Navigation API , a modern browser API that provides a unified way to handle navigation. This guide explains the key differences from the older History API and the benefits this brings to your application.
20
21
  - [Nested Routes](./LearnNestedRoutesPage.tsx) - Nested routes let you build complex page layouts where parts of the UI persist across navigation while other parts change. Think of a dashboard with a sidebar that stays in place while the main content area updates&mdash;that's nested routing in action.
21
22
  - [RSC with Route Features](./LearnRouteDefinitionsPage.tsx) - When using React Server Components as route components, you may also want route features like loaders, typed hooks ( useRouteParams, useRouteData), and navigation state. The challenge is that route definitions referencing server components cannot be imported from client modules. This guide shows how to split a route definition into a shared part (importable by client components for type safety) and a server part (where the component is attached), enabling full route features alongside RSC.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as routeState, a as ExtractRouteParams, c as OpaqueRouteDefinition, d as RouteComponentProps, f as RouteComponentPropsOf, g as route, h as TypefulOpaqueRouteDefinition, i as ExtractRouteId, l as PartialRouteDefinition, m as RouteDefinition, n as ActionArgs, o as ExtractRouteState, p as RouteComponentPropsWithData, r as ExtractRouteData, s as LoaderArgs, t as bindRoute, u as PathParams } from "./bindRoute-BtT4qPKI.mjs";
1
+ import { _ as routeState, a as ExtractRouteParams, c as OpaqueRouteDefinition, d as RouteComponentProps, f as RouteComponentPropsOf, g as route, h as TypefulOpaqueRouteDefinition, i as ExtractRouteId, l as PartialRouteDefinition, m as RouteDefinition, n as ActionArgs, o as ExtractRouteState, p as RouteComponentPropsWithData, r as ExtractRouteData, s as LoaderArgs, t as bindRoute, u as PathParams } from "./bindRoute-DulMzi5X.mjs";
2
2
  import { ComponentType, ReactNode } from "react";
3
3
 
4
4
  //#region src/types.d.ts
@@ -72,6 +72,26 @@ type Location = {
72
72
  pathname: string;
73
73
  search: string;
74
74
  hash: string;
75
+ /**
76
+ * NavigationHistoryEntry.id — unique identifier for this entry.
77
+ * A new id is assigned when the entry is replaced.
78
+ * Null when Navigation API is unavailable.
79
+ *
80
+ * **Warning:** Do not render this value directly in DOM, as it is not
81
+ * available during SSR and will cause a hydration mismatch. Use it as a
82
+ * React `key` or in effects/callbacks instead.
83
+ */
84
+ entryId: string | null;
85
+ /**
86
+ * NavigationHistoryEntry.key — represents the slot in the entry list.
87
+ * Stable across replacements.
88
+ * Null when Navigation API is unavailable.
89
+ *
90
+ * **Warning:** Do not render this value directly in DOM, as it is not
91
+ * available during SSR and will cause a hydration mismatch. Use it as a
92
+ * React `key` or in effects/callbacks instead.
93
+ */
94
+ entryKey: string | null;
75
95
  };
76
96
  /**
77
97
  * Callback invoked before navigation is intercepted.