@solidjs/router 1.0.0 → 2.0.0-next.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +606 -697
  2. package/dist/claims.d.ts +21 -0
  3. package/dist/claims.js +115 -0
  4. package/dist/data/action.d.ts +40 -11
  5. package/dist/data/action.js +307 -101
  6. package/dist/data/events.d.ts +8 -0
  7. package/dist/data/events.js +24 -23
  8. package/dist/data/index.d.ts +2 -4
  9. package/dist/data/index.js +2 -4
  10. package/dist/data/query.d.ts +1 -3
  11. package/dist/data/query.js +75 -32
  12. package/dist/data/serverForms.d.ts +1 -0
  13. package/dist/data/serverForms.js +5 -0
  14. package/dist/fs.d.ts +94 -0
  15. package/dist/fs.js +51 -0
  16. package/dist/index.d.ts +24 -3
  17. package/dist/index.js +1949 -1204
  18. package/dist/index.jsx +2 -2
  19. package/dist/lifecycle.d.ts +29 -4
  20. package/dist/lifecycle.js +40 -37
  21. package/dist/paths.d.ts +117 -0
  22. package/dist/paths.js +41 -0
  23. package/dist/routers/components.d.ts +12 -26
  24. package/dist/routers/components.jsx +68 -54
  25. package/dist/routers/factory.d.ts +121 -0
  26. package/dist/routers/factory.jsx +154 -0
  27. package/dist/routers/history.d.ts +26 -0
  28. package/dist/routers/history.js +180 -0
  29. package/dist/routers/index.d.ts +5 -11
  30. package/dist/routers/index.js +2 -6
  31. package/dist/routers/scrollRestoration.d.ts +10 -1
  32. package/dist/routers/scrollRestoration.js +49 -11
  33. package/dist/routing.d.ts +96 -52
  34. package/dist/routing.js +429 -172
  35. package/dist/server.d.ts +47 -0
  36. package/dist/server.js +156 -0
  37. package/dist/types.d.ts +158 -44
  38. package/dist/utils.d.ts +2 -0
  39. package/dist/utils.js +2 -0
  40. package/package.json +12 -7
  41. package/dist/components.d.ts +0 -31
  42. package/dist/components.jsx +0 -40
  43. package/dist/data/createAsync.d.ts +0 -32
  44. package/dist/data/createAsync.js +0 -96
  45. package/dist/data/response.d.ts +0 -4
  46. package/dist/data/response.js +0 -42
  47. package/dist/routers/HashRouter.d.ts +0 -9
  48. package/dist/routers/HashRouter.js +0 -41
  49. package/dist/routers/MemoryRouter.d.ts +0 -24
  50. package/dist/routers/MemoryRouter.js +0 -57
  51. package/dist/routers/Router.d.ts +0 -17
  52. package/dist/routers/Router.js +0 -59
  53. package/dist/routers/StaticRouter.d.ts +0 -6
  54. package/dist/routers/StaticRouter.js +0 -15
  55. package/dist/routers/createRouter.d.ts +0 -10
  56. package/dist/routers/createRouter.js +0 -41
package/dist/routing.d.ts CHANGED
@@ -1,11 +1,15 @@
1
- import { JSX, Accessor } from "solid-js";
2
- import type { BeforeLeaveEventArgs, Branch, Intent, Location, MatchFilters, NavigateOptions, Navigator, Params, RouteDescription, RouteContext, RouteDefinition, RouteMatch, RouterContext, RouterIntegration, SearchParams, SetSearchParams } from "./types.js";
1
+ import type { JSX } from "@solidjs/web";
2
+ import type { Branch, Intent, LazyBoundary, Location, MatchFilters, NavigateOptions, Navigator, Params, PathMatch, RouteDescription, RouteContext, RouteDefinition, RouteMatch, RouteParams, RouterContext, RouterIntegration, SearchParams, SetSearchParams, TypedPath, TypedSearchPath } from "./types.js";
3
+ import type { FlashSubmission } from "@solidjs/web/server-functions/server";
3
4
  /** Consider this API opaque and internal. It is likely to change in the future. */
