@coherent.js/client 1.1.2 → 2.0.0-rc.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 +126 -66
- package/dist/chunk-EAOAAY2X.js +1550 -0
- package/dist/chunk-EAOAAY2X.js.map +7 -0
- package/dist/{chunk-N36BSMJU.js → chunk-UYL3RRRC.js} +134 -32
- package/dist/chunk-UYL3RRRC.js.map +7 -0
- package/dist/events/index.js +1 -1
- package/dist/hmr.js +34 -4
- package/dist/hmr.js.map +3 -3
- package/dist/index.js +598 -1732
- package/dist/index.js.map +4 -4
- package/dist/router.js +209 -31
- package/dist/router.js.map +2 -2
- package/package.json +4 -1
- package/types/hmr.d.ts +32 -1
- package/types/index.d.ts +258 -701
- package/types/router.d.ts +34 -11
- package/dist/chunk-N36BSMJU.js.map +0 -7
package/dist/router.js
CHANGED
|
@@ -1,10 +1,51 @@
|
|
|
1
1
|
// src/router.js
|
|
2
|
+
function compilePattern(pattern) {
|
|
3
|
+
if (!pattern.includes(":") && !pattern.includes("*")) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const keys = [];
|
|
7
|
+
const source = pattern.split("/").map((segment) => {
|
|
8
|
+
if (segment === "*") {
|
|
9
|
+
keys.push("pathMatch");
|
|
10
|
+
return "(.*)";
|
|
11
|
+
}
|
|
12
|
+
if (segment.startsWith(":")) {
|
|
13
|
+
keys.push(segment.slice(1));
|
|
14
|
+
return "([^/]+)";
|
|
15
|
+
}
|
|
16
|
+
return segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
17
|
+
}).join("/");
|
|
18
|
+
return { regex: new RegExp(`^${source}/?$`), keys };
|
|
19
|
+
}
|
|
20
|
+
function parseLocation(fullPath) {
|
|
21
|
+
let rest = String(fullPath);
|
|
22
|
+
let hash = "";
|
|
23
|
+
const hashIndex = rest.indexOf("#");
|
|
24
|
+
if (hashIndex !== -1) {
|
|
25
|
+
hash = rest.slice(hashIndex);
|
|
26
|
+
rest = rest.slice(0, hashIndex);
|
|
27
|
+
}
|
|
28
|
+
let search = "";
|
|
29
|
+
const queryIndex = rest.indexOf("?");
|
|
30
|
+
if (queryIndex !== -1) {
|
|
31
|
+
search = rest.slice(queryIndex + 1);
|
|
32
|
+
rest = rest.slice(0, queryIndex);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
path: rest || "/",
|
|
36
|
+
query: Object.fromEntries(new URLSearchParams(search)),
|
|
37
|
+
hash
|
|
38
|
+
};
|
|
39
|
+
}
|
|
2
40
|
function createRouter(options = {}) {
|
|
3
41
|
const opts = {
|
|
4
42
|
mode: options.mode || "history",
|
|
5
43
|
base: options.base || "/",
|
|
6
44
|
...options
|
|
7
45
|
};
|
|
46
|
+
let baseEnd = opts.base.length;
|
|
47
|
+
while (baseEnd > 0 && opts.base[baseEnd - 1] === "/") baseEnd--;
|
|
48
|
+
const base = opts.base.slice(0, baseEnd);
|
|
8
49
|
opts.prefetch = {
|
|
9
50
|
enabled: false,
|
|
10
51
|
strategy: "hover",
|
|
@@ -55,8 +96,11 @@ function createRouter(options = {}) {
|
|
|
55
96
|
prefetching: /* @__PURE__ */ new Set(),
|
|
56
97
|
loadedChunks: /* @__PURE__ */ new Map(),
|
|
57
98
|
savedPositions: /* @__PURE__ */ new Map(),
|
|
58
|
-
transitionState: null
|
|
99
|
+
transitionState: null,
|
|
100
|
+
forwardStack: []
|
|
59
101
|
};
|
|
102
|
+
let navigationId = 0;
|
|
103
|
+
let listening = null;
|
|
60
104
|
const stats = {
|
|
61
105
|
navigations: 0,
|
|
62
106
|
prefetches: 0,
|
|
@@ -67,6 +111,7 @@ function createRouter(options = {}) {
|
|
|
67
111
|
function addRoute(path, config) {
|
|
68
112
|
state.routes.set(path, {
|
|
69
113
|
path,
|
|
114
|
+
pattern: compilePattern(path),
|
|
70
115
|
component: config.component,
|
|
71
116
|
meta: config.meta || {},
|
|
72
117
|
beforeEnter: config.beforeEnter,
|
|
@@ -81,8 +126,25 @@ function createRouter(options = {}) {
|
|
|
81
126
|
loadRoute(path);
|
|
82
127
|
}
|
|
83
128
|
}
|
|
129
|
+
function matchRoute(path) {
|
|
130
|
+
const exact = state.routes.get(path);
|
|
131
|
+
if (exact) {
|
|
132
|
+
return { route: exact, params: {} };
|
|
133
|
+
}
|
|
134
|
+
for (const route of state.routes.values()) {
|
|
135
|
+
const match = route.pattern?.regex.exec(path);
|
|
136
|
+
if (match) {
|
|
137
|
+
const params = {};
|
|
138
|
+
route.pattern.keys.forEach((key, i) => {
|
|
139
|
+
params[key] = decodeURIComponent(match[i + 1]);
|
|
140
|
+
});
|
|
141
|
+
return { route, params };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
84
146
|
async function loadRoute(path) {
|
|
85
|
-
const route = state.routes.get(path);
|
|
147
|
+
const route = state.routes.get(path) ?? matchRoute(parseLocation(path).path)?.route;
|
|
86
148
|
if (!route) {
|
|
87
149
|
throw new Error(`Route not found: ${path}`);
|
|
88
150
|
}
|
|
@@ -113,7 +175,7 @@ function createRouter(options = {}) {
|
|
|
113
175
|
}
|
|
114
176
|
async function prefetchRoute(path, priority = opts.prefetch.priority.normal) {
|
|
115
177
|
if (!opts.prefetch.enabled) return;
|
|
116
|
-
const route = state.routes.get(path);
|
|
178
|
+
const route = state.routes.get(path) ?? matchRoute(parseLocation(path).path)?.route;
|
|
117
179
|
if (!route || route.loaded || state.prefetching.has(path)) {
|
|
118
180
|
return;
|
|
119
181
|
}
|
|
@@ -208,7 +270,7 @@ function createRouter(options = {}) {
|
|
|
208
270
|
});
|
|
209
271
|
}
|
|
210
272
|
function handleScroll(to, from, savedPosition) {
|
|
211
|
-
if (!opts.scrollBehavior.enabled) return;
|
|
273
|
+
if (!opts.scrollBehavior.enabled || typeof document === "undefined") return;
|
|
212
274
|
if (opts.scrollBehavior.custom) {
|
|
213
275
|
const position2 = opts.scrollBehavior.custom(to, from, savedPosition);
|
|
214
276
|
scrollToPosition(position2);
|
|
@@ -219,7 +281,12 @@ function createRouter(options = {}) {
|
|
|
219
281
|
position = savedPosition;
|
|
220
282
|
stats.scrollRestores++;
|
|
221
283
|
} else if (to.hash) {
|
|
222
|
-
|
|
284
|
+
let id = to.hash.slice(1);
|
|
285
|
+
try {
|
|
286
|
+
id = decodeURIComponent(id);
|
|
287
|
+
} catch {
|
|
288
|
+
}
|
|
289
|
+
const element = document.getElementById(id);
|
|
223
290
|
if (element) {
|
|
224
291
|
position = {
|
|
225
292
|
el: element,
|
|
@@ -258,59 +325,168 @@ function createRouter(options = {}) {
|
|
|
258
325
|
y: window.scrollY
|
|
259
326
|
});
|
|
260
327
|
}
|
|
261
|
-
|
|
328
|
+
function hasHistoryApi() {
|
|
329
|
+
return typeof window !== "undefined" && Boolean(window.history) && typeof window.history.pushState === "function";
|
|
330
|
+
}
|
|
331
|
+
function toURL(fullPath) {
|
|
332
|
+
if (opts.mode === "hash") {
|
|
333
|
+
return `#${fullPath}`;
|
|
334
|
+
}
|
|
335
|
+
return `${base}${fullPath}` || "/";
|
|
336
|
+
}
|
|
337
|
+
function currentLocation() {
|
|
338
|
+
if (opts.mode === "hash") {
|
|
339
|
+
return window.location.hash.slice(1) || "/";
|
|
340
|
+
}
|
|
341
|
+
let path = window.location.pathname;
|
|
342
|
+
if (base && (path === base || path.startsWith(`${base}/`))) {
|
|
343
|
+
path = path.slice(base.length) || "/";
|
|
344
|
+
}
|
|
345
|
+
return `${path}${window.location.search}${window.location.hash}`;
|
|
346
|
+
}
|
|
347
|
+
async function navigate(fullPath, options2, historyAction) {
|
|
262
348
|
stats.navigations++;
|
|
349
|
+
const id = ++navigationId;
|
|
263
350
|
const from = state.currentRoute;
|
|
264
|
-
const
|
|
351
|
+
const location = parseLocation(fullPath);
|
|
352
|
+
const matched = matchRoute(location.path);
|
|
353
|
+
const to = {
|
|
354
|
+
...options2,
|
|
355
|
+
path: location.path,
|
|
356
|
+
fullPath: String(fullPath),
|
|
357
|
+
params: matched?.params ?? {},
|
|
358
|
+
query: location.query,
|
|
359
|
+
hash: location.hash,
|
|
360
|
+
meta: matched?.route.meta ?? {}
|
|
361
|
+
};
|
|
265
362
|
if (from) {
|
|
266
363
|
saveScrollPosition(from.path);
|
|
267
364
|
}
|
|
268
365
|
try {
|
|
366
|
+
if (!matched) {
|
|
367
|
+
throw new Error(`Route not found: ${location.path}`);
|
|
368
|
+
}
|
|
369
|
+
const leaving = from ? matchRoute(from.path)?.route : null;
|
|
370
|
+
if (leaving?.beforeLeave && await leaving.beforeLeave(to, from) === false) {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
if (matched.route.beforeEnter && await matched.route.beforeEnter(to, from) === false) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
if (id !== navigationId) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
269
379
|
if (opts.transitions.enabled) {
|
|
270
|
-
await executeTransition(from?.path, path);
|
|
380
|
+
await executeTransition(from?.path, location.path);
|
|
271
381
|
}
|
|
272
|
-
const component = await loadRoute(path);
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
382
|
+
const component = await loadRoute(matched.route.path);
|
|
383
|
+
if (id !== navigationId) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
state.currentRoute = { ...to, component };
|
|
387
|
+
const entry = { path: location.path, fullPath: String(fullPath), timestamp: Date.now() };
|
|
388
|
+
if (historyAction === "replace" && state.history.length > 0) {
|
|
389
|
+
state.history[state.history.length - 1] = entry;
|
|
390
|
+
} else if (historyAction === "push" || state.history.length === 0) {
|
|
391
|
+
state.history.push(entry);
|
|
392
|
+
if (historyAction === "push") state.forwardStack = [];
|
|
393
|
+
}
|
|
394
|
+
if (hasHistoryApi() && historyAction !== "pop") {
|
|
395
|
+
const method = historyAction === "replace" ? "replaceState" : "pushState";
|
|
396
|
+
window.history[method]({ path: String(fullPath) }, "", toURL(String(fullPath)));
|
|
397
|
+
}
|
|
398
|
+
const savedPosition = state.savedPositions.get(location.path);
|
|
399
|
+
handleScroll(to, from, historyAction === "pop" ? savedPosition : null);
|
|
285
400
|
return true;
|
|
286
401
|
} catch (error) {
|
|
287
402
|
console.error("Navigation failed:", error);
|
|
288
403
|
return false;
|
|
289
404
|
}
|
|
290
405
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return result;
|
|
406
|
+
function push(path, options2 = {}) {
|
|
407
|
+
return navigate(path, options2, "push");
|
|
408
|
+
}
|
|
409
|
+
function replace(path, options2 = {}) {
|
|
410
|
+
return navigate(path, options2, "replace");
|
|
297
411
|
}
|
|
298
412
|
function back() {
|
|
413
|
+
if (listening) {
|
|
414
|
+
window.history.back();
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
299
417
|
if (state.history.length > 1) {
|
|
300
|
-
|
|
301
|
-
|
|
418
|
+
state.forwardStack.push(state.history.pop());
|
|
419
|
+
const previous = state.history[state.history.length - 1];
|
|
420
|
+
navigate(previous.fullPath ?? previous.path, {}, "pop");
|
|
302
421
|
}
|
|
303
422
|
}
|
|
304
423
|
function forward() {
|
|
305
|
-
if (
|
|
424
|
+
if (listening) {
|
|
306
425
|
window.history.forward();
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
const next = state.forwardStack.pop();
|
|
429
|
+
if (next) {
|
|
430
|
+
state.history.push(next);
|
|
431
|
+
navigate(next.fullPath ?? next.path, {}, "pop");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function start(startOptions = {}) {
|
|
435
|
+
if (typeof window === "undefined" || listening) {
|
|
436
|
+
return Promise.resolve(false);
|
|
437
|
+
}
|
|
438
|
+
const onPop = () => {
|
|
439
|
+
navigate(currentLocation(), {}, "pop");
|
|
440
|
+
};
|
|
441
|
+
const onClick = (event) => {
|
|
442
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const link = typeof event.target?.closest === "function" ? event.target.closest("a[href]") : null;
|
|
446
|
+
const target = link?.getAttribute("target");
|
|
447
|
+
if (!link || link.hasAttribute("download") || link.hasAttribute("data-router-ignore") || target && target !== "_self") {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
let url;
|
|
451
|
+
try {
|
|
452
|
+
url = new URL(link.getAttribute("href"), window.location.href);
|
|
453
|
+
} catch {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (url.origin !== window.location.origin) return;
|
|
457
|
+
let fullPath;
|
|
458
|
+
if (opts.mode === "hash") {
|
|
459
|
+
if (!url.hash.startsWith("#/")) return;
|
|
460
|
+
fullPath = url.hash.slice(1);
|
|
461
|
+
} else {
|
|
462
|
+
if (base && url.pathname !== base && !url.pathname.startsWith(`${base}/`)) return;
|
|
463
|
+
fullPath = `${url.pathname.slice(base.length) || "/"}${url.search}${url.hash}`;
|
|
464
|
+
}
|
|
465
|
+
if (!matchRoute(parseLocation(fullPath).path)) return;
|
|
466
|
+
event.preventDefault();
|
|
467
|
+
push(fullPath);
|
|
468
|
+
};
|
|
469
|
+
const popEvent = opts.mode === "hash" ? "hashchange" : "popstate";
|
|
470
|
+
window.addEventListener(popEvent, onPop);
|
|
471
|
+
if (startOptions.interceptLinks !== false && typeof document !== "undefined") {
|
|
472
|
+
document.addEventListener("click", onClick);
|
|
473
|
+
}
|
|
474
|
+
listening = { popEvent, onPop, onClick };
|
|
475
|
+
return navigate(currentLocation(), {}, "replace");
|
|
476
|
+
}
|
|
477
|
+
function stop() {
|
|
478
|
+
if (!listening) return;
|
|
479
|
+
window.removeEventListener(listening.popEvent, listening.onPop);
|
|
480
|
+
if (typeof document !== "undefined") {
|
|
481
|
+
document.removeEventListener("click", listening.onClick);
|
|
307
482
|
}
|
|
483
|
+
listening = null;
|
|
308
484
|
}
|
|
309
485
|
function prefetchRoutes(paths, priority) {
|
|
310
486
|
paths.forEach((path) => prefetchRoute(path, priority));
|
|
311
487
|
}
|
|
312
488
|
function getRoute(path) {
|
|
313
|
-
return state.routes.get(path);
|
|
489
|
+
return state.routes.get(path) ?? matchRoute(parseLocation(path).path)?.route;
|
|
314
490
|
}
|
|
315
491
|
function getRoutes() {
|
|
316
492
|
return Array.from(state.routes.values());
|
|
@@ -366,6 +542,8 @@ function createRouter(options = {}) {
|
|
|
366
542
|
replace,
|
|
367
543
|
back,
|
|
368
544
|
forward,
|
|
545
|
+
start,
|
|
546
|
+
stop,
|
|
369
547
|
prefetchRoute,
|
|
370
548
|
prefetchRoutes,
|
|
371
549
|
setupPrefetchStrategy,
|
package/dist/router.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/router.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * Enhanced Routing System\n *\n * Provides advanced routing features:\n * - Route prefetching strategies\n * - Page transitions\n * - Code splitting per route\n * - Advanced scroll behavior\n */\n\n/**\n * Create an enhanced router with advanced features\n *\n * @param {Object} options - Configuration options\n * @param {Object} [options.prefetch] - Prefetching configuration\n * @param {Object} [options.transitions] - Page transition configuration\n * @param {Object} [options.codeSplitting] - Code splitting configuration\n * @param {Object} [options.scrollBehavior] - Scroll behavior configuration\n * @returns {Object} Enhanced router instance\n */\nexport function createRouter(options = {}) {\n const opts = {\n mode: options.mode || 'history',\n base: options.base || '/',\n ...options\n };\n\n // Ensure nested defaults are preserved\n opts.prefetch = {\n enabled: false,\n strategy: 'hover',\n delay: 100,\n maxConcurrent: 3,\n priority: {\n critical: 100,\n high: 50,\n normal: 0,\n low: -50\n },\n ...(options.prefetch || {})\n };\n\n opts.transitions = {\n enabled: false,\n default: {\n enter: 'fade-in',\n leave: 'fade-out',\n duration: 300\n },\n routes: {},\n onStart: null,\n onComplete: null,\n ...(options.transitions || {})\n };\n\n opts.codeSplitting = {\n enabled: false,\n strategy: 'route',\n chunkNaming: '[name]-[hash]',\n preload: [],\n onLoad: null,\n ...(options.codeSplitting || {})\n };\n\n opts.scrollBehavior = {\n enabled: true,\n behavior: 'smooth',\n position: 'top',\n delay: 0,\n savePosition: true,\n custom: null,\n ...(options.scrollBehavior || {})\n };\n\n // Router state\n const state = {\n routes: new Map(),\n currentRoute: null,\n history: [],\n prefetchQueue: [],\n prefetching: new Set(),\n loadedChunks: new Map(),\n savedPositions: new Map(),\n transitionState: null\n };\n\n // Statistics\n const stats = {\n navigations: 0,\n prefetches: 0,\n transitionsCompleted: 0,\n chunksLoaded: 0,\n scrollRestores: 0\n };\n\n /**\n * Register a route\n */\n function addRoute(path, config) {\n state.routes.set(path, {\n path,\n component: config.component,\n meta: config.meta || {},\n beforeEnter: config.beforeEnter,\n beforeLeave: config.beforeLeave,\n priority: config.priority || opts.prefetch.priority.normal,\n transition: config.transition || opts.transitions.default,\n lazy: typeof config.component === 'function',\n loaded: !config.component || typeof config.component !== 'function',\n chunk: null\n });\n\n // Preload if configured\n if (opts.codeSplitting.enabled &&\n Array.isArray(opts.codeSplitting.preload) &&\n opts.codeSplitting.preload.includes(path)) {\n loadRoute(path);\n }\n }\n\n /**\n * Load a route component\n */\n async function loadRoute(path) {\n const route = state.routes.get(path);\n if (!route) {\n throw new Error(`Route not found: ${path}`);\n }\n\n if (route.loaded) {\n return route.component;\n }\n\n try {\n const startTime = performance.now();\n\n // Load the component\n const component = await route.component();\n route.component = component;\n route.loaded = true;\n route.chunk = opts.codeSplitting.chunkNaming\n .replace('[name]', path.replace(/\\//g, '-'))\n .replace('[hash]', generateHash(path));\n\n const loadTime = performance.now() - startTime;\n\n state.loadedChunks.set(path, {\n path,\n loadTime,\n timestamp: Date.now()\n });\n\n stats.chunksLoaded++;\n\n if (opts.codeSplitting.onLoad) {\n opts.codeSplitting.onLoad(path, component, loadTime);\n }\n\n return component;\n } catch (error) {\n route.loaded = false;\n throw new Error(`Failed to load route ${path}: ${error.message}`);\n }\n }\n\n /**\n * Prefetch a route\n */\n async function prefetchRoute(path, priority = opts.prefetch.priority.normal) {\n if (!opts.prefetch.enabled) return;\n\n const route = state.routes.get(path);\n if (!route || route.loaded || state.prefetching.has(path)) {\n return;\n }\n\n // Add to queue with priority\n state.prefetchQueue.push({ path, priority });\n state.prefetchQueue.sort((a, b) => b.priority - a.priority);\n\n // Process queue\n processPrefetchQueue();\n }\n\n /**\n * Process prefetch queue\n */\n async function processPrefetchQueue() {\n // Limit concurrent prefetches\n if (state.prefetching.size >= opts.prefetch.maxConcurrent) {\n return;\n }\n\n const item = state.prefetchQueue.shift();\n if (!item) return;\n\n const { path } = item;\n state.prefetching.add(path);\n\n try {\n await loadRoute(path);\n stats.prefetches++;\n } catch (error) {\n console.warn(`Prefetch failed for ${path}:`, error);\n } finally {\n state.prefetching.delete(path);\n // Process next item in queue\n if (state.prefetchQueue.length > 0) {\n processPrefetchQueue();\n }\n }\n }\n\n /**\n * Setup prefetch strategy\n */\n function setupPrefetchStrategy(element, path) {\n if (!opts.prefetch.enabled || !element) return;\n\n if (opts.prefetch.strategy === 'hover') {\n let timeoutId;\n element.addEventListener('mouseenter', () => {\n timeoutId = setTimeout(() => {\n prefetchRoute(path);\n }, opts.prefetch.delay);\n });\n element.addEventListener('mouseleave', () => {\n clearTimeout(timeoutId);\n });\n } else if (opts.prefetch.strategy === 'visible') {\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n prefetchRoute(path);\n observer.unobserve(element);\n }\n });\n });\n observer.observe(element);\n } else if (opts.prefetch.strategy === 'idle') {\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => prefetchRoute(path));\n } else {\n setTimeout(() => prefetchRoute(path), 1);\n }\n }\n }\n\n /**\n * Execute page transition\n */\n async function executeTransition(from, to) {\n if (!opts.transitions.enabled) return;\n\n const transition = state.routes.get(to)?.transition || opts.transitions.default;\n\n state.transitionState = {\n from,\n to,\n phase: 'start'\n };\n\n if (opts.transitions.onStart) {\n opts.transitions.onStart(from, to);\n }\n\n // Leave transition\n state.transitionState.phase = 'leave';\n await applyTransition(transition.leave, transition.duration / 2);\n\n // Enter transition\n state.transitionState.phase = 'enter';\n await applyTransition(transition.enter, transition.duration / 2);\n\n state.transitionState.phase = 'complete';\n stats.transitionsCompleted++;\n\n if (opts.transitions.onComplete) {\n opts.transitions.onComplete(from, to);\n }\n\n state.transitionState = null;\n }\n\n /**\n * Apply transition animation\n */\n function applyTransition(animationName, duration) {\n return new Promise(resolve => {\n const element = document.querySelector('[data-router-view]');\n if (!element) {\n resolve();\n return;\n }\n\n element.style.animation = `${animationName} ${duration}ms`;\n\n setTimeout(() => {\n element.style.animation = '';\n resolve();\n }, duration);\n });\n }\n\n /**\n * Handle scroll behavior\n */\n function handleScroll(to, from, savedPosition) {\n if (!opts.scrollBehavior.enabled) return;\n\n // Custom scroll behavior\n if (opts.scrollBehavior.custom) {\n const position = opts.scrollBehavior.custom(to, from, savedPosition);\n scrollToPosition(position);\n return;\n }\n\n // Default scroll behavior\n let position;\n\n if (savedPosition && opts.scrollBehavior.savePosition) {\n // Restore saved position\n position = savedPosition;\n stats.scrollRestores++;\n } else if (to.hash) {\n // Scroll to hash\n const element = document.querySelector(to.hash);\n if (element) {\n position = {\n el: element,\n behavior: opts.scrollBehavior.behavior\n };\n }\n } else if (opts.scrollBehavior.position === 'top') {\n // Scroll to top\n position = { x: 0, y: 0 };\n } else if (opts.scrollBehavior.position === 'saved' && savedPosition) {\n position = savedPosition;\n }\n\n if (position) {\n setTimeout(() => {\n scrollToPosition(position);\n }, opts.scrollBehavior.delay);\n }\n }\n\n /**\n * Scroll to position\n */\n function scrollToPosition(position) {\n if (typeof window === 'undefined') return;\n\n if (position.el) {\n position.el.scrollIntoView({\n behavior: position.behavior || opts.scrollBehavior.behavior\n });\n } else {\n window.scrollTo({\n left: position.x || 0,\n top: position.y || 0,\n behavior: position.behavior || opts.scrollBehavior.behavior\n });\n }\n }\n\n /**\n * Save current scroll position\n */\n function saveScrollPosition(path) {\n if (!opts.scrollBehavior.savePosition || typeof window === 'undefined') return;\n\n state.savedPositions.set(path, {\n x: window.scrollX,\n y: window.scrollY\n });\n }\n\n /**\n * Navigate to a route\n */\n async function push(path, options = {}) {\n stats.navigations++;\n\n const from = state.currentRoute;\n const to = { path, ...options };\n\n // Save scroll position\n if (from) {\n saveScrollPosition(from.path);\n }\n\n try {\n // Execute transition (leave phase)\n if (opts.transitions.enabled) {\n await executeTransition(from?.path, path);\n }\n\n // Load route component\n const component = await loadRoute(path);\n\n // Update current route\n state.currentRoute = {\n path,\n component,\n meta: state.routes.get(path)?.meta || {},\n ...options\n };\n\n // Add to history\n state.history.push({\n path,\n timestamp: Date.now()\n });\n\n // Handle scroll\n const savedPosition = state.savedPositions.get(path);\n handleScroll(to, from, savedPosition);\n\n return true;\n } catch (error) {\n console.error('Navigation failed:', error);\n return false;\n }\n }\n\n /**\n * Replace current route\n */\n async function replace(path, options = {}) {\n const result = await push(path, options);\n\n if (result && state.history.length > 1) {\n // Remove the previous history entry\n state.history.splice(state.history.length - 2, 1);\n }\n\n return result;\n }\n\n /**\n * Go back in history\n */\n function back() {\n if (state.history.length > 1) {\n const previous = state.history[state.history.length - 2];\n push(previous.path);\n }\n }\n\n /**\n * Go forward (if supported by browser)\n */\n function forward() {\n if (typeof window !== 'undefined') {\n window.history.forward();\n }\n }\n\n /**\n * Prefetch multiple routes\n */\n function prefetchRoutes(paths, priority) {\n paths.forEach(path => prefetchRoute(path, priority));\n }\n\n /**\n * Get route by path\n */\n function getRoute(path) {\n return state.routes.get(path);\n }\n\n /**\n * Get all routes\n */\n function getRoutes() {\n return Array.from(state.routes.values());\n }\n\n /**\n * Get current route\n */\n function getCurrentRoute() {\n return state.currentRoute;\n }\n\n /**\n * Get router statistics\n */\n function getStats() {\n return {\n ...stats,\n routesRegistered: state.routes.size,\n prefetchQueueSize: state.prefetchQueue.length,\n activePrefetches: state.prefetching.size,\n loadedChunks: state.loadedChunks.size,\n savedPositions: state.savedPositions.size,\n historyLength: state.history.length\n };\n }\n\n /**\n * Clear all caches\n */\n function clearCaches() {\n state.prefetchQueue = [];\n state.prefetching.clear();\n state.savedPositions.clear();\n\n // Unload lazy-loaded chunks\n state.routes.forEach(route => {\n if (route.lazy && route.loaded) {\n route.loaded = false;\n }\n });\n\n state.loadedChunks.clear();\n }\n\n /**\n * Generate hash for chunk naming\n */\n function generateHash(input) {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36).substring(0, 8);\n }\n\n // Initialize\n if (opts.prefetch.enabled && opts.prefetch.strategy === 'idle') {\n // Prefetch all routes on idle\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n requestIdleCallback(() => {\n state.routes.forEach((route, path) => {\n if (!route.loaded) {\n prefetchRoute(path, opts.prefetch.priority.low);\n }\n });\n });\n }\n }\n\n return {\n addRoute,\n push,\n replace,\n back,\n forward,\n prefetchRoute,\n prefetchRoutes,\n setupPrefetchStrategy,\n getRoute,\n getRoutes,\n getCurrentRoute,\n getStats,\n clearCaches,\n // Expose state for testing\n _state: state\n };\n}\n\n// Export default instance\nexport const router = createRouter();\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Enhanced Routing System\n *\n * Provides advanced routing features:\n * - Route patterns with `:param` segments and a trailing `*`\n * - Browser history integration (`start()`): pushState/replaceState,\n * back/forward via popstate, `mode: 'hash'` and a `base` path, and\n * interception of clicks on links to registered routes\n * - Route prefetching strategies\n * - Page transitions\n * - Code splitting per route\n * - Advanced scroll behavior\n *\n * The router resolves routes and tracks the current one; rendering the\n * matched component is left to the application (see getCurrentRoute()).\n */\n\n/**\n * Compile a route pattern: `/users/:id` captures `id`, a trailing `/*`\n * captures the rest as `params.pathMatch`.\n * @param {string} pattern\n * @returns {{ regex: RegExp, keys: string[] } | null} null for a static path\n */\nfunction compilePattern(pattern) {\n if (!pattern.includes(':') && !pattern.includes('*')) {\n return null;\n }\n const keys = [];\n const source = pattern\n .split('/')\n .map((segment) => {\n if (segment === '*') {\n keys.push('pathMatch');\n return '(.*)';\n }\n if (segment.startsWith(':')) {\n keys.push(segment.slice(1));\n return '([^/]+)';\n }\n return segment.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n })\n .join('/');\n return { regex: new RegExp(`^${source}/?$`), keys };\n}\n\n/**\n * Split `/path?query#hash` into its parts.\n * @param {string} fullPath\n * @returns {{ path: string, query: Object, hash: string }}\n */\nfunction parseLocation(fullPath) {\n let rest = String(fullPath);\n let hash = '';\n const hashIndex = rest.indexOf('#');\n if (hashIndex !== -1) {\n hash = rest.slice(hashIndex);\n rest = rest.slice(0, hashIndex);\n }\n let search = '';\n const queryIndex = rest.indexOf('?');\n if (queryIndex !== -1) {\n search = rest.slice(queryIndex + 1);\n rest = rest.slice(0, queryIndex);\n }\n return {\n path: rest || '/',\n query: Object.fromEntries(new URLSearchParams(search)),\n hash,\n };\n}\n\n/**\n * Create an enhanced router with advanced features\n *\n * @param {Object} options - Configuration options\n * @param {Object} [options.prefetch] - Prefetching configuration\n * @param {Object} [options.transitions] - Page transition configuration\n * @param {Object} [options.codeSplitting] - Code splitting configuration\n * @param {Object} [options.scrollBehavior] - Scroll behavior configuration\n * @returns {Object} Enhanced router instance\n */\nexport function createRouter(options = {}) {\n const opts = {\n mode: options.mode || 'history',\n base: options.base || '/',\n ...options\n };\n\n // '/app/' and '/app' mean the same base; '/' means none. Trimmed with a\n // loop: /\\/+$/ is quadratic on input like '////\u2026x'.\n let baseEnd = opts.base.length;\n while (baseEnd > 0 && opts.base[baseEnd - 1] === '/') baseEnd--;\n const base = opts.base.slice(0, baseEnd);\n\n // Ensure nested defaults are preserved\n opts.prefetch = {\n enabled: false,\n strategy: 'hover',\n delay: 100,\n maxConcurrent: 3,\n priority: {\n critical: 100,\n high: 50,\n normal: 0,\n low: -50\n },\n ...(options.prefetch || {})\n };\n\n opts.transitions = {\n enabled: false,\n default: {\n enter: 'fade-in',\n leave: 'fade-out',\n duration: 300\n },\n routes: {},\n onStart: null,\n onComplete: null,\n ...(options.transitions || {})\n };\n\n opts.codeSplitting = {\n enabled: false,\n strategy: 'route',\n chunkNaming: '[name]-[hash]',\n preload: [],\n onLoad: null,\n ...(options.codeSplitting || {})\n };\n\n opts.scrollBehavior = {\n enabled: true,\n behavior: 'smooth',\n position: 'top',\n delay: 0,\n savePosition: true,\n custom: null,\n ...(options.scrollBehavior || {})\n };\n\n // Router state\n const state = {\n routes: new Map(),\n currentRoute: null,\n history: [],\n prefetchQueue: [],\n prefetching: new Set(),\n loadedChunks: new Map(),\n savedPositions: new Map(),\n transitionState: null,\n forwardStack: []\n };\n\n /** Incremented per navigation; only the latest one may commit */\n let navigationId = 0;\n\n /** Browser listeners attached by start() */\n let listening = null;\n\n // Statistics\n const stats = {\n navigations: 0,\n prefetches: 0,\n transitionsCompleted: 0,\n chunksLoaded: 0,\n scrollRestores: 0\n };\n\n /**\n * Register a route\n */\n function addRoute(path, config) {\n state.routes.set(path, {\n path,\n pattern: compilePattern(path),\n component: config.component,\n meta: config.meta || {},\n beforeEnter: config.beforeEnter,\n beforeLeave: config.beforeLeave,\n priority: config.priority || opts.prefetch.priority.normal,\n transition: config.transition || opts.transitions.default,\n lazy: typeof config.component === 'function',\n loaded: !config.component || typeof config.component !== 'function',\n chunk: null\n });\n\n // Preload if configured\n if (opts.codeSplitting.enabled &&\n Array.isArray(opts.codeSplitting.preload) &&\n opts.codeSplitting.preload.includes(path)) {\n loadRoute(path);\n }\n }\n\n /**\n * Find the route for a path: an exact registration first, then patterns in\n * registration order.\n * @param {string} path - Path without query or hash\n * @returns {{ route: Object, params: Object } | null}\n */\n function matchRoute(path) {\n const exact = state.routes.get(path);\n if (exact) {\n return { route: exact, params: {} };\n }\n for (const route of state.routes.values()) {\n const match = route.pattern?.regex.exec(path);\n if (match) {\n const params = {};\n route.pattern.keys.forEach((key, i) => {\n params[key] = decodeURIComponent(match[i + 1]);\n });\n return { route, params };\n }\n }\n return null;\n }\n\n /**\n * Load a route component\n */\n async function loadRoute(path) {\n const route = state.routes.get(path) ?? matchRoute(parseLocation(path).path)?.route;\n if (!route) {\n throw new Error(`Route not found: ${path}`);\n }\n\n if (route.loaded) {\n return route.component;\n }\n\n try {\n const startTime = performance.now();\n\n // Load the component\n const component = await route.component();\n route.component = component;\n route.loaded = true;\n route.chunk = opts.codeSplitting.chunkNaming\n .replace('[name]', path.replace(/\\//g, '-'))\n .replace('[hash]', generateHash(path));\n\n const loadTime = performance.now() - startTime;\n\n state.loadedChunks.set(path, {\n path,\n loadTime,\n timestamp: Date.now()\n });\n\n stats.chunksLoaded++;\n\n if (opts.codeSplitting.onLoad) {\n opts.codeSplitting.onLoad(path, component, loadTime);\n }\n\n return component;\n } catch (error) {\n route.loaded = false;\n throw new Error(`Failed to load route ${path}: ${error.message}`);\n }\n }\n\n /**\n * Prefetch a route\n */\n async function prefetchRoute(path, priority = opts.prefetch.priority.normal) {\n if (!opts.prefetch.enabled) return;\n\n const route = state.routes.get(path) ?? matchRoute(parseLocation(path).path)?.route;\n if (!route || route.loaded || state.prefetching.has(path)) {\n return;\n }\n\n // Add to queue with priority\n state.prefetchQueue.push({ path, priority });\n state.prefetchQueue.sort((a, b) => b.priority - a.priority);\n\n // Process queue\n processPrefetchQueue();\n }\n\n /**\n * Process prefetch queue\n */\n async function processPrefetchQueue() {\n // Limit concurrent prefetches\n if (state.prefetching.size >= opts.prefetch.maxConcurrent) {\n return;\n }\n\n const item = state.prefetchQueue.shift();\n if (!item) return;\n\n const { path } = item;\n state.prefetching.add(path);\n\n try {\n await loadRoute(path);\n stats.prefetches++;\n } catch (error) {\n console.warn(`Prefetch failed for ${path}:`, error);\n } finally {\n state.prefetching.delete(path);\n // Process next item in queue\n if (state.prefetchQueue.length > 0) {\n processPrefetchQueue();\n }\n }\n }\n\n /**\n * Setup prefetch strategy\n */\n function setupPrefetchStrategy(element, path) {\n if (!opts.prefetch.enabled || !element) return;\n\n if (opts.prefetch.strategy === 'hover') {\n let timeoutId;\n element.addEventListener('mouseenter', () => {\n timeoutId = setTimeout(() => {\n prefetchRoute(path);\n }, opts.prefetch.delay);\n });\n element.addEventListener('mouseleave', () => {\n clearTimeout(timeoutId);\n });\n } else if (opts.prefetch.strategy === 'visible') {\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n prefetchRoute(path);\n observer.unobserve(element);\n }\n });\n });\n observer.observe(element);\n } else if (opts.prefetch.strategy === 'idle') {\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => prefetchRoute(path));\n } else {\n setTimeout(() => prefetchRoute(path), 1);\n }\n }\n }\n\n /**\n * Execute page transition\n */\n async function executeTransition(from, to) {\n if (!opts.transitions.enabled) return;\n\n const transition = state.routes.get(to)?.transition || opts.transitions.default;\n\n state.transitionState = {\n from,\n to,\n phase: 'start'\n };\n\n if (opts.transitions.onStart) {\n opts.transitions.onStart(from, to);\n }\n\n // Leave transition\n state.transitionState.phase = 'leave';\n await applyTransition(transition.leave, transition.duration / 2);\n\n // Enter transition\n state.transitionState.phase = 'enter';\n await applyTransition(transition.enter, transition.duration / 2);\n\n state.transitionState.phase = 'complete';\n stats.transitionsCompleted++;\n\n if (opts.transitions.onComplete) {\n opts.transitions.onComplete(from, to);\n }\n\n state.transitionState = null;\n }\n\n /**\n * Apply transition animation\n */\n function applyTransition(animationName, duration) {\n return new Promise(resolve => {\n const element = document.querySelector('[data-router-view]');\n if (!element) {\n resolve();\n return;\n }\n\n element.style.animation = `${animationName} ${duration}ms`;\n\n setTimeout(() => {\n element.style.animation = '';\n resolve();\n }, duration);\n });\n }\n\n /**\n * Handle scroll behavior\n */\n function handleScroll(to, from, savedPosition) {\n // Without a DOM there is nothing to scroll. This runs after the route is\n // committed, so throwing here (document is not defined) reported a\n // navigation that had happened as failed.\n if (!opts.scrollBehavior.enabled || typeof document === 'undefined') return;\n\n // Custom scroll behavior\n if (opts.scrollBehavior.custom) {\n const position = opts.scrollBehavior.custom(to, from, savedPosition);\n scrollToPosition(position);\n return;\n }\n\n // Default scroll behavior\n let position;\n\n if (savedPosition && opts.scrollBehavior.savePosition) {\n // Restore saved position\n position = savedPosition;\n stats.scrollRestores++;\n } else if (to.hash) {\n // Scroll to hash. By id rather than querySelector(to.hash), which\n // throws on ids that aren't valid selectors (#123, #a.b).\n let id = to.hash.slice(1);\n try {\n id = decodeURIComponent(id);\n } catch {\n // keep the raw id\n }\n const element = document.getElementById(id);\n if (element) {\n position = {\n el: element,\n behavior: opts.scrollBehavior.behavior\n };\n }\n } else if (opts.scrollBehavior.position === 'top') {\n // Scroll to top\n position = { x: 0, y: 0 };\n } else if (opts.scrollBehavior.position === 'saved' && savedPosition) {\n position = savedPosition;\n }\n\n if (position) {\n setTimeout(() => {\n scrollToPosition(position);\n }, opts.scrollBehavior.delay);\n }\n }\n\n /**\n * Scroll to position\n */\n function scrollToPosition(position) {\n if (typeof window === 'undefined') return;\n\n if (position.el) {\n position.el.scrollIntoView({\n behavior: position.behavior || opts.scrollBehavior.behavior\n });\n } else {\n window.scrollTo({\n left: position.x || 0,\n top: position.y || 0,\n behavior: position.behavior || opts.scrollBehavior.behavior\n });\n }\n }\n\n /**\n * Save current scroll position\n */\n function saveScrollPosition(path) {\n if (!opts.scrollBehavior.savePosition || typeof window === 'undefined') return;\n\n state.savedPositions.set(path, {\n x: window.scrollX,\n y: window.scrollY\n });\n }\n\n /** Whether the browser History API is available */\n function hasHistoryApi() {\n return typeof window !== 'undefined' &&\n Boolean(window.history) &&\n typeof window.history.pushState === 'function';\n }\n\n /** The URL written to the address bar for a router path */\n function toURL(fullPath) {\n if (opts.mode === 'hash') {\n return `#${fullPath}`;\n }\n return `${base}${fullPath}` || '/';\n }\n\n /** The router path of the browser's current location */\n function currentLocation() {\n if (opts.mode === 'hash') {\n return window.location.hash.slice(1) || '/';\n }\n let path = window.location.pathname;\n if (base && (path === base || path.startsWith(`${base}/`))) {\n path = path.slice(base.length) || '/';\n }\n return `${path}${window.location.search}${window.location.hash}`;\n }\n\n /**\n * Resolve, guard, load and commit a navigation.\n *\n * @param {string} fullPath - Path, optionally with ?query and #hash\n * @param {Object} options - Extra fields for the route record\n * @param {'push'|'replace'|'pop'} historyAction - How to record it\n * @returns {Promise<boolean>} false when not found, cancelled by a guard,\n * failed, or superseded by a later navigation\n */\n async function navigate(fullPath, options, historyAction) {\n stats.navigations++;\n const id = ++navigationId;\n\n const from = state.currentRoute;\n const location = parseLocation(fullPath);\n const matched = matchRoute(location.path);\n const to = {\n ...options,\n path: location.path,\n fullPath: String(fullPath),\n params: matched?.params ?? {},\n query: location.query,\n hash: location.hash,\n meta: matched?.route.meta ?? {}\n };\n\n // Save scroll position\n if (from) {\n saveScrollPosition(from.path);\n }\n\n try {\n if (!matched) {\n throw new Error(`Route not found: ${location.path}`);\n }\n\n // Guards: returning false cancels the navigation\n const leaving = from ? matchRoute(from.path)?.route : null;\n if (leaving?.beforeLeave && (await leaving.beforeLeave(to, from)) === false) {\n return false;\n }\n if (matched.route.beforeEnter && (await matched.route.beforeEnter(to, from)) === false) {\n return false;\n }\n if (id !== navigationId) {\n return false;\n }\n\n // Execute transition (leave phase)\n if (opts.transitions.enabled) {\n await executeTransition(from?.path, location.path);\n }\n\n // Load route component\n const component = await loadRoute(matched.route.path);\n\n // A later navigation started meanwhile: it wins\n if (id !== navigationId) {\n return false;\n }\n\n // Update current route\n state.currentRoute = { ...to, component };\n\n // Record in history\n const entry = { path: location.path, fullPath: String(fullPath), timestamp: Date.now() };\n if (historyAction === 'replace' && state.history.length > 0) {\n state.history[state.history.length - 1] = entry;\n } else if (historyAction === 'push' || state.history.length === 0) {\n state.history.push(entry);\n if (historyAction === 'push') state.forwardStack = [];\n }\n\n if (hasHistoryApi() && historyAction !== 'pop') {\n const method = historyAction === 'replace' ? 'replaceState' : 'pushState';\n window.history[method]({ path: String(fullPath) }, '', toURL(String(fullPath)));\n }\n\n // Handle scroll\n const savedPosition = state.savedPositions.get(location.path);\n handleScroll(to, from, historyAction === 'pop' ? savedPosition : null);\n\n return true;\n } catch (error) {\n console.error('Navigation failed:', error);\n return false;\n }\n }\n\n /**\n * Navigate to a route, adding a history entry\n */\n function push(path, options = {}) {\n return navigate(path, options, 'push');\n }\n\n /**\n * Replace current route (and the current history entry)\n */\n function replace(path, options = {}) {\n return navigate(path, options, 'replace');\n }\n\n /**\n * Go back in history. After start() the browser's history drives it\n * (popstate); otherwise the router's own history is used.\n */\n function back() {\n if (listening) {\n window.history.back();\n return;\n }\n if (state.history.length > 1) {\n state.forwardStack.push(state.history.pop());\n const previous = state.history[state.history.length - 1];\n navigate(previous.fullPath ?? previous.path, {}, 'pop');\n }\n }\n\n /**\n * Go forward in history\n */\n function forward() {\n if (listening) {\n window.history.forward();\n return;\n }\n const next = state.forwardStack.pop();\n if (next) {\n state.history.push(next);\n navigate(next.fullPath ?? next.path, {}, 'pop');\n }\n }\n\n /**\n * Follow the browser: navigate to the current location, then handle\n * back/forward (popstate, or hashchange in hash mode) and, unless\n * `interceptLinks` is false, clicks on same-origin links whose path is a\n * registered route. Idempotent; stop() detaches.\n *\n * @param {Object} [startOptions]\n * @param {boolean} [startOptions.interceptLinks=true]\n * @returns {Promise<boolean>} Result of the initial navigation\n */\n function start(startOptions = {}) {\n if (typeof window === 'undefined' || listening) {\n return Promise.resolve(false);\n }\n\n const onPop = () => {\n navigate(currentLocation(), {}, 'pop');\n };\n\n const onClick = (event) => {\n if (event.defaultPrevented || event.button !== 0 ||\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {\n return;\n }\n const link = typeof event.target?.closest === 'function' ? event.target.closest('a[href]') : null;\n const target = link?.getAttribute('target');\n if (!link || link.hasAttribute('download') || link.hasAttribute('data-router-ignore') ||\n (target && target !== '_self')) {\n return;\n }\n\n let url;\n try {\n url = new URL(link.getAttribute('href'), window.location.href);\n } catch {\n return;\n }\n if (url.origin !== window.location.origin) return;\n\n let fullPath;\n if (opts.mode === 'hash') {\n if (!url.hash.startsWith('#/')) return;\n fullPath = url.hash.slice(1);\n } else {\n if (base && url.pathname !== base && !url.pathname.startsWith(`${base}/`)) return;\n fullPath = `${url.pathname.slice(base.length) || '/'}${url.search}${url.hash}`;\n }\n if (!matchRoute(parseLocation(fullPath).path)) return;\n\n event.preventDefault();\n push(fullPath);\n };\n\n const popEvent = opts.mode === 'hash' ? 'hashchange' : 'popstate';\n window.addEventListener(popEvent, onPop);\n if (startOptions.interceptLinks !== false && typeof document !== 'undefined') {\n document.addEventListener('click', onClick);\n }\n listening = { popEvent, onPop, onClick };\n\n return navigate(currentLocation(), {}, 'replace');\n }\n\n /**\n * Detach the listeners added by start()\n */\n function stop() {\n if (!listening) return;\n window.removeEventListener(listening.popEvent, listening.onPop);\n if (typeof document !== 'undefined') {\n document.removeEventListener('click', listening.onClick);\n }\n listening = null;\n }\n\n /**\n * Prefetch multiple routes\n */\n function prefetchRoutes(paths, priority) {\n paths.forEach(path => prefetchRoute(path, priority));\n }\n\n /**\n * Get route by path\n */\n function getRoute(path) {\n return state.routes.get(path) ?? matchRoute(parseLocation(path).path)?.route;\n }\n\n /**\n * Get all routes\n */\n function getRoutes() {\n return Array.from(state.routes.values());\n }\n\n /**\n * Get current route\n */\n function getCurrentRoute() {\n return state.currentRoute;\n }\n\n /**\n * Get router statistics\n */\n function getStats() {\n return {\n ...stats,\n routesRegistered: state.routes.size,\n prefetchQueueSize: state.prefetchQueue.length,\n activePrefetches: state.prefetching.size,\n loadedChunks: state.loadedChunks.size,\n savedPositions: state.savedPositions.size,\n historyLength: state.history.length\n };\n }\n\n /**\n * Clear all caches\n */\n function clearCaches() {\n state.prefetchQueue = [];\n state.prefetching.clear();\n state.savedPositions.clear();\n\n // Unload lazy-loaded chunks\n state.routes.forEach(route => {\n if (route.lazy && route.loaded) {\n route.loaded = false;\n }\n });\n\n state.loadedChunks.clear();\n }\n\n /**\n * Generate hash for chunk naming\n */\n function generateHash(input) {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36).substring(0, 8);\n }\n\n // Initialize\n if (opts.prefetch.enabled && opts.prefetch.strategy === 'idle') {\n // Prefetch all routes on idle\n if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {\n requestIdleCallback(() => {\n state.routes.forEach((route, path) => {\n if (!route.loaded) {\n prefetchRoute(path, opts.prefetch.priority.low);\n }\n });\n });\n }\n }\n\n return {\n addRoute,\n push,\n replace,\n back,\n forward,\n start,\n stop,\n prefetchRoute,\n prefetchRoutes,\n setupPrefetchStrategy,\n getRoute,\n getRoutes,\n getCurrentRoute,\n getStats,\n clearCaches,\n // Expose state for testing\n _state: state\n };\n}\n\n// Export default instance\nexport const router = createRouter();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["position", "options"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coherent.js/client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-rc.0",
|
|
4
4
|
"description": "Client-side hydration/HMR utilities for Coherent.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"expect-type": "1.4.0"
|
|
52
52
|
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@coherent.js/core": "^2.0.0-rc.0"
|
|
55
|
+
},
|
|
53
56
|
"scripts": {
|
|
54
57
|
"build": "node build.mjs",
|
|
55
58
|
"clean": "rm -rf dist/",
|
package/types/hmr.d.ts
CHANGED
|
@@ -1 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `@coherent.js/client/hmr` — the HMR client API on its own. Importing it has
|
|
3
|
+
* no side effects; call `hmrClient.initialize()` to connect.
|
|
4
|
+
*/
|
|
5
|
+
export {
|
|
6
|
+
HMRClient,
|
|
7
|
+
hmrClient,
|
|
8
|
+
ModuleTracker,
|
|
9
|
+
moduleTracker,
|
|
10
|
+
createHotContext,
|
|
11
|
+
CleanupTracker,
|
|
12
|
+
cleanupTracker,
|
|
13
|
+
StateCapturer,
|
|
14
|
+
stateCapturer,
|
|
15
|
+
ErrorOverlay,
|
|
16
|
+
errorOverlay,
|
|
17
|
+
ConnectionIndicator,
|
|
18
|
+
connectionIndicator,
|
|
19
|
+
} from './index.js';
|
|
20
|
+
|
|
21
|
+
/** Escape text for insertion into the overlay's HTML */
|
|
22
|
+
export function escapeHtml(str: unknown): string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Render a code frame as HTML, highlighting `highlightLine`; line numbers
|
|
26
|
+
* start at `startLine`
|
|
27
|
+
*/
|
|
28
|
+
export function formatCodeFrame(
|
|
29
|
+
frame: string,
|
|
30
|
+
highlightLine?: number | null,
|
|
31
|
+
startLine?: number
|
|
32
|
+
): string;
|