@nano_kit/router 1.0.0-alpha.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/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/di.d.ts +45 -0
- package/dist/di.d.ts.map +1 -0
- package/dist/diy.d.ts +51 -0
- package/dist/diy.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +606 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation.d.ts +26 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.types.d.ts +50 -0
- package/dist/navigation.types.d.ts.map +1 -0
- package/dist/paths.d.ts +18 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.types.d.ts +7 -0
- package/dist/paths.types.d.ts.map +1 -0
- package/dist/router.d.ts +87 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.types.d.ts +54 -0
- package/dist/router.types.d.ts.map +1 -0
- package/dist/searchParams.d.ts +19 -0
- package/dist/searchParams.d.ts.map +1 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +62 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +45 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
import { mountable, signal, action, onMount, record, readonly, atIndex, untracked, computed, batch, updateList, inject } from '@nano_kit/store';
|
|
2
|
+
|
|
3
|
+
const PushHistoryAction = "push";
|
|
4
|
+
const ReplaceHistoryAction = "replace";
|
|
5
|
+
const PopHistoryAction = "pop";
|
|
6
|
+
|
|
7
|
+
function onLinkClick(event) {
|
|
8
|
+
const link = event.target.closest("a");
|
|
9
|
+
if (link && event.button === 0 && link.target !== "_blank" && link.origin === location.origin && link.rel !== "external" && link.target !== "_self" && !link.download && !event.altKey && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.defaultPrevented) {
|
|
10
|
+
event.preventDefault();
|
|
11
|
+
this.push(link.href);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function listenLinks(navigation) {
|
|
15
|
+
const onClick = onLinkClick.bind(navigation);
|
|
16
|
+
document.body.addEventListener("click", onClick);
|
|
17
|
+
return () => {
|
|
18
|
+
document.body.removeEventListener("click", onClick);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function resetScroll() {
|
|
22
|
+
window.scrollTo(0, 0);
|
|
23
|
+
}
|
|
24
|
+
function scrollToAnchor(hash, options) {
|
|
25
|
+
if (hash) {
|
|
26
|
+
const id = hash.slice(1);
|
|
27
|
+
const anchor = document.getElementById(id) || document.getElementsByName(id)[0];
|
|
28
|
+
if (anchor) {
|
|
29
|
+
anchor.scrollIntoView(options);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
class ScrollRestorator {
|
|
34
|
+
#storageKeyPrefix;
|
|
35
|
+
/**
|
|
36
|
+
* Create a ScrollRestorator instance.
|
|
37
|
+
* @param storageKeyPrefix - Prefix for session storage keys
|
|
38
|
+
*/
|
|
39
|
+
constructor(storageKeyPrefix = "krsp-") {
|
|
40
|
+
this.#storageKeyPrefix = storageKeyPrefix;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Save the current scroll position for the given location.
|
|
44
|
+
* @param location - The location object
|
|
45
|
+
*/
|
|
46
|
+
save(location2) {
|
|
47
|
+
sessionStorage.setItem(this.#storageKeyPrefix + location2.href, String(window.scrollY));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Restore the scroll position for the given location.
|
|
51
|
+
* @param location - The location object
|
|
52
|
+
* @returns True if a saved position was restored, false otherwise
|
|
53
|
+
*/
|
|
54
|
+
restore(location2) {
|
|
55
|
+
const key = this.#storageKeyPrefix + location2.href;
|
|
56
|
+
const value = parseInt(sessionStorage.getItem(key));
|
|
57
|
+
if (!isNaN(value)) {
|
|
58
|
+
window.scrollTo(0, value);
|
|
59
|
+
this.clear(location2);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Clear the saved scroll position for the given location.
|
|
66
|
+
* @param location - The location object
|
|
67
|
+
*/
|
|
68
|
+
clear(location2) {
|
|
69
|
+
sessionStorage.removeItem(this.#storageKeyPrefix + location2.href);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// @__NO_SIDE_EFFECTS__
|
|
74
|
+
function removeTrailingSlash(path) {
|
|
75
|
+
return path.replace(/(.)\/($|\?)/, "$1$2");
|
|
76
|
+
}
|
|
77
|
+
// @__NO_SIDE_EFFECTS__
|
|
78
|
+
function parseHref(href) {
|
|
79
|
+
return new URL(/* @__PURE__ */ removeTrailingSlash(href), "http://a");
|
|
80
|
+
}
|
|
81
|
+
// @__NO_SIDE_EFFECTS__
|
|
82
|
+
function getHref(location) {
|
|
83
|
+
return /* @__PURE__ */ removeTrailingSlash(location.pathname + location.search + location.hash);
|
|
84
|
+
}
|
|
85
|
+
// @__NO_SIDE_EFFECTS__
|
|
86
|
+
function createHrefObject(url) {
|
|
87
|
+
return {
|
|
88
|
+
pathname: url.pathname,
|
|
89
|
+
search: url.search,
|
|
90
|
+
hash: url.hash,
|
|
91
|
+
href: /* @__PURE__ */ getHref(url)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// @__NO_SIDE_EFFECTS__
|
|
95
|
+
function updateHrefObject(url, update) {
|
|
96
|
+
const updateObject = typeof update === "string" ? /* @__PURE__ */ parseHref(update) : update;
|
|
97
|
+
const updatedUrl = /* @__PURE__ */ parseHref(updateObject.pathname ?? url.pathname);
|
|
98
|
+
updatedUrl.search = updateObject.search ?? url.search;
|
|
99
|
+
updatedUrl.hash = updateObject.hash ?? url.hash;
|
|
100
|
+
if (updateObject.searchParams) {
|
|
101
|
+
updatedUrl.search = updateObject.searchParams.toString();
|
|
102
|
+
}
|
|
103
|
+
return /* @__PURE__ */ createHrefObject(updatedUrl);
|
|
104
|
+
}
|
|
105
|
+
function updateHref(href, update) {
|
|
106
|
+
if (typeof update === "string") {
|
|
107
|
+
return /* @__PURE__ */ removeTrailingSlash(update);
|
|
108
|
+
}
|
|
109
|
+
return (/* @__PURE__ */ updateHrefObject(/* @__PURE__ */ parseHref(href), update)).href;
|
|
110
|
+
}
|
|
111
|
+
// @__NO_SIDE_EFFECTS__
|
|
112
|
+
function composeMatchers(matchers, nomatch = null) {
|
|
113
|
+
const len = matchers.length;
|
|
114
|
+
return (...args) => {
|
|
115
|
+
for (let i = 0, result; i < len; i++) {
|
|
116
|
+
if (result = matchers[i](...args)) {
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return nomatch;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// @__NO_SIDE_EFFECTS__
|
|
124
|
+
function createLocation(url, action = null) {
|
|
125
|
+
return {
|
|
126
|
+
.../* @__PURE__ */ createHrefObject(url),
|
|
127
|
+
action
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// @__NO_SIDE_EFFECTS__
|
|
131
|
+
function updateLocation(url, update, action) {
|
|
132
|
+
return {
|
|
133
|
+
.../* @__PURE__ */ updateHrefObject(url, update),
|
|
134
|
+
action
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function createPatternRegex(pattern) {
|
|
139
|
+
return new RegExp(`^${removeTrailingSlash(pattern).replace(/[\s!#$()+,.:<=?[\\\]^{|}]/g, "\\$&").replace(/\/\\:(\w+)\\\?/g, "(?:/(?<$1>(?<=/)[^/]+))?").replace(/\/\\:(\w+)/g, "/(?<$1>[^/]+)").replace(/\/\*$/g, "(?:/(?<wildcard>.+))?$")}/?$`, "i");
|
|
140
|
+
}
|
|
141
|
+
function patternMatcher(route, path) {
|
|
142
|
+
const matches = path.match(this);
|
|
143
|
+
if (!matches) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const params = {};
|
|
147
|
+
if (matches.groups) {
|
|
148
|
+
Object.entries(matches.groups).forEach(([key, value]) => {
|
|
149
|
+
params[key] = value ? decodeURIComponent(value) : "";
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
route,
|
|
154
|
+
params
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const nomatch = {
|
|
158
|
+
route: null,
|
|
159
|
+
params: {}
|
|
160
|
+
};
|
|
161
|
+
function createMatcher$1(routes) {
|
|
162
|
+
return composeMatchers(Object.entries(routes).map(
|
|
163
|
+
([route, pattern]) => patternMatcher.bind(
|
|
164
|
+
createPatternRegex(pattern),
|
|
165
|
+
route
|
|
166
|
+
)
|
|
167
|
+
), nomatch);
|
|
168
|
+
}
|
|
169
|
+
const matcherCache$1 = /* @__PURE__ */ new WeakMap();
|
|
170
|
+
function createCachedMatcher$1(routes) {
|
|
171
|
+
let matcher = matcherCache$1.get(routes);
|
|
172
|
+
if (!matcher) {
|
|
173
|
+
matcher = createMatcher$1(routes);
|
|
174
|
+
matcherCache$1.set(routes, matcher);
|
|
175
|
+
}
|
|
176
|
+
return matcher;
|
|
177
|
+
}
|
|
178
|
+
function applyBrowserLocation({ href, action: action2 }) {
|
|
179
|
+
if (action2 === PushHistoryAction) {
|
|
180
|
+
history.pushState(null, "", href);
|
|
181
|
+
} else if (action2 === ReplaceHistoryAction) {
|
|
182
|
+
history.replaceState(null, "", href);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// @__NO_SIDE_EFFECTS__
|
|
186
|
+
function browserNavigation(routes = {}) {
|
|
187
|
+
const match = createCachedMatcher$1(routes);
|
|
188
|
+
const routerLocation = (location2) => ({
|
|
189
|
+
...location2,
|
|
190
|
+
...match(location2.pathname)
|
|
191
|
+
});
|
|
192
|
+
const $location = mountable(signal(
|
|
193
|
+
routerLocation(createLocation(location))
|
|
194
|
+
));
|
|
195
|
+
const update = (location2) => {
|
|
196
|
+
if (location2 !== null) {
|
|
197
|
+
applyBrowserLocation(location2);
|
|
198
|
+
$location(location2);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const maybeUpdate = (nextLocation) => {
|
|
202
|
+
const location2 = $location();
|
|
203
|
+
if (location2.href !== nextLocation.href || nextLocation.hash.length > 1) {
|
|
204
|
+
const { action: action2 } = nextLocation;
|
|
205
|
+
const nextRouteLocation = routerLocation(nextLocation);
|
|
206
|
+
if (action2 === null || action2 === PopHistoryAction) {
|
|
207
|
+
update(nextRouteLocation);
|
|
208
|
+
} else {
|
|
209
|
+
navigation.transition(
|
|
210
|
+
update,
|
|
211
|
+
nextRouteLocation,
|
|
212
|
+
location2
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
const sync = (event) => {
|
|
218
|
+
maybeUpdate(
|
|
219
|
+
createLocation(
|
|
220
|
+
location,
|
|
221
|
+
event ? PopHistoryAction : null
|
|
222
|
+
)
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
const navigation = {
|
|
226
|
+
transition(fn, nextLocation) {
|
|
227
|
+
fn(nextLocation);
|
|
228
|
+
},
|
|
229
|
+
get length() {
|
|
230
|
+
return history.length;
|
|
231
|
+
},
|
|
232
|
+
back: action(() => {
|
|
233
|
+
navigation.transition(history.back, null, $location());
|
|
234
|
+
}),
|
|
235
|
+
forward: action(() => {
|
|
236
|
+
navigation.transition(history.forward, null, $location());
|
|
237
|
+
}),
|
|
238
|
+
push: action((to) => {
|
|
239
|
+
maybeUpdate(
|
|
240
|
+
updateLocation(location, to, PushHistoryAction)
|
|
241
|
+
);
|
|
242
|
+
}),
|
|
243
|
+
replace: action((to) => {
|
|
244
|
+
maybeUpdate(
|
|
245
|
+
updateLocation(location, to, ReplaceHistoryAction)
|
|
246
|
+
);
|
|
247
|
+
})
|
|
248
|
+
};
|
|
249
|
+
onMount($location, () => {
|
|
250
|
+
sync();
|
|
251
|
+
window.addEventListener("popstate", sync);
|
|
252
|
+
return () => {
|
|
253
|
+
window.removeEventListener("popstate", sync);
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
return [record(readonly($location)), navigation];
|
|
257
|
+
}
|
|
258
|
+
// @__NO_SIDE_EFFECTS__
|
|
259
|
+
function virtualNavigation(initialPath = "/", routes = {}) {
|
|
260
|
+
const match = createCachedMatcher$1(routes);
|
|
261
|
+
const routerLocation = (location2) => ({
|
|
262
|
+
...location2,
|
|
263
|
+
...match(location2.pathname)
|
|
264
|
+
});
|
|
265
|
+
const $history = signal(
|
|
266
|
+
[routerLocation(createLocation(parseHref(initialPath)))]
|
|
267
|
+
);
|
|
268
|
+
const $activeIndex = signal(0);
|
|
269
|
+
const $location = mountable(atIndex($history, $activeIndex));
|
|
270
|
+
const go = (steps) => {
|
|
271
|
+
const newIndex = Math.max(0, Math.min(
|
|
272
|
+
$history().length - 1,
|
|
273
|
+
$activeIndex() + steps
|
|
274
|
+
));
|
|
275
|
+
batch(() => {
|
|
276
|
+
$activeIndex(newIndex);
|
|
277
|
+
$location((location2) => ({
|
|
278
|
+
...location2,
|
|
279
|
+
action: PopHistoryAction
|
|
280
|
+
}));
|
|
281
|
+
});
|
|
282
|
+
};
|
|
283
|
+
const back = () => go(-1);
|
|
284
|
+
const forward = () => go(1);
|
|
285
|
+
const update = (location2) => {
|
|
286
|
+
if (location2 !== null) {
|
|
287
|
+
if (location2.action === PushHistoryAction) {
|
|
288
|
+
const activeIndex = $activeIndex();
|
|
289
|
+
const nextIndex = activeIndex + 1;
|
|
290
|
+
batch(() => {
|
|
291
|
+
updateList($history, (history2) => {
|
|
292
|
+
history2.splice(nextIndex, history2.length - activeIndex - 1, location2);
|
|
293
|
+
});
|
|
294
|
+
$activeIndex(nextIndex);
|
|
295
|
+
});
|
|
296
|
+
} else if (location2.action === ReplaceHistoryAction) {
|
|
297
|
+
$location(location2);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
const maybeUpdate = (nextLocation, location2) => {
|
|
302
|
+
if (location2.href !== nextLocation.href || nextLocation.hash.length > 1) {
|
|
303
|
+
const nextRouteLocation = routerLocation(nextLocation);
|
|
304
|
+
navigation.transition(
|
|
305
|
+
update,
|
|
306
|
+
nextRouteLocation,
|
|
307
|
+
location2
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
const navigation = {
|
|
312
|
+
transition(fn, location2) {
|
|
313
|
+
fn(location2);
|
|
314
|
+
},
|
|
315
|
+
get length() {
|
|
316
|
+
return untracked($history).length;
|
|
317
|
+
},
|
|
318
|
+
back: action(() => {
|
|
319
|
+
navigation.transition(back, null, $location());
|
|
320
|
+
}),
|
|
321
|
+
forward: action(() => {
|
|
322
|
+
navigation.transition(forward, null, $location());
|
|
323
|
+
}),
|
|
324
|
+
push: action((to) => {
|
|
325
|
+
const location2 = $location();
|
|
326
|
+
maybeUpdate(
|
|
327
|
+
updateLocation(location2, to, PushHistoryAction),
|
|
328
|
+
location2
|
|
329
|
+
);
|
|
330
|
+
}),
|
|
331
|
+
replace: action((to) => {
|
|
332
|
+
const location2 = $location();
|
|
333
|
+
maybeUpdate(
|
|
334
|
+
updateLocation(location2, to, ReplaceHistoryAction),
|
|
335
|
+
location2
|
|
336
|
+
);
|
|
337
|
+
})
|
|
338
|
+
};
|
|
339
|
+
return [record(readonly($location)), navigation];
|
|
340
|
+
}
|
|
341
|
+
// @__NO_SIDE_EFFECTS__
|
|
342
|
+
function routeParam($location, key, parser = (_) => _) {
|
|
343
|
+
const { $params } = $location;
|
|
344
|
+
return computed(() => parser($params()[key]));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// @__NO_SIDE_EFFECTS__
|
|
348
|
+
function searchParams($location) {
|
|
349
|
+
const { $search } = $location;
|
|
350
|
+
return computed(() => new URLSearchParams($search()));
|
|
351
|
+
}
|
|
352
|
+
// @__NO_SIDE_EFFECTS__
|
|
353
|
+
function searchParam($searchParams, key, parser = (_) => _) {
|
|
354
|
+
return computed(() => parser($searchParams().get(key)));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function execPattern(params) {
|
|
358
|
+
return this.map((part, i) => i % 2 === 0 ? part : part(params)).join("");
|
|
359
|
+
}
|
|
360
|
+
function partToFunction(part, i) {
|
|
361
|
+
return i % 2 === 0 ? part : part === void 0 ? (params = {}) => params.wildcard ? `/${params.wildcard}` : "" : (params = {}) => part in params ? `/${encodeURIComponent(params[part])}` : "";
|
|
362
|
+
}
|
|
363
|
+
function patternToFunction(pattern) {
|
|
364
|
+
const parts = pattern.split(/\/(?::(\w+)\??|\*)/g).map(partToFunction);
|
|
365
|
+
return execPattern.bind(parts);
|
|
366
|
+
}
|
|
367
|
+
// @__NO_SIDE_EFFECTS__
|
|
368
|
+
function buildPaths(routes) {
|
|
369
|
+
return Object.entries(routes).reduce(
|
|
370
|
+
(hrefs, [route, pattern]) => {
|
|
371
|
+
if (/:|\*/.test(pattern)) {
|
|
372
|
+
hrefs[route] = patternToFunction(pattern);
|
|
373
|
+
} else {
|
|
374
|
+
hrefs[route] = removeTrailingSlash(pattern);
|
|
375
|
+
}
|
|
376
|
+
return hrefs;
|
|
377
|
+
},
|
|
378
|
+
{}
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
// @__NO_SIDE_EFFECTS__
|
|
382
|
+
function basePath(base, routes) {
|
|
383
|
+
if (!base) {
|
|
384
|
+
return routes;
|
|
385
|
+
}
|
|
386
|
+
const normalizedBase = removeTrailingSlash(base).replace(/^\.\//, "/");
|
|
387
|
+
if (normalizedBase === "" || normalizedBase === "/") {
|
|
388
|
+
return routes;
|
|
389
|
+
}
|
|
390
|
+
return Object.entries(routes).reduce(
|
|
391
|
+
(paths, [route, pattern]) => {
|
|
392
|
+
paths[route] = removeTrailingSlash(`${normalizedBase}${pattern}`);
|
|
393
|
+
return paths;
|
|
394
|
+
},
|
|
395
|
+
{}
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
async function loadPages(pages, tasks) {
|
|
400
|
+
const allTasks = tasks ?? /* @__PURE__ */ new Set();
|
|
401
|
+
for (const ref of pages) {
|
|
402
|
+
if ("expected" in ref) {
|
|
403
|
+
ref.page(allTasks);
|
|
404
|
+
} else {
|
|
405
|
+
ref.layout(allTasks);
|
|
406
|
+
void loadPages(ref.pages, allTasks);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (!tasks) {
|
|
410
|
+
await Promise.all(allTasks);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async function loadPage(pages, route, tasks) {
|
|
414
|
+
const allTasks = tasks ?? /* @__PURE__ */ new Set();
|
|
415
|
+
for (const ref of pages) {
|
|
416
|
+
if ("expected" in ref) {
|
|
417
|
+
if (ref.expected === route) {
|
|
418
|
+
ref.page(allTasks);
|
|
419
|
+
allTasks.add(null);
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
} else if (allTasks.size < (loadPage(ref.pages, route, allTasks), allTasks.size)) {
|
|
423
|
+
ref.layout(allTasks);
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (!tasks) {
|
|
428
|
+
await Promise.all(allTasks);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// @__NO_SIDE_EFFECTS__
|
|
432
|
+
function loadable(load, fallback) {
|
|
433
|
+
const $viewRef = signal({
|
|
434
|
+
view: fallback,
|
|
435
|
+
loading: true
|
|
436
|
+
});
|
|
437
|
+
const init = (tasks) => {
|
|
438
|
+
const promise = load().then((module) => $viewRef({
|
|
439
|
+
view: module.default,
|
|
440
|
+
storesToPreload: module.storesToPreload,
|
|
441
|
+
loading: false
|
|
442
|
+
}));
|
|
443
|
+
tasks?.add(promise);
|
|
444
|
+
};
|
|
445
|
+
let initialized = false;
|
|
446
|
+
return {
|
|
447
|
+
load(tasks) {
|
|
448
|
+
if (!initialized) {
|
|
449
|
+
initialized = true;
|
|
450
|
+
init(tasks);
|
|
451
|
+
}
|
|
452
|
+
return $viewRef();
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function isLoadable(ref) {
|
|
457
|
+
return typeof ref?.load === "function";
|
|
458
|
+
}
|
|
459
|
+
function getViewRefGetter(page2, storesToPreload) {
|
|
460
|
+
let getter;
|
|
461
|
+
if (isLoadable(page2)) {
|
|
462
|
+
getter = page2.load;
|
|
463
|
+
} else {
|
|
464
|
+
const ref = {
|
|
465
|
+
view: page2,
|
|
466
|
+
storesToPreload
|
|
467
|
+
};
|
|
468
|
+
getter = () => ref;
|
|
469
|
+
}
|
|
470
|
+
return getter;
|
|
471
|
+
}
|
|
472
|
+
// @__NO_SIDE_EFFECTS__
|
|
473
|
+
function page(expected, page2, storesToPreload) {
|
|
474
|
+
return {
|
|
475
|
+
expected,
|
|
476
|
+
page: getViewRefGetter(page2, storesToPreload)
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
// @__NO_SIDE_EFFECTS__
|
|
480
|
+
function notFound(page2, storesToPreload) {
|
|
481
|
+
return {
|
|
482
|
+
expected: null,
|
|
483
|
+
page: getViewRefGetter(page2, storesToPreload)
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
// @__NO_SIDE_EFFECTS__
|
|
487
|
+
function layout(layout2, stroesToPreloadOrPages, maybePages) {
|
|
488
|
+
let pages;
|
|
489
|
+
let storesToPreload;
|
|
490
|
+
if (maybePages === void 0) {
|
|
491
|
+
pages = stroesToPreloadOrPages;
|
|
492
|
+
} else {
|
|
493
|
+
pages = maybePages;
|
|
494
|
+
storesToPreload = stroesToPreloadOrPages;
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
layout: getViewRefGetter(layout2, storesToPreload),
|
|
498
|
+
pages
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function createMatcher(pages) {
|
|
502
|
+
return composeMatchers(pages.map(
|
|
503
|
+
(ref) => "expected" in ref ? createPageMatcher(ref) : createLayoutMatcher(ref)
|
|
504
|
+
));
|
|
505
|
+
}
|
|
506
|
+
const matcherCache = /* @__PURE__ */ new WeakMap();
|
|
507
|
+
function createCachedMatcher(pages) {
|
|
508
|
+
let matcher = matcherCache.get(pages);
|
|
509
|
+
if (!matcher) {
|
|
510
|
+
matcher = createMatcher(pages);
|
|
511
|
+
matcherCache.set(pages, matcher);
|
|
512
|
+
}
|
|
513
|
+
return matcher;
|
|
514
|
+
}
|
|
515
|
+
function createPageMatcher({ expected, page: page2 }) {
|
|
516
|
+
return (route) => route === expected ? page2() : null;
|
|
517
|
+
}
|
|
518
|
+
function createLayoutMatcher({ layout: layout2, pages }) {
|
|
519
|
+
const match = createCachedMatcher(pages);
|
|
520
|
+
return (route, composed) => {
|
|
521
|
+
const ref = match(route, composed);
|
|
522
|
+
if (ref) {
|
|
523
|
+
const layoutRef = layout2();
|
|
524
|
+
if (layoutRef.loading || !layoutRef.view) {
|
|
525
|
+
return layoutRef;
|
|
526
|
+
}
|
|
527
|
+
const storesToPreload = () => [
|
|
528
|
+
...layoutRef.storesToPreload?.() ?? [],
|
|
529
|
+
...ref.storesToPreload?.() ?? []
|
|
530
|
+
];
|
|
531
|
+
return {
|
|
532
|
+
view: composed(layoutRef.view, ref.view),
|
|
533
|
+
storesToPreload
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
return null;
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
function createComposed(compose) {
|
|
540
|
+
const storage = /* @__PURE__ */ new Map();
|
|
541
|
+
return (layout2, page2) => {
|
|
542
|
+
let entry = storage.get(layout2);
|
|
543
|
+
if (!entry) {
|
|
544
|
+
const $page = signal(page2);
|
|
545
|
+
entry = {
|
|
546
|
+
page: $page,
|
|
547
|
+
composed: compose?.($page, layout2)
|
|
548
|
+
};
|
|
549
|
+
storage.set(layout2, entry);
|
|
550
|
+
} else {
|
|
551
|
+
entry.page(() => page2);
|
|
552
|
+
}
|
|
553
|
+
return entry.composed;
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
// @__NO_SIDE_EFFECTS__
|
|
557
|
+
function router($location, pages, compose) {
|
|
558
|
+
const { $route } = $location;
|
|
559
|
+
const match = createCachedMatcher(pages);
|
|
560
|
+
const composed = createComposed(compose);
|
|
561
|
+
let ref = null;
|
|
562
|
+
const $page = computed(() => (ref = match($route(), composed))?.view ?? null);
|
|
563
|
+
const storesToPreload = () => {
|
|
564
|
+
$page();
|
|
565
|
+
return ref?.storesToPreload?.() ?? [];
|
|
566
|
+
};
|
|
567
|
+
return [$page, storesToPreload];
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// @__NO_SIDE_EFFECTS__
|
|
571
|
+
function browserNavigation$(routes = {}) {
|
|
572
|
+
const BrowserNavigation$ = () => browserNavigation(routes);
|
|
573
|
+
const Location$ = () => inject(BrowserNavigation$)[0];
|
|
574
|
+
const Navigation$ = () => inject(BrowserNavigation$)[1];
|
|
575
|
+
return [
|
|
576
|
+
Location$,
|
|
577
|
+
Navigation$
|
|
578
|
+
];
|
|
579
|
+
}
|
|
580
|
+
// @__NO_SIDE_EFFECTS__
|
|
581
|
+
function virtualNavigation$(initialPath, routes) {
|
|
582
|
+
const VirtualNavigation$ = () => virtualNavigation(initialPath, routes);
|
|
583
|
+
const Location$ = () => inject(VirtualNavigation$)[0];
|
|
584
|
+
const Navigation$ = () => inject(VirtualNavigation$)[1];
|
|
585
|
+
return [
|
|
586
|
+
Location$,
|
|
587
|
+
Navigation$
|
|
588
|
+
];
|
|
589
|
+
}
|
|
590
|
+
// @__NO_SIDE_EFFECTS__
|
|
591
|
+
function router$(Location$, pages, compose) {
|
|
592
|
+
const Router$ = () => router(
|
|
593
|
+
inject(Location$),
|
|
594
|
+
pages,
|
|
595
|
+
compose
|
|
596
|
+
);
|
|
597
|
+
const Page$ = () => inject(Router$)[0];
|
|
598
|
+
const StoresToPreload$ = () => inject(Router$)[1];
|
|
599
|
+
return [
|
|
600
|
+
Page$,
|
|
601
|
+
StoresToPreload$
|
|
602
|
+
];
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export { PopHistoryAction, PushHistoryAction, ReplaceHistoryAction, ScrollRestorator, basePath, browserNavigation, browserNavigation$, buildPaths, composeMatchers, createHrefObject, createLocation, getHref, layout, listenLinks, loadPage, loadPages, loadable, notFound, onLinkClick, page, parseHref, removeTrailingSlash, resetScroll, routeParam, router, router$, scrollToAnchor, searchParam, searchParams, updateHref, updateHrefObject, updateLocation, virtualNavigation, virtualNavigation$ };
|
|
606
|
+
//# sourceMappingURL=index.js.map
|