4
- export declare const RouterContextObj: import("solid-js").Context<RouterContext | undefined>;
5
- export declare const RouteContextObj: import("solid-js").Context<RouteContext | undefined>;
5
+ export declare const RouterContextObj: import("solid-js").Context<RouterContext>;
6
+ export declare const RouteContextObj: import("solid-js").Context<RouteContext>;
7
+ export declare function useOptionalContext<T>(context: {
8
+ defaultValue?: T;
9
+ }): T | undefined;
6
10
  export declare const useRouter: () => RouterContext;
7
11
  export declare const useRoute: () => RouteContext;
8
- export declare const useResolvedPath: (path: () => string) => Accessor<string | undefined>;
12
+ export declare const useResolvedPath: (path: () => string) => import("solid-js").SourceAccessor<string | undefined>;
9
13
  export declare const useHref: <T extends string | undefined>(to: () => T) => () => string | T;
10
14
  /**
11
15
  * Retrieves method to do navigation. The method accepts a path to navigate to and an optional object with the following options:
@@ -39,8 +43,8 @@ export declare const useNavigate: () => Navigator;
39
43
  */
40
44
  export declare const useLocation: <S = unknown>() => Location<S>;
41
45
  /**
42
- * Retrieves signal that indicates whether the route is currently in a *Transition*.
43
- * Useful for showing stale/pending state when the route resolution is *Suspended* during concurrent rendering.
46
+ * Retrieves a signal that indicates whether the router is currently processing a navigation.
47
+ * Useful for showing pending navigation state while the next route and its data settle.
44
48
  *
45
49
  * @example
46
50
  * ```js
@@ -55,43 +59,55 @@ export declare const useLocation: <S = unknown>() => Location<S>;
55
59
  */
56
60
  export declare const useIsRouting: () => () => boolean;
57
61
  /**
58
- * usePreloadRoute returns a function that can be used to preload a route manual.
59
- * This is what happens automatically with link hovering and similar focus based behavior, but it is available here as an API.
62
+ * `useMatch` takes an accessor that returns the path and creates a `Memo` that returns match information if the current path matches the provided path.
63
+ * Useful for determining if a given path matches the current route.
64
+ *
65
+ * Accepts a pattern string — the match's `params` are typed from it — or a
66
+ * typed path node (a concrete URL, so no params to speak of):
60
67
  *
61
68
  * @example
62
69
  * ```js
63
- * const preload = usePreloadRoute();
70
+ * const match = useMatch(() => props.href);
71
+ *
72
+ * return <div classList={{ active: Boolean(match()) }} />;
64
73
  *
65
- * preload(`/users/settings`, { preloadData: true });
74
+ * const section = useMatch(() => "/docs/:page");
75
+ * section()?.params.page; // string
76
+ *
77
+ * const here = useMatch(() => paths.users(2));
66
78
  * ```
67
79
  */
68
- export declare const usePreloadRoute: () => (url: string | URL, options?: {
69
- preloadData?: boolean;
70
- }) => void;
80
+ export declare const useMatch: <S extends string | TypedPath>(path: () => S, matchFilters?: MatchFilters<S extends string ? S : string>) => (() => PathMatch<S extends string ? RouteParams<S> : Params> | undefined);
71
81
  /**
72
- * `useMatch` takes an accessor that returns the path and creates a `Memo` that returns match information if the current path matches the provided path.
73
- * Useful for determining if a given path matches the current route.
82
+ * `useRouteMatches` returns an accessor of the router's resolved matches for
83
+ * the current location — the chain of route definitions producing the current
84
+ * render, outermost first. Useful for reading `info` metadata off the matched
85
+ * chain. Unlike `useMatch`, which tests a path pattern you supply against the
86
+ * location, this reflects the route tree itself.
74
87
  *
75
88
  * @example
76
89
  * ```js
77
- * const match = useMatch(() => props.href);
90
+ * const matches = useRouteMatches();
78
91
  *
79
- * return <div classList={{ active: Boolean(match()) }} />;
92
+ * const breadcrumbs = createMemo(() => matches().map(m => m.route.info.breadcrumb));
80
93
  * ```
81
94
  */
