@solidjs/router 0.7.0 → 0.8.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.
package/README.md CHANGED
@@ -18,6 +18,7 @@ It supports all of Solid's SSR methods and has Solid's transitions baked in, so
18
18
  - [Data Functions](#data-functions)
19
19
  - [Nested Routes](#nested-routes)
20
20
  - [Hash Mode Router](#hash-mode-router)
21
+ - [Memory Mode Router](#memory-mode-router)
21
22
  - [Config Based Routing](#config-based-routing)
22
23
  - [Router Primitives](#router-primitives)
23
24
  - [useParams](#useparams)
@@ -419,6 +420,16 @@ import { Router, hashIntegration } from '@solidjs/router'
419
420
  <Router source={hashIntegration()}><App /></Router>
420
421
  ```
421
422
 
423
+ ## Memory Mode Router
424
+
425
+ You can also use memory mode router for testing purpose.
426
+
427
+ ```jsx
428
+ import { Router, memoryIntegration } from '@solidjs/router'
429
+
430
+ <Router source={memoryIntegration()}><App /></Router>
431
+ ```
432
+
422
433
  ## Config Based Routing
423
434
 
424
435
  You don't have to use JSX to set up your routes; you can pass an object directly with `useRoutes`:
@@ -533,7 +544,7 @@ const [searchParams, setSearchParams] = useSearchParams();
533
544
  return (
534
545
  <div>
535
546
  <span>Page: {searchParams.page}</span>
536
- <button onClick={() => setSearchParams({ page: searchParams.page + 1 })}>Next Page</button>
547
+ <button onClick={() => setSearchParams({ page: (parseInt(searchParams.page) || 0) + 1 })}>Next Page</button>
537
548
  </div>
538
549
  );
539
550
  ```
package/dist/index.js CHANGED
@@ -24,6 +24,49 @@ function scrollToHash(hash, fallbackTop) {
24
24
  window.scrollTo(0, 0);
25
25
  }
26
26
  }
27
+ function createMemoryHistory() {
28
+ const entries = ["/"];
29
+ let index = 0;
30
+ const listeners = [];
31
+ const go = n => {
32
+ // https://github.com/remix-run/react-router/blob/682810ca929d0e3c64a76f8d6e465196b7a2ac58/packages/router/history.ts#L245
33
+ index = Math.max(0, Math.min(index + n, entries.length - 1));
34
+ const value = entries[index];
35
+ listeners.forEach(listener => listener(value));
36
+ };
37
+ return {
38
+ get: () => entries[index],
39
+ set: ({
40
+ value,
41
+ scroll,
42
+ replace
43
+ }) => {
44
+ if (replace) {
45
+ entries[index] = value;
46
+ } else {
47
+ entries.splice(index + 1, entries.length - index, value);
48
+ index++;
49
+ }
50
+ if (scroll) {
51
+ scrollToHash(value.split("#")[1] || "", true);
52
+ }
53
+ },
54
+ back: () => {
55
+ go(-1);
56
+ },
57
+ forward: () => {
58
+ go(1);
59
+ },
60
+ go,
61
+ listen: listener => {
62
+ listeners.push(listener);
63
+ return () => {
64
+ const index = listeners.indexOf(listener);
65
+ listeners.splice(index, 1);
66
+ };
67
+ }
68
+ };
69
+ }
27
70
  function createIntegration(get, set, init, utils) {
28
71
  let ignore = false;
29
72
  const wrap = value => typeof value === "string" ? {
@@ -115,6 +158,12 @@ function hashIntegration() {
115
158
  }
116
159
  });
117
160
  }
161
+ function memoryIntegration() {
162
+ const memoryHistory = createMemoryHistory();
163
+ return createIntegration(memoryHistory.get, memoryHistory.set, memoryHistory.listen, {
164
+ go: memoryHistory.go
165
+ });
166
+ }
118
167
 
119
168
  function createBeforeLeave() {
120
169
  let listeners = new Set();
@@ -148,9 +197,9 @@ function createBeforeLeave() {
148
197
  }
149
198
 
150
199
  const hasSchemeRegex = /^(?:[a-z0-9]+:)?\/\//i;
151
- const trimPathRegex = /^\/+|\/+$/g;
200
+ const trimPathRegex = /^\/+|(\/)\/+$/g;
152
201
  function normalizePath(path, omitSlash = false) {
153
- const s = path.replace(trimPathRegex, "");
202
+ const s = path.replace(trimPathRegex, "$1");
154
203
  return s ? omitSlash || /^[?#]/.test(s) ? s : "/" + s : "";
155
204
  }
156
205
  function resolvePath(base, path, from) {
@@ -203,10 +252,11 @@ function createMatcher(path, partial, matchFilters) {
203
252
  for (let i = 0; i < len; i++) {
204
253
  const segment = segments[i];
205
254
  const locSegment = locSegments[i];
206
- const key = segment[0] === ":" ? segment.slice(1) : segment;
207
- if (segment[0] === ":" && matchSegment(locSegment, matchFilter(key))) {
255
+ const dynamic = segment[0] === ":";
256
+ const key = dynamic ? segment.slice(1) : segment;
257
+ if (dynamic && matchSegment(locSegment, matchFilter(key))) {
208
258
  match.params[key] = locSegment;
209
- } else if (!matchSegment(locSegment, segment)) {
259
+ } else if (dynamic || !matchSegment(locSegment, segment)) {
210
260
  return null;
211
261
  }
212
262
  match.path += `/${locSegment}`;
@@ -882,4 +932,4 @@ function Navigate(props) {
882
932
  return null;
883
933
  }
884
934
 
885
- export { A, A as Link, A as NavLink, Navigate, Outlet, Route, Router, Routes, mergeSearchString as _mergeSearchString, createBeforeLeave, createIntegration, hashIntegration, normalizeIntegration, pathIntegration, staticIntegration, useBeforeLeave, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useRouteData, useRoutes, useSearchParams };
935
+ export { A, A as Link, A as NavLink, Navigate, Outlet, Route, Router, Routes, mergeSearchString as _mergeSearchString, createBeforeLeave, createIntegration, createMemoryHistory, hashIntegration, memoryIntegration, normalizeIntegration, pathIntegration, staticIntegration, useBeforeLeave, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, useResolvedPath, useRouteData, useRoutes, useSearchParams };
@@ -1,6 +1,15 @@
1
1
  import type { LocationChange, LocationChangeSignal, RouterIntegration, RouterUtils } from "./types";
2
+ export declare function createMemoryHistory(): {
3
+ get: () => string;
4
+ set: ({ value, scroll, replace }: LocationChange) => void;
5
+ back: () => void;
6
+ forward: () => void;
7
+ go: (n: number) => void;
8
+ listen: (listener: (value: string) => void) => () => void;
9
+ };
2
10
  export declare function createIntegration(get: () => string | LocationChange, set: (next: LocationChange) => void, init?: (notify: (value?: string | LocationChange) => void) => () => void, utils?: Partial<RouterUtils>): RouterIntegration;
3
11
  export declare function normalizeIntegration(integration: RouterIntegration | LocationChangeSignal | undefined): RouterIntegration;
4
12
  export declare function staticIntegration(obj: LocationChange): RouterIntegration;
5
13
  export declare function pathIntegration(): RouterIntegration;
6
14
  export declare function hashIntegration(): RouterIntegration;
15
+ export declare function memoryIntegration(): RouterIntegration;
@@ -24,6 +24,46 @@ function scrollToHash(hash, fallbackTop) {
24
24
  window.scrollTo(0, 0);
25
25
  }
26
26
  }
27
+ export function createMemoryHistory() {
28
+ const entries = ["/"];
29
+ let index = 0;
30
+ const listeners = [];
31
+ const go = (n) => {
32
+ // https://github.com/remix-run/react-router/blob/682810ca929d0e3c64a76f8d6e465196b7a2ac58/packages/router/history.ts#L245
33
+ index = Math.max(0, Math.min(index + n, entries.length - 1));
34
+ const value = entries[index];
35
+ listeners.forEach(listener => listener(value));
36
+ };
37
+ return {
38
+ get: () => entries[index],
39
+ set: ({ value, scroll, replace }) => {
40
+ if (replace) {
41
+ entries[index] = value;
42
+ }
43
+ else {
44
+ entries.splice(index + 1, entries.length - index, value);
45
+ index++;
46
+ }
47
+ if (scroll) {
48
+ scrollToHash(value.split("#")[1] || "", true);
49
+ }
50
+ },
51
+ back: () => {
52
+ go(-1);
53
+ },
54
+ forward: () => {
55
+ go(1);
56
+ },
57
+ go,
58
+ listen: (listener) => {
59
+ listeners.push(listener);
60
+ return () => {
61
+ const index = listeners.indexOf(listener);
62
+ listeners.splice(index, 1);
63
+ };
64
+ }
65
+ };
66
+ }
27
67
  export function createIntegration(get, set, init, utils) {
28
68
  let ignore = false;
29
69
  const wrap = (value) => (typeof value === "string" ? { value } : value);
@@ -103,3 +143,9 @@ export function hashIntegration() {
103
143
  }
104
144
  });
105
145
  }
146
+ export function memoryIntegration() {
147
+ const memoryHistory = createMemoryHistory();
148
+ return createIntegration(memoryHistory.get, memoryHistory.set, memoryHistory.listen, {
149
+ go: memoryHistory.go
150
+ });
151
+ }
package/dist/utils.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { createMemo, getOwner, runWithOwner } from "solid-js";
2
2
  const hasSchemeRegex = /^(?:[a-z0-9]+:)?\/\//i;
3
- const trimPathRegex = /^\/+|\/+$/g;
3
+ const trimPathRegex = /^\/+|(\/)\/+$/g;
4
4
  export function normalizePath(path, omitSlash = false) {
5
- const s = path.replace(trimPathRegex, "");
5
+ const s = path.replace(trimPathRegex, "$1");
6
6
  return s ? (omitSlash || /^[?#]/.test(s) ? s : "/" + s) : "";
7
7
  }
8
8
  export function resolvePath(base, path, from) {
@@ -57,11 +57,12 @@ export function createMatcher(path, partial, matchFilters) {
57
57
  for (let i = 0; i < len; i++) {
58
58
  const segment = segments[i];
59
59
  const locSegment = locSegments[i];
60
- const key = segment[0] === ":" ? segment.slice(1) : segment;
61
- if (segment[0] === ":" && matchSegment(locSegment, matchFilter(key))) {
60
+ const dynamic = segment[0] === ":";
61
+ const key = dynamic ? segment.slice(1) : segment;
62
+ if (dynamic && matchSegment(locSegment, matchFilter(key))) {
62
63
  match.params[key] = locSegment;
63
64
  }
64
- else if (!matchSegment(locSegment, segment)) {
65
+ else if (dynamic || !matchSegment(locSegment, segment)) {
65
66
  return null;
66
67
  }
67
68
  match.path += `/${locSegment}`;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "Ryan Turnquist"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.7.0",
9
+ "version": "0.8.0",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",