@rangojs/router 0.0.0-experimental.7 → 0.0.0-experimental.70
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 +9 -0
- package/README.md +942 -4
- package/dist/bin/rango.js +1689 -0
- package/dist/vite/index.js +4951 -930
- package/package.json +70 -60
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +294 -0
- package/skills/caching/SKILL.md +93 -23
- 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 +92 -31
- package/skills/loader/SKILL.md +404 -44
- package/skills/middleware/SKILL.md +173 -34
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +204 -1
- package/skills/prerender/SKILL.md +685 -0
- package/skills/rango/SKILL.md +85 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +257 -14
- package/skills/router-setup/SKILL.md +210 -32
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +328 -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/app-version.ts +14 -0
- package/src/browser/event-controller.ts +92 -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 +296 -558
- package/src/browser/navigation-client.ts +179 -69
- package/src/browser/navigation-store.ts +73 -55
- package/src/browser/navigation-transaction.ts +297 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +328 -313
- package/src/browser/prefetch/cache.ts +206 -0
- package/src/browser/prefetch/fetch.ts +150 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +160 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +230 -74
- package/src/browser/react/NavigationProvider.tsx +87 -11
- package/src/browser/react/context.ts +11 -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 +30 -126
- 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 +76 -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 +214 -58
- package/src/browser/scroll-restoration.ts +127 -52
- package/src/browser/segment-reconciler.ts +221 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +510 -603
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +141 -48
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +235 -24
- package/src/build/generate-route-types.ts +39 -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 +418 -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 +618 -0
- package/src/build/route-types/scan-filter.ts +85 -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 +342 -0
- package/src/cache/cache-scope.ts +167 -309
- package/src/cache/cf/cf-cache-store.ts +571 -17
- package/src/cache/cf/index.ts +13 -3
- package/src/cache/document-cache.ts +116 -77
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +1 -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 +153 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +105 -179
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +156 -0
- package/src/debug.ts +19 -9
- package/src/errors.ts +108 -2
- package/src/handle.ts +55 -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 +155 -19
- package/src/index.ts +223 -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 +186 -0
- package/src/prerender.ts +524 -0
- package/src/reverse.ts +351 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +982 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +434 -0
- package/src/route-definition/index.ts +55 -0
- package/src/route-definition/redirect.ts +101 -0
- package/src/route-definition/resolve-handler-use.ts +149 -0
- package/src/route-definition.ts +1 -1428
- package/src/route-map-builder.ts +217 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +70 -8
- package/src/router/content-negotiation.ts +215 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +9 -9
- package/src/router/find-match.ts +160 -0
- package/src/router/handler-context.ts +435 -86
- package/src/router/intercept-resolution.ts +402 -0
- package/src/router/lazy-includes.ts +237 -0
- package/src/router/loader-resolution.ts +356 -128
- package/src/router/logging.ts +251 -0
- package/src/router/manifest.ts +154 -35
- package/src/router/match-api.ts +555 -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 +108 -93
- package/src/router/match-middleware/cache-lookup.ts +459 -10
- package/src/router/match-middleware/cache-store.ts +98 -26
- package/src/router/match-middleware/intercept-resolution.ts +57 -17
- package/src/router/match-middleware/segment-resolution.ts +80 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +55 -33
- package/src/router/metrics.ts +240 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +220 -0
- package/src/router/middleware.ts +324 -369
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +211 -43
- package/src/router/prerender-match.ts +502 -0
- package/src/router/preview-match.ts +98 -0
- package/src/router/request-classification.ts +310 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +41 -21
- package/src/router/router-interfaces.ts +484 -0
- package/src/router/router-options.ts +618 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +743 -0
- package/src/router/segment-resolution/helpers.ts +268 -0
- package/src/router/segment-resolution/loader-cache.ts +199 -0
- package/src/router/segment-resolution/revalidation.ts +1373 -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 +291 -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 +78 -3
- package/src/router.ts +740 -4252
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +907 -797
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +229 -0
- package/src/rsc/manifest-init.ts +90 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +391 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +246 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +356 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +46 -11
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +165 -17
- package/src/server/context.ts +315 -58
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +113 -15
- package/src/server/loader-registry.ts +24 -64
- package/src/server/request-context.ts +607 -81
- package/src/server.ts +35 -130
- package/src/ssr/index.tsx +103 -30
- package/src/static-handler.ts +126 -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 +791 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +210 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +109 -0
- package/src/types/segments.ts +150 -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 +346 -0
- package/src/urls/path-helper.ts +364 -0
- package/src/urls/pattern-types.ts +107 -0
- package/src/urls/response-types.ts +116 -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 +161 -81
- package/src/vite/discovery/bundle-postprocess.ts +181 -0
- package/src/vite/discovery/discover-routers.ts +348 -0
- package/src/vite/discovery/prerender-collection.ts +439 -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 +117 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +15 -1129
- package/src/vite/plugin-types.ts +103 -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 -53
- package/src/vite/plugins/expose-id-utils.ts +299 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +209 -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 +786 -0
- package/src/vite/plugins/performance-tracks.ts +88 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -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 +266 -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 +462 -0
- package/src/vite/router-discovery.ts +918 -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 +207 -0
- package/src/vite/utils/shared-utils.ts +170 -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 wrapped with Passthrough() (live handler for runtime 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,48 @@ 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 (passthroughRoutes && entry.isPassthrough === true) {
|
|
154
|
+
passthroughRoutes.push(name);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Collect response type routes from manifest entries
|
|
161
|
+
if (responseTypeRoutes) {
|
|
162
|
+
for (const [name, entry] of manifest) {
|
|
163
|
+
if (entry.type === "route" && entry.responseType) {
|
|
164
|
+
responseTypeRoutes[name] = entry.responseType;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Build children from tracked nested includes.
|
|
170
|
+
// Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
|
|
171
|
+
// include("/", patternsB)). Merge their routes instead of overwriting.
|
|
104
172
|
const children: Record<string, PrefixTreeNode> = {};
|
|
105
173
|
|
|
106
174
|
for (const include of trackedIncludes) {
|
|
@@ -109,12 +177,31 @@ function buildPrefixTreeNode(
|
|
|
109
177
|
include.namePrefix,
|
|
110
178
|
include.patterns as UrlPatterns<any>,
|
|
111
179
|
routeManifest,
|
|
112
|
-
|
|
180
|
+
routeAncestry,
|
|
181
|
+
mountIndex,
|
|
182
|
+
visited,
|
|
183
|
+
routeTrailingSlash,
|
|
184
|
+
prerenderRoutes,
|
|
185
|
+
prerenderDefs,
|
|
186
|
+
passthroughRoutes,
|
|
187
|
+
responseTypeRoutes,
|
|
188
|
+
routeSearchSchemas,
|
|
113
189
|
);
|
|
114
190
|
|
|
115
|
-
children[include.fullPrefix]
|
|
191
|
+
const existing = children[include.fullPrefix];
|
|
192
|
+
if (existing) {
|
|
193
|
+
existing.routes.push(...childNode.routes);
|
|
194
|
+
Object.assign(existing.children, childNode.children);
|
|
195
|
+
} else {
|
|
196
|
+
children[include.fullPrefix] = childNode;
|
|
197
|
+
}
|
|
116
198
|
}
|
|
117
199
|
|
|
200
|
+
// Remove from visited so sibling branches can reuse the same patterns
|
|
201
|
+
// without false circular-include detection. Only ancestors in the current
|
|
202
|
+
// recursion path should trigger the cycle guard.
|
|
203
|
+
visited.delete(patterns);
|
|
204
|
+
|
|
118
205
|
return {
|
|
119
206
|
staticPrefix: extractStaticPrefix(urlPrefix),
|
|
120
207
|
fullPrefix: urlPrefix,
|
|
@@ -125,11 +212,40 @@ function buildPrefixTreeNode(
|
|
|
125
212
|
}
|
|
126
213
|
|
|
127
214
|
/**
|
|
128
|
-
*
|
|
215
|
+
* Walk parent chains of route entries to extract ancestry shortCodes.
|
|
216
|
+
*/
|
|
217
|
+
function captureAncestry(
|
|
218
|
+
manifest: Map<string, EntryData>,
|
|
219
|
+
routeAncestry: Record<string, string[]>,
|
|
220
|
+
): void {
|
|
221
|
+
for (const [routeName, entry] of manifest) {
|
|
222
|
+
if (entry.type === "route") {
|
|
223
|
+
const ancestry: string[] = [];
|
|
224
|
+
let current: EntryData | null = entry;
|
|
225
|
+
while (current) {
|
|
226
|
+
ancestry.unshift(current.shortCode);
|
|
227
|
+
current = current.parent;
|
|
228
|
+
}
|
|
229
|
+
routeAncestry[routeName] = ancestry;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Internal manifest result including build-pipeline-only fields.
|
|
236
|
+
* Not part of the public API — use generateManifest() for the public surface.
|
|
237
|
+
*/
|
|
238
|
+
export interface FullManifest extends GeneratedManifest {
|
|
239
|
+
_routeAncestry: Record<string, string[]>;
|
|
240
|
+
_prerenderDefs?: Record<string, any>;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Generate manifest from UrlPatterns (public API).
|
|
129
245
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
246
|
+
* Returns only the public GeneratedManifest fields. Internal build pipeline
|
|
247
|
+
* consumers that need _routeAncestry or _prerenderDefs should use
|
|
248
|
+
* generateManifestFull() instead.
|
|
133
249
|
*
|
|
134
250
|
* @example
|
|
135
251
|
* ```typescript
|
|
@@ -145,9 +261,31 @@ function buildPrefixTreeNode(
|
|
|
145
261
|
* ```
|
|
146
262
|
*/
|
|
147
263
|
export function generateManifest<TEnv>(
|
|
148
|
-
urlpatterns: UrlPatterns<TEnv, any
|
|
264
|
+
urlpatterns: UrlPatterns<TEnv, any>,
|
|
265
|
+
mountIndex: number = 0,
|
|
149
266
|
): GeneratedManifest {
|
|
267
|
+
const {
|
|
268
|
+
_routeAncestry: _,
|
|
269
|
+
_prerenderDefs: __,
|
|
270
|
+
...publicManifest
|
|
271
|
+
} = generateManifestFull(urlpatterns, mountIndex);
|
|
272
|
+
return publicManifest;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Generate manifest with internal build-pipeline fields.
|
|
277
|
+
*
|
|
278
|
+
* Used by the Vite plugin (discover-routers via dynamic import through
|
|
279
|
+
* @rangojs/router/build), manifest-init (direct import), and trie
|
|
280
|
+
* building. Not intended for external use.
|
|
281
|
+
*/
|
|
282
|
+
export function generateManifestFull<TEnv>(
|
|
283
|
+
urlpatterns: UrlPatterns<TEnv, any>,
|
|
284
|
+
mountIndex: number = 0,
|
|
285
|
+
options?: { urlPrefix?: string },
|
|
286
|
+
): FullManifest {
|
|
150
287
|
const routeManifest: Record<string, string> = {};
|
|
288
|
+
const routeAncestry: Record<string, string[]> = {};
|
|
151
289
|
const prefixTree: Record<string, PrefixTreeNode> = {};
|
|
152
290
|
|
|
153
291
|
// Run the root patterns handler with tracking enabled
|
|
@@ -155,6 +293,7 @@ export function generateManifest<TEnv>(
|
|
|
155
293
|
const patternsMap = new Map<string, string>();
|
|
156
294
|
const patternsByPrefix = new Map<string, Map<string, string>>();
|
|
157
295
|
const trailingSlashMap = new Map<string, TrailingSlashMode>();
|
|
296
|
+
const searchSchemasMap = new Map<string, Record<string, string>>();
|
|
158
297
|
const trackedIncludes: TrackedInclude[] = [];
|
|
159
298
|
|
|
160
299
|
RSCRouterContext.run(
|
|
@@ -163,22 +302,63 @@ export function generateManifest<TEnv>(
|
|
|
163
302
|
patterns: patternsMap,
|
|
164
303
|
patternsByPrefix,
|
|
165
304
|
trailingSlash: trailingSlashMap,
|
|
305
|
+
searchSchemas: searchSchemasMap,
|
|
166
306
|
namespace: "build",
|
|
167
307
|
parent: null,
|
|
168
308
|
counters: {},
|
|
309
|
+
mountIndex,
|
|
169
310
|
trackedIncludes, // Enable include tracking
|
|
311
|
+
// basename sets the initial URL prefix for all path() registrations
|
|
312
|
+
...(options?.urlPrefix ? { urlPrefix: options.urlPrefix } : {}),
|
|
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.isPassthrough === 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,39 @@
|
|
|
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
|
+
extractUrlsFromRouter,
|
|
29
|
+
extractBasenameFromRouter,
|
|
30
|
+
type UrlsExtractionResult,
|
|
31
|
+
buildCombinedRouteMapForRouterFile,
|
|
32
|
+
detectUnresolvableIncludes,
|
|
33
|
+
detectUnresolvableIncludesForUrlsFile,
|
|
34
|
+
findNestedRouterConflict,
|
|
35
|
+
formatNestedRouterConflictError,
|
|
36
|
+
findRouterFiles,
|
|
37
|
+
writeCombinedRouteTypes,
|
|
38
|
+
} from "./route-types/router-processing.js";
|
|
39
|
+
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";
|