82
- export declare const useMatch: <S extends string>(path: () => S, matchFilters?: MatchFilters<S>) => Accessor<import("./types.js").PathMatch | undefined>;
95
+ export declare const useRouteMatches: () => () => RouteMatch[];
83
96
  /**
84
- * `useCurrentMatches` returns all the matches for the current matched route.
85
- * Useful for getting all the route information.
97
+ * `usePreloadRoute` returns a function for warming a route by hand — the same
98
+ * work link hover/focus intent triggers automatically: the matched routes'
99
+ * lazy components load, and with `preloadData` their `preload` functions run.
86
100
  *
87
101
  * @example
88
102
  * ```js
89
- * const matches = useCurrentMatches();
103
+ * const preload = usePreloadRoute();
90
104
  *
91
- * const breadcrumbs = createMemo(() => matches().map(m => m.route.info.breadcrumb))
105
+ * preload(paths.users(2).settings, { preloadData: true });
92
106
  * ```
93
107
  */
94
- export declare const useCurrentMatches: () => () => RouteMatch[];
108
+ export declare const usePreloadRoute: () => (url: string | URL | TypedPath, options?: {
109
+ preloadData?: boolean;
110
+ }) => void;
95
111
  /**
96
112
  * Retrieves a reactive, store-like object containing the current route path parameters as defined in the Route.
97
113
  *
@@ -100,10 +116,13 @@ export declare const useCurrentMatches: () => () => RouteMatch[];
100
116
  * const params = useParams();
101
117
  *
102
118
  * // fetch user based on the id path parameter
103
- * const [user] = createResource(() => params.id, fetchUser);
119
+ * const getUser = query(() => fetchUser(params.id), "user");
104
120
  * ```
105
121
  */
106
- export declare const useParams: <T extends Params>() => T;
122
+ export declare function useParams<T extends Params>(): T;
123
+ export declare function useParams<P extends Params>(path: TypedPath<P>): {
124
+ [K in keyof P]: P[K];
125
+ };
107
126
  /**
108
127
  * Retrieves a tuple containing a reactive object to read the current location's query parameters and a method to update them.
109
128
  * The object is a proxy so you must access properties to subscribe to reactive updates.
@@ -131,39 +150,64 @@ export declare const useParams: <T extends Params>() => T;
131
150
  * );
132
151
  * ```
133
152
  */
134
- export declare const useSearchParams: <T extends SearchParams>() => [Partial<T>, (params: SetSearchParams, options?: Partial<NavigateOptions>) => void];
153
+ export declare function useSearchParams<In, Out>(path: TypedSearchPath<In, Out>): [Out, (params: Partial<In>, options?: Partial<NavigateOptions>) => void];
154
+ export declare function useSearchParams<T extends SearchParams>(): [
155
+ Partial<T>,
156
+ (params: SetSearchParams, options?: Partial<NavigateOptions>) => void
157
+ ];
158
+ export interface LinkState {
159
+ /** The location matches this link or lives under it (exact-only when `end`). Styling: `data-active`. */
160
+ active: () => boolean;
161
+ /** The location matches this link exactly — what `aria-current="page"` reflects. */
162
+ current: () => boolean;
163
+ /** This link is the target of an in-flight navigation. Styling: `data-pending`. */
164
+ pending: () => boolean;
165
+ }
135
166
  /**
136
- * useBeforeLeave takes a function that will be called prior to leaving a route.
137
- * The function will be called with:
138
- *
139
- * - from (*Location*): current location (before change).
140
- * - to (*string | number*): path passed to `navigate`.
141
- * - options (*NavigateOptions*): options passed to navigate.
142
- * - preventDefault (*function*): call to block the route change.
143
- * - defaultPrevented (*readonly boolean*): `true` if any previously called leave handlers called `preventDefault`.
144
- * - retry (*function*, force?: boolean ): call to retry the same navigation, perhaps after confirming with the user. Pass `true` to skip running the leave handlers again (i.e. force navigate without confirming).
167
+ * Reactive link state for custom link components — the programmatic
168
+ * counterpart of the attribute vocabulary plain anchors receive
169
+ * (`aria-current`, `data-active`, `data-pending`).
145
170
  *
146
171
  * @example
147
- * ```js
148
- * useBeforeLeave((e: BeforeLeaveEventArgs) => {
149
- * if (form.isDirty && !e.defaultPrevented) {
150
- * // preventDefault to block immediately and prompt user async
151
- * e.preventDefault();
152
- * setTimeout(() => {
153
- * if (window.confirm("Discard unsaved changes - are you sure?")) {
154
- * // user wants to proceed anyway so retry with force=true
155
- * e.retry(true);
156
- * }
157
- * }, 100);
158
- * }
159
- * });
172
+ * ```tsx
173
+ * function TabLink(props: { href: string; children: JSX.Element }) {
174
+ * const link = useLinkState(() => props.href);
175
+ * return (
176
+ * <a href={props.href} class="tab" data-selected={link.active() || undefined}>
177
+ * {props.children}
178
+ * </a>
179
+ * );
180
+ * }
160
181
  * ```
161
182
  */
