sv-router 0.10.2 → 0.10.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv-router",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "Modern Svelte Routing",
5
5
  "keywords": [
6
6
  "svelte",
@@ -37,28 +37,28 @@
37
37
  },
38
38
  "devDependencies": {
39
39
  "@changesets/cli": "^2.29.7",
40
- "@eslint/js": "^9.36.0",
40
+ "@eslint/js": "^9.39.0",
41
41
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
42
- "@testing-library/jest-dom": "^6.9.0",
42
+ "@testing-library/jest-dom": "^6.9.1",
43
43
  "@testing-library/svelte": "^5.2.8",
44
44
  "@testing-library/user-event": "^14.6.1",
45
- "@types/node": "^24.6.0",
46
- "eslint": "^9.36.0",
45
+ "@types/node": "^24.9.2",
46
+ "eslint": "^9.39.0",
47
47
  "eslint-config-prettier": "^10.1.8",
48
48
  "eslint-plugin-simple-import-sort": "^12.1.1",
49
- "eslint-plugin-svelte": "^3.12.4",
50
- "eslint-plugin-unicorn": "^61.0.2",
51
- "globals": "^16.4.0",
52
- "happy-dom": "^20.0.0",
49
+ "eslint-plugin-svelte": "^3.13.0",
50
+ "eslint-plugin-unicorn": "^62.0.0",
51
+ "globals": "^16.5.0",
52
+ "happy-dom": "^20.0.10",
53
53
  "prettier": "^3.6.2",
54
- "prettier-plugin-jsdoc": "^1.3.3",
54
+ "prettier-plugin-jsdoc": "^1.5.0",
55
55
  "prettier-plugin-svelte": "^3.4.0",
56
- "svelte-check": "^4.3.2",
56
+ "svelte-check": "^4.3.3",
57
57
  "type-testing": "^0.2.0",
58
- "typescript": "^5.9.2",
59
- "typescript-eslint": "^8.45.0",
60
- "vite": "^7.1.7",
61
- "vitest": "^3.2.4"
58
+ "typescript": "^5.9.3",
59
+ "typescript-eslint": "^8.46.2",
60
+ "vite": "^7.1.12",
61
+ "vitest": "^4.0.6"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "svelte": "^5"
@@ -12,6 +12,7 @@ import {
12
12
  stripBase,
13
13
  updatedLocation,
14
14
  } from './helpers/utils.js';
15
+ import { Navigation } from './navigation.js';
15
16
  import { syncSearchParams } from './search-params.svelte.js';
16
17
 
17
18
  /** @type {import('./index.d.ts').Routes} */
@@ -118,7 +119,7 @@ export function createRouter(r) {
118
119
  function navigate(path, options = {}) {
119
120
  if (typeof path === 'number') {
120
121
  globalThis.history.go(path);
121
- return;
122
+ return new Navigation(`History entry: ${path}`);
122
123
  }
123
124
 
124
125
  path = constructPath(path, options.params);
@@ -128,6 +129,7 @@ function navigate(path, options = {}) {
128
129
  options.hash = '#' + options.hash;
129
130
  }
130
131
  onNavigate(path, options);
132
+ return new Navigation(`${path}${serializeSearch(options?.search ?? '')}${options?.hash ?? ''}`);
131
133
  }
132
134
 
133
135
  /**
@@ -142,7 +144,7 @@ export async function onNavigate(path, options = {}) {
142
144
  navigationIndex++;
143
145
  const currentNavigationIndex = navigationIndex;
144
146
 
145
- let matchPath = getMatchPath(path);
147
+ const matchPath = getMatchPath(path);
146
148
  const { match, layouts, hooks, meta: newMeta, params: newParams } = matchRoute(matchPath, routes);
147
149
 
148
150
  const search = parseSearch(options.search);
@@ -220,7 +222,7 @@ export async function onNavigate(path, options = {}) {
220
222
 
221
223
  /** @param {string} [path] */
222
224
  function getMatchPath(path) {
223
- let matchPath = '';
225
+ let matchPath;
224
226
 
225
227
  if (path) {
226
228
  matchPath = path;
@@ -254,8 +254,8 @@ export function pathToCorrectCasing(value) {
254
254
 
255
255
  const uppercased = parts.map((part, index) => {
256
256
  part = part.replace(/^_+/, '');
257
+ part = part.replace(/^[[(]+([^[\]()]+)[\])]+$/, '$1');
257
258
  if (index === 0 && (lastPart === 'hooks' || lastPart === 'meta')) return part;
258
- part = part.replace(/^\[(.*)\]$/, '$1');
259
259
  return part.charAt(0).toUpperCase() + part.slice(1);
260
260
  });
261
261
  return uppercased.join('');
package/src/index.d.ts CHANGED
@@ -106,6 +106,10 @@ export type IsActiveLink = Action<
106
106
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
107
107
  export interface RouteMeta {}
108
108
 
109
+ export class Navigation extends Error {
110
+ constructor(target: string);
111
+ }
112
+
109
113
  export type RouterApi<T extends Routes> = {
110
114
  /**
111
115
  * Construct a path while ensuring type safety.
@@ -139,8 +143,9 @@ export type RouterApi<T extends Routes> = {
139
143
  *
140
144
  * @param route The route to navigate to.
141
145
  * @param options The navigation options.
146
+ * @returns {@link Navigation} For use with `throw navigate(...)` inside hooks.
142
147
  */
143
- navigate<U extends Path<T>>(...args: NavigateArgs<U>): void;
148
+ navigate<U extends Path<T>>(...args: NavigateArgs<U>): Navigation;
144
149
 
145
150
  /**
146
151
  * Will return `true` if the given path is active.
@@ -273,8 +278,8 @@ export type SearchParams = Omit<
273
278
 
274
279
  type NavigateArgs<T extends string> =
275
280
  | (PathParams<T> extends never
276
- ? [T] | [T, Omit<NavigateOptions, 'search'> & { search: Search }]
277
- : [T, Omit<NavigateOptions, 'search'> & { search: Search; params: PathParams<T> }])
281
+ ? [T] | [T, NavigateOptions]
282
+ : [T, NavigateOptions & { params: PathParams<T> }])
278
283
  | [number];
279
284
 
280
285
  type StripNonRoutes<T extends Routes> = {
package/src/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { isActiveLink } from './actions.svelte.js';
2
2
  export { createRouter } from './create-router.svelte.js';
3
3
  export { serializeSearch } from './helpers/utils.js';
4
+ export { Navigation } from './navigation.js';
4
5
  export { default as Router } from './Router.svelte';
5
6
  export { searchParams } from './search-params.svelte.js';
@@ -0,0 +1,9 @@
1
+ export class Navigation extends Error {
2
+ constructor(
3
+ /** @type {string} target */
4
+ target,
5
+ ) {
6
+ super(`Navigating to: ${target}`);
7
+ this.name = 'Redirect';
8
+ }
9
+ }