@zenithbuild/router 0.6.5 → 0.6.7
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/dist/events.d.ts +21 -0
- package/dist/events.js +23 -75
- package/dist/history.d.ts +26 -0
- package/dist/history.js +2 -10
- package/dist/index.d.ts +4 -41
- package/dist/index.js +0 -1
- package/dist/match.d.ts +22 -0
- package/dist/match.js +40 -98
- package/dist/navigate.d.ts +5 -0
- package/dist/navigate.js +6 -40
- package/dist/router.d.ts +18 -0
- package/dist/router.js +22 -63
- package/package.json +11 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/manifest.d.ts +0 -32
- package/dist/manifest.d.ts.map +0 -1
- package/dist/manifest.js +0 -180
- package/dist/manifest.js.map +0 -1
- package/dist/navigation/client-router.d.ts +0 -59
- package/dist/navigation/client-router.d.ts.map +0 -1
- package/dist/navigation/client-router.js +0 -373
- package/dist/navigation/client-router.js.map +0 -1
- package/dist/navigation/index.d.ts +0 -30
- package/dist/navigation/index.d.ts.map +0 -1
- package/dist/navigation/index.js +0 -44
- package/dist/navigation/index.js.map +0 -1
- package/dist/navigation/zen-link.d.ts +0 -234
- package/dist/navigation/zen-link.d.ts.map +0 -1
- package/dist/navigation/zen-link.js +0 -437
- package/dist/navigation/zen-link.js.map +0 -1
- package/dist/runtime.d.ts +0 -33
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -157
- package/dist/runtime.js.map +0 -1
- package/dist/types.d.ts +0 -50
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
package/dist/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// router.
|
|
2
|
+
// router.ts — Zenith Router V0
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
// Router assembly: wires match engine + history + runtime mount/unmount.
|
|
5
5
|
//
|
|
@@ -11,101 +11,60 @@
|
|
|
11
11
|
// - Mount/unmount delegated to @zenithbuild/runtime
|
|
12
12
|
// - Deterministic first-match-wins
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
import { matchRoute } from './match.js';
|
|
16
|
-
import { listen, current } from './history.js';
|
|
17
14
|
import { _dispatchRouteChange } from './events.js';
|
|
15
|
+
import { current, listen } from './history.js';
|
|
16
|
+
import { matchRoute } from './match.js';
|
|
18
17
|
import { _setNavigationResolver } from './navigate.js';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create a router instance.
|
|
22
|
-
*
|
|
23
|
-
* @param {{ routes: Array<{ path: string, load: Function }>, container: HTMLElement, mount?: Function, cleanup?: Function }} config
|
|
24
|
-
* @returns {{ start: () => Promise<void>, destroy: () => void }}
|
|
25
|
-
*/
|
|
26
18
|
export function createRouter(config) {
|
|
27
19
|
const { routes, container } = config;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const mountFn = config.mount || null;
|
|
31
|
-
const cleanupFn = config.cleanup || null;
|
|
32
|
-
|
|
20
|
+
const mountFn = typeof config.mount === 'function' ? config.mount : null;
|
|
21
|
+
const cleanupFn = typeof config.cleanup === 'function' ? config.cleanup : null;
|
|
33
22
|
if (!container || !(container instanceof HTMLElement)) {
|
|
34
23
|
throw new Error('[Zenith Router] createRouter() requires an HTMLElement container');
|
|
35
24
|
}
|
|
36
|
-
|
|
37
25
|
if (!Array.isArray(routes) || routes.length === 0) {
|
|
38
26
|
throw new Error('[Zenith Router] createRouter() requires a non-empty routes array');
|
|
39
27
|
}
|
|
40
|
-
|
|
41
|
-
let
|
|
42
|
-
let
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Resolve a path: match → load → mount.
|
|
47
|
-
*
|
|
48
|
-
* @param {string} path
|
|
49
|
-
*/
|
|
50
|
-
async function _resolve(path) {
|
|
28
|
+
let unlisten = null;
|
|
29
|
+
let started = false;
|
|
30
|
+
let hasMounted = false;
|
|
31
|
+
async function resolvePath(path) {
|
|
51
32
|
const result = matchRoute(routes, path);
|
|
52
|
-
|
|
53
33
|
if (!result) {
|
|
54
34
|
_dispatchRouteChange({ path, matched: false });
|
|
55
35
|
return;
|
|
56
36
|
}
|
|
57
|
-
|
|
58
|
-
// Teardown previous page (only if we've mounted before)
|
|
59
|
-
if (_hasMounted && cleanupFn) {
|
|
37
|
+
if (hasMounted && cleanupFn) {
|
|
60
38
|
cleanupFn();
|
|
61
39
|
}
|
|
62
|
-
|
|
63
|
-
// Load module
|
|
64
40
|
const pageModule = await result.route.load(result.params);
|
|
65
|
-
|
|
66
|
-
// Mount new page
|
|
67
41
|
if (mountFn) {
|
|
68
42
|
mountFn(container, pageModule);
|
|
69
|
-
|
|
43
|
+
hasMounted = true;
|
|
70
44
|
}
|
|
71
|
-
|
|
72
45
|
_dispatchRouteChange({
|
|
73
46
|
path,
|
|
74
47
|
params: result.params,
|
|
75
48
|
matched: true
|
|
76
49
|
});
|
|
77
50
|
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Start the router — match initial route and begin listening.
|
|
81
|
-
*/
|
|
82
51
|
async function start() {
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// Listen for popstate (back/forward)
|
|
90
|
-
_unlisten = listen((path) => {
|
|
91
|
-
_resolve(path);
|
|
52
|
+
if (started)
|
|
53
|
+
return;
|
|
54
|
+
started = true;
|
|
55
|
+
_setNavigationResolver(resolvePath);
|
|
56
|
+
unlisten = listen((path) => {
|
|
57
|
+
void resolvePath(path);
|
|
92
58
|
});
|
|
93
|
-
|
|
94
|
-
// Initial route
|
|
95
|
-
await _resolve(current());
|
|
59
|
+
await resolvePath(current());
|
|
96
60
|
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Tear down the router — remove listeners, clear state.
|
|
100
|
-
*/
|
|
101
61
|
function destroy() {
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
62
|
+
if (unlisten) {
|
|
63
|
+
unlisten();
|
|
64
|
+
unlisten = null;
|
|
105
65
|
}
|
|
106
66
|
_setNavigationResolver(null);
|
|
107
|
-
|
|
67
|
+
started = false;
|
|
108
68
|
}
|
|
109
|
-
|
|
110
69
|
return { start, destroy };
|
|
111
70
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenithbuild/router",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
4
4
|
"description": "File-based SPA router for Zenith framework with deterministic, compile-time route resolution",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,13 +30,18 @@
|
|
|
30
30
|
"author": "Zenith Team",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "
|
|
33
|
+
"url": "https://github.com/zenithbuild/framework",
|
|
34
|
+
"directory": "packages/router"
|
|
34
35
|
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/zenithbuild/framework/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/zenithbuild/framework#readme",
|
|
35
40
|
"scripts": {
|
|
36
41
|
"format": "prettier --write \"**/*.ts\"",
|
|
37
42
|
"format:check": "prettier --check \"**/*.ts\"",
|
|
38
|
-
"typecheck": "tsc --noEmit",
|
|
39
|
-
"build": "
|
|
43
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
44
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && cp src/ZenLink.zen dist/ZenLink.zen",
|
|
40
45
|
"release": "bun run scripts/release.ts",
|
|
41
46
|
"release:dry": "bun run scripts/release.ts --dry-run",
|
|
42
47
|
"release:patch": "bun run scripts/release.ts --bump=patch",
|
|
@@ -57,6 +62,7 @@
|
|
|
57
62
|
"@napi-rs/cli": "^2.18.4",
|
|
58
63
|
"@types/bun": "latest",
|
|
59
64
|
"@types/node": "latest",
|
|
60
|
-
"prettier": "^3.7.4"
|
|
65
|
+
"prettier": "^3.7.4",
|
|
66
|
+
"typescript": "^5.7.3"
|
|
61
67
|
}
|
|
62
68
|
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,cAAc,SAAS,CAAA;AAMvB,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EAC5B,MAAM,YAAY,CAAA;AAMnB,OAAO,EACH,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,yBAAyB,EACzB,QAAQ,EACX,MAAM,WAAW,CAAA;AAMlB,OAAO,EAEH,WAAW,EACX,OAAO,EACP,UAAU,EACV,KAAK,EACL,WAAW,EACX,WAAW,EACX,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO,EAEP,IAAI,EACJ,OAAO,EACP,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EAC1B,MAAM,oBAAoB,CAAA;AAM3B,YAAY,EACR,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACpB,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,+CAA+C;AAC/C,aAAa;AACb,+CAA+C;AAE/C,cAAc,SAAS,CAAA;AAEvB,+CAA+C;AAC/C,iCAAiC;AACjC,+CAA+C;AAE/C,OAAO,EACH,qBAAqB,EACrB,yBAAyB,EAC5B,MAAM,YAAY,CAAA;AAEnB,+CAA+C;AAC/C,iBAAiB;AACjB,+CAA+C;AAE/C,OAAO,EACH,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,yBAAyB,EACzB,QAAQ,EACX,MAAM,WAAW,CAAA;AAElB,+CAA+C;AAC/C,uBAAuB;AACvB,+CAA+C;AAE/C,OAAO;AACH,uCAAuC;AACvC,WAAW,EACX,OAAO,EACP,UAAU,EACV,KAAK,EACL,WAAW,EACX,WAAW,EACX,eAAe,EACf,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO;AACP,kCAAkC;AAClC,IAAI,EACJ,OAAO,EACP,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EAC1B,MAAM,oBAAoB,CAAA"}
|
package/dist/manifest.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { type RouteDefinition, type ParsedSegment } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Discover all .zen files in the pages directory
|
|
4
|
-
*/
|
|
5
|
-
export declare function discoverPages(pagesDir: string): string[];
|
|
6
|
-
/**
|
|
7
|
-
* Convert a file path to a route path
|
|
8
|
-
*/
|
|
9
|
-
export declare function filePathToRoutePath(filePath: string, pagesDir: string): string;
|
|
10
|
-
/**
|
|
11
|
-
* Parse a route path into segments
|
|
12
|
-
*/
|
|
13
|
-
export declare function parseRouteSegments(routePath: string): ParsedSegment[];
|
|
14
|
-
/**
|
|
15
|
-
* Calculate route score
|
|
16
|
-
*/
|
|
17
|
-
export declare function calculateRouteScore(segments: ParsedSegment[]): number;
|
|
18
|
-
/**
|
|
19
|
-
* Extract parameter names
|
|
20
|
-
*/
|
|
21
|
-
export declare function extractParamNames(segments: ParsedSegment[]): string[];
|
|
22
|
-
/**
|
|
23
|
-
* Convert route path to regex pattern
|
|
24
|
-
*/
|
|
25
|
-
export declare function routePathToRegex(routePath: string): RegExp;
|
|
26
|
-
/**
|
|
27
|
-
* Generate a route definition from a file path
|
|
28
|
-
*/
|
|
29
|
-
export declare function generateRouteDefinition(filePath: string, pagesDir: string): RouteDefinition;
|
|
30
|
-
export declare function generateRouteManifest(pagesDir: string): RouteDefinition[];
|
|
31
|
-
export declare function generateRouteManifestCode(definitions: RouteDefinition[]): string;
|
|
32
|
-
//# sourceMappingURL=manifest.d.ts.map
|
package/dist/manifest.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,eAAe,EACpB,KAAK,aAAa,EAErB,MAAM,SAAS,CAAA;AAchB;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgC9E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAuBrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CASrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAIrE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAc3F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAMzE;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,eAAe,EAAE,GAAG,MAAM,CAahF"}
|
package/dist/manifest.js
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import native from "../index.js";
|
|
4
|
-
const { generateRouteManifestNative } = native;
|
|
5
|
-
/**
|
|
6
|
-
* Scoring constants for route ranking
|
|
7
|
-
*/
|
|
8
|
-
const SEGMENT_SCORES = {
|
|
9
|
-
[0 /* SegmentType.Static */]: 10,
|
|
10
|
-
[1 /* SegmentType.Dynamic */]: 5,
|
|
11
|
-
[2 /* SegmentType.CatchAll */]: 1,
|
|
12
|
-
[3 /* SegmentType.OptionalCatchAll */]: 0
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Discover all .zen files in the pages directory
|
|
16
|
-
*/
|
|
17
|
-
export function discoverPages(pagesDir) {
|
|
18
|
-
const pages = [];
|
|
19
|
-
function walk(dir) {
|
|
20
|
-
if (!fs.existsSync(dir))
|
|
21
|
-
return;
|
|
22
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
const fullPath = path.join(dir, entry.name);
|
|
25
|
-
if (entry.isDirectory()) {
|
|
26
|
-
walk(fullPath);
|
|
27
|
-
}
|
|
28
|
-
else if (entry.isFile() && entry.name.endsWith(".zen")) {
|
|
29
|
-
pages.push(fullPath);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
walk(pagesDir);
|
|
34
|
-
return pages;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Convert a file path to a route path
|
|
38
|
-
*/
|
|
39
|
-
export function filePathToRoutePath(filePath, pagesDir) {
|
|
40
|
-
const relativePath = path.relative(pagesDir, filePath);
|
|
41
|
-
const withoutExt = relativePath.replace(/\.zen$/, "");
|
|
42
|
-
const segmentsList = withoutExt.split(path.sep);
|
|
43
|
-
const routeSegments = [];
|
|
44
|
-
for (const segment of segmentsList) {
|
|
45
|
-
if (segment === "index")
|
|
46
|
-
continue;
|
|
47
|
-
const optionalCatchAllMatch = segment.match(/^\[\[\.\.\.(\w+)\]\]$/);
|
|
48
|
-
if (optionalCatchAllMatch) {
|
|
49
|
-
routeSegments.push(`*${optionalCatchAllMatch[1]}?`);
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const catchAllMatch = segment.match(/^\[\.\.\.(\w+)\]$/);
|
|
53
|
-
if (catchAllMatch) {
|
|
54
|
-
routeSegments.push(`*${catchAllMatch[1]}`);
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const dynamicMatch = segment.match(/^\[(\w+)\]$/);
|
|
58
|
-
if (dynamicMatch) {
|
|
59
|
-
routeSegments.push(`:${dynamicMatch[1]}`);
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
routeSegments.push(segment);
|
|
63
|
-
}
|
|
64
|
-
const routePath = "/" + routeSegments.join("/");
|
|
65
|
-
return routePath === "/" ? "/" : routePath.replace(/\/$/, "");
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Parse a route path into segments
|
|
69
|
-
*/
|
|
70
|
-
export function parseRouteSegments(routePath) {
|
|
71
|
-
if (routePath === "/")
|
|
72
|
-
return [];
|
|
73
|
-
const segmentsList = routePath.slice(1).split("/");
|
|
74
|
-
const parsed = [];
|
|
75
|
-
for (const segment of segmentsList) {
|
|
76
|
-
if (segment.startsWith("*") && segment.endsWith("?")) {
|
|
77
|
-
parsed.push({ segmentType: 3 /* SegmentType.OptionalCatchAll */, paramName: segment.slice(1, -1), raw: segment });
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
if (segment.startsWith("*")) {
|
|
81
|
-
parsed.push({ segmentType: 2 /* SegmentType.CatchAll */, paramName: segment.slice(1), raw: segment });
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (segment.startsWith(":")) {
|
|
85
|
-
parsed.push({ segmentType: 1 /* SegmentType.Dynamic */, paramName: segment.slice(1), raw: segment });
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
parsed.push({ segmentType: 0 /* SegmentType.Static */, raw: segment });
|
|
89
|
-
}
|
|
90
|
-
return parsed;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Calculate route score
|
|
94
|
-
*/
|
|
95
|
-
export function calculateRouteScore(segments) {
|
|
96
|
-
if (segments.length === 0)
|
|
97
|
-
return 100;
|
|
98
|
-
let score = 0;
|
|
99
|
-
for (const segment of segments) {
|
|
100
|
-
score += SEGMENT_SCORES[segment.segmentType];
|
|
101
|
-
}
|
|
102
|
-
const staticCount = segments.filter(s => s.segmentType === 0 /* SegmentType.Static */).length;
|
|
103
|
-
score += staticCount * 2;
|
|
104
|
-
return score;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Extract parameter names
|
|
108
|
-
*/
|
|
109
|
-
export function extractParamNames(segments) {
|
|
110
|
-
return segments
|
|
111
|
-
.filter(s => s.paramName !== undefined)
|
|
112
|
-
.map(s => s.paramName);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Convert route path to regex pattern
|
|
116
|
-
*/
|
|
117
|
-
export function routePathToRegex(routePath) {
|
|
118
|
-
if (routePath === "/")
|
|
119
|
-
return /^\/$/;
|
|
120
|
-
const segmentsList = routePath.slice(1).split("/");
|
|
121
|
-
const regexParts = [];
|
|
122
|
-
for (let i = 0; i < segmentsList.length; i++) {
|
|
123
|
-
const segment = segmentsList[i];
|
|
124
|
-
if (!segment)
|
|
125
|
-
continue;
|
|
126
|
-
if (segment.startsWith("*") && segment.endsWith("?")) {
|
|
127
|
-
regexParts.push("(?:\\/(.*))?");
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (segment.startsWith("*")) {
|
|
131
|
-
regexParts.push("\\/(.+)");
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
if (segment.startsWith(":")) {
|
|
135
|
-
regexParts.push("\\/([^/]+)");
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
const escaped = segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
139
|
-
regexParts.push(`\\/${escaped}`);
|
|
140
|
-
}
|
|
141
|
-
return new RegExp(`^${regexParts.join("")}\\/?$`);
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Generate a route definition from a file path
|
|
145
|
-
*/
|
|
146
|
-
export function generateRouteDefinition(filePath, pagesDir) {
|
|
147
|
-
const routePath = filePathToRoutePath(filePath, pagesDir);
|
|
148
|
-
const segments = parseRouteSegments(routePath);
|
|
149
|
-
const paramNames = extractParamNames(segments);
|
|
150
|
-
const score = calculateRouteScore(segments);
|
|
151
|
-
// Note: RouteDefinition extends RouteRecord, which no longer has segments
|
|
152
|
-
return {
|
|
153
|
-
path: routePath,
|
|
154
|
-
paramNames,
|
|
155
|
-
score,
|
|
156
|
-
filePath,
|
|
157
|
-
regex: routePathToRegex(routePath)
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
export function generateRouteManifest(pagesDir) {
|
|
161
|
-
// Optional: use native generator if available, but for now we keep the TS one for build-time safety
|
|
162
|
-
const pages = discoverPages(pagesDir);
|
|
163
|
-
const definitions = pages.map(filePath => generateRouteDefinition(filePath, pagesDir));
|
|
164
|
-
definitions.sort((a, b) => b.score - a.score);
|
|
165
|
-
return definitions;
|
|
166
|
-
}
|
|
167
|
-
export function generateRouteManifestCode(definitions) {
|
|
168
|
-
const routeEntries = definitions.map(def => {
|
|
169
|
-
const regex = routePathToRegex(def.path);
|
|
170
|
-
return ` {
|
|
171
|
-
path: ${JSON.stringify(def.path)},
|
|
172
|
-
regex: ${regex.toString()},
|
|
173
|
-
paramNames: ${JSON.stringify(def.paramNames)},
|
|
174
|
-
score: ${def.score},
|
|
175
|
-
filePath: ${JSON.stringify(def.filePath)}
|
|
176
|
-
}`;
|
|
177
|
-
});
|
|
178
|
-
return `// Auto-generated route manifest\n// Do not edit directly\n\nexport const routeManifest = [\n${routeEntries.join(",\n")}\n];\n`;
|
|
179
|
-
}
|
|
180
|
-
//# sourceMappingURL=manifest.js.map
|
package/dist/manifest.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Navigation & Prefetch Runtime
|
|
3
|
-
*
|
|
4
|
-
* Phase 7: Prefetch compiled output, safe SPA navigation, route caching
|
|
5
|
-
*
|
|
6
|
-
* This runtime handles:
|
|
7
|
-
* - Prefetching compiled HTML + JS for routes
|
|
8
|
-
* - Caching prefetched routes
|
|
9
|
-
* - Safe DOM mounting and hydration
|
|
10
|
-
* - Browser history management
|
|
11
|
-
* - Explicit data exposure for navigation
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Route cache entry containing compiled output
|
|
15
|
-
*/
|
|
16
|
-
export interface RouteCacheEntry {
|
|
17
|
-
html: string;
|
|
18
|
-
js: string;
|
|
19
|
-
styles: string[];
|
|
20
|
-
routePath: string;
|
|
21
|
-
compiledAt: number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Navigation options with explicit data
|
|
25
|
-
*/
|
|
26
|
-
export interface NavigateOptions {
|
|
27
|
-
loaderData?: any;
|
|
28
|
-
props?: any;
|
|
29
|
-
stores?: any;
|
|
30
|
-
replace?: boolean;
|
|
31
|
-
prefetch?: boolean;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Prefetch a route's compiled output
|
|
35
|
-
*
|
|
36
|
-
* @param routePath - The route path to prefetch (e.g., "/dashboard")
|
|
37
|
-
* @returns Promise that resolves when prefetch is complete
|
|
38
|
-
*/
|
|
39
|
-
export declare function prefetchRoute(routePath: string): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Get cached route entry
|
|
42
|
-
*/
|
|
43
|
-
export declare function getCachedRoute(routePath: string): RouteCacheEntry | null;
|
|
44
|
-
/**
|
|
45
|
-
* Navigate to a route with explicit data
|
|
46
|
-
*
|
|
47
|
-
* @param routePath - The route path to navigate to
|
|
48
|
-
* @param options - Navigation options with loaderData, props, stores
|
|
49
|
-
*/
|
|
50
|
-
export declare function navigate(routePath: string, options?: NavigateOptions): Promise<void>;
|
|
51
|
-
/**
|
|
52
|
-
* Handle browser back/forward navigation
|
|
53
|
-
*/
|
|
54
|
-
export declare function setupHistoryHandling(): void;
|
|
55
|
-
/**
|
|
56
|
-
* Generate navigation runtime code (to be included in bundle)
|
|
57
|
-
*/
|
|
58
|
-
export declare function generateNavigationRuntime(): string;
|
|
59
|
-
//# sourceMappingURL=client-router.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-router.d.ts","sourceRoot":"","sources":["../../src/navigation/client-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,UAAU,CAAC,EAAE,GAAG,CAAA;IAChB,KAAK,CAAC,EAAE,GAAG,CAAA;IACX,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAaD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAGxE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,eAAoB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAgEf;AAoGD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAY3C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAgJlD"}
|