@funstack/router 0.0.3-alpha.1 → 0.0.4

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.
@@ -1,149 +0,0 @@
1
- import { ComponentType, ReactNode } from "react";
2
-
3
- //#region src/route.d.ts
4
- declare const routeDefinitionSymbol: unique symbol;
5
- /**
6
- * Extracts parameter names from a path pattern.
7
- * E.g., "/users/:id/posts/:postId" -> "id" | "postId"
8
- */
9
- type ExtractParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractParams<`/${Rest}`> : T extends `${string}:${infer Param}` ? Param : never;
10
- /**
11
- * Creates a params object type from a path pattern.
12
- * E.g., "/users/:id" -> { id: string }
13
- */
14
- type PathParams<T extends string> = [ExtractParams<T>] extends [never] ? Record<string, never> : { [K in ExtractParams<T>]: string };
15
- /**
16
- * Arguments passed to loader functions.
17
- */
18
- type LoaderArgs = {
19
- /** Extracted path parameters */
20
- params: Record<string, string>;
21
- /** Request object with URL and headers */
22
- request: Request;
23
- /** AbortSignal for cancellation on navigation */
24
- signal: AbortSignal;
25
- };
26
- /**
27
- * Props for route components without loader.
28
- * Includes navigation state management props.
29
- */
30
- type RouteComponentProps<TParams extends Record<string, string>, TState = undefined> = {
31
- /** Extracted path parameters */
32
- params: TParams;
33
- /** Current navigation state for this route (undefined on first visit) */
34
- state: TState | undefined;
35
- /** Update navigation state for this route asynchronously via replace navigation */
36
- setState: (state: TState | ((prev: TState | undefined) => TState)) => Promise<void>;
37
- /** Update navigation state for this route synchronously via updateCurrentEntry */
38
- setStateSync: (state: TState | ((prev: TState | undefined) => TState)) => void;
39
- /** Reset navigation state to undefined */
40
- resetState: () => void;
41
- /** Ephemeral navigation info (only available during navigation, not persisted) */
42
- info: unknown;
43
- };
44
- /**
45
- * Props for route components with loader.
46
- * Includes data from loader and navigation state management props.
47
- */
48
- type RouteComponentPropsWithData<TParams extends Record<string, string>, TData, TState = undefined> = RouteComponentProps<TParams, TState> & {
49
- /** Data returned from the loader */
50
- data: TData;
51
- };
52
- /**
53
- * Route definition created by the `route` helper function.
54
- */
55
- interface OpaqueRouteDefinition {
56
- [routeDefinitionSymbol]: never;
57
- path: string;
58
- children?: RouteDefinition[];
59
- }
60
- /**
61
- * Any route definition defined by user.
62
- */
63
- type RouteDefinition = OpaqueRouteDefinition | {
64
- path: string;
65
- component?: ComponentType<object> | ReactNode;
66
- children?: RouteDefinition[];
67
- };
68
- /**
69
- * Route definition with loader - infers TData from loader return type.
70
- * TPath is used to infer params type from the path pattern.
71
- * TState is the type of navigation state for this route.
72
- */
73
- type RouteWithLoader<TPath extends string, TData, TState> = {
74
- path: TPath;
75
- loader: (args: LoaderArgs) => TData;
76
- component: ComponentType<RouteComponentPropsWithData<PathParams<TPath>, TData, TState>> | ReactNode;
77
- children?: RouteDefinition[];
78
- };
79
- /**
80
- * Route definition without loader.
81
- * TPath is used to infer params type from the path pattern.
82
- * TState is the type of navigation state for this route.
83
- */
84
- type RouteWithoutLoader<TPath extends string, TState> = {
85
- path: TPath;
86
- component?: ComponentType<RouteComponentProps<PathParams<TPath>, TState>> | ReactNode;
87
- children?: RouteDefinition[];
88
- };
89
- /**
90
- * Helper function for creating type-safe route definitions.
91
- *
92
- * When a loader is provided, TypeScript infers the return type and ensures
93
- * the component accepts a `data` prop of that type. Components always receive
94
- * a `params` prop with types inferred from the path pattern.
95
- *
96
- * For routes with navigation state, use `routeState<TState>()({ ... })` instead.
97
- *
98
- * @example
99
- * ```typescript
100
- * // Route with async loader
101
- * route({
102
- * path: "users/:userId",
103
- * loader: async ({ params, signal }) => {
104
- * const res = await fetch(`/api/users/${params.userId}`, { signal });
105
- * return res.json() as Promise<User>;
106
- * },
107
- * component: UserDetail, // Must accept { data: Promise<User>, params: { userId: string }, state, setState, resetState }
108
- * });
109
- *
110
- * // Route without loader
111
- * route({
112
- * path: "about",
113
- * component: AboutPage, // Must accept { params: {}, state, setState, resetState }
114
- * });
115
- * ```
116
- */
117
- declare function route<TPath extends string, TData>(definition: RouteWithLoader<TPath, TData, undefined>): OpaqueRouteDefinition;
118
- declare function route<TPath extends string>(definition: RouteWithoutLoader<TPath, undefined>): OpaqueRouteDefinition;
119
- /**
120
- * Helper function for creating type-safe route definitions with navigation state.
121
- *
122
- * Use this curried function when your route component needs to manage navigation state.
123
- * The state is tied to the navigation history entry and persists across back/forward navigation.
124
- *
125
- * @example
126
- * ```typescript
127
- * // Route with navigation state
128
- * type MyState = { scrollPosition: number };
129
- * routeState<MyState>()({
130
- * path: "users/:userId",
131
- * component: UserPage, // Receives { params, state, setState, resetState }
132
- * });
133
- *
134
- * // Route with both loader and navigation state
135
- * type FilterState = { filter: string };
136
- * routeState<FilterState>()({
137
- * path: "products",
138
- * loader: async () => fetchProducts(),
139
- * component: ProductList, // Receives { data, params, state, setState, resetState }
140
- * });
141
- * ```
142
- */
143
- declare function routeState<TState>(): {
144
- <TPath extends string, TData>(definition: RouteWithLoader<TPath, TData, TState>): OpaqueRouteDefinition;
145
- <TPath extends string>(definition: RouteWithoutLoader<TPath, TState>): OpaqueRouteDefinition;
146
- };
147
- //#endregion
148
- export { RouteDefinition as a, RouteComponentPropsWithData as i, PathParams as n, route as o, RouteComponentProps as r, routeState as s, LoaderArgs as t };
149
- //# sourceMappingURL=route-BXVQqSlR.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"route-BXVQqSlR.d.mts","names":[],"sources":["../src/route.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"route-DiO6FM2A.mjs","names":[],"sources":["../src/route.ts"],"sourcesContent":["import type { ComponentType, ReactNode } from \"react\";\n\nconst routeDefinitionSymbol = 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 loader functions.\n */\nexport type LoaderArgs = {\n /** Extracted path parameters */\n params: Record<string, string>;\n /** Request object with URL and headers */\n request: Request;\n /** AbortSignal for cancellation on navigation */\n signal: AbortSignal;\n};\n\n/**\n * Props for route components without loader.\n * Includes navigation state management props.\n */\nexport type 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 */\n resetState: () => void;\n /** Ephemeral navigation info (only available during navigation, not persisted) */\n info: unknown;\n};\n\n/**\n * Props for route components with loader.\n * Includes data from loader and navigation state management props.\n */\nexport type RouteComponentPropsWithData<\n TParams extends Record<string, string>,\n TData,\n TState = undefined,\n> = 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]: never;\n path: string;\n children?: RouteDefinition[];\n}\n\n/**\n * Any route definition defined by user.\n */\nexport type RouteDefinition =\n | OpaqueRouteDefinition\n | {\n path: string;\n component?: ComponentType<object> | ReactNode;\n children?: RouteDefinition[];\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 */\ntype RouteWithLoader<TPath extends string, TData, TState> = {\n path: TPath;\n loader: (args: LoaderArgs) => TData;\n component:\n | ComponentType<\n RouteComponentPropsWithData<PathParams<TPath>, TData, TState>\n >\n | ReactNode;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children?: RouteDefinition[];\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 */\ntype RouteWithoutLoader<TPath extends string, TState> = {\n path: TPath;\n component?:\n | ComponentType<RouteComponentProps<PathParams<TPath>, TState>>\n | ReactNode;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children?: RouteDefinition[];\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// Overload with loader\nexport function route<TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, undefined>,\n): OpaqueRouteDefinition;\n// Overload without loader\nexport function route<TPath extends string>(\n definition: RouteWithoutLoader<TPath, undefined>,\n): OpaqueRouteDefinition;\n// Implementation\nexport function route<TPath extends string, TData>(\n definition:\n | RouteWithLoader<TPath, TData, undefined>\n | RouteWithoutLoader<TPath, undefined>,\n): OpaqueRouteDefinition {\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 <TPath extends string, TData>(\n definition: RouteWithLoader<TPath, TData, TState>,\n ): OpaqueRouteDefinition;\n <TPath extends string>(\n definition: RouteWithoutLoader<TPath, TState>,\n ): OpaqueRouteDefinition;\n} {\n return function <TPath extends string, TData>(\n definition:\n | RouteWithLoader<TPath, TData, TState>\n | RouteWithoutLoader<TPath, TState>,\n ): OpaqueRouteDefinition {\n return definition as unknown as OpaqueRouteDefinition;\n };\n}\n"],"mappings":";AAkKA,SAAgB,MACd,YAGuB;AACvB,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BT,SAAgB,aAOd;AACA,QAAO,SACL,YAGuB;AACvB,SAAO"}