@solidjs/router 0.14.6 → 0.14.8

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
@@ -856,7 +856,7 @@ const isRouting = useIsRouting();
856
856
 
857
857
  return (
858
858
  <div classList={{ "grey-out": isRouting() }}>
859
- <MyAwesomeConent />
859
+ <MyAwesomeContent />
860
860
  </div>
861
861
  );
862
862
  ```
@@ -19,7 +19,7 @@ export function A(props) {
19
19
  if (to_ === undefined)
20
20
  return [false, false];
21
21
  const path = normalizePath(to_.split(/[?#]/, 1)[0]).toLowerCase();
22
- const loc = normalizePath(location.pathname).toLowerCase();
22
+ const loc = decodeURI(normalizePath(location.pathname).toLowerCase());
23
23
  return [props.end ? path === loc : loc.startsWith(path + "/") || loc === path, path === loc];
24
24
  });
25
25
  return (<a {...rest} href={href() || props.href} state={JSON.stringify(props.state)} classList={{
@@ -14,6 +14,9 @@ export function useSubmissions(fn, filter) {
14
14
  if (property === "pending")
15
15
  return subs().some(sub => !sub.result);
16
16
  return subs()[property];
17
+ },
18
+ has(_, property) {
19
+ return property in subs();
17
20
  }
18
21
  });
19
22
  }
@@ -6,7 +6,8 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
6
6
  return (router) => {
7
7
  const basePath = router.base.path();
8
8
  const navigateFromRoute = router.navigatorFactory(router.base);
9
- let preloadTimeout = {};
9
+ let preloadTimeout;
10
+ let lastElement;
10
11
  function isSvg(el) {
11
12
  return el.namespaceURI === "http://www.w3.org/2000/svg";
12
13
  }
@@ -57,39 +58,22 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
57
58
  if (!res)
58
59
  return;
59
60
  const [a, url] = res;
60
- if (typeof transformUrl === "function") {
61
- url.pathname = transformUrl(url.pathname);
62
- }
63
- if (!preloadTimeout[url.pathname])
64
- router.preloadRoute(url, { preloadData: a.getAttribute("preload") !== "false" });
61
+ transformUrl && (url.pathname = transformUrl(url.pathname));
62
+ router.preloadRoute(url, { preloadData: a.getAttribute("preload") !== "false" });
65
63
  }
66
- function handleAnchorIn(evt) {
64
+ function handleAnchorMove(evt) {
65
+ clearTimeout(preloadTimeout);
67
66
  const res = handleAnchor(evt);
68
67
  if (!res)
69
- return;
68
+ return lastElement = null;
70
69
  const [a, url] = res;
71
- if (typeof transformUrl === "function") {
72
- url.pathname = transformUrl(url.pathname);
73
- }
74
- if (preloadTimeout[url.pathname])
70
+ if (lastElement === a)
75
71
  return;
76
- preloadTimeout[url.pathname] = setTimeout(() => {
72
+ transformUrl && (url.pathname = transformUrl(url.pathname));
73
+ preloadTimeout = setTimeout(() => {
77
74
  router.preloadRoute(url, { preloadData: a.getAttribute("preload") !== "false" });
78
- delete preloadTimeout[url.pathname];
79
- }, 200);
80
- }
81
- function handleAnchorOut(evt) {
82
- const res = handleAnchor(evt);
83
- if (!res)
84
- return;
85
- const [, url] = res;
86
- if (typeof transformUrl === "function") {
87
- url.pathname = transformUrl(url.pathname);
88
- }
89
- if (preloadTimeout[url.pathname]) {
90
- clearTimeout(preloadTimeout[url.pathname]);
91
- delete preloadTimeout[url.pathname];
92
- }
75
+ lastElement = a;
76
+ }, 20);
93
77
  }
94
78
  function handleFormSubmit(evt) {
95
79
  if (evt.defaultPrevented)
@@ -121,17 +105,15 @@ export function setupNativeEvents(preload = true, explicitLinks = false, actionB
121
105
  delegateEvents(["click", "submit"]);
122
106
  document.addEventListener("click", handleAnchorClick);
123
107
  if (preload) {
124
- document.addEventListener("mouseover", handleAnchorIn);
125
- document.addEventListener("mouseout", handleAnchorOut);
126
- document.addEventListener("focusin", handleAnchorPreload);
127
- document.addEventListener("touchstart", handleAnchorPreload);
108
+ document.addEventListener("mousemove", handleAnchorMove, { passive: true });
109
+ document.addEventListener("focusin", handleAnchorPreload, { passive: true });
110
+ document.addEventListener("touchstart", handleAnchorPreload, { passive: true });
128
111
  }
129
112
  document.addEventListener("submit", handleFormSubmit);
130
113
  onCleanup(() => {
131
114
  document.removeEventListener("click", handleAnchorClick);
132
115
  if (preload) {
133
- document.removeEventListener("mouseover", handleAnchorIn);
134
- document.removeEventListener("mouseout", handleAnchorOut);
116
+ document.removeEventListener("mousemove", handleAnchorMove);
135
117
  document.removeEventListener("focusin", handleAnchorPreload);
136
118
  document.removeEventListener("touchstart", handleAnchorPreload);
137
119
  }
package/dist/index.js CHANGED
@@ -367,7 +367,7 @@ function getRouteMatches(branches, location) {
367
367
  }
368
368
  return [];
369
369
  }
370
- function createLocation(path, state) {
370
+ function createLocation(path, state, queryWrapper) {
371
371
  const origin = new URL(mockBase);
372
372
  const url = createMemo(prev => {
373
373
  const path_ = path();
@@ -384,6 +384,7 @@ function createLocation(path, state) {
384
384
  const search = createMemo(() => url().search, true);
385
385
  const hash = createMemo(() => url().hash);
386
386
  const key = () => "";
387
+ const queryFn = on(search, () => extractSearchParams(url()));
387
388
  return {
388
389
  get pathname() {
389
390
  return pathname();
@@ -400,7 +401,7 @@ function createLocation(path, state) {
400
401
  get key() {
401
402
  return key();
402
403
  },
403
- query: createMemoObject(on(search, () => extractSearchParams(url())))
404
+ query: queryWrapper ? queryWrapper(queryFn) : createMemoObject(queryFn)
404
405
  };
405
406
  }
406
407
  let intent;
@@ -463,7 +464,7 @@ function createRouterContext(integration, branches, getContext, options = {}) {
463
464
  };
464
465
  const [reference, setReference] = createSignal(source().value);
465
466
  const [state, setState] = createSignal(source().state);
466
- const location = createLocation(reference, state);
467
+ const location = createLocation(reference, state, utils.queryWrapper);
467
468
  const referrers = [];
468
469
  const submissions = createSignal(isServer ? initFromFlash() : []);
469
470
  const matches = createMemo(() => {
@@ -472,14 +473,15 @@ function createRouterContext(integration, branches, getContext, options = {}) {
472
473
  }
473
474
  return getRouteMatches(branches(), location.pathname);
474
475
  });
475
- const params = createMemoObject(() => {
476
+ const buildParams = () => {
476
477
  const m = matches();
477
478
  const params = {};
478
479
  for (let i = 0; i < m.length; i++) {
479
480
  Object.assign(params, m[i].params);
480
481
  }
481
482
  return params;
482
- });
483
+ };
484
+ const params = utils.paramsWrapper ? utils.paramsWrapper(buildParams, branches) : createMemoObject(buildParams);
483
485
  const baseRoute = {
484
486
  pattern: basePath,
485
487
  path: () => basePath,
@@ -1057,6 +1059,9 @@ function useSubmissions(fn, filter) {
1057
1059
  if (property === $TRACK) return subs();
1058
1060
  if (property === "pending") return subs().some(sub => !sub.result);
1059
1061
  return subs()[property];
1062
+ },
1063
+ has(_, property) {
1064
+ return property in subs();
1060
1065
  }
1061
1066
  });
1062
1067
  }
@@ -1183,7 +1188,8 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
1183
1188
  return router => {
1184
1189
  const basePath = router.base.path();
1185
1190
  const navigateFromRoute = router.navigatorFactory(router.base);
1186
- let preloadTimeout = {};
1191
+ let preloadTimeout;
1192
+ let lastElement;
1187
1193
  function isSvg(el) {
1188
1194
  return el.namespaceURI === "http://www.w3.org/2000/svg";
1189
1195
  }
@@ -1219,39 +1225,24 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
1219
1225
  const res = handleAnchor(evt);
1220
1226
  if (!res) return;
1221
1227
  const [a, url] = res;
1222
- if (typeof transformUrl === "function") {
1223
- url.pathname = transformUrl(url.pathname);
1224
- }
1225
- if (!preloadTimeout[url.pathname]) router.preloadRoute(url, {
1228
+ transformUrl && (url.pathname = transformUrl(url.pathname));
1229
+ router.preloadRoute(url, {
1226
1230
  preloadData: a.getAttribute("preload") !== "false"
1227
1231
  });
1228
1232
  }
1229
- function handleAnchorIn(evt) {
1233
+ function handleAnchorMove(evt) {
1234
+ clearTimeout(preloadTimeout);
1230
1235
  const res = handleAnchor(evt);
1231
- if (!res) return;
1236
+ if (!res) return lastElement = null;
1232
1237
  const [a, url] = res;
1233
- if (typeof transformUrl === "function") {
1234
- url.pathname = transformUrl(url.pathname);
1235
- }
1236
- if (preloadTimeout[url.pathname]) return;
1237
- preloadTimeout[url.pathname] = setTimeout(() => {
1238
+ if (lastElement === a) return;
1239
+ transformUrl && (url.pathname = transformUrl(url.pathname));
1240
+ preloadTimeout = setTimeout(() => {
1238
1241
  router.preloadRoute(url, {
1239
1242
  preloadData: a.getAttribute("preload") !== "false"
1240
1243
  });
1241
- delete preloadTimeout[url.pathname];
1242
- }, 200);
1243
- }
1244
- function handleAnchorOut(evt) {
1245
- const res = handleAnchor(evt);
1246
- if (!res) return;
1247
- const [, url] = res;
1248
- if (typeof transformUrl === "function") {
1249
- url.pathname = transformUrl(url.pathname);
1250
- }
1251
- if (preloadTimeout[url.pathname]) {
1252
- clearTimeout(preloadTimeout[url.pathname]);
1253
- delete preloadTimeout[url.pathname];
1254
- }
1244
+ lastElement = a;
1245
+ }, 20);
1255
1246
  }
1256
1247
  function handleFormSubmit(evt) {
1257
1248
  if (evt.defaultPrevented) return;
@@ -1279,17 +1270,21 @@ function setupNativeEvents(preload = true, explicitLinks = false, actionBase = "
1279
1270
  delegateEvents(["click", "submit"]);
1280
1271
  document.addEventListener("click", handleAnchorClick);
1281
1272
  if (preload) {
1282
- document.addEventListener("mouseover", handleAnchorIn);
1283
- document.addEventListener("mouseout", handleAnchorOut);
1284
- document.addEventListener("focusin", handleAnchorPreload);
1285
- document.addEventListener("touchstart", handleAnchorPreload);
1273
+ document.addEventListener("mousemove", handleAnchorMove, {
1274
+ passive: true
1275
+ });
1276
+ document.addEventListener("focusin", handleAnchorPreload, {
1277
+ passive: true
1278
+ });
1279
+ document.addEventListener("touchstart", handleAnchorPreload, {
1280
+ passive: true
1281
+ });
1286
1282
  }
1287
1283
  document.addEventListener("submit", handleFormSubmit);
1288
1284
  onCleanup(() => {
1289
1285
  document.removeEventListener("click", handleAnchorClick);
1290
1286
  if (preload) {
1291
- document.removeEventListener("mouseover", handleAnchorIn);
1292
- document.removeEventListener("mouseout", handleAnchorOut);
1287
+ document.removeEventListener("mousemove", handleAnchorMove);
1293
1288
  document.removeEventListener("focusin", handleAnchorPreload);
1294
1289
  document.removeEventListener("touchstart", handleAnchorPreload);
1295
1290
  }
@@ -1445,7 +1440,7 @@ function MemoryRouter(props) {
1445
1440
  })(props);
1446
1441
  }
1447
1442
 
1448
- const _tmpl$ = /*#__PURE__*/template(`<a>`);
1443
+ var _tmpl$ = /*#__PURE__*/template(`<a>`);
1449
1444
  function A(props) {
1450
1445
  props = mergeProps({
1451
1446
  inactiveClass: "inactive",
@@ -1459,11 +1454,11 @@ function A(props) {
1459
1454
  const to_ = to();
1460
1455
  if (to_ === undefined) return [false, false];
1461
1456
  const path = normalizePath(to_.split(/[?#]/, 1)[0]).toLowerCase();
1462
- const loc = normalizePath(location.pathname).toLowerCase();
1457
+ const loc = decodeURI(normalizePath(location.pathname).toLowerCase());
1463
1458
  return [props.end ? path === loc : loc.startsWith(path + "/") || loc === path, path === loc];
1464
1459
  });
1465
1460
  return (() => {
1466
- const _el$ = _tmpl$();
1461
+ var _el$ = _tmpl$();
1467
1462
  spread(_el$, mergeProps$1(rest, {
1468
1463
  get href() {
1469
1464
  return href() || props.href;
package/dist/routing.d.ts CHANGED
@@ -21,7 +21,6 @@ export declare function createRoutes(routeDef: RouteDefinition, base?: string):
21
21
  export declare function createBranch(routes: RouteDescription[], index?: number): Branch;
22
22
  export declare function createBranches(routeDef: RouteDefinition | RouteDefinition[], base?: string, stack?: RouteDescription[], branches?: Branch[]): Branch[];
23
23
  export declare function getRouteMatches(branches: Branch[], location: string): RouteMatch[];
24
- export declare function createLocation(path: Accessor<string>, state: Accessor<any>): Location;
25
24
  export declare function getIntent(): Intent | undefined;
26
25
  export declare function getInPreloadFn(): boolean;
27
26
  export declare function setInPreloadFn(value: boolean): void;
package/dist/routing.js CHANGED
@@ -145,7 +145,7 @@ export function getRouteMatches(branches, location) {
145
145
  }
146
146
  return [];
147
147
  }
148
- export function createLocation(path, state) {
148
+ function createLocation(path, state, queryWrapper) {
149
149
  const origin = new URL(mockBase);
150
150
  const url = createMemo(prev => {
151
151
  const path_ = path();
@@ -163,6 +163,7 @@ export function createLocation(path, state) {
163
163
  const search = createMemo(() => url().search, true);
164
164
  const hash = createMemo(() => url().hash);
165
165
  const key = () => "";
166
+ const queryFn = on(search, () => extractSearchParams(url()));
166
167
  return {
167
168
  get pathname() {
168
169
  return pathname();
@@ -179,7 +180,7 @@ export function createLocation(path, state) {
179
180
  get key() {
180
181
  return key();
181
182
  },
182
- query: createMemoObject(on(search, () => extractSearchParams(url())))
183
+ query: queryWrapper ? queryWrapper(queryFn) : createMemoObject(queryFn)
183
184
  };
184
185
  }
185
186
  let intent;
@@ -239,7 +240,7 @@ export function createRouterContext(integration, branches, getContext, options =
239
240
  };
240
241
  const [reference, setReference] = createSignal(source().value);
241
242
  const [state, setState] = createSignal(source().state);
242
- const location = createLocation(reference, state);
243
+ const location = createLocation(reference, state, utils.queryWrapper);
243
244
  const referrers = [];
244
245
  const submissions = createSignal(isServer ? initFromFlash() : []);
245
246
  const matches = createMemo(() => {
@@ -248,14 +249,17 @@ export function createRouterContext(integration, branches, getContext, options =
248
249
  }
249
250
  return getRouteMatches(branches(), location.pathname);
250
251
  });
251
- const params = createMemoObject(() => {
252
+ const buildParams = () => {
252
253
  const m = matches();
253
254
  const params = {};
254
255
  for (let i = 0; i < m.length; i++) {
255
256
  Object.assign(params, m[i].params);
256
257
  }
257
258
  return params;
258
- });
259
+ };
260
+ const params = utils.paramsWrapper
261
+ ? utils.paramsWrapper(buildParams, branches)
262
+ : createMemoObject(buildParams);
259
263
  const baseRoute = {
260
264
  pattern: basePath,
261
265
  path: () => basePath,
@@ -302,7 +306,6 @@ export function createRouterContext(integration, branches, getContext, options =
302
306
  scroll: true,
303
307
  ...options
304
308
  };
305
- let s;
306
309
  const resolvedTo = resolve
307
310
  ? route.resolvePath(to)
308
311
  : resolvePath((queryOnly && location.pathname) || "", to);
package/dist/types.d.ts CHANGED
@@ -126,6 +126,8 @@ export interface RouterUtils {
126
126
  parsePath(str: string): string;
127
127
  go(delta: number): void;
128
128
  beforeLeave: BeforeLeaveLifecycle;
129
+ paramsWrapper: (getParams: () => Params, branches: () => Branch[]) => Params;
130
+ queryWrapper: (getQuery: () => Params) => Params;
129
131
  }
130
132
  export interface RouterContext {
131
133
  base: RouteContext;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "Ryan Turnquist"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.14.6",
9
+ "version": "0.14.8",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",
@@ -37,15 +37,15 @@
37
37
  "@rollup/plugin-terser": "0.4.4",
38
38
  "@types/jest": "^29.5.11",
39
39
  "@types/node": "^20.11.14",
40
- "babel-preset-solid": "^1.8.6",
40
+ "babel-preset-solid": "^1.9.2",
41
41
  "jsdom": "^24.0.0",
42
42
  "prettier": "^2.7.0",
43
43
  "rollup": "^4.9.6",
44
- "solid-js": "^1.8.7",
44
+ "solid-js": "^1.9.2",
45
45
  "typescript": "^5.3.3",
46
- "vite": "^5.0.12",
46
+ "vite": "^5.4.8",
47
47
  "vite-plugin-solid": "^2.9.1",
48
- "vitest": "^1.2.2"
48
+ "vitest": "^2.1.2"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "solid-js": "^1.8.6"