@solidjs/router 0.10.5 → 0.10.7

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
@@ -609,7 +609,7 @@ const updateTodo = action(async (todo: Todo) => {
609
609
 
610
610
  ## Config Based Routing
611
611
 
612
- 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:
613
613
 
614
614
  ```jsx
615
615
  import { lazy } from "solid-js";
@@ -655,6 +655,21 @@ render(() =>
655
655
  );
656
656
  ```
657
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
+
658
673
  ## Alternative Routers
659
674
 
660
675
  ### Hash Mode Router
@@ -697,7 +712,7 @@ This is the main Router component for the browser.
697
712
 
698
713
  | prop | type | description |
699
714
  |-----|----|----|
700
- | children | `JSX.Element` or `RouteDefinition[]` | The route definitions |
715
+ | children | `JSX.Element`, `RouteDefinition`, or `RouteDefinition[]` | The route definitions |
701
716
  | root | Component | Top level layout component |
702
717
  | base | string | Base url to use for matching routes |
703
718
  | actionBase | string | Root url for server actions, default: `/_server` |
@@ -874,7 +889,7 @@ The biggest changes are around removed APIs that need to be replaced.
874
889
 
875
890
  ### `<Outlet>`, `<Routes>`, `useRoutes`
876
891
 
877
- 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.
878
893
 
879
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)
880
895
 
@@ -66,8 +66,8 @@ export function action(fn, name) {
66
66
  return p;
67
67
  }
68
68
  const url = fn.url ||
69
- (name && `action:${name}`) ||
70
- (!isServer ? `action:${hashString(fn.toString())}` : "");
69
+ (name && `https://action/${name}`) ||
70
+ (!isServer ? `https://action/${hashString(fn.toString())}` : "");
71
71
  return toAction(mutate, url);
72
72
  }
73
73
  function toAction(fn, url) {
@@ -82,7 +82,7 @@ function toAction(fn, url) {
82
82
  };
83
83
  const uri = new URL(url, "http://sar");
84
84
  uri.searchParams.set("args", hashKey(args));
85
- return toAction(newFn, (uri.protocol === "action:" ? uri.protocol : "") + uri.pathname + uri.search);
85
+ return toAction(newFn, (uri.origin === "https://action" ? uri.origin : "") + uri.pathname + uri.search);
86
86
  };
87
87
  fn.url = url;
88
88
  if (!isServer) {
@@ -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
  }
@@ -124,7 +124,7 @@ export function cache(fn, name, options) {
124
124
  return;
125
125
  }
126
126
  if (error)
127
- throw error;
127
+ throw v;
128
128
  if (isServer)
129
129
  return v;
130
130
  setStore(key, reconcile(v, options));
@@ -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))
@@ -87,7 +87,7 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
87
87
  : evt.target.action;
88
88
  if (!actionRef)
89
89
  return;
90
- if (!actionRef.startsWith("action:")) {
90
+ if (!actionRef.startsWith("https://action/")) {
91
91
  const url = new URL(actionRef);
92
92
  actionRef = router.parsePath(url.pathname + url.search);
93
93
  if (!actionRef.startsWith(actionBase))
@@ -99,6 +99,8 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
99
99
  if (handler) {
100
100
  evt.preventDefault();
101
101
  const data = new FormData(evt.target);
102
+ if (evt.submitter && evt.submitter.name)
103
+ data.append(evt.submitter.name, evt.submitter.value);
102
104
  handler.call(router, data);
103
105
  }
104
106
  }
@@ -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;
@@ -875,7 +878,7 @@ function cache(fn, name, options) {
875
878
  }
876
879
  return;
877
880
  }
878
- if (error) throw error;
881
+ if (error) throw v;
879
882
  if (isServer) return v;
880
883
  setStore(key, reconcile(v, options));
881
884
  return store[key];
@@ -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;
@@ -984,7 +988,7 @@ function action(fn, name) {
984
988
  p.then(handler, handler);
985
989
  return p;
986
990
  }
987
- const url = fn.url || name && `action:${name}` || (!isServer ? `action:${hashString(fn.toString())}` : "");
991
+ const url = fn.url || name && `https://action/${name}` || (!isServer ? `https://action/${hashString(fn.toString())}` : "");
988
992
  return toAction(mutate, url);
989
993
  }
990
994
  function toAction(fn, url) {
@@ -998,7 +1002,7 @@ function toAction(fn, url) {
998
1002
  };
999
1003
  const uri = new URL(url, "http://sar");
1000
1004
  uri.searchParams.set("args", hashKey(args));
1001
- return toAction(newFn, (uri.protocol === "action:" ? uri.protocol : "") + uri.pathname + uri.search);
1005
+ return toAction(newFn, (uri.origin === "https://action" ? uri.origin : "") + uri.pathname + uri.search);
1002
1006
  };
1003
1007
  fn.url = url;
1004
1008
  if (!isServer) {
@@ -1094,7 +1098,7 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
1094
1098
  function handleFormSubmit(evt) {
1095
1099
  let actionRef = evt.submitter && evt.submitter.hasAttribute("formaction") ? evt.submitter.formAction : evt.target.action;
1096
1100
  if (!actionRef) return;
1097
- if (!actionRef.startsWith("action:")) {
1101
+ if (!actionRef.startsWith("https://action/")) {
1098
1102
  const url = new URL(actionRef);
1099
1103
  actionRef = router.parsePath(url.pathname + url.search);
1100
1104
  if (!actionRef.startsWith(actionBase)) return;
@@ -1104,6 +1108,7 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
1104
1108
  if (handler) {
1105
1109
  evt.preventDefault();
1106
1110
  const data = new FormData(evt.target);
1111
+ if (evt.submitter && evt.submitter.name) data.append(evt.submitter.name, evt.submitter.value);
1107
1112
  handler.call(router, data);
1108
1113
  }
1109
1114
  }
@@ -1392,5 +1397,17 @@ function redirect(url, init = 302) {
1392
1397
  });
1393
1398
  return response;
1394
1399
  }
1400
+ function reload(init) {
1401
+ const {
1402
+ revalidate,
1403
+ ...responseInit
1404
+ } = init;
1405
+ return new Response(null, {
1406
+ ...responseInit,
1407
+ ...(revalidate ? {
1408
+ headers: new Headers(responseInit.headers).set("X-Revalidate", revalidate.toString())
1409
+ } : {})
1410
+ });
1411
+ }
1395
1412
 
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 };
1413
+ 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,6 +2,9 @@ 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
  };
@@ -14,4 +17,4 @@ export type RouteProps<S extends string, T = unknown> = {
14
17
  component?: Component<RouteSectionProps<T>>;
15
18
  metadata?: Record<string, any>;
16
19
  };
17
- export declare const Route: <S extends string>(props: RouteProps<S, unknown>) => 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.5",
9
+ "version": "0.10.7",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",