@rangojs/router 0.0.0-experimental.7 → 0.0.0-experimental.8a4d0430
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/AGENTS.md +5 -0
- package/README.md +884 -4
- package/dist/bin/rango.js +1601 -0
- package/dist/vite/index.js +4474 -863
- package/package.json +60 -51
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +262 -0
- package/skills/caching/SKILL.md +50 -21
- package/skills/composability/SKILL.md +172 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +18 -16
- package/skills/fonts/SKILL.md +167 -0
- package/skills/hooks/SKILL.md +334 -72
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +131 -8
- package/skills/layout/SKILL.md +100 -3
- package/skills/links/SKILL.md +89 -30
- package/skills/loader/SKILL.md +388 -38
- package/skills/middleware/SKILL.md +171 -34
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +78 -1
- package/skills/prerender/SKILL.md +643 -0
- package/skills/rango/SKILL.md +85 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +226 -14
- package/skills/router-setup/SKILL.md +123 -30
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +318 -89
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +321 -0
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/event-controller.ts +87 -64
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +285 -553
- package/src/browser/navigation-client.ts +124 -71
- package/src/browser/navigation-store.ts +33 -50
- package/src/browser/navigation-transaction.ts +295 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +258 -308
- package/src/browser/prefetch/cache.ts +146 -0
- package/src/browser/prefetch/fetch.ts +135 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +42 -0
- package/src/browser/prefetch/queue.ts +88 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +185 -73
- package/src/browser/react/NavigationProvider.tsx +51 -11
- package/src/browser/react/context.ts +6 -0
- package/src/browser/react/filter-segment-order.ts +11 -0
- package/src/browser/react/index.ts +12 -12
- package/src/browser/react/location-state-shared.ts +95 -53
- package/src/browser/react/location-state.ts +60 -15
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +32 -79
- package/src/browser/react/use-href.tsx +2 -2
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +22 -63
- package/src/browser/react/use-params.ts +65 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-router.ts +63 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +80 -97
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +107 -26
- package/src/browser/scroll-restoration.ts +92 -16
- package/src/browser/segment-reconciler.ts +216 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +504 -599
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +109 -47
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +235 -24
- package/src/build/generate-route-types.ts +36 -0
- package/src/build/index.ts +13 -0
- package/src/build/route-trie.ts +265 -0
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +411 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +128 -0
- package/src/build/route-types/router-processing.ts +469 -0
- package/src/build/route-types/scan-filter.ts +78 -0
- package/src/build/runtime-discovery.ts +231 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +338 -0
- package/src/cache/cache-scope.ts +120 -303
- package/src/cache/cf/cf-cache-store.ts +119 -7
- package/src/cache/cf/index.ts +8 -2
- package/src/cache/document-cache.ts +101 -72
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +0 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +98 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +106 -126
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +86 -0
- package/src/debug.ts +17 -7
- package/src/errors.ts +108 -2
- package/src/handle.ts +15 -29
- package/src/handles/MetaTags.tsx +73 -20
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +30 -13
- package/src/host/cookie-handler.ts +21 -15
- package/src/host/errors.ts +8 -8
- package/src/host/index.ts +4 -7
- package/src/host/pattern-matcher.ts +27 -27
- package/src/host/router.ts +61 -39
- package/src/host/testing.ts +8 -8
- package/src/host/types.ts +15 -7
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +119 -29
- package/src/index.rsc.ts +153 -19
- package/src/index.ts +211 -30
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +26 -157
- package/src/loader.ts +27 -10
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +37 -0
- package/src/prerender/store.ts +185 -0
- package/src/prerender.ts +463 -0
- package/src/reverse.ts +330 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +934 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +430 -0
- package/src/route-definition/index.ts +52 -0
- package/src/route-definition/redirect.ts +93 -0
- package/src/route-definition.ts +1 -1428
- package/src/route-map-builder.ts +211 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +59 -8
- package/src/router/content-negotiation.ts +116 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +9 -9
- package/src/router/find-match.ts +158 -0
- package/src/router/handler-context.ts +374 -81
- package/src/router/intercept-resolution.ts +395 -0
- package/src/router/lazy-includes.ts +234 -0
- package/src/router/loader-resolution.ts +215 -122
- package/src/router/logging.ts +248 -0
- package/src/router/manifest.ts +148 -35
- package/src/router/match-api.ts +620 -0
- package/src/router/match-context.ts +5 -3
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +80 -93
- package/src/router/match-middleware/cache-lookup.ts +382 -9
- package/src/router/match-middleware/cache-store.ts +51 -22
- package/src/router/match-middleware/intercept-resolution.ts +55 -17
- package/src/router/match-middleware/segment-resolution.ts +24 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +34 -28
- package/src/router/metrics.ts +235 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +222 -0
- package/src/router/middleware.ts +324 -367
- package/src/router/pattern-matching.ts +211 -43
- package/src/router/prerender-match.ts +402 -0
- package/src/router/preview-match.ts +170 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/router-context.ts +36 -21
- package/src/router/router-interfaces.ts +452 -0
- package/src/router/router-options.ts +592 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +570 -0
- package/src/router/segment-resolution/helpers.ts +263 -0
- package/src/router/segment-resolution/loader-cache.ts +198 -0
- package/src/router/segment-resolution/revalidation.ts +1241 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -0
- package/src/router/segment-wrappers.ts +289 -0
- package/src/router/telemetry-otel.ts +299 -0
- package/src/router/telemetry.ts +300 -0
- package/src/router/timeout.ts +148 -0
- package/src/router/trie-matching.ts +239 -0
- package/src/router/types.ts +77 -3
- package/src/router.ts +692 -4257
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +764 -754
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +209 -0
- package/src/rsc/manifest-init.ts +86 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +379 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +235 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +348 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +38 -11
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +25 -13
- package/src/server/context.ts +182 -51
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +94 -15
- package/src/server/loader-registry.ts +15 -56
- package/src/server/request-context.ts +430 -70
- package/src/server.ts +35 -130
- package/src/ssr/index.tsx +100 -31
- package/src/static-handler.ts +114 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +5 -2
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +4 -30
- package/src/theme/theme-script.ts +21 -18
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +100 -0
- package/src/types/handler-context.ts +687 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +183 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +102 -0
- package/src/types/segments.ts +148 -0
- package/src/types.ts +1 -1623
- package/src/urls/include-helper.ts +197 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +339 -0
- package/src/urls/path-helper.ts +329 -0
- package/src/urls/pattern-types.ts +95 -0
- package/src/urls/response-types.ts +106 -0
- package/src/urls/type-extraction.ts +372 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -802
- package/src/use-loader.tsx +85 -77
- package/src/vite/discovery/bundle-postprocess.ts +184 -0
- package/src/vite/discovery/discover-routers.ts +344 -0
- package/src/vite/discovery/prerender-collection.ts +385 -0
- package/src/vite/discovery/route-types-writer.ts +258 -0
- package/src/vite/discovery/self-gen-tracking.ts +47 -0
- package/src/vite/discovery/state.ts +110 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +11 -1129
- package/src/vite/plugin-types.ts +131 -0
- package/src/vite/plugins/cjs-to-esm.ts +93 -0
- package/src/vite/plugins/client-ref-dedup.ts +115 -0
- package/src/vite/plugins/client-ref-hashing.ts +105 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -51
- package/src/vite/plugins/expose-id-utils.ts +287 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +569 -0
- package/src/vite/plugins/refresh-cmd.ts +65 -0
- package/src/vite/plugins/use-cache-transform.ts +323 -0
- package/src/vite/plugins/version-injector.ts +83 -0
- package/src/vite/plugins/version-plugin.ts +254 -0
- package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +23 -14
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +510 -0
- package/src/vite/router-discovery.ts +785 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +137 -0
- package/src/vite/utils/manifest-utils.ts +70 -0
- package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
- package/src/vite/utils/prerender-utils.ts +189 -0
- package/src/vite/utils/shared-utils.ts +169 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/href-context.ts +0 -33
- package/src/href.ts +0 -255
- package/src/server/route-manifest-cache.ts +0 -173
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -426
- package/src/vite/expose-location-state-id.ts +0 -177
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -14,6 +14,8 @@ import { extractStaticPrefix } from "../router/pattern-matching.js";
|
|
|
14
14
|
import { RSCRouterContext, runWithPrefixes } from "../server/context.js";
|
|
15
15
|
import type { EntryData, TrackedInclude } from "../server/context.js";
|
|
16
16
|
import type { TrailingSlashMode } from "../types.js";
|
|
17
|
+
import { createRouteHelpers } from "../route-definition.js";
|
|
18
|
+
import MapRootLayout from "../server/root-layout.js";
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Node in the prefix tree
|
|
@@ -39,8 +41,16 @@ export interface GeneratedManifest {
|
|
|
39
41
|
prefixTree: Record<string, PrefixTreeNode>;
|
|
40
42
|
/** Complete route name → pattern mapping for href() */
|
|
41
43
|
routeManifest: Record<string, string>;
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
+
/** Route name → trailing slash mode for trie redirect handling */
|
|
45
|
+
routeTrailingSlash?: Record<string, string>;
|
|
46
|
+
/** Route names using Prerender (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
|
+
/** Route name -> search schema descriptor for typed URL helpers */
|
|
53
|
+
routeSearchSchemas?: Record<string, Record<string, string>>;
|
|
44
54
|
}
|
|
45
55
|
|
|
46
56
|
/**
|
|
@@ -52,11 +62,19 @@ function buildPrefixTreeNode(
|
|
|
52
62
|
namePrefix: string | undefined,
|
|
53
63
|
patterns: UrlPatterns<any>,
|
|
54
64
|
routeManifest: Record<string, string>,
|
|
55
|
-
|
|
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
|
+
routeSearchSchemas?: Record<string, Record<string, string>>,
|
|
56
74
|
): PrefixTreeNode {
|
|
57
75
|
if (visited.has(patterns)) {
|
|
58
76
|
console.warn(
|
|
59
|
-
`[@rangojs/router] Circular include detected at prefix "${urlPrefix}". Skipping
|
|
77
|
+
`[@rangojs/router] Circular include detected at prefix "${urlPrefix}". Skipping.`,
|
|
60
78
|
);
|
|
61
79
|
return {
|
|
62
80
|
staticPrefix: extractStaticPrefix(urlPrefix),
|
|
@@ -72,6 +90,7 @@ function buildPrefixTreeNode(
|
|
|
72
90
|
const patternsMap = new Map<string, string>();
|
|
73
91
|
const patternsByPrefix = new Map<string, Map<string, string>>();
|
|
74
92
|
const trailingSlashMap = new Map<string, TrailingSlashMode>();
|
|
93
|
+
const searchSchemasMap = new Map<string, Record<string, string>>();
|
|
75
94
|
const trackedIncludes: TrackedInclude[] = [];
|
|
76
95
|
|
|
77
96
|
RSCRouterContext.run(
|
|
@@ -80,17 +99,25 @@ function buildPrefixTreeNode(
|
|
|
80
99
|
patterns: patternsMap,
|
|
81
100
|
patternsByPrefix,
|
|
82
101
|
trailingSlash: trailingSlashMap,
|
|
102
|
+
searchSchemas: searchSchemasMap,
|
|
83
103
|
namespace: "build",
|
|
84
104
|
parent: null,
|
|
85
105
|
counters: {},
|
|
106
|
+
mountIndex,
|
|
86
107
|
trackedIncludes, // Enable nested include tracking
|
|
87
108
|
},
|
|
88
109
|
() => {
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
const helpers = createRouteHelpers();
|
|
111
|
+
// Wrap in root layout for correct parent hierarchy (matches runtime)
|
|
112
|
+
helpers.layout(MapRootLayout, () => {
|
|
113
|
+
if (urlPrefix || namePrefix) {
|
|
114
|
+
return runWithPrefixes(urlPrefix, namePrefix, () => {
|
|
115
|
+
return patterns.handler() as AllUseItems[];
|
|
116
|
+
});
|
|
117
|
+
}
|
|
91
118
|
return patterns.handler() as AllUseItems[];
|
|
92
119
|
});
|
|
93
|
-
}
|
|
120
|
+
},
|
|
94
121
|
);
|
|
95
122
|
|
|
96
123
|
// Collect route names defined in this include (routes have prefixes applied)
|
|
@@ -100,7 +127,51 @@ function buildPrefixTreeNode(
|
|
|
100
127
|
routeManifest[name] = pattern;
|
|
101
128
|
}
|
|
102
129
|
|
|
103
|
-
//
|
|
130
|
+
// Collect trailing slash config
|
|
131
|
+
if (routeTrailingSlash) {
|
|
132
|
+
for (const [name, mode] of trailingSlashMap.entries()) {
|
|
133
|
+
routeTrailingSlash[name] = mode;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (routeSearchSchemas) {
|
|
137
|
+
for (const [name, schema] of searchSchemasMap.entries()) {
|
|
138
|
+
routeSearchSchemas[name] = schema;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Capture ancestry from manifest entries' parent chains
|
|
143
|
+
captureAncestry(manifest, routeAncestry);
|
|
144
|
+
|
|
145
|
+
// Collect prerender route names and handler definitions from manifest entries
|
|
146
|
+
if (prerenderRoutes) {
|
|
147
|
+
for (const [name, entry] of manifest) {
|
|
148
|
+
if (entry.type === "route" && entry.isPrerender) {
|
|
149
|
+
prerenderRoutes.push(name);
|
|
150
|
+
if (prerenderDefs && entry.prerenderDef) {
|
|
151
|
+
prerenderDefs[name] = entry.prerenderDef;
|
|
152
|
+
}
|
|
153
|
+
if (
|
|
154
|
+
passthroughRoutes &&
|
|
155
|
+
entry.prerenderDef?.options?.passthrough === true
|
|
156
|
+
) {
|
|
157
|
+
passthroughRoutes.push(name);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Collect response type routes from manifest entries
|
|
164
|
+
if (responseTypeRoutes) {
|
|
165
|
+
for (const [name, entry] of manifest) {
|
|
166
|
+
if (entry.type === "route" && entry.responseType) {
|
|
167
|
+
responseTypeRoutes[name] = entry.responseType;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Build children from tracked nested includes.
|
|
173
|
+
// Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
|
|
174
|
+
// include("/", patternsB)). Merge their routes instead of overwriting.
|
|
104
175
|
const children: Record<string, PrefixTreeNode> = {};
|
|
105
176
|
|
|
106
177
|
for (const include of trackedIncludes) {
|
|
@@ -109,12 +180,31 @@ function buildPrefixTreeNode(
|
|
|
109
180
|
include.namePrefix,
|
|
110
181
|
include.patterns as UrlPatterns<any>,
|
|
111
182
|
routeManifest,
|
|
112
|
-
|
|
183
|
+
routeAncestry,
|
|
184
|
+
mountIndex,
|
|
185
|
+
visited,
|
|
186
|
+
routeTrailingSlash,
|
|
187
|
+
prerenderRoutes,
|
|
188
|
+
prerenderDefs,
|
|
189
|
+
passthroughRoutes,
|
|
190
|
+
responseTypeRoutes,
|
|
191
|
+
routeSearchSchemas,
|
|
113
192
|
);
|
|
114
193
|
|
|
115
|
-
children[include.fullPrefix]
|
|
194
|
+
const existing = children[include.fullPrefix];
|
|
195
|
+
if (existing) {
|
|
196
|
+
existing.routes.push(...childNode.routes);
|
|
197
|
+
Object.assign(existing.children, childNode.children);
|
|
198
|
+
} else {
|
|
199
|
+
children[include.fullPrefix] = childNode;
|
|
200
|
+
}
|
|
116
201
|
}
|
|
117
202
|
|
|
203
|
+
// Remove from visited so sibling branches can reuse the same patterns
|
|
204
|
+
// without false circular-include detection. Only ancestors in the current
|
|
205
|
+
// recursion path should trigger the cycle guard.
|
|
206
|
+
visited.delete(patterns);
|
|
207
|
+
|
|
118
208
|
return {
|
|
119
209
|
staticPrefix: extractStaticPrefix(urlPrefix),
|
|
120
210
|
fullPrefix: urlPrefix,
|
|
@@ -125,11 +215,40 @@ function buildPrefixTreeNode(
|
|
|
125
215
|
}
|
|
126
216
|
|
|
127
217
|
/**
|
|
128
|
-
*
|
|
218
|
+
* Walk parent chains of route entries to extract ancestry shortCodes.
|
|
219
|
+
*/
|
|
220
|
+
function captureAncestry(
|
|
221
|
+
manifest: Map<string, EntryData>,
|
|
222
|
+
routeAncestry: Record<string, string[]>,
|
|
223
|
+
): void {
|
|
224
|
+
for (const [routeName, entry] of manifest) {
|
|
225
|
+
if (entry.type === "route") {
|
|
226
|
+
const ancestry: string[] = [];
|
|
227
|
+
let current: EntryData | null = entry;
|
|
228
|
+
while (current) {
|
|
229
|
+
ancestry.unshift(current.shortCode);
|
|
230
|
+
current = current.parent;
|
|
231
|
+
}
|
|
232
|
+
routeAncestry[routeName] = ancestry;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Internal manifest result including build-pipeline-only fields.
|
|
239
|
+
* Not part of the public API — use generateManifest() for the public surface.
|
|
240
|
+
*/
|
|
241
|
+
export interface FullManifest extends GeneratedManifest {
|
|
242
|
+
_routeAncestry: Record<string, string[]>;
|
|
243
|
+
_prerenderDefs?: Record<string, any>;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Generate manifest from UrlPatterns (public API).
|
|
129
248
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
249
|
+
* Returns only the public GeneratedManifest fields. Internal build pipeline
|
|
250
|
+
* consumers that need _routeAncestry or _prerenderDefs should use
|
|
251
|
+
* generateManifestFull() instead.
|
|
133
252
|
*
|
|
134
253
|
* @example
|
|
135
254
|
* ```typescript
|
|
@@ -145,9 +264,30 @@ function buildPrefixTreeNode(
|
|
|
145
264
|
* ```
|
|
146
265
|
*/
|
|
147
266
|
export function generateManifest<TEnv>(
|
|
148
|
-
urlpatterns: UrlPatterns<TEnv, any
|
|
267
|
+
urlpatterns: UrlPatterns<TEnv, any>,
|
|
268
|
+
mountIndex: number = 0,
|
|
149
269
|
): GeneratedManifest {
|
|
270
|
+
const {
|
|
271
|
+
_routeAncestry: _,
|
|
272
|
+
_prerenderDefs: __,
|
|
273
|
+
...publicManifest
|
|
274
|
+
} = generateManifestFull(urlpatterns, mountIndex);
|
|
275
|
+
return publicManifest;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Generate manifest with internal build-pipeline fields.
|
|
280
|
+
*
|
|
281
|
+
* Used by the Vite plugin (discover-routers via dynamic import through
|
|
282
|
+
* @rangojs/router/build), manifest-init (direct import), and trie
|
|
283
|
+
* building. Not intended for external use.
|
|
284
|
+
*/
|
|
285
|
+
export function generateManifestFull<TEnv>(
|
|
286
|
+
urlpatterns: UrlPatterns<TEnv, any>,
|
|
287
|
+
mountIndex: number = 0,
|
|
288
|
+
): FullManifest {
|
|
150
289
|
const routeManifest: Record<string, string> = {};
|
|
290
|
+
const routeAncestry: Record<string, string[]> = {};
|
|
151
291
|
const prefixTree: Record<string, PrefixTreeNode> = {};
|
|
152
292
|
|
|
153
293
|
// Run the root patterns handler with tracking enabled
|
|
@@ -155,6 +295,7 @@ export function generateManifest<TEnv>(
|
|
|
155
295
|
const patternsMap = new Map<string, string>();
|
|
156
296
|
const patternsByPrefix = new Map<string, Map<string, string>>();
|
|
157
297
|
const trailingSlashMap = new Map<string, TrailingSlashMode>();
|
|
298
|
+
const searchSchemasMap = new Map<string, Record<string, string>>();
|
|
158
299
|
const trackedIncludes: TrackedInclude[] = [];
|
|
159
300
|
|
|
160
301
|
RSCRouterContext.run(
|
|
@@ -163,22 +304,61 @@ export function generateManifest<TEnv>(
|
|
|
163
304
|
patterns: patternsMap,
|
|
164
305
|
patternsByPrefix,
|
|
165
306
|
trailingSlash: trailingSlashMap,
|
|
307
|
+
searchSchemas: searchSchemasMap,
|
|
166
308
|
namespace: "build",
|
|
167
309
|
parent: null,
|
|
168
310
|
counters: {},
|
|
311
|
+
mountIndex,
|
|
169
312
|
trackedIncludes, // Enable include tracking
|
|
170
313
|
},
|
|
171
314
|
() => {
|
|
172
|
-
|
|
173
|
-
|
|
315
|
+
const helpers = createRouteHelpers();
|
|
316
|
+
// Wrap in root layout for correct parent hierarchy (matches runtime)
|
|
317
|
+
helpers.layout(MapRootLayout, () => {
|
|
318
|
+
return urlpatterns.handler() as AllUseItems[];
|
|
319
|
+
});
|
|
320
|
+
},
|
|
174
321
|
);
|
|
175
322
|
|
|
176
|
-
// Collect root-level routes
|
|
323
|
+
// Collect root-level routes and trailing slash config
|
|
324
|
+
const routeTrailingSlash: Record<string, string> = {};
|
|
177
325
|
for (const [name, pattern] of patternsMap.entries()) {
|
|
178
326
|
routeManifest[name] = pattern;
|
|
179
327
|
}
|
|
328
|
+
for (const [name, mode] of trailingSlashMap.entries()) {
|
|
329
|
+
routeTrailingSlash[name] = mode;
|
|
330
|
+
}
|
|
331
|
+
const routeSearchSchemas: Record<string, Record<string, string>> = {};
|
|
332
|
+
for (const [name, schema] of searchSchemasMap.entries()) {
|
|
333
|
+
routeSearchSchemas[name] = schema;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Capture ancestry from manifest entries' parent chains
|
|
337
|
+
captureAncestry(manifest, routeAncestry);
|
|
338
|
+
|
|
339
|
+
// Collect prerender route names and handler definitions across all levels
|
|
340
|
+
const prerenderRoutes: string[] = [];
|
|
341
|
+
const prerenderDefs: Record<string, any> = {};
|
|
342
|
+
const passthroughRoutes: string[] = [];
|
|
343
|
+
const responseTypeRoutes: Record<string, string> = {};
|
|
344
|
+
for (const [name, entry] of manifest) {
|
|
345
|
+
if (entry.type === "route" && entry.isPrerender) {
|
|
346
|
+
prerenderRoutes.push(name);
|
|
347
|
+
if (entry.prerenderDef) {
|
|
348
|
+
prerenderDefs[name] = entry.prerenderDef;
|
|
349
|
+
}
|
|
350
|
+
if (entry.prerenderDef?.options?.passthrough === true) {
|
|
351
|
+
passthroughRoutes.push(name);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (entry.type === "route" && entry.responseType) {
|
|
355
|
+
responseTypeRoutes[name] = entry.responseType;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
180
358
|
|
|
181
|
-
// Build prefix tree from tracked includes (shared visited set for cycle detection)
|
|
359
|
+
// Build prefix tree from tracked includes (shared visited set for cycle detection).
|
|
360
|
+
// Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
|
|
361
|
+
// include("/", patternsB)). Merge their routes instead of overwriting.
|
|
182
362
|
const visited = new Set<unknown>();
|
|
183
363
|
for (const include of trackedIncludes) {
|
|
184
364
|
const node = buildPrefixTreeNode(
|
|
@@ -186,16 +366,48 @@ export function generateManifest<TEnv>(
|
|
|
186
366
|
include.namePrefix,
|
|
187
367
|
include.patterns as UrlPatterns<any>,
|
|
188
368
|
routeManifest,
|
|
189
|
-
|
|
369
|
+
routeAncestry,
|
|
370
|
+
mountIndex,
|
|
371
|
+
visited,
|
|
372
|
+
routeTrailingSlash,
|
|
373
|
+
prerenderRoutes,
|
|
374
|
+
prerenderDefs,
|
|
375
|
+
passthroughRoutes,
|
|
376
|
+
responseTypeRoutes,
|
|
377
|
+
routeSearchSchemas,
|
|
190
378
|
);
|
|
191
379
|
|
|
192
|
-
prefixTree[include.fullPrefix]
|
|
380
|
+
const existing = prefixTree[include.fullPrefix];
|
|
381
|
+
if (existing) {
|
|
382
|
+
existing.routes.push(...node.routes);
|
|
383
|
+
Object.assign(existing.children, node.children);
|
|
384
|
+
} else {
|
|
385
|
+
prefixTree[include.fullPrefix] = node;
|
|
386
|
+
}
|
|
193
387
|
}
|
|
194
388
|
|
|
195
389
|
return {
|
|
196
390
|
prefixTree,
|
|
197
391
|
routeManifest,
|
|
198
|
-
|
|
392
|
+
routeTrailingSlash:
|
|
393
|
+
Object.keys(routeTrailingSlash).length > 0
|
|
394
|
+
? routeTrailingSlash
|
|
395
|
+
: undefined,
|
|
396
|
+
prerenderRoutes: prerenderRoutes.length > 0 ? prerenderRoutes : undefined,
|
|
397
|
+
passthroughRoutes:
|
|
398
|
+
passthroughRoutes.length > 0 ? passthroughRoutes : undefined,
|
|
399
|
+
responseTypeRoutes:
|
|
400
|
+
Object.keys(responseTypeRoutes).length > 0
|
|
401
|
+
? responseTypeRoutes
|
|
402
|
+
: undefined,
|
|
403
|
+
routeSearchSchemas:
|
|
404
|
+
Object.keys(routeSearchSchemas).length > 0
|
|
405
|
+
? routeSearchSchemas
|
|
406
|
+
: undefined,
|
|
407
|
+
_routeAncestry: routeAncestry,
|
|
408
|
+
// Internal: prerender handler definitions for build-time getParams() access
|
|
409
|
+
_prerenderDefs:
|
|
410
|
+
Object.keys(prerenderDefs).length > 0 ? prerenderDefs : undefined,
|
|
199
411
|
};
|
|
200
412
|
}
|
|
201
413
|
|
|
@@ -209,13 +421,12 @@ export function generateManifest<TEnv>(
|
|
|
209
421
|
* ```
|
|
210
422
|
*/
|
|
211
423
|
export function generateManifestCode<TEnv>(
|
|
212
|
-
urlpatterns: UrlPatterns<TEnv, any
|
|
424
|
+
urlpatterns: UrlPatterns<TEnv, any>,
|
|
213
425
|
): string {
|
|
214
426
|
const manifest = generateManifest(urlpatterns);
|
|
215
427
|
|
|
216
428
|
return `/**
|
|
217
429
|
* Auto-generated route manifest
|
|
218
|
-
* Generated at: ${manifest.generatedAt}
|
|
219
430
|
*
|
|
220
431
|
* DO NOT EDIT - This file is generated by @rangojs/router
|
|
221
432
|
*/
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Barrel re-export -- see route-types/ for implementations.
|
|
2
|
+
export {
|
|
3
|
+
extractParamsFromPattern,
|
|
4
|
+
formatRouteEntry,
|
|
5
|
+
} from "./route-types/param-extraction.js";
|
|
6
|
+
export { extractRoutesFromSource } from "./route-types/ast-route-extraction.js";
|
|
7
|
+
export {
|
|
8
|
+
generatePerModuleTypesSource,
|
|
9
|
+
generateRouteTypesSource,
|
|
10
|
+
} from "./route-types/codegen.js";
|
|
11
|
+
export {
|
|
12
|
+
DEFAULT_EXCLUDE_PATTERNS,
|
|
13
|
+
type ScanFilter,
|
|
14
|
+
createScanFilter,
|
|
15
|
+
findTsFiles,
|
|
16
|
+
} from "./route-types/scan-filter.js";
|
|
17
|
+
export {
|
|
18
|
+
writePerModuleRouteTypes,
|
|
19
|
+
writePerModuleRouteTypesForFile,
|
|
20
|
+
} from "./route-types/per-module-writer.js";
|
|
21
|
+
export {
|
|
22
|
+
type UnresolvableReason,
|
|
23
|
+
type UnresolvableInclude,
|
|
24
|
+
extractIncludesWithDiagnostics,
|
|
25
|
+
} from "./route-types/include-resolution.js";
|
|
26
|
+
export {
|
|
27
|
+
extractUrlsVariableFromRouter,
|
|
28
|
+
buildCombinedRouteMapForRouterFile,
|
|
29
|
+
detectUnresolvableIncludes,
|
|
30
|
+
detectUnresolvableIncludesForUrlsFile,
|
|
31
|
+
findNestedRouterConflict,
|
|
32
|
+
formatNestedRouterConflictError,
|
|
33
|
+
findRouterFiles,
|
|
34
|
+
writeCombinedRouteTypes,
|
|
35
|
+
} from "./route-types/router-processing.js";
|
|
36
|
+
export { findUrlsVariableNames } from "./route-types/per-module-writer.js";
|
package/src/build/index.ts
CHANGED
|
@@ -17,6 +17,19 @@
|
|
|
17
17
|
|
|
18
18
|
export {
|
|
19
19
|
generateManifest,
|
|
20
|
+
generateManifestFull,
|
|
20
21
|
generateManifestCode,
|
|
21
22
|
type GeneratedManifest,
|
|
22
23
|
} from "./generate-manifest.js";
|
|
24
|
+
|
|
25
|
+
export { buildRouteTrie, type TrieNode, type TrieLeaf } from "./route-trie.js";
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
writePerModuleRouteTypes,
|
|
29
|
+
extractRoutesFromSource,
|
|
30
|
+
generatePerModuleTypesSource,
|
|
31
|
+
createScanFilter,
|
|
32
|
+
type ScanFilter,
|
|
33
|
+
} from "./generate-route-types.js";
|
|
34
|
+
|
|
35
|
+
export { hashParams } from "../prerender/param-hash.js";
|