@rangojs/router 0.0.0-experimental.10

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.
Files changed (172) hide show
  1. package/CLAUDE.md +43 -0
  2. package/README.md +19 -0
  3. package/dist/bin/rango.js +227 -0
  4. package/dist/vite/index.js +3039 -0
  5. package/package.json +171 -0
  6. package/skills/caching/SKILL.md +191 -0
  7. package/skills/debug-manifest/SKILL.md +108 -0
  8. package/skills/document-cache/SKILL.md +180 -0
  9. package/skills/fonts/SKILL.md +165 -0
  10. package/skills/hooks/SKILL.md +442 -0
  11. package/skills/intercept/SKILL.md +190 -0
  12. package/skills/layout/SKILL.md +213 -0
  13. package/skills/links/SKILL.md +180 -0
  14. package/skills/loader/SKILL.md +246 -0
  15. package/skills/middleware/SKILL.md +202 -0
  16. package/skills/mime-routes/SKILL.md +124 -0
  17. package/skills/parallel/SKILL.md +228 -0
  18. package/skills/prerender/SKILL.md +283 -0
  19. package/skills/rango/SKILL.md +54 -0
  20. package/skills/response-routes/SKILL.md +358 -0
  21. package/skills/route/SKILL.md +173 -0
  22. package/skills/router-setup/SKILL.md +346 -0
  23. package/skills/tailwind/SKILL.md +129 -0
  24. package/skills/theme/SKILL.md +78 -0
  25. package/skills/typesafety/SKILL.md +394 -0
  26. package/src/__internal.ts +175 -0
  27. package/src/bin/rango.ts +24 -0
  28. package/src/browser/event-controller.ts +876 -0
  29. package/src/browser/index.ts +18 -0
  30. package/src/browser/link-interceptor.ts +121 -0
  31. package/src/browser/lru-cache.ts +69 -0
  32. package/src/browser/merge-segment-loaders.ts +126 -0
  33. package/src/browser/navigation-bridge.ts +913 -0
  34. package/src/browser/navigation-client.ts +165 -0
  35. package/src/browser/navigation-store.ts +823 -0
  36. package/src/browser/partial-update.ts +600 -0
  37. package/src/browser/react/Link.tsx +248 -0
  38. package/src/browser/react/NavigationProvider.tsx +346 -0
  39. package/src/browser/react/ScrollRestoration.tsx +94 -0
  40. package/src/browser/react/context.ts +53 -0
  41. package/src/browser/react/index.ts +52 -0
  42. package/src/browser/react/location-state-shared.ts +120 -0
  43. package/src/browser/react/location-state.ts +62 -0
  44. package/src/browser/react/mount-context.ts +32 -0
  45. package/src/browser/react/use-action.ts +240 -0
  46. package/src/browser/react/use-client-cache.ts +56 -0
  47. package/src/browser/react/use-handle.ts +203 -0
  48. package/src/browser/react/use-href.tsx +40 -0
  49. package/src/browser/react/use-link-status.ts +134 -0
  50. package/src/browser/react/use-mount.ts +31 -0
  51. package/src/browser/react/use-navigation.ts +140 -0
  52. package/src/browser/react/use-segments.ts +188 -0
  53. package/src/browser/request-controller.ts +164 -0
  54. package/src/browser/rsc-router.tsx +352 -0
  55. package/src/browser/scroll-restoration.ts +324 -0
  56. package/src/browser/segment-structure-assert.ts +67 -0
  57. package/src/browser/server-action-bridge.ts +762 -0
  58. package/src/browser/shallow.ts +35 -0
  59. package/src/browser/types.ts +478 -0
  60. package/src/build/generate-manifest.ts +377 -0
  61. package/src/build/generate-route-types.ts +828 -0
  62. package/src/build/index.ts +36 -0
  63. package/src/build/route-trie.ts +239 -0
  64. package/src/cache/cache-scope.ts +563 -0
  65. package/src/cache/cf/cf-cache-store.ts +428 -0
  66. package/src/cache/cf/index.ts +19 -0
  67. package/src/cache/document-cache.ts +340 -0
  68. package/src/cache/index.ts +58 -0
  69. package/src/cache/memory-segment-store.ts +150 -0
  70. package/src/cache/memory-store.ts +253 -0
  71. package/src/cache/types.ts +392 -0
  72. package/src/client.rsc.tsx +83 -0
  73. package/src/client.tsx +643 -0
  74. package/src/component-utils.ts +76 -0
  75. package/src/components/DefaultDocument.tsx +23 -0
  76. package/src/debug.ts +233 -0
  77. package/src/default-error-boundary.tsx +88 -0
  78. package/src/deps/browser.ts +8 -0
  79. package/src/deps/html-stream-client.ts +2 -0
  80. package/src/deps/html-stream-server.ts +2 -0
  81. package/src/deps/rsc.ts +10 -0
  82. package/src/deps/ssr.ts +2 -0
  83. package/src/errors.ts +295 -0
  84. package/src/handle.ts +130 -0
  85. package/src/handles/MetaTags.tsx +193 -0
  86. package/src/handles/index.ts +6 -0
  87. package/src/handles/meta.ts +247 -0
  88. package/src/host/cookie-handler.ts +159 -0
  89. package/src/host/errors.ts +97 -0
  90. package/src/host/index.ts +56 -0
  91. package/src/host/pattern-matcher.ts +214 -0
  92. package/src/host/router.ts +330 -0
  93. package/src/host/testing.ts +79 -0
  94. package/src/host/types.ts +138 -0
  95. package/src/host/utils.ts +25 -0
  96. package/src/href-client.ts +202 -0
  97. package/src/href-context.ts +33 -0
  98. package/src/index.rsc.ts +121 -0
  99. package/src/index.ts +165 -0
  100. package/src/loader.rsc.ts +207 -0
  101. package/src/loader.ts +47 -0
  102. package/src/network-error-thrower.tsx +21 -0
  103. package/src/outlet-context.ts +15 -0
  104. package/src/prerender/param-hash.ts +35 -0
  105. package/src/prerender/store.ts +40 -0
  106. package/src/prerender.ts +156 -0
  107. package/src/reverse.ts +267 -0
  108. package/src/root-error-boundary.tsx +277 -0
  109. package/src/route-content-wrapper.tsx +193 -0
  110. package/src/route-definition.ts +1431 -0
  111. package/src/route-map-builder.ts +242 -0
  112. package/src/route-types.ts +220 -0
  113. package/src/router/error-handling.ts +287 -0
  114. package/src/router/handler-context.ts +158 -0
  115. package/src/router/intercept-resolution.ts +387 -0
  116. package/src/router/loader-resolution.ts +327 -0
  117. package/src/router/manifest.ts +216 -0
  118. package/src/router/match-api.ts +621 -0
  119. package/src/router/match-context.ts +264 -0
  120. package/src/router/match-middleware/background-revalidation.ts +236 -0
  121. package/src/router/match-middleware/cache-lookup.ts +382 -0
  122. package/src/router/match-middleware/cache-store.ts +276 -0
  123. package/src/router/match-middleware/index.ts +81 -0
  124. package/src/router/match-middleware/intercept-resolution.ts +281 -0
  125. package/src/router/match-middleware/segment-resolution.ts +184 -0
  126. package/src/router/match-pipelines.ts +214 -0
  127. package/src/router/match-result.ts +213 -0
  128. package/src/router/metrics.ts +62 -0
  129. package/src/router/middleware.ts +791 -0
  130. package/src/router/pattern-matching.ts +407 -0
  131. package/src/router/revalidation.ts +190 -0
  132. package/src/router/router-context.ts +301 -0
  133. package/src/router/segment-resolution.ts +1315 -0
  134. package/src/router/trie-matching.ts +172 -0
  135. package/src/router/types.ts +163 -0
  136. package/src/router.gen.ts +6 -0
  137. package/src/router.ts +2423 -0
  138. package/src/rsc/handler.ts +1443 -0
  139. package/src/rsc/helpers.ts +64 -0
  140. package/src/rsc/index.ts +56 -0
  141. package/src/rsc/nonce.ts +18 -0
  142. package/src/rsc/types.ts +236 -0
  143. package/src/segment-system.tsx +442 -0
  144. package/src/server/context.ts +466 -0
  145. package/src/server/handle-store.ts +229 -0
  146. package/src/server/loader-registry.ts +174 -0
  147. package/src/server/request-context.ts +554 -0
  148. package/src/server/root-layout.tsx +10 -0
  149. package/src/server/tsconfig.json +14 -0
  150. package/src/server.ts +171 -0
  151. package/src/ssr/index.tsx +296 -0
  152. package/src/theme/ThemeProvider.tsx +291 -0
  153. package/src/theme/ThemeScript.tsx +61 -0
  154. package/src/theme/constants.ts +59 -0
  155. package/src/theme/index.ts +58 -0
  156. package/src/theme/theme-context.ts +70 -0
  157. package/src/theme/theme-script.ts +152 -0
  158. package/src/theme/types.ts +182 -0
  159. package/src/theme/use-theme.ts +44 -0
  160. package/src/types.ts +1757 -0
  161. package/src/urls.gen.ts +8 -0
  162. package/src/urls.ts +1282 -0
  163. package/src/use-loader.tsx +346 -0
  164. package/src/vite/expose-action-id.ts +344 -0
  165. package/src/vite/expose-handle-id.ts +209 -0
  166. package/src/vite/expose-loader-id.ts +426 -0
  167. package/src/vite/expose-location-state-id.ts +177 -0
  168. package/src/vite/expose-prerender-handler-id.ts +429 -0
  169. package/src/vite/index.ts +2068 -0
  170. package/src/vite/package-resolution.ts +125 -0
  171. package/src/vite/version.d.ts +12 -0
  172. package/src/vite/virtual-entries.ts +114 -0
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Build-time manifest generation for @rangojs/router
3
+ *
4
+ * Extracts the prefix tree and route manifest from UrlPatterns at build time.
5
+ * This enables:
6
+ * - Pre-computed prefix tree for fast short-circuit checks
7
+ * - Complete route manifest for href() without runtime evaluation
8
+ * - Support for nested includes
9
+ */
10
+
11
+ import type { UrlPatterns } from "../urls.js";
12
+ import type { AllUseItems } from "../route-types.js";
13
+ import { extractStaticPrefix } from "../router/pattern-matching.js";
14
+ import { RSCRouterContext, runWithPrefixes } from "../server/context.js";
15
+ import type { EntryData, TrackedInclude } from "../server/context.js";
16
+ import type { TrailingSlashMode } from "../types.js";
17
+ import { createRouteHelpers } from "../route-definition.js";
18
+ import MapRootLayout from "../server/root-layout.js";
19
+
20
+ /**
21
+ * Node in the prefix tree
22
+ */
23
+ export interface PrefixTreeNode {
24
+ /** The static prefix for this node */
25
+ staticPrefix: string;
26
+ /** The full URL prefix (including parent prefixes) */
27
+ fullPrefix: string;
28
+ /** Name prefix for routes in this include */
29
+ namePrefix?: string;
30
+ /** Child nodes (nested includes) */
31
+ children: Record<string, PrefixTreeNode>;
32
+ /** Route names defined directly in this include (not in children) */
33
+ routes: string[];
34
+ }
35
+
36
+ /**
37
+ * Generated manifest containing prefix tree and route mappings
38
+ */
39
+ export interface GeneratedManifest {
40
+ /** Nested prefix tree for short-circuit optimization */
41
+ prefixTree: Record<string, PrefixTreeNode>;
42
+ /** Complete route name → pattern mapping for href() */
43
+ routeManifest: Record<string, string>;
44
+ /** Route name → trailing slash mode for trie redirect handling */
45
+ routeTrailingSlash?: Record<string, string>;
46
+ /** Route names using createPrerenderHandler (for dev-mode Node.js delegation) */
47
+ prerenderRoutes?: string[];
48
+ /** Route names with passthrough: true (handler kept in bundle for live fallback) */
49
+ passthroughRoutes?: string[];
50
+ /** Route name → response type for non-RSC routes */
51
+ responseTypeRoutes?: Record<string, string>;
52
+ /** Generation timestamp */
53
+ generatedAt: string;
54
+ }
55
+
56
+ /**
57
+ * Build prefix tree node by running the patterns with proper context.
58
+ * Uses a visited set to detect circular includes and prevent infinite recursion.
59
+ */
60
+ function buildPrefixTreeNode(
61
+ urlPrefix: string,
62
+ namePrefix: string | undefined,
63
+ patterns: UrlPatterns<any>,
64
+ routeManifest: Record<string, string>,
65
+ routeAncestry: Record<string, string[]>, // internal: feeds trie building, not exported
66
+ mountIndex: number,
67
+ visited: Set<unknown> = new Set(),
68
+ routeTrailingSlash?: Record<string, string>,
69
+ prerenderRoutes?: string[],
70
+ prerenderDefs?: Record<string, any>,
71
+ passthroughRoutes?: string[],
72
+ responseTypeRoutes?: Record<string, string>,
73
+ ): PrefixTreeNode {
74
+ if (visited.has(patterns)) {
75
+ console.warn(
76
+ `[@rangojs/router] Circular include detected at prefix "${urlPrefix}". Skipping.`
77
+ );
78
+ return {
79
+ staticPrefix: extractStaticPrefix(urlPrefix),
80
+ fullPrefix: urlPrefix,
81
+ namePrefix: namePrefix || undefined,
82
+ children: {},
83
+ routes: [],
84
+ };
85
+ }
86
+ visited.add(patterns);
87
+ // Create context for running patterns with include tracking
88
+ const manifest = new Map<string, EntryData>();
89
+ const patternsMap = new Map<string, string>();
90
+ const patternsByPrefix = new Map<string, Map<string, string>>();
91
+ const trailingSlashMap = new Map<string, TrailingSlashMode>();
92
+ const trackedIncludes: TrackedInclude[] = [];
93
+
94
+ RSCRouterContext.run(
95
+ {
96
+ manifest,
97
+ patterns: patternsMap,
98
+ patternsByPrefix,
99
+ trailingSlash: trailingSlashMap,
100
+ namespace: "build",
101
+ parent: null,
102
+ counters: {},
103
+ mountIndex,
104
+ trackedIncludes, // Enable nested include tracking
105
+ },
106
+ () => {
107
+ const helpers = createRouteHelpers();
108
+ // Wrap in root layout for correct parent hierarchy (matches runtime)
109
+ helpers.layout(MapRootLayout, () => {
110
+ if (urlPrefix || namePrefix) {
111
+ return runWithPrefixes(urlPrefix, namePrefix, () => {
112
+ return patterns.handler() as AllUseItems[];
113
+ });
114
+ }
115
+ return patterns.handler() as AllUseItems[];
116
+ });
117
+ }
118
+ );
119
+
120
+ // Collect route names defined in this include (routes have prefixes applied)
121
+ const routes: string[] = [];
122
+ for (const [name, pattern] of patternsMap.entries()) {
123
+ routes.push(name);
124
+ routeManifest[name] = pattern;
125
+ }
126
+
127
+ // Collect trailing slash config
128
+ if (routeTrailingSlash) {
129
+ for (const [name, mode] of trailingSlashMap.entries()) {
130
+ routeTrailingSlash[name] = mode;
131
+ }
132
+ }
133
+
134
+ // Capture ancestry from manifest entries' parent chains
135
+ captureAncestry(manifest, routeAncestry);
136
+
137
+ // Collect prerender route names and handler definitions from manifest entries
138
+ if (prerenderRoutes) {
139
+ for (const [name, entry] of manifest) {
140
+ if (entry.type === "route" && entry.isPrerender) {
141
+ prerenderRoutes.push(name);
142
+ if (prerenderDefs && entry.prerenderDef) {
143
+ prerenderDefs[name] = entry.prerenderDef;
144
+ }
145
+ if (passthroughRoutes && entry.prerenderDef?.options?.passthrough === true) {
146
+ passthroughRoutes.push(name);
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ // Collect response type routes from manifest entries
153
+ if (responseTypeRoutes) {
154
+ for (const [name, entry] of manifest) {
155
+ if (entry.type === "route" && entry.responseType) {
156
+ responseTypeRoutes[name] = entry.responseType;
157
+ }
158
+ }
159
+ }
160
+
161
+ // Build children from tracked nested includes.
162
+ // Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
163
+ // include("/", patternsB)). Merge their routes instead of overwriting.
164
+ const children: Record<string, PrefixTreeNode> = {};
165
+
166
+ for (const include of trackedIncludes) {
167
+ const childNode = buildPrefixTreeNode(
168
+ include.fullPrefix,
169
+ include.namePrefix,
170
+ include.patterns as UrlPatterns<any>,
171
+ routeManifest,
172
+ routeAncestry,
173
+ mountIndex,
174
+ visited,
175
+ routeTrailingSlash,
176
+ prerenderRoutes,
177
+ prerenderDefs,
178
+ passthroughRoutes,
179
+ responseTypeRoutes,
180
+ );
181
+
182
+ const existing = children[include.fullPrefix];
183
+ if (existing) {
184
+ existing.routes.push(...childNode.routes);
185
+ Object.assign(existing.children, childNode.children);
186
+ } else {
187
+ children[include.fullPrefix] = childNode;
188
+ }
189
+ }
190
+
191
+ return {
192
+ staticPrefix: extractStaticPrefix(urlPrefix),
193
+ fullPrefix: urlPrefix,
194
+ namePrefix: namePrefix || undefined,
195
+ children,
196
+ routes,
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Walk parent chains of route entries to extract ancestry shortCodes.
202
+ */
203
+ function captureAncestry(
204
+ manifest: Map<string, EntryData>,
205
+ routeAncestry: Record<string, string[]>,
206
+ ): void {
207
+ for (const [routeName, entry] of manifest) {
208
+ if (entry.type === "route") {
209
+ const ancestry: string[] = [];
210
+ let current: EntryData | null = entry;
211
+ while (current) {
212
+ ancestry.unshift(current.shortCode);
213
+ current = current.parent;
214
+ }
215
+ routeAncestry[routeName] = ancestry;
216
+ }
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Generate manifest from UrlPatterns
222
+ *
223
+ * This runs all patterns (including lazy ones) at build time to extract:
224
+ * - The complete prefix tree for short-circuit optimization
225
+ * - The complete route manifest for href()
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * import { generateManifest } from "@rangojs/router/build";
230
+ * import { urlpatterns } from "./urls";
231
+ *
232
+ * const manifest = generateManifest(urlpatterns);
233
+ * // Write to file for runtime use
234
+ * fs.writeFileSync(
235
+ * "src/generated/route-manifest.json",
236
+ * JSON.stringify(manifest, null, 2)
237
+ * );
238
+ * ```
239
+ */
240
+ export function generateManifest<TEnv>(
241
+ urlpatterns: UrlPatterns<TEnv, any>,
242
+ mountIndex: number = 0,
243
+ ): GeneratedManifest & { _routeAncestry: Record<string, string[]>; _prerenderDefs?: Record<string, any> } {
244
+ const routeManifest: Record<string, string> = {};
245
+ const routeAncestry: Record<string, string[]> = {};
246
+ const prefixTree: Record<string, PrefixTreeNode> = {};
247
+
248
+ // Run the root patterns handler with tracking enabled
249
+ const manifest = new Map<string, EntryData>();
250
+ const patternsMap = new Map<string, string>();
251
+ const patternsByPrefix = new Map<string, Map<string, string>>();
252
+ const trailingSlashMap = new Map<string, TrailingSlashMode>();
253
+ const trackedIncludes: TrackedInclude[] = [];
254
+
255
+ RSCRouterContext.run(
256
+ {
257
+ manifest,
258
+ patterns: patternsMap,
259
+ patternsByPrefix,
260
+ trailingSlash: trailingSlashMap,
261
+ namespace: "build",
262
+ parent: null,
263
+ counters: {},
264
+ mountIndex,
265
+ trackedIncludes, // Enable include tracking
266
+ },
267
+ () => {
268
+ const helpers = createRouteHelpers();
269
+ // Wrap in root layout for correct parent hierarchy (matches runtime)
270
+ helpers.layout(MapRootLayout, () => {
271
+ return urlpatterns.handler() as AllUseItems[];
272
+ });
273
+ }
274
+ );
275
+
276
+ // Collect root-level routes and trailing slash config
277
+ const routeTrailingSlash: Record<string, string> = {};
278
+ for (const [name, pattern] of patternsMap.entries()) {
279
+ routeManifest[name] = pattern;
280
+ }
281
+ for (const [name, mode] of trailingSlashMap.entries()) {
282
+ routeTrailingSlash[name] = mode;
283
+ }
284
+
285
+ // Capture ancestry from manifest entries' parent chains
286
+ captureAncestry(manifest, routeAncestry);
287
+
288
+ // Collect prerender route names and handler definitions across all levels
289
+ const prerenderRoutes: string[] = [];
290
+ const prerenderDefs: Record<string, any> = {};
291
+ const passthroughRoutes: string[] = [];
292
+ const responseTypeRoutes: Record<string, string> = {};
293
+ for (const [name, entry] of manifest) {
294
+ if (entry.type === "route" && entry.isPrerender) {
295
+ prerenderRoutes.push(name);
296
+ if (entry.prerenderDef) {
297
+ prerenderDefs[name] = entry.prerenderDef;
298
+ }
299
+ if (entry.prerenderDef?.options?.passthrough === true) {
300
+ passthroughRoutes.push(name);
301
+ }
302
+ }
303
+ if (entry.type === "route" && entry.responseType) {
304
+ responseTypeRoutes[name] = entry.responseType;
305
+ }
306
+ }
307
+
308
+ // Build prefix tree from tracked includes (shared visited set for cycle detection).
309
+ // Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
310
+ // include("/", patternsB)). Merge their routes instead of overwriting.
311
+ const visited = new Set<unknown>();
312
+ for (const include of trackedIncludes) {
313
+ const node = buildPrefixTreeNode(
314
+ include.fullPrefix,
315
+ include.namePrefix,
316
+ include.patterns as UrlPatterns<any>,
317
+ routeManifest,
318
+ routeAncestry,
319
+ mountIndex,
320
+ visited,
321
+ routeTrailingSlash,
322
+ prerenderRoutes,
323
+ prerenderDefs,
324
+ passthroughRoutes,
325
+ responseTypeRoutes,
326
+ );
327
+
328
+ const existing = prefixTree[include.fullPrefix];
329
+ if (existing) {
330
+ existing.routes.push(...node.routes);
331
+ Object.assign(existing.children, node.children);
332
+ } else {
333
+ prefixTree[include.fullPrefix] = node;
334
+ }
335
+ }
336
+
337
+ return {
338
+ prefixTree,
339
+ routeManifest,
340
+ routeTrailingSlash: Object.keys(routeTrailingSlash).length > 0 ? routeTrailingSlash : undefined,
341
+ prerenderRoutes: prerenderRoutes.length > 0 ? prerenderRoutes : undefined,
342
+ passthroughRoutes: passthroughRoutes.length > 0 ? passthroughRoutes : undefined,
343
+ responseTypeRoutes: Object.keys(responseTypeRoutes).length > 0 ? responseTypeRoutes : undefined,
344
+ generatedAt: new Date().toISOString(),
345
+ // Internal: routeAncestry is used only for trie building, not exported
346
+ _routeAncestry: routeAncestry,
347
+ // Internal: prerender handler definitions for build-time getParams() access
348
+ _prerenderDefs: Object.keys(prerenderDefs).length > 0 ? prerenderDefs : undefined,
349
+ };
350
+ }
351
+
352
+ /**
353
+ * Generate TypeScript code for the manifest
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * const code = generateManifestCode(urlpatterns);
358
+ * fs.writeFileSync("src/generated/route-manifest.ts", code);
359
+ * ```
360
+ */
361
+ export function generateManifestCode<TEnv>(
362
+ urlpatterns: UrlPatterns<TEnv, any>
363
+ ): string {
364
+ const manifest = generateManifest(urlpatterns);
365
+
366
+ return `/**
367
+ * Auto-generated route manifest
368
+ * Generated at: ${manifest.generatedAt}
369
+ *
370
+ * DO NOT EDIT - This file is generated by @rangojs/router
371
+ */
372
+
373
+ export const routeManifest = ${JSON.stringify(manifest.routeManifest, null, 2)} as const;
374
+
375
+ export type RouteNames = keyof typeof routeManifest;
376
+ `;
377
+ }