sv-router 0.10.4 → 0.11.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sv-router",
3
- "version": "0.10.4",
3
+ "version": "0.11.0",
4
4
  "description": "Modern Svelte Routing",
5
5
  "keywords": [
6
6
  "svelte",
package/src/cli/index.js CHANGED
@@ -27,4 +27,7 @@ if (jsArg) genConfig.routesInJs = true;
27
27
  const pathArg = arg('path');
28
28
  if (pathArg) genConfig.routesPath = pathArg;
29
29
 
30
+ const ignoreArg = arg('ignore');
31
+ if (ignoreArg) genConfig.ignore = ignoreArg.split(',').map((ignore) => new RegExp(ignore, 'gu'));
32
+
30
33
  writeRouterCode();
@@ -26,7 +26,17 @@ export const base = {
26
26
  /** @type {{ value: import('svelte').Component[] }} */
27
27
  export let componentTree = $state({ value: [] });
28
28
 
29
- export let location = $state(updatedLocation());
29
+ export let location = $state({ pathname: '/', search: '', state: null, hash: '' });
30
+
31
+ if (BROWSER) {
32
+ queueMicrotask(() => {
33
+ const updated = updatedLocation();
34
+ location.pathname = updated.pathname;
35
+ location.search = updated.search;
36
+ location.state = updated.state;
37
+ location.hash = updated.hash;
38
+ });
39
+ }
30
40
 
31
41
  /** @type {{ value: Record<string, string> }} */
32
42
  let params = $state({ value: {} });
@@ -247,7 +257,8 @@ export function onGlobalClick(event) {
247
257
  if (
248
258
  anchor.hasAttribute('target') ||
249
259
  anchor.hasAttribute('download') ||
250
- !anchor.hasAttribute('href')
260
+ !anchor.hasAttribute('href') ||
261
+ anchor.getAttribute('href')?.startsWith('#')
251
262
  )
252
263
  return;
253
264
 
@@ -260,10 +271,20 @@ export function onGlobalClick(event) {
260
271
 
261
272
  event.preventDefault();
262
273
  const { replace, state, scrollToTop, viewTransition } = anchor.dataset;
274
+
275
+ let parsedState;
276
+ if (state) {
277
+ try {
278
+ parsedState = JSON.parse(state);
279
+ } catch {
280
+ parsedState = state;
281
+ }
282
+ }
283
+
263
284
  onNavigate(path, {
264
285
  replace: replace === '' || replace === 'true',
265
286
  search: url.search,
266
- state,
287
+ state: parsedState,
267
288
  hash,
268
289
  scrollToTop: scrollToTop === 'false' ? false : /** @type ScrollBehavior */ (scrollToTop),
269
290
  viewTransition: viewTransition === '' || viewTransition === 'true',
package/src/gen/config.js CHANGED
@@ -1,22 +1,24 @@
1
1
  /**
2
2
  * @type {{
3
3
  * allLazy: boolean;
4
- * routesInJs: boolean;
5
- * routesPath: string;
4
+ * ignore: RegExp[];
5
+ * readonly genCodeAlias: string;
6
6
  * readonly genCodeDirPath: string;
7
7
  * readonly routerPath: string;
8
8
  * readonly tsconfigPath: string;
9
- * readonly genCodeAlias: string;
9
+ * routesInJs: boolean;
10
+ * routesPath: string;
10
11
  * }}
11
12
  */
12
13
  export const genConfig = {
13
14
  allLazy: false,
14
- routesInJs: false,
15
- routesPath: 'src/routes',
15
+ genCodeAlias: 'sv-router/generated',
16
16
  genCodeDirPath: '.router',
17
+ ignore: [],
17
18
  get routerPath() {
18
19
  return '.router/router.' + (this.routesInJs ? 'js' : 'ts');
19
20
  },
21
+ routesInJs: false,
22
+ routesPath: 'src/routes',
20
23
  tsconfigPath: '.router/tsconfig.json',
21
- genCodeAlias: 'sv-router/generated',
22
24
  };
@@ -18,7 +18,7 @@ const META_FILENAME_REGEX = /(?<=[/.]|^)(meta)(\.svelte)?\.(js|ts)$/; // meta.js
18
18
 
19
19
  /**
20
20
  * @param {string} routesPath
21
- * @param {{ allLazy?: boolean; js?: boolean }} [options]
21
+ * @param {{ allLazy?: boolean; js?: boolean; ignore?: RegExp[] }} [options]
22
22
  * @returns {string}
23
23
  */
24
24
  export function generateRouterCode(routesPath, options) {
@@ -26,29 +26,31 @@ export function generateRouterCode(routesPath, options) {
26
26
  if (!fs.existsSync(absoluteRoutesPath)) {
27
27
  throw new Error(`Routes directory not found at \`${routesPath}\``);
28
28
  }
29
- const fileTree = buildFileTree(absoluteRoutesPath);
29
+ const fileTree = buildFileTree(absoluteRoutesPath, options?.ignore ?? []);
30
30
  const routeMap = createRouteMap(fileTree);
31
31
  return createRouterCode(routeMap, path.posix.join('..', routesPath), options);
32
32
  }
33
33
 
34
34
  /**
35
35
  * @param {string} routesPath
36
+ * @param {RegExp[]} ignores
36
37
  * @returns {FileTree}
37
38
  */
38
- export function buildFileTree(routesPath) {
39
+ export function buildFileTree(routesPath, ignores) {
39
40
  const entries = fs.readdirSync(routesPath);
40
41
  /** @type {FileTree} */
41
42
  const tree = [];
42
43
  for (const entry of entries) {
43
44
  const stat = fs.lstatSync(path.join(routesPath, entry));
44
45
  if (stat.isDirectory()) {
45
- tree.push({ name: entry, tree: buildFileTree(path.join(routesPath, entry)) });
46
+ tree.push({ name: entry, tree: buildFileTree(path.join(routesPath, entry), ignores) });
46
47
  continue;
47
48
  }
48
49
  if (
49
- !entry.endsWith('.svelte') &&
50
- !HOOKS_FILENAME_REGEX.test(entry) &&
51
- !META_FILENAME_REGEX.test(entry)
50
+ (!entry.endsWith('.svelte') &&
51
+ !HOOKS_FILENAME_REGEX.test(entry) &&
52
+ !META_FILENAME_REGEX.test(entry)) ||
53
+ ignores.some((ignore) => ignore.test(entry))
52
54
  ) {
53
55
  continue;
54
56
  }
@@ -35,6 +35,7 @@ export function writeRouterCode() {
35
35
  const routerCode = generateRouterCode(genConfig.routesPath, {
36
36
  allLazy: genConfig.allLazy,
37
37
  js: genConfig.routesInJs,
38
+ ignore: genConfig.ignore,
38
39
  });
39
40
  const written = writeFileIfDifferent(genConfig.routerPath, routerCode);
40
41
 
package/src/index.d.ts CHANGED
@@ -241,14 +241,14 @@ export type HooksContext = {
241
241
  pathname: string;
242
242
  replace?: boolean;
243
243
  search: Record<string, string | number | boolean>;
244
- state?: string;
244
+ state?: unknown;
245
245
  };
246
246
 
247
247
  export type NavigateOptions =
248
248
  | {
249
249
  replace?: boolean;
250
250
  search?: Search;
251
- state?: string;
251
+ state?: unknown;
252
252
  hash?: string;
253
253
  scrollToTop?: ScrollBehavior | false;
254
254
  viewTransition?: boolean;
@@ -19,6 +19,12 @@ export type RouterOptions = {
19
19
  * @default 'src/routes'
20
20
  */
21
21
  path?: string;
22
+ /**
23
+ * Regular expressions for files to ignore when generating routes.
24
+ *
25
+ * @default empty array
26
+ */
27
+ ignore?: RegExp[];
22
28
  };
23
29
 
24
30
  export const router: (options?: RouterOptions) => Plugin;
@@ -8,6 +8,7 @@ import { writeRouterCode } from '../gen/write-router-code.js';
8
8
  */
9
9
  export function router(options) {
10
10
  genConfig.allLazy = options?.allLazy || false;
11
+ genConfig.ignore = options?.ignore || [];
11
12
  genConfig.routesInJs = options?.js || false;
12
13
  genConfig.routesPath = options?.path || 'src/routes';
13
14