@evjs/manifest 0.0.21 → 0.0.23
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/esm/index.d.ts +52 -0
- package/esm/index.js +124 -1
- package/package.json +1 -1
package/esm/index.d.ts
CHANGED
|
@@ -65,3 +65,55 @@ export interface ClientManifest {
|
|
|
65
65
|
/** Discovered client routes. */
|
|
66
66
|
routes?: RouteEntry[];
|
|
67
67
|
}
|
|
68
|
+
/** Route metadata extracted from a createRoute() call. */
|
|
69
|
+
export interface ExtractedRoute {
|
|
70
|
+
/** Route path (e.g. "/", "/posts/$postId"). */
|
|
71
|
+
path: string;
|
|
72
|
+
/** Variable name of the parent route (e.g. "rootRoute", "postsRoute"). */
|
|
73
|
+
parentName?: string;
|
|
74
|
+
/** Variable name this route is assigned to (e.g. "homeRoute"). */
|
|
75
|
+
varName?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolve a flat list of extracted routes into de-duplicated full paths.
|
|
79
|
+
*
|
|
80
|
+
* Builds the parent-child hierarchy using `varName` / `parentName` and
|
|
81
|
+
* walks the tree to construct full URL paths.
|
|
82
|
+
*
|
|
83
|
+
* Index routes (child `path: "/"` under a non-root parent) are excluded
|
|
84
|
+
* since they resolve to the same URL as their parent route.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* resolveRoutes([
|
|
89
|
+
* { path: "/posts", varName: "postsRoute", parentName: "rootRoute" },
|
|
90
|
+
* { path: "/", varName: "postsIndexRoute", parentName: "postsRoute" },
|
|
91
|
+
* { path: "$postId", varName: "postDetailRoute", parentName: "postsRoute" },
|
|
92
|
+
* ])
|
|
93
|
+
* // => [{ path: "/posts" }, { path: "/posts/$postId" }]
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function resolveRoutes(routes: ExtractedRoute[]): Array<{
|
|
97
|
+
path: string;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Collects server function registrations, route metadata, and client assets
|
|
101
|
+
* throughout the compilation lifecycle, then produces the final manifests.
|
|
102
|
+
*
|
|
103
|
+
* This class is bundler-agnostic — it is used by bundler adapters
|
|
104
|
+
* (e.g. `@evjs/bundler-webpack`) to accumulate build metadata.
|
|
105
|
+
*/
|
|
106
|
+
export declare class ManifestCollector {
|
|
107
|
+
fns: Record<string, ServerFnEntry>;
|
|
108
|
+
routes: ExtractedRoute[];
|
|
109
|
+
entry: string | undefined;
|
|
110
|
+
private jsAssets;
|
|
111
|
+
private cssAssets;
|
|
112
|
+
addServerFn(id: string, meta: ServerFnEntry): void;
|
|
113
|
+
addRoutes(entries: ExtractedRoute[]): void;
|
|
114
|
+
setAssets(js: string[], css: string[]): void;
|
|
115
|
+
getJsAssets(): string[];
|
|
116
|
+
getCssAssets(): string[];
|
|
117
|
+
getServerManifest(): ServerManifest;
|
|
118
|
+
getClientManifest(assetPrefix?: string): ClientManifest;
|
|
119
|
+
}
|
package/esm/index.js
CHANGED
|
@@ -10,4 +10,127 @@
|
|
|
10
10
|
* For CSR-only builds (`server: false`), only the client manifest
|
|
11
11
|
* is emitted to `dist/manifest.json` (flat output).
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a flat list of extracted routes into de-duplicated full paths.
|
|
15
|
+
*
|
|
16
|
+
* Builds the parent-child hierarchy using `varName` / `parentName` and
|
|
17
|
+
* walks the tree to construct full URL paths.
|
|
18
|
+
*
|
|
19
|
+
* Index routes (child `path: "/"` under a non-root parent) are excluded
|
|
20
|
+
* since they resolve to the same URL as their parent route.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* resolveRoutes([
|
|
25
|
+
* { path: "/posts", varName: "postsRoute", parentName: "rootRoute" },
|
|
26
|
+
* { path: "/", varName: "postsIndexRoute", parentName: "postsRoute" },
|
|
27
|
+
* { path: "$postId", varName: "postDetailRoute", parentName: "postsRoute" },
|
|
28
|
+
* ])
|
|
29
|
+
* // => [{ path: "/posts" }, { path: "/posts/$postId" }]
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function resolveRoutes(routes) {
|
|
33
|
+
// Build a lookup: varName → ExtractedRoute
|
|
34
|
+
const byName = new Map();
|
|
35
|
+
for (const r of routes) {
|
|
36
|
+
if (r.varName) {
|
|
37
|
+
byName.set(r.varName, r);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Walk up the parent chain to build the full path prefix for a route.
|
|
42
|
+
* Returns the full resolved path of the given route variable.
|
|
43
|
+
*/
|
|
44
|
+
function resolveParentPath(route, visited = new Set()) {
|
|
45
|
+
if (!route.parentName)
|
|
46
|
+
return route.path;
|
|
47
|
+
// Guard against circular parent references
|
|
48
|
+
if (route.varName) {
|
|
49
|
+
if (visited.has(route.varName))
|
|
50
|
+
return route.path;
|
|
51
|
+
visited.add(route.varName);
|
|
52
|
+
}
|
|
53
|
+
const parent = byName.get(route.parentName);
|
|
54
|
+
if (!parent) {
|
|
55
|
+
// Parent not in the extracted set (e.g. rootRoute from createRootRoute)
|
|
56
|
+
// — treat as top-level, no prefix.
|
|
57
|
+
return route.path;
|
|
58
|
+
}
|
|
59
|
+
const parentPath = resolveParentPath(parent, visited);
|
|
60
|
+
return joinPaths(parentPath, route.path);
|
|
61
|
+
}
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
const result = [];
|
|
64
|
+
for (const r of routes) {
|
|
65
|
+
const fullPath = resolveParentPath(r);
|
|
66
|
+
// Skip index routes that resolve to the same path as their parent.
|
|
67
|
+
// An index route has path "/" and a parent that is not the root.
|
|
68
|
+
if (r.path === "/" && r.parentName) {
|
|
69
|
+
const parent = byName.get(r.parentName);
|
|
70
|
+
if (parent) {
|
|
71
|
+
// This is a non-root index route — it duplicates the parent path.
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!seen.has(fullPath)) {
|
|
76
|
+
seen.add(fullPath);
|
|
77
|
+
result.push({ path: fullPath });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/** Join two path segments, normalizing double slashes. */
|
|
83
|
+
function joinPaths(parent, child) {
|
|
84
|
+
if (child === "/")
|
|
85
|
+
return parent;
|
|
86
|
+
if (child.startsWith("/"))
|
|
87
|
+
return child;
|
|
88
|
+
const base = parent.endsWith("/") ? parent : `${parent}/`;
|
|
89
|
+
return base + child;
|
|
90
|
+
}
|
|
91
|
+
// ── ManifestCollector ───────────────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Collects server function registrations, route metadata, and client assets
|
|
94
|
+
* throughout the compilation lifecycle, then produces the final manifests.
|
|
95
|
+
*
|
|
96
|
+
* This class is bundler-agnostic — it is used by bundler adapters
|
|
97
|
+
* (e.g. `@evjs/bundler-webpack`) to accumulate build metadata.
|
|
98
|
+
*/
|
|
99
|
+
export class ManifestCollector {
|
|
100
|
+
fns = {};
|
|
101
|
+
routes = [];
|
|
102
|
+
entry = undefined;
|
|
103
|
+
jsAssets = [];
|
|
104
|
+
cssAssets = [];
|
|
105
|
+
addServerFn(id, meta) {
|
|
106
|
+
this.fns[id] = meta;
|
|
107
|
+
}
|
|
108
|
+
addRoutes(entries) {
|
|
109
|
+
this.routes.push(...entries);
|
|
110
|
+
}
|
|
111
|
+
setAssets(js, css) {
|
|
112
|
+
this.jsAssets = js;
|
|
113
|
+
this.cssAssets = css;
|
|
114
|
+
}
|
|
115
|
+
getJsAssets() {
|
|
116
|
+
return this.jsAssets;
|
|
117
|
+
}
|
|
118
|
+
getCssAssets() {
|
|
119
|
+
return this.cssAssets;
|
|
120
|
+
}
|
|
121
|
+
getServerManifest() {
|
|
122
|
+
return {
|
|
123
|
+
version: 1,
|
|
124
|
+
entry: this.entry,
|
|
125
|
+
fns: this.fns,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
getClientManifest(assetPrefix) {
|
|
129
|
+
return {
|
|
130
|
+
version: 1,
|
|
131
|
+
assetPrefix: assetPrefix && assetPrefix !== "/" ? assetPrefix : undefined,
|
|
132
|
+
assets: { js: this.jsAssets, css: this.cssAssets },
|
|
133
|
+
routes: resolveRoutes(this.routes),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|