@solidjs/router 0.10.4 → 0.10.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,7 +102,35 @@ render(() => (
102
102
  ), document.getElementById("app"));
103
103
  ```
104
104
 
105
- 3. Lazy-load route components
105
+ 3. Create a CatchAll Route (404 page)
106
+
107
+ We can create catchall routes for pages not found at any nested level of the router. We use `*` and optionally the name of a parameter to retrieve the rest of the path.
108
+
109
+ ```jsx
110
+ import { render } from "solid-js/web";
111
+ import { Router, Route } from "@solidjs/router";
112
+
113
+ import Home from "./pages/Home";
114
+ import Users from "./pages/Users";
115
+ import NotFound from "./pages/404";
116
+
117
+ const App = props => (
118
+ <>
119
+ <h1>My Site with lots of pages</h1>
120
+ {props.children}
121
+ </>
122
+ )
123
+
124
+ render(() => (
125
+ <Router root={App}>
126
+ <Route path="/users" component={Users} />
127
+ <Route path="/" component={Home} />
128
+ <Route path="*404" component={NotFound} />
129
+ </Router>
130
+ ), document.getElementById("app"));
131
+ ```
132
+
133
+ 4. Lazy-load route components
106
134
 
107
135
  This way, the `Users` and `Home` components will only be loaded if you're navigating to `/users` or `/`, respectively.
108
136
 
@@ -581,7 +609,7 @@ const updateTodo = action(async (todo: Todo) => {
581
609
 
582
610
  ## Config Based Routing
583
611
 
584
- You don't have to use JSX to set up your routes; you can pass an object:
612
+ You don't have to use JSX to set up your routes; you can pass an array of route definitions:
585
613
 
586
614
  ```jsx
587
615
  import { lazy } from "solid-js";
@@ -627,6 +655,21 @@ render(() =>
627
655
  );
