@rangojs/router 0.0.0-experimental.18 → 0.0.0-experimental.19
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/README.md +46 -8
- package/dist/bin/rango.js +105 -18
- package/dist/vite/index.js +227 -93
- package/package.json +15 -14
- package/skills/hooks/SKILL.md +1 -1
- package/skills/intercept/SKILL.md +79 -0
- package/skills/layout/SKILL.md +62 -2
- package/skills/loader/SKILL.md +94 -1
- package/skills/middleware/SKILL.md +81 -0
- package/skills/parallel/SKILL.md +57 -2
- package/skills/prerender/SKILL.md +187 -17
- package/skills/route/SKILL.md +42 -1
- package/skills/router-setup/SKILL.md +77 -0
- package/src/__internal.ts +1 -1
- package/src/bin/rango.ts +38 -19
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/event-controller.ts +25 -27
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +1 -1
- package/src/browser/link-interceptor.ts +0 -3
- package/src/browser/merge-segment-loaders.ts +9 -2
- package/src/browser/navigation-bridge.ts +46 -13
- package/src/browser/navigation-client.ts +32 -61
- package/src/browser/navigation-store.ts +1 -31
- package/src/browser/navigation-transaction.ts +46 -207
- package/src/browser/partial-update.ts +102 -150
- package/src/browser/{prefetch-cache.ts → prefetch/cache.ts} +23 -4
- package/src/browser/{prefetch-fetch.ts → prefetch/fetch.ts} +36 -8
- package/src/browser/prefetch/policy.ts +42 -0
- package/src/browser/{prefetch-queue.ts → prefetch/queue.ts} +10 -3
- package/src/browser/react/Link.tsx +28 -23
- package/src/browser/react/NavigationProvider.tsx +9 -1
- package/src/browser/react/index.ts +2 -6
- package/src/browser/react/location-state-shared.ts +1 -1
- package/src/browser/react/location-state.ts +2 -0
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/use-action.ts +9 -1
- package/src/browser/react/use-handle.ts +3 -25
- package/src/browser/react/use-params.ts +2 -4
- package/src/browser/react/use-pathname.ts +2 -3
- package/src/browser/react/use-router.ts +1 -1
- package/src/browser/react/use-search-params.ts +2 -1
- package/src/browser/react/use-segments.ts +7 -60
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +29 -23
- package/src/browser/scroll-restoration.ts +10 -7
- package/src/browser/server-action-bridge.ts +115 -96
- package/src/browser/types.ts +1 -31
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +5 -0
- package/src/build/generate-route-types.ts +2 -0
- package/src/build/route-types/codegen.ts +13 -4
- package/src/build/route-types/include-resolution.ts +13 -0
- package/src/build/route-types/per-module-writer.ts +15 -3
- package/src/build/route-types/router-processing.ts +45 -3
- package/src/build/runtime-discovery.ts +13 -1
- 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 +132 -96
- package/src/cache/cache-scope.ts +71 -73
- package/src/cache/cf/cf-cache-store.ts +9 -4
- package/src/cache/document-cache.ts +72 -47
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/memory-segment-store.ts +18 -7
- package/src/cache/profile-registry.ts +43 -8
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +101 -112
- package/src/cache/taint.ts +26 -0
- package/src/client.tsx +53 -30
- package/src/errors.ts +6 -1
- package/src/handle.ts +1 -1
- package/src/handles/MetaTags.tsx +5 -2
- package/src/host/cookie-handler.ts +8 -3
- package/src/host/router.ts +14 -1
- package/src/href-client.ts +3 -1
- package/src/index.rsc.ts +33 -1
- package/src/index.ts +27 -0
- package/src/loader.rsc.ts +12 -4
- package/src/loader.ts +8 -0
- package/src/prerender/store.ts +4 -3
- package/src/prerender.ts +76 -18
- package/src/reverse.ts +11 -7
- package/src/root-error-boundary.tsx +30 -26
- package/src/route-definition/dsl-helpers.ts +9 -6
- package/src/route-definition/redirect.ts +15 -3
- package/src/route-map-builder.ts +38 -2
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +7 -0
- package/src/router/content-negotiation.ts +1 -1
- package/src/router/debug-manifest.ts +16 -3
- package/src/router/handler-context.ts +94 -15
- package/src/router/intercept-resolution.ts +6 -4
- package/src/router/lazy-includes.ts +4 -0
- package/src/router/loader-resolution.ts +1 -0
- package/src/router/logging.ts +100 -3
- package/src/router/manifest.ts +32 -3
- package/src/router/match-api.ts +61 -7
- package/src/router/match-context.ts +3 -0
- package/src/router/match-handlers.ts +185 -11
- package/src/router/match-middleware/background-revalidation.ts +65 -85
- package/src/router/match-middleware/cache-lookup.ts +69 -4
- package/src/router/match-middleware/cache-store.ts +2 -0
- package/src/router/match-pipelines.ts +8 -43
- package/src/router/middleware-types.ts +7 -0
- package/src/router/middleware.ts +93 -8
- package/src/router/pattern-matching.ts +41 -5
- package/src/router/prerender-match.ts +34 -6
- package/src/router/preview-match.ts +7 -1
- package/src/router/revalidation.ts +61 -2
- package/src/router/router-context.ts +15 -0
- package/src/router/router-interfaces.ts +34 -0
- package/src/router/router-options.ts +200 -0
- package/src/router/segment-resolution/fresh.ts +123 -30
- package/src/router/segment-resolution/helpers.ts +19 -0
- package/src/router/segment-resolution/loader-cache.ts +37 -146
- package/src/router/segment-resolution/revalidation.ts +358 -94
- package/src/router/segment-wrappers.ts +3 -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/types.ts +7 -1
- package/src/router.ts +155 -11
- package/src/rsc/handler-context.ts +11 -0
- package/src/rsc/handler.ts +380 -88
- package/src/rsc/helpers.ts +25 -16
- package/src/rsc/loader-fetch.ts +84 -42
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +232 -19
- package/src/rsc/response-route-handler.ts +37 -26
- package/src/rsc/rsc-rendering.ts +12 -5
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +134 -58
- package/src/rsc/types.ts +8 -0
- package/src/search-params.ts +22 -10
- package/src/server/context.ts +53 -5
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +66 -9
- package/src/server/loader-registry.ts +11 -46
- package/src/server/request-context.ts +90 -9
- package/src/ssr/index.tsx +63 -27
- package/src/static-handler.ts +7 -0
- package/src/theme/ThemeProvider.tsx +6 -1
- package/src/theme/index.ts +1 -6
- package/src/theme/theme-context.ts +1 -28
- package/src/theme/theme-script.ts +2 -1
- package/src/types/cache-types.ts +5 -0
- package/src/types/error-types.ts +3 -0
- package/src/types/global-namespace.ts +9 -0
- package/src/types/handler-context.ts +35 -13
- package/src/types/loader-types.ts +7 -0
- package/src/types/route-entry.ts +28 -0
- package/src/urls/include-helper.ts +49 -8
- package/src/urls/index.ts +1 -0
- package/src/urls/path-helper-types.ts +30 -12
- package/src/urls/path-helper.ts +17 -2
- package/src/urls/pattern-types.ts +21 -1
- package/src/urls/response-types.ts +27 -2
- package/src/urls/type-extraction.ts +23 -15
- package/src/use-loader.tsx +12 -4
- package/src/vite/discovery/bundle-postprocess.ts +12 -7
- package/src/vite/discovery/discover-routers.ts +30 -18
- package/src/vite/discovery/prerender-collection.ts +24 -27
- package/src/vite/discovery/route-types-writer.ts +7 -7
- package/src/vite/discovery/virtual-module-codegen.ts +5 -2
- package/src/vite/plugins/client-ref-hashing.ts +3 -3
- package/src/vite/plugins/use-cache-transform.ts +91 -3
- package/src/vite/rango.ts +3 -3
- package/src/vite/router-discovery.ts +99 -36
- package/src/vite/utils/prerender-utils.ts +21 -0
- package/src/vite/utils/shared-utils.ts +3 -1
- package/src/browser/request-controller.ts +0 -164
- package/src/href-context.ts +0 -33
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- /package/src/browser/{prefetch-observer.ts → prefetch/observer.ts} +0 -0
package/README.md
CHANGED
|
@@ -21,6 +21,12 @@ Named-route RSC router with structural composability and type-safe partial rende
|
|
|
21
21
|
- **Trailing slash control** — Per-route canonical URLs with `"never"`, `"always"`, or `"ignore"`
|
|
22
22
|
- **CLI codegen** — `rango generate` for route type generation
|
|
23
23
|
|
|
24
|
+
## Design Docs
|
|
25
|
+
|
|
26
|
+
- [Execution model](./docs/internal/execution-model.md)
|
|
27
|
+
- [Semantic change checklist](./docs/internal/semantic-change-checklist.md)
|
|
28
|
+
- [Stability roadmap](./docs/internal/stability-roadmap.md)
|
|
29
|
+
|
|
24
30
|
## Installation
|
|
25
31
|
|
|
26
32
|
```bash
|
|
@@ -417,10 +423,10 @@ import { useLoader } from "@rangojs/router/client";
|
|
|
417
423
|
import { BlogSidebarLoader } from "./loaders/blog";
|
|
418
424
|
|
|
419
425
|
function BlogSidebar() {
|
|
420
|
-
const {
|
|
426
|
+
const { data } = useLoader(BlogSidebarLoader);
|
|
421
427
|
return (
|
|
422
428
|
<ul>
|
|
423
|
-
{posts.map((p) => (
|
|
429
|
+
{data.posts.map((p) => (
|
|
424
430
|
<li key={p.slug}>{p.title}</li>
|
|
425
431
|
))}
|
|
426
432
|
</ul>
|
|
@@ -482,7 +488,7 @@ function Nav() {
|
|
|
482
488
|
return (
|
|
483
489
|
<nav>
|
|
484
490
|
<Link to={href("/")}>Home</Link>
|
|
485
|
-
<Link to={href("/blog")} prefetch="
|
|
491
|
+
<Link to={href("/blog")} prefetch="hybrid">
|
|
486
492
|
Blog
|
|
487
493
|
</Link>
|
|
488
494
|
<Link to={href("/about")}>About</Link>
|
|
@@ -493,20 +499,21 @@ function Nav() {
|
|
|
493
499
|
|
|
494
500
|
`href()` validates that the path matches a registered route pattern at compile time (e.g. `/blog/my-post` matches `/blog/:slug`).
|
|
495
501
|
|
|
496
|
-
### Navigation
|
|
502
|
+
### Navigation Hooks
|
|
497
503
|
|
|
498
504
|
```tsx
|
|
499
505
|
"use client";
|
|
500
|
-
import { useNavigation } from "@rangojs/router/client";
|
|
506
|
+
import { useNavigation, useRouter } from "@rangojs/router/client";
|
|
501
507
|
|
|
502
508
|
function SearchForm() {
|
|
503
|
-
const
|
|
509
|
+
const router = useRouter();
|
|
510
|
+
const nav = useNavigation();
|
|
504
511
|
|
|
505
512
|
function handleSubmit(query: string) {
|
|
506
|
-
|
|
513
|
+
router.push(`/search?q=${encodeURIComponent(query)}`);
|
|
507
514
|
}
|
|
508
515
|
|
|
509
|
-
return <form onSubmit={...}>{
|
|
516
|
+
return <form onSubmit={...}>{nav.state !== "idle" && <Spinner />}</form>;
|
|
510
517
|
}
|
|
511
518
|
```
|
|
512
519
|
|
|
@@ -554,6 +561,20 @@ export const urlpatterns = urls(({ path, include }) => [
|
|
|
554
561
|
|
|
555
562
|
Included route names are prefixed with the include name: `reverse("api.health")`, `reverse("api.products")`.
|
|
556
563
|
|
|
564
|
+
### Include name scoping
|
|
565
|
+
|
|
566
|
+
The `name` option controls how child route names appear globally:
|
|
567
|
+
|
|
568
|
+
| Form | Child names | Generated types | Reverse resolution |
|
|
569
|
+
| ---------------------------------- | ------------------- | ---------------------- | -------------------------------------------------------------------- |
|
|
570
|
+
| `include("/x", p, { name: "ns" })` | `ns.child` | Exported as `ns.child` | `reverse("ns.child")` globally, `reverse(".child")` inside |
|
|
571
|
+
| `include("/x", p, { name: "" })` | `child` (flattened) | Exported as-is | `reverse("child")` globally, `reverse(".child")` inside (root-scope) |
|
|
572
|
+
| `include("/x", p)` | Private scope | Not exported | `reverse(".child")` inside only |
|
|
573
|
+
|
|
574
|
+
Without a `name`, included routes are local to the mounted module. They still match requests and render normally, but their names are hidden from the generated route map and cannot be reversed globally. Use `{ name: "" }` to merge children into the parent namespace without adding a prefix.
|
|
575
|
+
|
|
576
|
+
**`{ name: "" }` is flattening, not isolation.** Flattened routes behave as if defined inline at the include site — dot-local reverse (`.name`) can reach any sibling route at root scope, including routes from other `{ name: "" }` mounts. If you need module-level isolation, omit the `name` option or use a namespace.
|
|
577
|
+
|
|
557
578
|
## Middleware
|
|
558
579
|
|
|
559
580
|
```tsx
|
|
@@ -680,6 +701,23 @@ export const ProductPage = Prerender(
|
|
|
680
701
|
|
|
681
702
|
With `passthrough: true`, known params are served from the build-time cache and unknown params fall through to live rendering.
|
|
682
703
|
|
|
704
|
+
Handlers can also skip individual param sets with `ctx.passthrough()`, deferring them to the live handler at runtime:
|
|
705
|
+
|
|
706
|
+
```tsx
|
|
707
|
+
export const ProductPage = Prerender(
|
|
708
|
+
async () => {
|
|
709
|
+
const all = await db.getAllProducts();
|
|
710
|
+
return all.map((p) => ({ id: p.id }));
|
|
711
|
+
},
|
|
712
|
+
async (ctx) => {
|
|
713
|
+
const product = await db.getProduct(ctx.params.id);
|
|
714
|
+
if (!product.published) return ctx.passthrough();
|
|
715
|
+
return <Product data={product} />;
|
|
716
|
+
},
|
|
717
|
+
{ passthrough: true },
|
|
718
|
+
);
|
|
719
|
+
```
|
|
720
|
+
|
|
683
721
|
## Theme
|
|
684
722
|
|
|
685
723
|
### Router Configuration
|
package/dist/bin/rango.js
CHANGED
|
@@ -119,6 +119,21 @@ var init_ast_route_extraction = __esm({
|
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
+
// src/route-name.ts
|
|
123
|
+
function isAutoGeneratedRouteName(name) {
|
|
124
|
+
return name.split(".").some((segment) => {
|
|
125
|
+
return segment.startsWith(AUTO_GENERATED_ROUTE_PREFIX) || segment.startsWith(INTERNAL_INCLUDE_SCOPE_PREFIX);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
var AUTO_GENERATED_ROUTE_PREFIX, INTERNAL_INCLUDE_SCOPE_PREFIX;
|
|
129
|
+
var init_route_name = __esm({
|
|
130
|
+
"src/route-name.ts"() {
|
|
131
|
+
"use strict";
|
|
132
|
+
AUTO_GENERATED_ROUTE_PREFIX = "$path_";
|
|
133
|
+
INTERNAL_INCLUDE_SCOPE_PREFIX = "$prefix_";
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
122
137
|
// src/build/route-types/codegen.ts
|
|
123
138
|
function generatePerModuleTypesSource(routes) {
|
|
124
139
|
const valid = routes.filter(({ name }) => {
|
|
@@ -153,13 +168,16 @@ export type routes = typeof routes;
|
|
|
153
168
|
`;
|
|
154
169
|
}
|
|
155
170
|
function generateRouteTypesSource(routeManifest, searchSchemas) {
|
|
156
|
-
const entries = Object.entries(routeManifest).sort(
|
|
157
|
-
|
|
158
|
-
|
|
171
|
+
const entries = Object.entries(routeManifest).filter(([name]) => !isAutoGeneratedRouteName(name)).sort(([a], [b]) => a.localeCompare(b));
|
|
172
|
+
const filteredSearchSchemas = searchSchemas ? Object.fromEntries(
|
|
173
|
+
Object.entries(searchSchemas).filter(
|
|
174
|
+
([name]) => !isAutoGeneratedRouteName(name)
|
|
175
|
+
)
|
|
176
|
+
) : void 0;
|
|
159
177
|
const objectBody = entries.map(([name, pattern]) => {
|
|
160
178
|
const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : `"${name}"`;
|
|
161
179
|
const params = extractParamsFromPattern(pattern);
|
|
162
|
-
const search =
|
|
180
|
+
const search = filteredSearchSchemas?.[name];
|
|
163
181
|
return formatRouteEntry(key, pattern, params, search);
|
|
164
182
|
}).join("\n");
|
|
165
183
|
return `// Auto-generated by @rangojs/router - do not edit
|
|
@@ -178,6 +196,7 @@ var init_codegen = __esm({
|
|
|
178
196
|
"src/build/route-types/codegen.ts"() {
|
|
179
197
|
"use strict";
|
|
180
198
|
init_param_extraction();
|
|
199
|
+
init_route_name();
|
|
181
200
|
}
|
|
182
201
|
});
|
|
183
202
|
|
|
@@ -410,6 +429,9 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
410
429
|
diagnosticsOut
|
|
411
430
|
);
|
|
412
431
|
}
|
|
432
|
+
if (namePrefix === null) {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
413
435
|
for (const [name, pattern] of Object.entries(childResult.routes)) {
|
|
414
436
|
const prefixedName = namePrefix ? `${namePrefix}.${name}` : name;
|
|
415
437
|
let prefixedPattern;
|
|
@@ -460,6 +482,7 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
460
482
|
searchSchemas,
|
|
461
483
|
diagnosticsOut
|
|
462
484
|
);
|
|
485
|
+
visited.delete(key);
|
|
463
486
|
return { routes, searchSchemas };
|
|
464
487
|
}
|
|
465
488
|
var init_include_resolution = __esm({
|
|
@@ -517,8 +540,16 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
517
540
|
} else {
|
|
518
541
|
routes = extractRoutesFromSource(source);
|
|
519
542
|
}
|
|
520
|
-
if (routes.length === 0) return;
|
|
521
543
|
const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
|
|
544
|
+
if (routes.length === 0) {
|
|
545
|
+
if (varNames.length > 0 && !existsSync2(genPath)) {
|
|
546
|
+
writeFileSync(genPath, generatePerModuleTypesSource([]));
|
|
547
|
+
console.log(
|
|
548
|
+
`[rsc-router] Generated route types (placeholder) -> ${genPath}`
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
522
553
|
const genSource = generatePerModuleTypesSource(routes);
|
|
523
554
|
const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
|
|
524
555
|
if (existing !== genSource) {
|
|
@@ -546,6 +577,17 @@ var init_per_module_writer = __esm({
|
|
|
546
577
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, unlinkSync } from "node:fs";
|
|
547
578
|
import { join as join2, dirname as dirname2, resolve as resolve2, basename as pathBasename } from "node:path";
|
|
548
579
|
import ts5 from "typescript";
|
|
580
|
+
function countPublicRouteEntries(source) {
|
|
581
|
+
const matches = source.matchAll(/^\s+(?:"([^"]+)"|([a-zA-Z_$][^:]*)):\s*["{]/gm) ?? [];
|
|
582
|
+
let count = 0;
|
|
583
|
+
for (const match of matches) {
|
|
584
|
+
const routeName = match[1] || match[2];
|
|
585
|
+
if (routeName && !isAutoGeneratedRouteName(routeName.trim())) {
|
|
586
|
+
count++;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return count;
|
|
590
|
+
}
|
|
549
591
|
function extractUrlsVariableFromRouter(code) {
|
|
550
592
|
const sourceFile = ts5.createSourceFile(
|
|
551
593
|
"router.tsx",
|
|
@@ -652,6 +694,22 @@ function detectUnresolvableIncludes(routerFilePath) {
|
|
|
652
694
|
);
|
|
653
695
|
return diagnostics;
|
|
654
696
|
}
|
|
697
|
+
function detectUnresolvableIncludesForUrlsFile(filePath) {
|
|
698
|
+
const realPath = resolve2(filePath);
|
|
699
|
+
let source;
|
|
700
|
+
try {
|
|
701
|
+
source = readFileSync3(realPath, "utf-8");
|
|
702
|
+
} catch {
|
|
703
|
+
return [];
|
|
704
|
+
}
|
|
705
|
+
const varNames = findUrlsVariableNames(source);
|
|
706
|
+
if (varNames.length === 0) return [];
|
|
707
|
+
const diagnostics = [];
|
|
708
|
+
for (const varName of varNames) {
|
|
709
|
+
buildCombinedRouteMapWithSearch(realPath, varName, /* @__PURE__ */ new Set(), diagnostics);
|
|
710
|
+
}
|
|
711
|
+
return diagnostics;
|
|
712
|
+
}
|
|
655
713
|
function findRouterFiles(root, filter) {
|
|
656
714
|
const files = findTsFiles(root, filter);
|
|
657
715
|
const result = [];
|
|
@@ -725,8 +783,10 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
725
783
|
);
|
|
726
784
|
if (existing !== source) {
|
|
727
785
|
if (opts?.preserveIfLarger && existing) {
|
|
728
|
-
const existingCount = (existing
|
|
729
|
-
const newCount = Object.keys(result.routes).
|
|
786
|
+
const existingCount = countPublicRouteEntries(existing);
|
|
787
|
+
const newCount = Object.keys(result.routes).filter(
|
|
788
|
+
(name) => !isAutoGeneratedRouteName(name)
|
|
789
|
+
).length;
|
|
730
790
|
if (existingCount > newCount) {
|
|
731
791
|
continue;
|
|
732
792
|
}
|
|
@@ -744,6 +804,8 @@ var init_router_processing = __esm({
|
|
|
744
804
|
init_codegen();
|
|
745
805
|
init_scan_filter();
|
|
746
806
|
init_include_resolution();
|
|
807
|
+
init_per_module_writer();
|
|
808
|
+
init_route_name();
|
|
747
809
|
}
|
|
748
810
|
});
|
|
749
811
|
|
|
@@ -758,6 +820,7 @@ var init_generate_route_types = __esm({
|
|
|
758
820
|
init_per_module_writer();
|
|
759
821
|
init_include_resolution();
|
|
760
822
|
init_router_processing();
|
|
823
|
+
init_per_module_writer();
|
|
761
824
|
}
|
|
762
825
|
});
|
|
763
826
|
|
|
@@ -1139,7 +1202,13 @@ async function discoverAndWriteRouteTypes(opts) {
|
|
|
1139
1202
|
if (!router.urlpatterns) continue;
|
|
1140
1203
|
const manifest = generateManifest(router.urlpatterns, routerMountIndex);
|
|
1141
1204
|
routerMountIndex++;
|
|
1142
|
-
const
|
|
1205
|
+
const rawManifest = manifest.routeManifest;
|
|
1206
|
+
const routeManifest = {};
|
|
1207
|
+
for (const [name, pattern] of Object.entries(rawManifest)) {
|
|
1208
|
+
if (!isAutoGeneratedRouteName(name)) {
|
|
1209
|
+
routeManifest[name] = pattern;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1143
1212
|
let routeSearchSchemas = manifest.routeSearchSchemas;
|
|
1144
1213
|
const sourceFile = router.__sourceFile;
|
|
1145
1214
|
if (!sourceFile) {
|
|
@@ -1201,6 +1270,7 @@ var init_runtime_discovery = __esm({
|
|
|
1201
1270
|
"src/build/runtime-discovery.ts"() {
|
|
1202
1271
|
"use strict";
|
|
1203
1272
|
init_generate_route_types();
|
|
1273
|
+
init_route_name();
|
|
1204
1274
|
}
|
|
1205
1275
|
});
|
|
1206
1276
|
|
|
@@ -1305,16 +1375,15 @@ function runStaticGeneration(args, mode) {
|
|
|
1305
1375
|
process.exit(0);
|
|
1306
1376
|
}
|
|
1307
1377
|
const routerFiles = [];
|
|
1378
|
+
const urlsFiles = [];
|
|
1308
1379
|
for (const filePath of files) {
|
|
1309
1380
|
try {
|
|
1310
1381
|
const source = readFileSync5(filePath, "utf-8");
|
|
1311
|
-
|
|
1312
|
-
const isUrls = source.includes("urls(");
|
|
1313
|
-
if (isRouter) {
|
|
1382
|
+
if (/\bcreateRouter\s*[<(]/.test(source)) {
|
|
1314
1383
|
routerFiles.push(filePath);
|
|
1315
1384
|
}
|
|
1316
|
-
if (
|
|
1317
|
-
|
|
1385
|
+
if (source.includes("urls(")) {
|
|
1386
|
+
urlsFiles.push(filePath);
|
|
1318
1387
|
}
|
|
1319
1388
|
} catch (err) {
|
|
1320
1389
|
console.warn(
|
|
@@ -1329,21 +1398,39 @@ function runStaticGeneration(args, mode) {
|
|
|
1329
1398
|
allDiagnostics.push({ ...d, routerFile });
|
|
1330
1399
|
}
|
|
1331
1400
|
}
|
|
1332
|
-
|
|
1401
|
+
const routerFileSet = new Set(routerFiles);
|
|
1402
|
+
for (const urlsFile of urlsFiles) {
|
|
1403
|
+
if (routerFileSet.has(urlsFile)) continue;
|
|
1404
|
+
const diagnostics = detectUnresolvableIncludesForUrlsFile(urlsFile);
|
|
1405
|
+
for (const d of diagnostics) {
|
|
1406
|
+
allDiagnostics.push({ ...d, routerFile: urlsFile });
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1410
|
+
const uniqueDiagnostics = allDiagnostics.filter((d) => {
|
|
1411
|
+
const key = `${d.sourceFile}:${d.pathPrefix}:${d.reason}`;
|
|
1412
|
+
if (seen.has(key)) return false;
|
|
1413
|
+
seen.add(key);
|
|
1414
|
+
return true;
|
|
1415
|
+
});
|
|
1416
|
+
if (uniqueDiagnostics.length > 0 && mode === "default") {
|
|
1333
1417
|
console.error("\n[rango] Unresolvable includes detected:\n");
|
|
1334
|
-
formatDiagnostics(
|
|
1418
|
+
formatDiagnostics(uniqueDiagnostics);
|
|
1335
1419
|
console.error(
|
|
1336
1420
|
"\nThe static parser cannot resolve these includes because they use factory functions or dynamic expressions.\n\nOptions:\n rango generate <path> --runtime Use Vite-based discovery (requires vite)\n rango generate <path> --static Accept partial output (missing routes above)\n"
|
|
1337
1421
|
);
|
|
1338
1422
|
process.exit(1);
|
|
1339
1423
|
}
|
|
1340
|
-
if (
|
|
1424
|
+
if (uniqueDiagnostics.length > 0 && mode === "static") {
|
|
1341
1425
|
console.warn(
|
|
1342
1426
|
"\n[rango] Warning: partial output (unresolvable includes):\n"
|
|
1343
1427
|
);
|
|
1344
|
-
formatDiagnostics(
|
|
1428
|
+
formatDiagnostics(uniqueDiagnostics);
|
|
1345
1429
|
console.warn("");
|
|
1346
1430
|
}
|
|
1431
|
+
for (const urlsFile of urlsFiles) {
|
|
1432
|
+
writePerModuleRouteTypesForFile(urlsFile);
|
|
1433
|
+
}
|
|
1347
1434
|
for (const routerFile of routerFiles) {
|
|
1348
1435
|
const projectRoot = findProjectRoot(routerFile);
|
|
1349
1436
|
writeCombinedRouteTypes(projectRoot, [routerFile]);
|
|
@@ -1398,8 +1485,8 @@ async function runRuntimeDiscovery(args, configFile) {
|
|
|
1398
1485
|
}
|
|
1399
1486
|
process.exit(1);
|
|
1400
1487
|
}
|
|
1401
|
-
const projectRoot = findProjectRoot(routerEntries[0]);
|
|
1402
1488
|
for (const entry of routerEntries) {
|
|
1489
|
+
const projectRoot = findProjectRoot(entry);
|
|
1403
1490
|
const result = await discoverAndWriteRouteTypes2({
|
|
1404
1491
|
root: projectRoot,
|
|
1405
1492
|
configFile,
|