@fluixi/router 0.1.2-alpha.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fluixi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/fluixi/assets/main/logos/128x128.png" alt="Fluixi" width="120" height="120" />
3
+ </p>
4
+
5
+ # @fluixi/router
6
+
7
+ **Framework-agnostic router core — URL → a resolved match tree + navigation.**
8
+
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-22c55e.svg)](./LICENSE)
10
+ ![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white)
11
+ ![Registry](https://img.shields.io/badge/registry-GitHub%20Packages-181717?logo=github)
12
+ ![Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)
13
+
14
+ ---
15
+
16
+ ## ✨ Overview
17
+
18
+ `@fluixi/router` is the routing **core** — pure state and a `subscribe` API, with **no
19
+ reactivity, no DOM, no view framework**. View adapters (the Fluixi adapter lives in
20
+ [`@fluixi/core/router-next`](../core)) render the match tree **top-down**, which makes
21
+ deeply nested layout/outlet rendering work by construction. See [DESIGN.md](./DESIGN.md).
22
+
23
+ ## 📦 Installation
24
+
25
+ ```ini
26
+ # .npmrc
27
+ @fluixi:registry=https://npm.pkg.github.com
28
+ //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
29
+ ```
30
+
31
+ ```sh
32
+ pnpm add @fluixi/router
33
+ ```
34
+
35
+ ## 🚀 Usage
36
+
37
+ ```ts
38
+ import { createRouter, createMemoryHistory } from '@fluixi/router';
39
+
40
+ const routes = [
41
+ { path: '/app', component: AppLayout, children: [
42
+ { path: '/app/home', component: HomePage },
43
+ { path: '/app/user/:id', component: UserPage },
44
+ ]},
45
+ ];
46
+
47
+ const router = createRouter({ routes, history: createMemoryHistory('/app/home') });
48
+
49
+ router.state().match; // { matched: [AppLayout, HomePage], params, pathname }
50
+ router.subscribe((s) => render(s.match));
51
+ router.navigate('/app/user/42');
52
+ router.state().match.params; // { id: '42' }
53
+ ```
54
+
55
+ ## 📖 API
56
+
57
+ | Export | What |
58
+ | --- | --- |
59
+ | `matchRoutes(routes, pathname)` | pure matcher → `RouteMatch \| null` |
60
+ | `createRouter({ routes, history, base? })` | `Router` with `state()`, `subscribe()`, `navigate()`, `match()`, `destroy()` |
61
+ | `createMemoryHistory(initial?)` / `createBrowserHistory()` | pluggable history adapters |
62
+
63
+ ## 🧭 Rendering contract
64
+
65
+ `match.matched` is parent → child. An adapter folds from the deepest child upward,
66
+ passing each rendered child to its parent as that parent's outlet — all concrete values,
67
+ never a deferred build. That top-down composition is what makes deeply nested `<Outlet/>`
68
+ rendering work at any depth.
69
+
70
+ ## 📄 License
71
+
72
+ [MIT](./LICENSE) © [Fluixi](https://fluixi.dev)
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fluixi/router — framework-agnostic router core.
3
+ *
4
+ * Routing as pure state: URL → resolved match tree + navigation. No reactivity,
5
+ * no DOM, no view framework. View adapters subscribe and render the match tree
6
+ * top-down (see DESIGN.md).
7
+ */
8
+ export type { RouteDefinition, MatchedRoute, RouteMatch, RouterLocation, NavigateOptions, RouterState, HistoryAdapter, Router, RouterConfig, RouteData, } from './lib/types.js';
9
+ export { matchRoutes, matchPath, scoreRoute, rankRoutes } from './lib/match.js';
10
+ export { createMemoryHistory, createBrowserHistory, splitPath, } from './lib/history.js';
11
+ export { createRouter } from './lib/router.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,eAAe,EACf,YAAY,EACZ,UAAU,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,cAAc,EACd,MAAM,EACN,YAAY,EACZ,SAAS,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @fluixi/router — framework-agnostic router core.
3
+ *
4
+ * Routing as pure state: URL → resolved match tree + navigation. No reactivity,
5
+ * no DOM, no view framework. View adapters subscribe and render the match tree
6
+ * top-down (see DESIGN.md).
7
+ */
8
+ export { matchRoutes, matchPath, scoreRoute, rankRoutes } from './lib/match.js';
9
+ export { createMemoryHistory, createBrowserHistory, splitPath, } from './lib/history.js';
10
+ export { createRouter } from './lib/router.js';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview Pluggable history backends.
3
+ *
4
+ * The router core depends only on the {@link HistoryAdapter} interface, so it
5
+ * runs identically in tests/SSR (memory) and the browser (History API).
6
+ */
7
+ import type { HistoryAdapter } from './types.js';
8
+ /** Split a full path string into pathname / search / hash. */
9
+ export declare function splitPath(to: string): {
10
+ pathname: string;
11
+ search: string;
12
+ hash: string;
13
+ };
14
+ /**
15
+ * In-memory history — for tests and server-side rendering. Holds a stack of
16
+ * entries; `push`/`replace` mutate it and notify subscribers synchronously.
17
+ */
18
+ export declare function createMemoryHistory(initial?: string): HistoryAdapter;
19
+ /**
20
+ * Browser history backed by the History API. `pushState`/`replaceState` do NOT
21
+ * emit `popstate`, so the adapter keeps its own listener set and notifies on
22
+ * push/replace AND on popstate (back/forward). This makes the history adapter
23
+ * the single source of change notification for the router.
24
+ */
25
+ export declare function createBrowserHistory(): HistoryAdapter;
26
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/lib/history.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAeA;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAM,GAAG,cAAc,CA4BjE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAyBrD"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @fileoverview Pluggable history backends.
3
+ *
4
+ * The router core depends only on the {@link HistoryAdapter} interface, so it
5
+ * runs identically in tests/SSR (memory) and the browser (History API).
6
+ */
7
+ /** Split a full path string into pathname / search / hash. */
8
+ export function splitPath(to) {
9
+ let rest = to;
10
+ let hash = '';
11
+ const hashIdx = rest.indexOf('#');
12
+ if (hashIdx !== -1) {
13
+ hash = rest.slice(hashIdx);
14
+ rest = rest.slice(0, hashIdx);
15
+ }
16
+ let search = '';
17
+ const qIdx = rest.indexOf('?');
18
+ if (qIdx !== -1) {
19
+ search = rest.slice(qIdx);
20
+ rest = rest.slice(0, qIdx);
21
+ }
22
+ return { pathname: rest || '/', search, hash };
23
+ }
24
+ /**
25
+ * In-memory history — for tests and server-side rendering. Holds a stack of
26
+ * entries; `push`/`replace` mutate it and notify subscribers synchronously.
27
+ */
28
+ export function createMemoryHistory(initial = '/') {
29
+ let entries = [
30
+ { path: initial, state: null },
31
+ ];
32
+ let index = 0;
33
+ const listeners = new Set();
34
+ const notify = () => listeners.forEach((l) => l());
35
+ return {
36
+ get() {
37
+ const { path, state } = entries[index];
38
+ return { ...splitPath(path), state };
39
+ },
40
+ push(to, state = null) {
41
+ entries = entries.slice(0, index + 1);
42
+ entries.push({ path: to, state });
43
+ index = entries.length - 1;
44
+ notify();
45
+ },
46
+ replace(to, state = null) {
47
+ entries[index] = { path: to, state };
48
+ notify();
49
+ },
50
+ subscribe(onChange) {
51
+ listeners.add(onChange);
52
+ return () => listeners.delete(onChange);
53
+ },
54
+ };
55
+ }
56
+ /**
57
+ * Browser history backed by the History API. `pushState`/`replaceState` do NOT
58
+ * emit `popstate`, so the adapter keeps its own listener set and notifies on
59
+ * push/replace AND on popstate (back/forward). This makes the history adapter
60
+ * the single source of change notification for the router.
61
+ */
62
+ export function createBrowserHistory() {
63
+ const w = typeof window !== 'undefined' ? window : undefined;
64
+ const listeners = new Set();
65
+ const notify = () => listeners.forEach((l) => l());
66
+ if (w)
67
+ w.addEventListener('popstate', notify);
68
+ return {
69
+ get() {
70
+ if (!w)
71
+ return { pathname: '/', search: '', hash: '', state: null };
72
+ const { pathname, search, hash } = w.location;
73
+ return { pathname, search, hash, state: w.history.state ?? null };
74
+ },
75
+ push(to, state = null) {
76
+ w?.history.pushState(state, '', to);
77
+ notify();
78
+ },
79
+ replace(to, state = null) {
80
+ w?.history.replaceState(state, '', to);
81
+ notify();
82
+ },
83
+ subscribe(onChange) {
84
+ listeners.add(onChange);
85
+ return () => listeners.delete(onChange);
86
+ },
87
+ };
88
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Pure route matching.
3
+ *
4
+ * `matchRoutes(routes, pathname)` resolves a pathname to a parent → child
5
+ * {@link RouteMatch}. No side effects, no reactivity — same input, same output.
6
+ * Ported from the fluixi router's matcher and made framework-agnostic.
7
+ */
8
+ import type { RouteDefinition, RouteMatch } from './types.js';
9
+ /** Internal: result of matching a single pattern segment-prefix against a path. */
10
+ interface SegmentMatch {
11
+ params: Record<string, string>;
12
+ /** The portion of `path` consumed by `pattern`. */
13
+ path: string;
14
+ }
15
+ /**
16
+ * Match a single route `pattern` against `path`.
17
+ *
18
+ * - `exact` (leaf routes) anchors the end; non-exact (layouts) matches a prefix
19
+ * up to a `/` boundary so children can consume the rest.
20
+ * - Supports `:param` and `*` / `*name` wildcards.
21
+ */
22
+ export declare function matchPath(pattern: string, path: string, exact?: boolean): SegmentMatch | null;
23
+ /** Specificity score: static segments > params > wildcards. Higher = more specific. */
24
+ export declare function scoreRoute(def: RouteDefinition): number;
25
+ /** Most-specific-first ordering, without mutating the input. */
26
+ export declare function rankRoutes<C>(defs: RouteDefinition<C>[]): RouteDefinition<C>[];
27
+ /** Match `pathname` against a route tree, returning the parent → child match. */
28
+ export declare function matchRoutes<C>(routes: RouteDefinition<C>[], pathname: string): RouteMatch<C> | null;
29
+ export {};
30
+ //# sourceMappingURL=match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/lib/match.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAgB,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5E,mFAAmF;AACnF,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;CACd;AAOD;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,UAAQ,GACZ,YAAY,GAAG,IAAI,CA6BrB;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAUvD;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,EAAE,CAE9E;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,CAAC,EAC3B,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,EAC5B,QAAQ,EAAE,MAAM,GACf,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CA4BtB"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @fileoverview Pure route matching.
3
+ *
4
+ * `matchRoutes(routes, pathname)` resolves a pathname to a parent → child
5
+ * {@link RouteMatch}. No side effects, no reactivity — same input, same output.
6
+ * Ported from the fluixi router's matcher and made framework-agnostic.
7
+ */
8
+ /** Normalise accidental double slashes (`//x` → `/x`). */
9
+ function normalizePath(p) {
10
+ return p.startsWith('//') ? p.replace(/^\/+/, '/') : p;
11
+ }
12
+ /**
13
+ * Match a single route `pattern` against `path`.
14
+ *
15
+ * - `exact` (leaf routes) anchors the end; non-exact (layouts) matches a prefix
16
+ * up to a `/` boundary so children can consume the rest.
17
+ * - Supports `:param` and `*` / `*name` wildcards.
18
+ */
19
+ export function matchPath(pattern, path, exact = false) {
20
+ const keys = [];
21
+ if (pattern === path)
22
+ return { params: {}, path };
23
+ if (!exact && pattern === '/' && path.startsWith('/'))
24
+ return { params: {}, path: '/' };
25
+ let regexStr = pattern
26
+ .replace(/:([a-zA-Z0-9_]+)/g, (_, key) => {
27
+ keys.push(key);
28
+ return '([^/]+)';
29
+ })
30
+ .replace(/\*([a-zA-Z0-9_]*)/g, (_, name) => {
31
+ if (name)
32
+ keys.push(name);
33
+ return '(.*)';
34
+ });
35
+ if (!regexStr.startsWith('/'))
36
+ regexStr = '/' + regexStr;
37
+ if (regexStr === '')
38
+ regexStr = '/';
39
+ const regex = new RegExp(`^${regexStr}${exact ? '$' : '(?=/|$)'}`);
40
+ const match = path.match(regex);
41
+ if (!match)
42
+ return null;
43
+ const params = {};
44
+ keys.forEach((key, i) => {
45
+ params[key] = match[i + 1];
46
+ });
47
+ return { params, path: match[0] };
48
+ }
49
+ /** Specificity score: static segments > params > wildcards. Higher = more specific. */
50
+ export function scoreRoute(def) {
51
+ const segments = def.path.split('/').filter(Boolean);
52
+ if (segments.length === 0)
53
+ return 5;
54
+ let score = 0;
55
+ for (const seg of segments) {
56
+ if (seg.startsWith('*'))
57
+ score += 1;
58
+ else if (seg.startsWith(':'))
59
+ score += 10;
60
+ else
61
+ score += 100;
62
+ }
63
+ return score;
64
+ }
65
+ /** Most-specific-first ordering, without mutating the input. */
66
+ export function rankRoutes(defs) {
67
+ return [...defs].sort((a, b) => scoreRoute(b) - scoreRoute(a));
68
+ }
69
+ /** Match `pathname` against a route tree, returning the parent → child match. */
70
+ export function matchRoutes(routes, pathname) {
71
+ // Tolerate a trailing slash (static hosts like Cloudflare Pages canonicalise
72
+ // `/a/b` → `/a/b/`). Leaf routes match exactly (`^…$`), so a stray `/` would
73
+ // otherwise match nothing and render an empty root. Root `/` is preserved.
74
+ const path = pathname.length > 1 ? pathname.replace(/\/+$/, '') || '/' : pathname;
75
+ const result = matchInto(routes, path);
76
+ if (!result)
77
+ return null;
78
+ // Build the public match shape: cumulative pathnames + merged params.
79
+ const matched = [];
80
+ let cumulative = '';
81
+ const params = {};
82
+ for (const layer of result.layers) {
83
+ cumulative = normalizePath(joinMatched(cumulative, layer.consumed));
84
+ // A layer's `params` is the DELTA it introduces — full-path nested routes
85
+ // re-match ancestor params, but those belong to the ancestor layer, not here.
86
+ const layerParams = {};
87
+ for (const [k, v] of Object.entries(layer.params)) {
88
+ if (!(k in params))
89
+ layerParams[k] = v;
90
+ params[k] = v;
91
+ }
92
+ matched.push({
93
+ route: layer.route,
94
+ component: layer.route.component,
95
+ params: layerParams,
96
+ pathname: cumulative || '/',
97
+ });
98
+ }
99
+ return { matched, params, pathname };
100
+ }
101
+ function matchInto(defs, currentPath) {
102
+ if (!defs || defs.length === 0)
103
+ return null;
104
+ const ranked = rankRoutes(defs);
105
+ for (const def of ranked) {
106
+ const hasChildren = !!def.children && def.children.length > 0;
107
+ const seg = matchPath(def.path, currentPath, !hasChildren);
108
+ if (!seg)
109
+ continue;
110
+ if (hasChildren) {
111
+ const childMatch = matchInto(def.children, currentPath);
112
+ if (childMatch) {
113
+ return {
114
+ layers: [
115
+ { route: def, params: seg.params, consumed: seg.path },
116
+ ...childMatch.layers,
117
+ ],
118
+ };
119
+ }
120
+ // A layout matched the prefix but no child matched the remainder — keep
121
+ // searching siblings (this layout is not the right branch).
122
+ continue;
123
+ }
124
+ return { layers: [{ route: def, params: seg.params, consumed: seg.path }] };
125
+ }
126
+ return null;
127
+ }
128
+ /** Join the cumulative matched path with a layer's consumed segment. */
129
+ function joinMatched(cumulative, consumed) {
130
+ if (!cumulative)
131
+ return consumed;
132
+ if (consumed === cumulative)
133
+ return cumulative;
134
+ if (consumed.startsWith(cumulative))
135
+ return consumed;
136
+ const a = cumulative.replace(/\/$/, '');
137
+ const b = consumed.replace(/^\//, '');
138
+ return `${a}/${b}`;
139
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview The router state machine.
3
+ *
4
+ * Pure: holds the current location + match, recomputes the match on every
5
+ * history change, and notifies subscribers. Performs NO rendering — a view
6
+ * adapter subscribes and renders the resolved match tree top-down (see DESIGN.md).
7
+ */
8
+ import { splitPath } from './history.js';
9
+ import type { Router, RouterConfig } from './types.js';
10
+ export declare function createRouter<C = unknown>(config: RouterConfig<C>): Router<C>;
11
+ /** Re-export the public helper for parsing a raw path. */
12
+ export { splitPath };
13
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/lib/router.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EAKb,MAAM,YAAY,CAAC;AA8BpB,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EACtC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,MAAM,CAAC,CAAC,CAAC,CAuDX;AAED,0DAA0D;AAC1D,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @fileoverview The router state machine.
3
+ *
4
+ * Pure: holds the current location + match, recomputes the match on every
5
+ * history change, and notifies subscribers. Performs NO rendering — a view
6
+ * adapter subscribes and renders the resolved match tree top-down (see DESIGN.md).
7
+ */
8
+ import { matchRoutes } from './match.js';
9
+ import { splitPath } from './history.js';
10
+ /** Parse a `?a=1&b=2` search string into an object. */
11
+ function parseQuery(search) {
12
+ const q = {};
13
+ if (!search)
14
+ return q;
15
+ const usp = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search);
16
+ usp.forEach((v, k) => (q[k] = v));
17
+ return q;
18
+ }
19
+ /** Strip a base prefix from a pathname (so matching is base-relative). */
20
+ function stripBase(pathname, base) {
21
+ if (!base)
22
+ return pathname || '/';
23
+ const b = base.replace(/\/$/, '');
24
+ if (pathname === b)
25
+ return '/';
26
+ if (pathname.startsWith(b + '/'))
27
+ return pathname.slice(b.length) || '/';
28
+ return pathname || '/';
29
+ }
30
+ /** Prefix a base onto a target path for navigation. */
31
+ function withBase(to, base) {
32
+ if (!base)
33
+ return to;
34
+ if (/^https?:\/\//.test(to))
35
+ return to;
36
+ const b = base.replace(/\/$/, '');
37
+ return `${b}${to.startsWith('/') ? to : '/' + to}`;
38
+ }
39
+ export function createRouter(config) {
40
+ const { routes, history, base } = config;
41
+ const listeners = new Set();
42
+ const readLocation = () => {
43
+ const raw = history.get();
44
+ return {
45
+ pathname: raw.pathname,
46
+ search: raw.search,
47
+ hash: raw.hash,
48
+ state: raw.state,
49
+ query: parseQuery(raw.search),
50
+ };
51
+ };
52
+ const computeMatch = (pathname) => matchRoutes(routes, stripBase(pathname, base));
53
+ let current = (() => {
54
+ const location = readLocation();
55
+ return { location, match: computeMatch(location.pathname) };
56
+ })();
57
+ const recompute = () => {
58
+ const location = readLocation();
59
+ current = { location, match: computeMatch(location.pathname) };
60
+ listeners.forEach((l) => l(current));
61
+ };
62
+ const unsubscribeHistory = history.subscribe(recompute);
63
+ return {
64
+ state() {
65
+ return current;
66
+ },
67
+ subscribe(listener) {
68
+ listeners.add(listener);
69
+ return () => listeners.delete(listener);
70
+ },
71
+ navigate(to, options = {}) {
72
+ const target = withBase(to, base);
73
+ // The history adapter notifies on push/replace (memory + browser), which
74
+ // drives `recompute` via the subscription below — so we must NOT recompute
75
+ // again here or subscribers would fire twice per navigation.
76
+ if (options.replace)
77
+ history.replace(target, options.state ?? null);
78
+ else
79
+ history.push(target, options.state ?? null);
80
+ },
81
+ match(pathname) {
82
+ return computeMatch(pathname);
83
+ },
84
+ destroy() {
85
+ unsubscribeHistory();
86
+ listeners.clear();
87
+ },
88
+ };
89
+ }
90
+ /** Re-export the public helper for parsing a raw path. */
91
+ export { splitPath };
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @fileoverview Public types for the framework-agnostic router core.
3
+ *
4
+ * The core is generic over the component payload type `C` — it never calls or
5
+ * instantiates a component, it only carries the reference through to the match
6
+ * result. A view adapter (fluixi, react, …) decides what `C` is and how to
7
+ * render it. This keeps the core pure and unit-testable with plain values.
8
+ */
9
+ /** Loader invoked for a route's data (opaque to the core; adapters define args). */
10
+ export type RouteData = unknown;
11
+ /** A node in the route tree the application declares. */
12
+ export interface RouteDefinition<C = unknown> {
13
+ /** Path pattern: static (`/users`), params (`/users/:id`), or wildcard (`/files/*`). */
14
+ path: string;
15
+ /** Opaque component reference for this layer (layout or page). Optional for pathless layout groups. */
16
+ component?: C;
17
+ /** Child routes nested under this one (a layout's pages/sub-layouts). */
18
+ children?: RouteDefinition<C>[];
19
+ /** Opaque data loader / metadata attached to this route. */
20
+ data?: RouteData;
21
+ /** Arbitrary adapter metadata (e.g. lazy markers). Ignored by the core. */
22
+ meta?: Record<string, unknown>;
23
+ }
24
+ /** One matched layer of a route match, parent → child order in {@link RouteMatch.matched}. */
25
+ export interface MatchedRoute<C = unknown> {
26
+ /** The route definition that matched at this layer. */
27
+ route: RouteDefinition<C>;
28
+ /** The component reference for this layer (may be undefined for pathless layouts). */
29
+ component?: C;
30
+ /** Params introduced AT THIS LAYER (not merged with ancestors). */
31
+ params: Record<string, string>;
32
+ /** Cumulative matched pathname up to and including this layer. */
33
+ pathname: string;
34
+ }
35
+ /** The result of matching a pathname against a route tree. */
36
+ export interface RouteMatch<C = unknown> {
37
+ /** Matched layers, parent → child. `matched[0]` is the outermost layout. */
38
+ matched: MatchedRoute<C>[];
39
+ /** All params merged across every matched layer. */
40
+ params: Record<string, string>;
41
+ /** The pathname that produced this match. */
42
+ pathname: string;
43
+ }
44
+ /** A parsed location. `query` is the parsed `search`. */
45
+ export interface RouterLocation {
46
+ pathname: string;
47
+ search: string;
48
+ hash: string;
49
+ state: unknown;
50
+ query: Record<string, string>;
51
+ }
52
+ /** Options for {@link Router.navigate}. */
53
+ export interface NavigateOptions {
54
+ /** Replace the current history entry instead of pushing a new one. */
55
+ replace?: boolean;
56
+ /** Opaque history state to attach. */
57
+ state?: unknown;
58
+ }
59
+ /** A snapshot of the router's current state. */
60
+ export interface RouterState<C = unknown> {
61
+ location: RouterLocation;
62
+ match: RouteMatch<C> | null;
63
+ }
64
+ /** Pluggable history backend. Memory for tests/SSR, browser for the DOM. */
65
+ export interface HistoryAdapter {
66
+ /** Read the current raw location. */
67
+ get(): {
68
+ pathname: string;
69
+ search: string;
70
+ hash: string;
71
+ state: unknown;
72
+ };
73
+ /** Push a new entry. `to` is a full path (may include search/hash). */
74
+ push(to: string, state?: unknown): void;
75
+ /** Replace the current entry. */
76
+ replace(to: string, state?: unknown): void;
77
+ /** Subscribe to external navigation (popstate). Returns an unsubscribe fn. */
78
+ subscribe(onChange: () => void): () => void;
79
+ }
80
+ /** A router instance — a pure state machine over location + match. */
81
+ export interface Router<C = unknown> {
82
+ /** Current snapshot. */
83
+ state(): RouterState<C>;
84
+ /** Subscribe to state changes. Returns an unsubscribe fn. */
85
+ subscribe(listener: (state: RouterState<C>) => void): () => void;
86
+ /** Navigate to a path. */
87
+ navigate(to: string, options?: NavigateOptions): void;
88
+ /** Pure match against this router's route tree (respects `base`). */
89
+ match(pathname: string): RouteMatch<C> | null;
90
+ /** Detach from history. */
91
+ destroy(): void;
92
+ }
93
+ /** Config for {@link createRouter}. */
94
+ export interface RouterConfig<C = unknown> {
95
+ routes: RouteDefinition<C>[];
96
+ history: HistoryAdapter;
97
+ /** Optional base path stripped from the pathname before matching. */
98
+ base?: string;
99
+ }
100
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Public types for the framework-agnostic router core.
3
+ *
4
+ * The core is generic over the component payload type `C` — it never calls or
5
+ * instantiates a component, it only carries the reference through to the match
6
+ * result. A view adapter (fluixi, react, …) decides what `C` is and how to
7
+ * render it. This keeps the core pure and unit-testable with plain values.
8
+ */
9
+ export {};
@@ -0,0 +1 @@
1
+ {"fileNames":["../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/.pnpm/typescript@5.8.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/tslib.d.ts","../../../node_modules/.pnpm/tslib@2.8.1/node_modules/tslib/modules/index.d.ts","../src/lib/types.ts","../src/lib/match.ts","../src/lib/history.ts","../src/lib/router.ts","../src/index.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/assert.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/assert/strict.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/globals.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/async_hooks.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/buffer.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/child_process.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/cluster.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/console.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/constants.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/crypto.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/dgram.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/dns.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/dns/promises.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/domain.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/dom-events.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/events.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/fs.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/fs/promises.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/http.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/http2.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/https.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/inspector.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/module.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/net.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/os.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/path.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/process.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/punycode.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/querystring.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/readline.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/readline/promises.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/repl.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/stream.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/stream/promises.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/stream/web.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/string_decoder.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/test.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/timers.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/timers/promises.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/tls.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/trace_events.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/tty.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/url.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/util.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/v8.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/vm.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/wasi.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/worker_threads.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/zlib.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/globals.global.d.ts","../../../node_modules/.pnpm/@types+node@18.16.9/node_modules/@types/node/index.d.ts"],"fileIdsList":[[61,107],[64,107],[65,70,98,107],[66,77,78,85,95,106,107],[66,67,77,85,107],[68,107],[69,70,78,86,107],[70,95,103,107],[71,73,77,85,107],[72,107],[73,74,107],[77,107],[75,77,107],[77,78,79,95,106,107],[77,78,79,92,95,98,107],[107,111],[107],[73,77,80,85,95,106,107],[77,78,80,81,85,95,103,106,107],[80,82,95,103,106,107],[61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113],[77,83,107],[84,106,107],[73,77,85,95,107],[86,107],[87,107],[64,88,107],[89,105,107,111],[90,107],[91,107],[77,92,93,107],[92,94,107,109],[65,77,95,96,97,98,107],[65,95,97,107],[95,96,107],[98,107],[99,107],[77,101,102,107],[101,102,107],[70,85,95,103,107],[104,107],[85,105,107],[65,80,91,106,107],[70,107],[95,107,108],[107,109],[107,110],[65,70,77,79,88,95,106,107,109,111],[95,107,112],[54,107],[55,56,57,58,59,107],[55,56,107],[55,56,57,58,107],[55,107]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6a5253138c5432c68a1510c70fe78a644fe2e632111ba778e1978010d6edfec","impliedFormat":1},{"version":"b8f34dd1757f68e03262b1ca3ddfa668a855b872f8bdd5224d6f993a7b37dc2c","impliedFormat":99},{"version":"86c2e7a253ceb071e1294a494bc808c51b1e31b8ca9b939248003526e45e2c4a","signature":"4d19aa2a9bf11f03350f885799abb2a399e49308ff23582f0bfc7ca3de1ef964","impliedFormat":99},{"version":"4e7b2fb7d220f92841910859386eaa5144d29bcf9da73aa9f38ee9a76a139d5b","signature":"3206bc8f6c9cf553a7bdd45999e405e7e95524558b6516359bd552ad49e02edb","impliedFormat":99},{"version":"616be7cd36a0fa09b88601304a002e2c8e9f15765d033d4eeb5fd263e3460080","signature":"d06367c35e944d602fec4a3bfe3cb00ca44fab949354392add4d6386c620d294","impliedFormat":99},{"version":"a610720ada450ef728d59ef7238d6880f5b94f2d20d4d78cebfc3bdb5904257e","signature":"f0c0df41d93b49b7a7fc3c69f9f2b2f6cfb58e59d8e0869f6bf7bd6a3003b7dd","impliedFormat":99},{"version":"94c2760d3ba05cdd8a0b0c02e70059701e3a1ce611561bb484acc1828dfa8084","signature":"a4766338e78a77ceb79b55f54ad3b9d6d9f0aa3ecea6d6097bbbb671020594a1","impliedFormat":99},{"version":"7e771891adaa85b690266bc37bd6eb43bc57eecc4b54693ead36467e7369952a","impliedFormat":1},{"version":"a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a","impliedFormat":1},{"version":"f749812878fecfa53cfc13b36e5d35086fb6377983a9df44175da83ccc23af1f","affectsGlobalScope":true,"impliedFormat":1},{"version":"7d2e3fea24c712c99c03ad8f556abedbfe105f87f1be10b95dbd409d24bc05a3","impliedFormat":1},{"version":"211e3f15fbced4ab4be19f49ffa990b9ff20d749d33b65ff753be691e7616239","affectsGlobalScope":true,"impliedFormat":1},{"version":"3719525a8f6ab731e3dfd585d9f87df55ec7d50d461df84f74eb4d68bb165244","impliedFormat":1},{"version":"5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713","impliedFormat":1},{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true,"impliedFormat":1},{"version":"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","impliedFormat":1},{"version":"e596c9bb2f29a2699fdd4ae89139612652245192f67f45617c5a4b20832aaae9","impliedFormat":1},{"version":"bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","impliedFormat":1},{"version":"1cdcfc1f624d6c08aa12c73935f6e13f095919cd99edf95752951796eb225729","impliedFormat":1},{"version":"4eaff3d8e10676fd7913d8c108890e71c688e1e7d52f6d1d55c39514f493dc47","impliedFormat":1},{"version":"14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","impliedFormat":1},{"version":"5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea","impliedFormat":1},{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true,"impliedFormat":1},{"version":"00dee7cdca8b8420c47ea4a31a34b8e8294013ebc4f463fd941e867e7bf05029","affectsGlobalScope":true,"impliedFormat":1},{"version":"3256f3cccd578f9e7fe3a28096c505634bebcee8afb738ffa99368e536ca3a0b","impliedFormat":1},{"version":"1c84b46267610a34028edfd0d035509341751262bac1062857f3c8df7aff7153","impliedFormat":1},{"version":"7f138842074d0a40681775af008c8452093b68c383c94de31759e853c6d06b5c","impliedFormat":1},{"version":"a3d541d303ee505053f5dcbf9fafb65cac3d5631037501cd616195863a6c5740","impliedFormat":1},{"version":"8d3c583a07e0c37e876908c2d5da575019f689df8d9fa4c081d99119d53dba22","impliedFormat":1},{"version":"2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58","impliedFormat":1},{"version":"e630e5528e899219ae319e83bef54bf3bcb91b01d76861ecf881e8e614b167f0","affectsGlobalScope":true,"impliedFormat":1},{"version":"bcebb922784739bdb34c18ee51095d25a92b560c78ccd2eaacd6bd00f7443d83","impliedFormat":1},{"version":"7ee6ed878c4528215c82b664fe0cfe80e8b4da6c0d4cc80869367868774db8b1","impliedFormat":1},{"version":"b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30","impliedFormat":1},{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true,"impliedFormat":1},{"version":"0715e4cd28ad471b2a93f3e552ff51a3ae423417a01a10aa1d3bc7c6b95059d6","affectsGlobalScope":true,"impliedFormat":1},{"version":"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","impliedFormat":1},{"version":"210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","impliedFormat":1},{"version":"36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","impliedFormat":1},{"version":"0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","impliedFormat":1},{"version":"25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","impliedFormat":1},{"version":"4f3fdeba4e28e21aa719c081b8dc8f91d47e12e773389b9d35679c08151c9d37","impliedFormat":1},{"version":"1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","impliedFormat":1},{"version":"69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","impliedFormat":1},{"version":"44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","impliedFormat":1},{"version":"23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","impliedFormat":1},{"version":"f69ff39996a61a0dd10f4bce73272b52e8024a4d58b13ab32bf4712909d0a2b7","impliedFormat":1},{"version":"3c4ba1dd9b12ffa284b565063108f2f031d150ea15b8fafbdc17f5d2a07251f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"e10177274a35a9d07c825615340b2fcde2f610f53f3fb40269fd196b4288dda6","impliedFormat":1},{"version":"1422cd9e705adcc09088fda85a900c2b70e3ad36ea85846f68bd1a884cdf4e2b","impliedFormat":1},{"version":"3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","impliedFormat":1},{"version":"5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2","impliedFormat":1},{"version":"a73ae8c0e62103bb9e21bb6538700881bf135b9a8b125b857ec68edfa0da4ed3","affectsGlobalScope":true,"impliedFormat":1},{"version":"e1c1b2fbe236bf7ee3e342eeae7e20efb8988a0ac7da1cbbfa2c1f66b76c3423","affectsGlobalScope":true,"impliedFormat":1},{"version":"868831cab82b65dfe1d68180e898af1f2101e89ba9b754d1db6fb8cc2fac1921","impliedFormat":1},{"version":"0fe8985a28f82c450a04a6edf1279d7181c0893f37da7d2a27f8efd4fd5edb03","impliedFormat":1},{"version":"e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa","impliedFormat":1},{"version":"52120bb7e4583612225bdf08e7c12559548170f11e660d33a33623bae9bbdbba","affectsGlobalScope":true,"impliedFormat":1},{"version":"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e","impliedFormat":1},{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6dd3dba8e665ac43d279e0fdf5219edda0eed69b5e9a5061f46cd6a65c4f7a1","impliedFormat":1}],"root":[[56,60]],"options":{"composite":true,"declarationMap":true,"emitDeclarationOnly":false,"importHelpers":true,"module":199,"noEmitOnError":true,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noUnusedLocals":false,"noUnusedParameters":false,"outDir":"./","rootDir":"../src","skipLibCheck":true,"strict":true,"target":9,"tsBuildInfoFile":"./tsconfig.lib.tsbuildinfo"},"referencedMap":[[61,1],[62,1],[64,2],[65,3],[66,4],[67,5],[68,6],[69,7],[70,8],[71,9],[72,10],[73,11],[74,11],[76,12],[75,13],[77,12],[78,14],[79,15],[63,16],[113,17],[80,18],[81,19],[82,20],[114,21],[83,22],[84,23],[85,24],[86,25],[87,26],[88,27],[89,28],[90,29],[91,30],[92,31],[93,31],[94,32],[95,33],[97,34],[96,35],[98,36],[99,37],[100,17],[101,38],[102,39],[103,40],[104,41],[105,42],[106,43],[107,44],[108,45],[109,46],[110,47],[111,48],[112,49],[55,50],[54,17],[52,17],[53,17],[9,17],[10,17],[12,17],[11,17],[2,17],[13,17],[14,17],[15,17],[16,17],[17,17],[18,17],[19,17],[20,17],[3,17],[21,17],[22,17],[4,17],[23,17],[27,17],[24,17],[25,17],[26,17],[28,17],[29,17],[30,17],[5,17],[31,17],[32,17],[33,17],[34,17],[6,17],[38,17],[35,17],[36,17],[37,17],[39,17],[7,17],[40,17],[45,17],[46,17],[41,17],[42,17],[43,17],[44,17],[8,17],[50,17],[47,17],[48,17],[49,17],[1,17],[51,17],[60,51],[58,52],[57,52],[59,53],[56,54]],"latestChangedDtsFile":"./index.d.ts","version":"5.8.3"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@fluixi/router",
3
+ "version": "0.1.2-alpha.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/fluixi/core.git",
7
+ "directory": "packages/router"
8
+ },
9
+ "private": false,
10
+ "publishConfig": {
11
+ "registry": "https://registry.npmjs.org/",
12
+ "access": "public"
13
+ },
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "exports": {
23
+ "./package.json": "./package.json",
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "default": "./dist/index.js"
28
+ }
29
+ },
30
+ "scripts": {
31
+ "test": "vitest run",
32
+ "build": "tsc -p tsconfig.lib.json"
33
+ }
34
+ }