162
- export declare const useBeforeLeave: (listener: (e: BeforeLeaveEventArgs) => void) => void;
183
+ export declare const useLinkState: (href: () => string | TypedPath, options?: {
184
+ end?: boolean;
185
+ }) => LinkState;
186
+ /** Reactive read of the lazy-subtree version — recompile compiled branches when it changes. */
187
+ export declare function trackLazySubtrees(): number;
188
+ /** Non-reactive read, for cache-busting outside the reactive graph (server collectors). */
189
+ export declare function peekLazySubtrees(): number;
190
+ /**
191
+ * Kicks (or joins) a boundary's resolution. Returns the resolved routes
192
+ * synchronously once available, the in-flight promise otherwise. Commit is
193
+ * always async — even for thunks returning arrays — so the version bump
194
+ * never writes a signal from inside a render computation.
195
+ */
196
+ export declare function resolveLazySubtree(record: LazyBoundary): readonly RouteDefinition[] | Promise<readonly RouteDefinition[]>;
197
+ /**
198
+ * The unresolved boundaries in a match chain. Rendering gates on these (the
199
+ * route-states memo suspends until they land — see routers/components.tsx)
200
+ * and the server's flight collector awaits them before its preload pass.
201
+ */
202
+ export declare function unresolvedLazyMatches(matches: RouteMatch[]): LazyBoundary[];
163
203
  export declare function createRoutes(routeDef: RouteDefinition, base?: string): RouteDescription[];
164
204
  export declare function createBranch(routes: RouteDescription[], index?: number): Branch;
165
- export declare function createBranches(routeDef: RouteDefinition | RouteDefinition[], base?: string, stack?: RouteDescription[], branches?: Branch[]): Branch[];
205
+ export declare function createBranches(routeDef: RouteDefinition | readonly RouteDefinition[], base?: string, stack?: RouteDescription[], branches?: Branch[]): Branch[];
166
206
  export declare function getRouteMatches(branches: Branch[], location: string): RouteMatch[];
207
+ export declare function mergeParams(matches: RouteMatch[]): Params;
208
+ export declare function registerFlightRouter(router: RouterContext): () => void;
209
+ export declare function provideFlightConsumer(factory: (router: RouterContext) => () => void): void;
210
+ export declare function provideFlashDecoder(decoder: (cookieHeader: string | null) => FlashSubmission | undefined): void;
167
211
  export declare function getIntent(): Intent | undefined;
168
212
  export declare function getInPreloadFn(): boolean;
169
213
  export declare function setInPreloadFn(value: boolean): void;
@@ -172,4 +216,4 @@ export declare function createRouterContext(integration: RouterIntegration, bran
172
216
  singleFlight?: boolean;
173
217
  transformUrl?: (url: string) => string;
174
218
  }): RouterContext;
175
- export declare function createRouteContext(router: RouterContext, parent: RouteContext, outlet: () => JSX.Element, match: () => RouteMatch): RouteContext;
219
+ export declare function createRouteContext(router: RouterContext, parent: RouteContext, outlet: () => JSX.Element, match: () => RouteMatch, matches?: () => RouteMatch[]): RouteContext;