@ripetchor/r-router 1.0.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 +1 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +460 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# r-router
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export declare type AfterEnterHook = (ctx: RouteContext) => void | Promise<void>;
|
|
2
|
+
|
|
3
|
+
declare interface AsyncRoute extends BaseRoute {
|
|
4
|
+
redirectTo?: never;
|
|
5
|
+
component?(): never;
|
|
6
|
+
loadComponent(ctx: RouteContext): Promise<HTMLElement>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare interface BaseRoute {
|
|
10
|
+
path: string;
|
|
11
|
+
title?: string | ((ctx: RouteContext) => string);
|
|
12
|
+
beforeEnter?: BeforeEnterHook[];
|
|
13
|
+
afterEnter?: AfterEnterHook[];
|
|
14
|
+
errorComponent?(error: unknown, ctx: RouteContext | null): HTMLElement;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export declare type BeforeEnterHook = (ctx: RouteContext) => boolean | string | Promise<boolean | string>;
|
|
18
|
+
|
|
19
|
+
export declare function createRouter(routes: Route[], options?: RouterOptions): Router;
|
|
20
|
+
|
|
21
|
+
declare interface RedirectRoute extends BaseRoute {
|
|
22
|
+
redirectTo: string;
|
|
23
|
+
component?(): never;
|
|
24
|
+
loadComponent?(): never;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export declare type Route = SyncRoute | AsyncRoute | RedirectRoute;
|
|
28
|
+
|
|
29
|
+
declare interface RouteContext {
|
|
30
|
+
from: string | null;
|
|
31
|
+
to: string;
|
|
32
|
+
params: Record<string, string>;
|
|
33
|
+
query: URLSearchParams;
|
|
34
|
+
signal: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export declare class Router {
|
|
38
|
+
private readonly routerController;
|
|
39
|
+
private initialized;
|
|
40
|
+
private navigationController;
|
|
41
|
+
private readonly matchers;
|
|
42
|
+
private readonly options;
|
|
43
|
+
private readonly rootOutletInternal;
|
|
44
|
+
private currentPath;
|
|
45
|
+
constructor(routes: Route[], options?: RouterOptions);
|
|
46
|
+
initialize(): Promise<Readonly<RouterOutlet>>;
|
|
47
|
+
destroy(): void;
|
|
48
|
+
private navigate;
|
|
49
|
+
push(path: string, state?: unknown): Promise<void>;
|
|
50
|
+
replace(path: string, state?: unknown): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
declare interface RouterOptions {
|
|
54
|
+
defaultTitle?: string;
|
|
55
|
+
globalErrorComponent?: (error: unknown) => HTMLElement;
|
|
56
|
+
sortRoutesBySpecificity?: boolean;
|
|
57
|
+
ignoreSameLocation?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare class RouterOutlet extends HTMLElement {
|
|
61
|
+
constructor(props: RouterOutletProps);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare type RouterOutletProps = {
|
|
65
|
+
outletId: string;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
declare interface SyncRoute extends BaseRoute {
|
|
69
|
+
redirectTo?: never;
|
|
70
|
+
component(ctx: RouteContext): HTMLElement;
|
|
71
|
+
loadComponent?(): Promise<HTMLElement>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
function P(t, e) {
|
|
2
|
+
const n = document.createElement("div");
|
|
3
|
+
n.style.cssText = `
|
|
4
|
+
position: fixed;
|
|
5
|
+
inset: 0;
|
|
6
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
z-index: 9999;
|
|
11
|
+
backdrop-filter: blur(4px);
|
|
12
|
+
animation: fadeIn 0.25s ease;
|
|
13
|
+
`;
|
|
14
|
+
const o = document.createElement("div");
|
|
15
|
+
o.style.cssText = `
|
|
16
|
+
position: relative;
|
|
17
|
+
max-width: 80dvh;
|
|
18
|
+
width: 100%;
|
|
19
|
+
background-color: var(--bg);
|
|
20
|
+
color: var(--text);
|
|
21
|
+
border-radius: 16px;
|
|
22
|
+
padding: 32px 28px;
|
|
23
|
+
box-shadow: 0 8px 40px rgba(0,0,0,0.3);
|
|
24
|
+
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
25
|
+
text-align: center;
|
|
26
|
+
animation: scaleIn 0.25s ease;
|
|
27
|
+
`;
|
|
28
|
+
const r = document.createElement("h1");
|
|
29
|
+
r.textContent = "Something went wrong", r.style.cssText = `
|
|
30
|
+
margin: 0 0 12px;
|
|
31
|
+
font-size: 2rem;
|
|
32
|
+
font-weight: 700;
|
|
33
|
+
color: var(--accent);
|
|
34
|
+
`;
|
|
35
|
+
const i = document.createElement("h2");
|
|
36
|
+
i.textContent = t?.message || "An unexpected error occurred.", i.style.cssText = `
|
|
37
|
+
font-size: 1.1rem;
|
|
38
|
+
margin-bottom: 16px;
|
|
39
|
+
opacity: 0.9;
|
|
40
|
+
`;
|
|
41
|
+
const a = document.createElement("div"), s = document.createElement("p"), c = document.createElement("p");
|
|
42
|
+
s.textContent = e?.from ?? "", c.textContent = e?.to ?? "", a.append(s, c);
|
|
43
|
+
const d = document.createElement("pre");
|
|
44
|
+
d.textContent = t?.stack || "", d.style.cssText = `
|
|
45
|
+
font-size: 0.9rem;
|
|
46
|
+
max-height: 30vh;
|
|
47
|
+
overflow: auto;
|
|
48
|
+
background: var(--code-bg);
|
|
49
|
+
padding: 12px;
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
text-align: left;
|
|
52
|
+
white-space: pre-wrap;
|
|
53
|
+
margin-bottom: 24px;
|
|
54
|
+
`;
|
|
55
|
+
const f = document.createElement("button");
|
|
56
|
+
f.textContent = "Reload Page", f.style.cssText = `
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
padding: 10px 20px;
|
|
59
|
+
border: none;
|
|
60
|
+
border-radius: 6px;
|
|
61
|
+
font-size: 1rem;
|
|
62
|
+
font-weight: 600;
|
|
63
|
+
background-color: var(--button-bg);
|
|
64
|
+
color: var(--button-text);
|
|
65
|
+
transition: background-color 0.25s;
|
|
66
|
+
`;
|
|
67
|
+
const l = document.createElement("button");
|
|
68
|
+
l.innerHTML = "✕", l.setAttribute("aria-label", "Close error dialog"), l.style.cssText = `
|
|
69
|
+
position: absolute;
|
|
70
|
+
top: 12px;
|
|
71
|
+
right: 12px;
|
|
72
|
+
font-size: 1.2rem;
|
|
73
|
+
background: none;
|
|
74
|
+
border: none;
|
|
75
|
+
color: var(--text);
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
opacity: 0.7;
|
|
78
|
+
transition: opacity 0.25s;
|
|
79
|
+
`, l.onmouseenter = () => {
|
|
80
|
+
l.style.opacity = "1";
|
|
81
|
+
}, l.onmouseleave = () => {
|
|
82
|
+
l.style.opacity = "0.7";
|
|
83
|
+
}, l.onclick = () => {
|
|
84
|
+
n.remove();
|
|
85
|
+
}, f.onmouseenter = () => {
|
|
86
|
+
f.style.backgroundColor = "var(--button-bg-hover)";
|
|
87
|
+
}, f.onmouseleave = () => {
|
|
88
|
+
f.style.backgroundColor = "var(--button-bg)";
|
|
89
|
+
}, f.onclick = () => {
|
|
90
|
+
location.reload();
|
|
91
|
+
}, n.appendChild(o), o.append(l, r, i, a), t.stack && o.append(d), o.append(f);
|
|
92
|
+
const g = (u) => {
|
|
93
|
+
u.key === "Escape" && n.remove();
|
|
94
|
+
};
|
|
95
|
+
window.addEventListener("keydown", g);
|
|
96
|
+
const w = new MutationObserver(() => {
|
|
97
|
+
document.body.contains(n) || (window.removeEventListener("keydown", g), w.disconnect());
|
|
98
|
+
});
|
|
99
|
+
w.observe(document.body, { childList: !0 });
|
|
100
|
+
const y = () => {
|
|
101
|
+
const u = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
102
|
+
o.style.setProperty("--bg", u ? "#2b2b2b" : "#fff"), o.style.setProperty("--text", u ? "#eee" : "#222"), o.style.setProperty("--accent", u ? "#ff6b6b" : "#e74c3c"), o.style.setProperty(
|
|
103
|
+
"--code-bg",
|
|
104
|
+
u ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.05)"
|
|
105
|
+
), o.style.setProperty("--button-bg", u ? "#3498db55" : "#3498db"), o.style.setProperty(
|
|
106
|
+
"--button-bg-hover",
|
|
107
|
+
u ? "#3498db88" : "#2980b9"
|
|
108
|
+
), o.style.setProperty("--button-text", "#fff");
|
|
109
|
+
};
|
|
110
|
+
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", y), y();
|
|
111
|
+
const b = document.createElement("style");
|
|
112
|
+
return b.textContent = `
|
|
113
|
+
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
114
|
+
@keyframes scaleIn { from { transform: scale(0.95); opacity: 0; } to { transform: scale(1); opacity: 1; } }
|
|
115
|
+
`, document.head.appendChild(b), n;
|
|
116
|
+
}
|
|
117
|
+
function k(t, e, n) {
|
|
118
|
+
t.title ? document.title = typeof t.title == "function" ? t.title(e) : t.title : document.title = n ?? "";
|
|
119
|
+
}
|
|
120
|
+
function p(t, e, n) {
|
|
121
|
+
const o = e ?? null;
|
|
122
|
+
switch (n) {
|
|
123
|
+
case "push":
|
|
124
|
+
window.history.pushState(o, "", t);
|
|
125
|
+
break;
|
|
126
|
+
case "replace":
|
|
127
|
+
window.history.replaceState(o, "", t);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function T(t, e) {
|
|
132
|
+
t.replaceChildren(e);
|
|
133
|
+
}
|
|
134
|
+
function h(t, e, n, o, r) {
|
|
135
|
+
const i = n?.errorComponent?.(e, o) ?? r?.(e) ?? P(e, o);
|
|
136
|
+
t.replaceChildren(i);
|
|
137
|
+
}
|
|
138
|
+
const A = "*";
|
|
139
|
+
function L({ path: t }) {
|
|
140
|
+
return t.includes(":");
|
|
141
|
+
}
|
|
142
|
+
function x(t) {
|
|
143
|
+
const [, e] = t.split("?");
|
|
144
|
+
return new URLSearchParams(e || "");
|
|
145
|
+
}
|
|
146
|
+
function $({ path: t }) {
|
|
147
|
+
const e = t.replace(
|
|
148
|
+
/:([^/]+)/g,
|
|
149
|
+
(n, o) => `(?<${o}>[^/]+)`
|
|
150
|
+
);
|
|
151
|
+
return new RegExp(`^${e}$`);
|
|
152
|
+
}
|
|
153
|
+
function S(t) {
|
|
154
|
+
const e = $(t);
|
|
155
|
+
return {
|
|
156
|
+
route: t,
|
|
157
|
+
redirectTo: t.redirectTo || null,
|
|
158
|
+
match(n) {
|
|
159
|
+
const o = n.split("?")[0];
|
|
160
|
+
return e.test(o);
|
|
161
|
+
},
|
|
162
|
+
getParams(n) {
|
|
163
|
+
return e.exec(n)?.groups ?? {};
|
|
164
|
+
},
|
|
165
|
+
getQuery: x
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function z({ path: t }) {
|
|
169
|
+
return t === A ? new RegExp("^.*$") : new RegExp(`^${t}$`);
|
|
170
|
+
}
|
|
171
|
+
function I(t) {
|
|
172
|
+
const e = z(t);
|
|
173
|
+
return {
|
|
174
|
+
route: t,
|
|
175
|
+
redirectTo: t.redirectTo || null,
|
|
176
|
+
match(n) {
|
|
177
|
+
const o = n.split("?")[0];
|
|
178
|
+
return e.test(o);
|
|
179
|
+
},
|
|
180
|
+
getParams() {
|
|
181
|
+
return {};
|
|
182
|
+
},
|
|
183
|
+
getQuery: x
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function O(t) {
|
|
187
|
+
return L(t) ? S(t) : I(t);
|
|
188
|
+
}
|
|
189
|
+
function M(t, e) {
|
|
190
|
+
for (let n = 0; n < e.length; n++)
|
|
191
|
+
if (e[n].match(t))
|
|
192
|
+
return e[n];
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
async function W(t, e) {
|
|
196
|
+
return typeof t.component == "function" ? t.component(e) : typeof t.loadComponent == "function" ? await t.loadComponent(e) : new Error("Failed to get component for route");
|
|
197
|
+
}
|
|
198
|
+
async function B(t, e) {
|
|
199
|
+
const n = t.afterEnter;
|
|
200
|
+
if (!(!n || n.length === 0))
|
|
201
|
+
for (const o of n)
|
|
202
|
+
await o(e);
|
|
203
|
+
}
|
|
204
|
+
async function H(t, e) {
|
|
205
|
+
const n = t.beforeEnter;
|
|
206
|
+
if (!n || n.length === 0)
|
|
207
|
+
return null;
|
|
208
|
+
for (const o of n) {
|
|
209
|
+
const r = await o(e);
|
|
210
|
+
if (r === !1 || typeof r == "string")
|
|
211
|
+
return r;
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
function E(t) {
|
|
216
|
+
return t instanceof DOMException && t.name === "AbortError";
|
|
217
|
+
}
|
|
218
|
+
class C extends HTMLElement {
|
|
219
|
+
constructor(e) {
|
|
220
|
+
super(), this.setAttribute("outlet-id", e.outletId);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
customElements.define("router-outlet", C);
|
|
224
|
+
async function m(t, e) {
|
|
225
|
+
if (e.aborted)
|
|
226
|
+
throw new DOMException("Aborted", "AbortError");
|
|
227
|
+
return new Promise((n, o) => {
|
|
228
|
+
const r = () => o(new DOMException("Aborted", "AbortError"));
|
|
229
|
+
e.addEventListener("abort", r), t().then(n).catch(o).finally(() => {
|
|
230
|
+
e.removeEventListener("abort", r);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
function v(t) {
|
|
235
|
+
const e = t.split("/").filter(Boolean);
|
|
236
|
+
if (e.length === 0)
|
|
237
|
+
return 0;
|
|
238
|
+
let n = 0;
|
|
239
|
+
for (let o = 0; o < e.length; o++) {
|
|
240
|
+
const r = e[o];
|
|
241
|
+
r === "*" ? n -= 100 : r.startsWith(":") ? n += 5 : n += 10;
|
|
242
|
+
}
|
|
243
|
+
return n += e.length * 0.1, n;
|
|
244
|
+
}
|
|
245
|
+
function U(t) {
|
|
246
|
+
return t.toSorted((e, n) => v(n.path) - v(e.path));
|
|
247
|
+
}
|
|
248
|
+
function D(t, e) {
|
|
249
|
+
if (t === null)
|
|
250
|
+
return !1;
|
|
251
|
+
const n = new URL(t, location.origin), o = new URL(e, location.origin);
|
|
252
|
+
return !(n.pathname !== o.pathname || n.search !== o.search);
|
|
253
|
+
}
|
|
254
|
+
function R(t) {
|
|
255
|
+
if (typeof t != "string")
|
|
256
|
+
throw new Error(`Path must be a string, got ${typeof t}`);
|
|
257
|
+
if (t.trim() === "")
|
|
258
|
+
throw new Error("Path cannot be an empty string");
|
|
259
|
+
if (t !== "*" && !t.startsWith("/"))
|
|
260
|
+
throw new Error(`Path must start with '/': "${t}"`);
|
|
261
|
+
if (t.length > 1 && t.endsWith("/"))
|
|
262
|
+
throw new Error(`Path must not end with '/': "${t}"`);
|
|
263
|
+
if (t.includes("//"))
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Path must not contain multiple consecutive slashes: "${t}"`
|
|
266
|
+
);
|
|
267
|
+
if (t === "*") return;
|
|
268
|
+
const e = t.match(/[^A-Za-z0-9\-._~:/@]/g);
|
|
269
|
+
if (e)
|
|
270
|
+
throw new Error(
|
|
271
|
+
`Path contains invalid characters: "${e.join("")}" in "${t}"`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
function Q(t) {
|
|
275
|
+
const e = /* @__PURE__ */ new Set();
|
|
276
|
+
for (let n = 0; n < t.length; n++) {
|
|
277
|
+
const o = t[n].path;
|
|
278
|
+
if (e.has(o))
|
|
279
|
+
throw new Error(`Duplicate root route path: "${o}"`);
|
|
280
|
+
e.add(o);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function _(t) {
|
|
284
|
+
if (!(t.redirectTo === null || t.redirectTo == null) && typeof t.redirectTo == "string") {
|
|
285
|
+
const e = t.redirectTo;
|
|
286
|
+
if (R(e), e === t.path)
|
|
287
|
+
throw new Error(`Route "${t.path}" cannot redirect to itself`);
|
|
288
|
+
if (t.path === "*")
|
|
289
|
+
throw new Error('Catch-all route "*" cannot have a redirect');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function q(t) {
|
|
293
|
+
const e = typeof t.redirectTo == "string", n = typeof t.component == "function", o = typeof t.loadComponent == "function";
|
|
294
|
+
if (e && (n || o))
|
|
295
|
+
throw new Error(
|
|
296
|
+
`Redirect route "${t.path}" must not define components`
|
|
297
|
+
);
|
|
298
|
+
if (n && o)
|
|
299
|
+
throw new Error(
|
|
300
|
+
`Route "${t.path}" cannot have both component and loadComponent`
|
|
301
|
+
);
|
|
302
|
+
if (!e && !n && !o)
|
|
303
|
+
throw new Error(
|
|
304
|
+
`Route "${t.path}" must define either "component" or "loadComponent"`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
function F(t) {
|
|
308
|
+
R(t.path), _(t), q(t);
|
|
309
|
+
}
|
|
310
|
+
function j(t) {
|
|
311
|
+
Q(t);
|
|
312
|
+
for (let e = 0; e < t.length; e++) {
|
|
313
|
+
const n = t[e];
|
|
314
|
+
F(n);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
class K {
|
|
318
|
+
routerController = new AbortController();
|
|
319
|
+
initialized = !1;
|
|
320
|
+
navigationController = null;
|
|
321
|
+
matchers = [];
|
|
322
|
+
options;
|
|
323
|
+
rootOutletInternal = new C({ outletId: "root" });
|
|
324
|
+
currentPath = null;
|
|
325
|
+
constructor(e, n) {
|
|
326
|
+
j(e), this.options = {
|
|
327
|
+
defaultTitle: document.title,
|
|
328
|
+
sortRoutesBySpecificity: !0,
|
|
329
|
+
...n
|
|
330
|
+
};
|
|
331
|
+
const o = this.options.sortRoutesBySpecificity ? U(e) : e;
|
|
332
|
+
this.matchers = o.map(O);
|
|
333
|
+
}
|
|
334
|
+
async initialize() {
|
|
335
|
+
if (this.initialized)
|
|
336
|
+
throw new Error("Router already initialized");
|
|
337
|
+
const e = async (o) => {
|
|
338
|
+
const r = window.location.pathname + window.location.search;
|
|
339
|
+
await this.navigate(r, o.state, "none");
|
|
340
|
+
};
|
|
341
|
+
window.addEventListener(
|
|
342
|
+
"popstate",
|
|
343
|
+
(o) => {
|
|
344
|
+
e(o).catch(console.error);
|
|
345
|
+
},
|
|
346
|
+
{ signal: this.routerController.signal }
|
|
347
|
+
);
|
|
348
|
+
const n = window.location.pathname + window.location.search;
|
|
349
|
+
return await this.navigate(n, null, "none"), this.initialized = !0, this.rootOutletInternal;
|
|
350
|
+
}
|
|
351
|
+
destroy() {
|
|
352
|
+
if (!this.initialized)
|
|
353
|
+
throw new Error("Router not initialized");
|
|
354
|
+
this.routerController.abort(), this.navigationController && (this.navigationController.abort(), this.navigationController = null), this.initialized = !1;
|
|
355
|
+
}
|
|
356
|
+
async navigate(e, n, o, r = 0) {
|
|
357
|
+
if (r > 5) {
|
|
358
|
+
h(
|
|
359
|
+
this.rootOutletInternal,
|
|
360
|
+
new Error("Too many redirects"),
|
|
361
|
+
null,
|
|
362
|
+
null,
|
|
363
|
+
this.options.globalErrorComponent
|
|
364
|
+
);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (this.options.ignoreSameLocation && D(this.currentPath, e))
|
|
368
|
+
return;
|
|
369
|
+
this.navigationController && (this.navigationController.abort("navigation canceled"), this.navigationController = null), this.navigationController = new AbortController();
|
|
370
|
+
const i = this.navigationController.signal, a = M(e, this.matchers), s = {
|
|
371
|
+
from: this.currentPath,
|
|
372
|
+
to: e,
|
|
373
|
+
params: a?.getParams(e) ?? {},
|
|
374
|
+
query: a?.getQuery(e) ?? new URLSearchParams(),
|
|
375
|
+
signal: i
|
|
376
|
+
};
|
|
377
|
+
try {
|
|
378
|
+
if (!a) {
|
|
379
|
+
p(e, n, o), h(
|
|
380
|
+
this.rootOutletInternal,
|
|
381
|
+
new Error('Route not found. Add "*" catch-all route'),
|
|
382
|
+
null,
|
|
383
|
+
s,
|
|
384
|
+
this.options.globalErrorComponent
|
|
385
|
+
), this.currentPath = e;
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (a.redirectTo) {
|
|
389
|
+
await this.navigate(a.redirectTo, n, "replace", r + 1);
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
if (i.aborted)
|
|
393
|
+
return;
|
|
394
|
+
const c = await m(
|
|
395
|
+
() => H(a.route, s),
|
|
396
|
+
i
|
|
397
|
+
);
|
|
398
|
+
if (c === !1)
|
|
399
|
+
return;
|
|
400
|
+
if (typeof c == "string") {
|
|
401
|
+
await this.navigate(c, n, "replace", r + 1);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (i.aborted)
|
|
405
|
+
return;
|
|
406
|
+
const d = await m(
|
|
407
|
+
() => W(a.route, s),
|
|
408
|
+
i
|
|
409
|
+
);
|
|
410
|
+
if (d instanceof Error) {
|
|
411
|
+
if (E(d))
|
|
412
|
+
return;
|
|
413
|
+
p(e, n, o), h(
|
|
414
|
+
this.rootOutletInternal,
|
|
415
|
+
d,
|
|
416
|
+
a.route,
|
|
417
|
+
s,
|
|
418
|
+
this.options.globalErrorComponent
|
|
419
|
+
), this.currentPath = e;
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (i.aborted)
|
|
423
|
+
return;
|
|
424
|
+
T(this.rootOutletInternal, d), p(e, n, o), k(a.route, s, this.options.defaultTitle), this.currentPath = e, await m(() => B(a.route, s), i);
|
|
425
|
+
} catch (c) {
|
|
426
|
+
if (E(c))
|
|
427
|
+
return;
|
|
428
|
+
h(
|
|
429
|
+
this.rootOutletInternal,
|
|
430
|
+
c instanceof Error ? c : new Error("Unknown error"),
|
|
431
|
+
a?.route ?? null,
|
|
432
|
+
s,
|
|
433
|
+
this.options.globalErrorComponent
|
|
434
|
+
);
|
|
435
|
+
} finally {
|
|
436
|
+
this.navigationController?.signal === i && (this.navigationController = null);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
async push(e, n) {
|
|
440
|
+
try {
|
|
441
|
+
await this.navigate(e, n, "push");
|
|
442
|
+
} catch (o) {
|
|
443
|
+
console.error("[Router.push] Error:", o);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
async replace(e, n) {
|
|
447
|
+
try {
|
|
448
|
+
await this.navigate(e, n, "replace");
|
|
449
|
+
} catch (o) {
|
|
450
|
+
console.error("[Router.replace] Error:", o);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
function G(t, e) {
|
|
455
|
+
return new K(t, e);
|
|
456
|
+
}
|
|
457
|
+
export {
|
|
458
|
+
K as Router,
|
|
459
|
+
G as createRouter
|
|
460
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ripetchor/r-router",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist"
|
|
7
|
+
],
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "vite",
|
|
19
|
+
"build": "tsc && vite build",
|
|
20
|
+
"preview": "vite preview",
|
|
21
|
+
"lint": "eslint .",
|
|
22
|
+
"typecheck": "tsc -b --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@eslint/js": "^9.37.0",
|
|
26
|
+
"eslint": "^9.37.0",
|
|
27
|
+
"typescript": "~5.9.3",
|
|
28
|
+
"typescript-eslint": "^8.45.0",
|
|
29
|
+
"vite": "^7.1.7",
|
|
30
|
+
"vite-plugin-dts": "^4.5.4"
|
|
31
|
+
}
|
|
32
|
+
}
|