628
656
  ```
629
657
 
658
+ Also you can pass a single route definition object for a single route:
659
+
660
+ ```jsx
661
+ import { lazy } from "solid-js";
662
+ import { render } from "solid-js/web";
663
+ import { Router } from "@solidjs/router";
664
+
665
+ const route = {
666
+ path: "/",
667
+ component: lazy(() => import("/pages/index.js"))
668
+ };
669
+
670
+ render(() => <Router>{route}</Router>, document.getElementById("app"));
671
+ ```
672
+
630
673
  ## Alternative Routers
631
674
 
632
675
  ### Hash Mode Router
@@ -669,7 +712,7 @@ This is the main Router component for the browser.
669
712
 
670
713
  | prop | type | description |
671
714
  |-----|----|----|
672
- | children | `JSX.Element` or `RouteDefinition[]` | The route definitions |
715
+ | children | `JSX.Element`, `RouteDefinition`, or `RouteDefinition[]` | The route definitions |
673
716
  | root | Component | Top level layout component |
674
717
  | base | string | Base url to use for matching routes |
675
718
  | actionBase | string | Root url for server actions, default: `/_server` |
@@ -846,7 +889,9 @@ The biggest changes are around removed APIs that need to be replaced.
846
889
 
847
890
  ### `<Outlet>`, `<Routes>`, `useRoutes`
848
891
 
849
- This is no longer used and instead will use `props.children` passed from into the page components for outlets. This keeps the outlet directly passed from its page and avoids oddness of trying to use context across Islands boundaries. Nested `<Routes>` components inherently cause waterfalls and are `<Outlets>` themselves so they have the same concerns. We do not want to encourage the pattern and if you must do it you can always nest `<Router>`s with appropriate base path.
892
+ This is no longer used and instead will use `props.children` passed from into the page components for outlets. This keeps the outlet directly passed from its page and avoids oddness of trying to use context across Islands boundaries. Nested `<Routes>` components inherently cause waterfalls and are `<Outlets>` themselves so they have the same concerns.
893
+
894
+ Keep in mind no `<Routes>` means the `<Router>` API is different. The `<Router>` acts as the `<Routes>` component and its children can only be `<Route>` components. Your top-level layout should go in the root prop of the router [as shown above](#configure-your-routes)
850
895
 
851
896
  ## `element` prop removed from `Route`
852
897
 
@@ -10,6 +10,7 @@ export type CachedFunction<T extends (...args: any) => U | Response, U> = T & {
10
10
  export declare function cache<T extends (...args: any) => U | Response, U>(fn: T, name: string, options?: ReconcileOptions): CachedFunction<T, U>;
11
11
  export declare namespace cache {
12
12
  var set: (key: string, value: any) => void;
13
+ var clear: () => any;
13
14
  }
14
15
  export declare function hashKey<T extends Array<any>>(args: T): string;
15
16
  export {};
@@ -70,12 +70,12 @@ export function cache(fn, name, options) {
70
70
  cached[0] = now;
71
71
  }
72
72
  let res = cached[1];
73
- if (!isServer && intent === "navigate") {
73
+ if (!isServer && intent !== "preload") {
74
74
  res =
75
75
  "then" in cached[1]
76
76
  ? cached[1].then(handleResponse(false), handleResponse(true))
77
77
  : handleResponse(false)(cached[1]);
78
- startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
78
+ intent === "navigate" && startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
79
79
  }
80
80
  return res;
81
81
  }
@@ -156,6 +156,7 @@ cache.set = (key, value) => {
156
156
  else
157
157
  cache.set(key, (cached = [now, value, , new Set(version ? [version] : [])]));
158
158
  };
159
+ cache.clear = () => getCache().clear();
159
160
  function matchKey(key, keys) {
160
161
  for (let k of keys) {
161
162
  if (key.startsWith(k))
@@ -1,4 +1,4 @@
1
1
  export { createAsync } from "./createAsync";
2
2
  export { action, useSubmission, useSubmissions, useAction, type Action } from "./action";
3
3
  export { cache, revalidate, type CachedFunction } from "./cache";
4
- export { redirect } from "./response";
4
+ export { redirect, reload } from "./response";
@@ -1,4 +1,4 @@
1
1
  export { createAsync } from "./createAsync";
2
2
  export { action, useSubmission, useSubmissions, useAction } from "./action";
3
3
  export { cache, revalidate } from "./cache";
4
- export { redirect } from "./response";
4
+ export { redirect, reload } from "./response";
package/dist/index.js CHANGED
@@ -22,7 +22,10 @@ function createBeforeLeave() {
22
22
  from: l.location,
23
23
  retry: force => {
24
24
  force && (ignore = true);
25
- l.navigate(to, options);
25
+ l.navigate(to, {
26
+ ...options,
27
+ resolve: false
28
+ });
26
29
  }
27
30
  });
28
31
  return !e.defaultPrevented;
@@ -830,9 +833,9 @@ function cache(fn, name, options) {
830
833
  cached[0] = now;
831
834
  }
832
835
  let res = cached[1];
833
- if (!isServer && intent === "navigate") {
836
+ if (!isServer && intent !== "preload") {
834
837
  res = "then" in cached[1] ? cached[1].then(handleResponse(false), handleResponse(true)) : handleResponse(false)(cached[1]);
835
- startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
838
+ intent === "navigate" && startTransition(() => revalidateSignals(cached[3], cached[0])); // update version
836
839
  }
837
840
 
838
841
  return res;
@@ -905,6 +908,7 @@ cache.set = (key, value) => {
905
908
  version && cached[3].add(version);
906
909
  } else cache.set(key, cached = [now, value,, new Set(version ? [version] : [])]);
907
910
  };
911
+ cache.clear = () => getCache().clear();
908
912
  function matchKey(key, keys) {
909
913
  for (let k of keys) {
910
914
  if (key.startsWith(k)) return true;
@@ -1392,5 +1396,17 @@ function redirect(url, init = 302) {
1392
1396
  });
1393
1397
  return response;
1394
1398
  }
1399
+ function reload(init) {
1400
+ const {
1401
+ revalidate,
1402
+ ...responseInit
1403
+ } = init;
1404
+ return new Response(null, {
1405
+ ...responseInit,
1406
+ ...(revalidate ? {
1407
+ headers: new Headers(responseInit.headers).set("X-Revalidate", revalidate.toString())
1408
+ } : {})
1409
+ });
1410
+ }
1395
1411
 
1396
- export { A, HashRouter, MemoryRouter, Navigate, Route, Router, StaticRouter, mergeSearchString as _mergeSearchString, action, cache, createAsync, createBeforeLeave, createMemoryHistory, createRouter, redirect, revalidate, useAction, useBeforeLeave, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useSearchParams, useSubmission, useSubmissions };
1412
+ export { A, HashRouter, MemoryRouter, Navigate, Route, Router, StaticRouter, mergeSearchString as _mergeSearchString, action, cache, createAsync, createBeforeLeave, createMemoryHistory, createRouter, redirect, reload, revalidate, useAction, useBeforeLeave, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useSearchParams, useSubmission, useSubmissions };
package/dist/lifecycle.js CHANGED
@@ -20,7 +20,7 @@ export function createBeforeLeave() {
20
20
  from: l.location,
21
21
  retry: (force) => {
22
22
  force && (ignore = true);
23
- l.navigate(to, options);
23
+ l.navigate(to, { ...options, resolve: false });
24
24
  }
25
25
  });
26
26
  return !e.defaultPrevented;
@@ -2,16 +2,19 @@ import type { Component, JSX } from "solid-js";
2
2
  import type { MatchFilters, RouteLoadFunc, RouteDefinition, RouterIntegration, RouteSectionProps } from "../types";
3
3
  export type BaseRouterProps = {
4
4
  base?: string;
5
+ /**
6
+ * A component that wraps the content of every route.
7
+ */
5
8
  root?: Component<RouteSectionProps>;
6
9
  children?: JSX.Element | RouteDefinition | RouteDefinition[];
7
10
  };
8
11
  export declare const createRouterComponent: (router: RouterIntegration) => (props: BaseRouterProps) => JSX.Element;
9
- export type RouteProps<S extends string> = {
12
+ export type RouteProps<S extends string, T = unknown> = {
10
13
  path?: S | S[];
11
14
  children?: JSX.Element;
12
- load?: RouteLoadFunc;
15
+ load?: RouteLoadFunc<T>;
13
16
  matchFilters?: MatchFilters<S>;
14
- component?: Component;
17
+ component?: Component<RouteSectionProps<T>>;
15
18
  metadata?: Record<string, any>;
16
19
  };
17
- export declare const Route: <S extends string>(props: RouteProps<S>) => JSX.Element;
20
+ export declare const Route: <S extends string, T = unknown>(props: RouteProps<S, T>) => JSX.Element;
package/dist/routing.d.ts CHANGED
@@ -11,7 +11,7 @@ export declare const useLocation: <S = unknown>() => Location<S>;
11
11
  export declare const useIsRouting: () => () => boolean;
12
12
  export declare const useMatch: <S extends string>(path: () => S, matchFilters?: MatchFilters<S> | undefined) => Accessor<import("./types").PathMatch | undefined>;
13
13
  export declare const useParams: <T extends Params>() => T;
14
- export declare const useSearchParams: <T extends Params>() => [T, (params: SetParams, options?: Partial<NavigateOptions>) => void];
14
+ export declare const useSearchParams: <T extends Params>() => [Partial<T>, (params: SetParams, options?: Partial<NavigateOptions>) => void];
15
15
  export declare const useBeforeLeave: (listener: (e: BeforeLeaveEventArgs) => void) => void;
16
16
  export declare function createRoutes(routeDef: RouteDefinition, base?: string): Route[];
17
17
  export declare function createBranch(routes: Route[], index?: number): Branch;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "Ryan Turnquist"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.10.4",
9
+ "version": "0.10.6",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",