@rangojs/router 0.0.0-experimental.57 → 0.0.0-experimental.57005a2b
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 +76 -18
- package/dist/bin/rango.js +2 -1
- package/dist/vite/index.js +507 -192
- package/dist/vite/index.js.bak +5448 -0
- package/package.json +3 -3
- package/skills/handler-use/SKILL.md +362 -0
- package/skills/intercept/SKILL.md +20 -0
- package/skills/layout/SKILL.md +22 -0
- package/skills/middleware/SKILL.md +32 -3
- package/skills/migrate-nextjs/SKILL.md +560 -0
- package/skills/migrate-react-router/SKILL.md +764 -0
- package/skills/parallel/SKILL.md +59 -0
- package/skills/prerender/SKILL.md +110 -68
- package/skills/rango/SKILL.md +24 -22
- package/skills/route/SKILL.md +24 -0
- package/src/__internal.ts +1 -1
- package/src/browser/navigation-bridge.ts +21 -2
- package/src/browser/navigation-client.ts +34 -6
- package/src/browser/partial-update.ts +14 -2
- package/src/browser/prefetch/cache.ts +16 -6
- package/src/browser/prefetch/fetch.ts +60 -4
- package/src/browser/react/Link.tsx +25 -2
- package/src/browser/react/use-handle.ts +9 -58
- package/src/browser/scroll-restoration.ts +10 -8
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/build/generate-manifest.ts +3 -6
- package/src/build/route-trie.ts +50 -24
- package/src/build/route-types/scan-filter.ts +8 -1
- package/src/client.tsx +84 -230
- package/src/handle.ts +40 -0
- package/src/index.rsc.ts +3 -1
- package/src/index.ts +46 -6
- package/src/prerender/store.ts +5 -4
- package/src/prerender.ts +138 -77
- package/src/reverse.ts +25 -1
- package/src/route-definition/dsl-helpers.ts +194 -32
- package/src/route-definition/helpers-types.ts +61 -14
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/resolve-handler-use.ts +149 -0
- package/src/route-types.ts +18 -0
- package/src/router/content-negotiation.ts +100 -1
- package/src/router/handler-context.ts +46 -6
- package/src/router/lazy-includes.ts +5 -5
- package/src/router/loader-resolution.ts +147 -19
- package/src/router/manifest.ts +12 -7
- package/src/router/match-api.ts +124 -189
- package/src/router/match-middleware/cache-lookup.ts +24 -7
- package/src/router/match-middleware/segment-resolution.ts +53 -0
- package/src/router/match-result.ts +82 -4
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/prerender-match.ts +108 -8
- package/src/router/preview-match.ts +30 -102
- package/src/router/request-classification.ts +310 -0
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-interfaces.ts +11 -0
- package/src/router/segment-resolution/fresh.ts +59 -2
- package/src/router/segment-resolution/revalidation.ts +79 -6
- package/src/router.ts +13 -1
- package/src/rsc/handler.ts +468 -377
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/progressive-enhancement.ts +10 -2
- package/src/rsc/rsc-rendering.ts +5 -1
- package/src/rsc/server-action.ts +6 -0
- package/src/rsc/ssr-setup.ts +1 -1
- package/src/rsc/types.ts +1 -0
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +11 -61
- package/src/server/context.ts +40 -4
- package/src/server/handle-store.ts +19 -0
- package/src/server/request-context.ts +125 -3
- package/src/static-handler.ts +18 -6
- package/src/types/handler-context.ts +12 -2
- package/src/types/loader-types.ts +32 -4
- package/src/types/route-entry.ts +12 -1
- package/src/types/segments.ts +1 -1
- package/src/urls/include-helper.ts +24 -14
- package/src/urls/path-helper-types.ts +39 -6
- package/src/urls/path-helper.ts +47 -12
- package/src/urls/response-types.ts +16 -6
- package/src/use-loader.tsx +77 -5
- package/src/vite/discovery/bundle-postprocess.ts +30 -33
- package/src/vite/discovery/prerender-collection.ts +128 -74
- package/src/vite/discovery/state.ts +13 -4
- package/src/vite/index.ts +4 -0
- package/src/vite/plugin-types.ts +60 -5
- package/src/vite/plugins/expose-id-utils.ts +12 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
- package/src/vite/plugins/expose-internal-ids.ts +257 -40
- package/src/vite/plugins/refresh-cmd.ts +88 -26
- package/src/vite/rango.ts +2 -1
- package/src/vite/router-discovery.ts +178 -37
- package/src/vite/utils/prerender-utils.ts +37 -5
package/README.md
CHANGED
|
@@ -91,24 +91,29 @@ This file is a server/RSC module and should import router construction APIs from
|
|
|
91
91
|
|
|
92
92
|
```tsx
|
|
93
93
|
// src/router.tsx
|
|
94
|
-
import { createRouter
|
|
95
|
-
import { Document } from "./document";
|
|
94
|
+
import { createRouter } from "@rangojs/router";
|
|
96
95
|
|
|
97
|
-
const
|
|
98
|
-
path("/",
|
|
99
|
-
path("
|
|
96
|
+
export const router = createRouter().routes(({ path }) => [
|
|
97
|
+
path("/", HomePage, { name: "home" }),
|
|
98
|
+
path("/about", AboutPage, { name: "about" }),
|
|
100
99
|
]);
|
|
101
100
|
|
|
101
|
+
export const reverse = router.reverse;
|
|
102
|
+
// reverse("home") -> "/"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For larger apps, extract route modules with `urls()` and compose with `include()`:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { createRouter, urls } from "@rangojs/router";
|
|
109
|
+
import { blogPatterns } from "./urls/blog";
|
|
110
|
+
|
|
102
111
|
const urlpatterns = urls(({ path, include }) => [
|
|
103
112
|
path("/", HomePage, { name: "home" }),
|
|
104
113
|
include("/blog", blogPatterns, { name: "blog" }),
|
|
105
114
|
]);
|
|
106
115
|
|
|
107
|
-
export const router = createRouter(
|
|
108
|
-
|
|
109
|
-
// Export typed reverse function for URL generation by route name
|
|
110
|
-
export const reverse = router.reverse;
|
|
111
|
-
|
|
116
|
+
export const router = createRouter().routes(urlpatterns);
|
|
112
117
|
// reverse("blog.post", { slug: "hello-world" }) -> "/blog/hello-world"
|
|
113
118
|
```
|
|
114
119
|
|
|
@@ -711,10 +716,12 @@ export const BlogPost = Prerender(
|
|
|
711
716
|
|
|
712
717
|
### Passthrough for Unknown Params
|
|
713
718
|
|
|
719
|
+
Wrap a `Prerender` definition with `Passthrough()` to add a live handler for unknown params at runtime. The build handler runs at build time, the live handler runs at request time for params not in the prerender cache.
|
|
720
|
+
|
|
714
721
|
```tsx
|
|
715
|
-
import { Prerender } from "@rangojs/router";
|
|
722
|
+
import { Prerender, Passthrough } from "@rangojs/router";
|
|
716
723
|
|
|
717
|
-
export const
|
|
724
|
+
export const ProductPageDef = Prerender(
|
|
718
725
|
async () => {
|
|
719
726
|
const featured = await db.getFeaturedProducts();
|
|
720
727
|
return featured.map((p) => ({ id: p.id }));
|
|
@@ -723,16 +730,22 @@ export const ProductPage = Prerender(
|
|
|
723
730
|
const product = await db.getProduct(ctx.params.id);
|
|
724
731
|
return <Product data={product} />;
|
|
725
732
|
},
|
|
726
|
-
{ passthrough: true },
|
|
727
733
|
);
|
|
728
|
-
```
|
|
729
734
|
|
|
730
|
-
|
|
735
|
+
// In route definition:
|
|
736
|
+
path(
|
|
737
|
+
"/products/:id",
|
|
738
|
+
Passthrough(ProductPageDef, async (ctx) => {
|
|
739
|
+
const product = await ctx.env.DB.getProduct(ctx.params.id);
|
|
740
|
+
return <Product data={product} />;
|
|
741
|
+
}),
|
|
742
|
+
);
|
|
743
|
+
```
|
|
731
744
|
|
|
732
|
-
|
|
745
|
+
Build handlers can also skip individual param sets with `ctx.passthrough()`, deferring them to the live handler:
|
|
733
746
|
|
|
734
747
|
```tsx
|
|
735
|
-
export const
|
|
748
|
+
export const ProductPageDef = Prerender(
|
|
736
749
|
async () => {
|
|
737
750
|
const all = await db.getAllProducts();
|
|
738
751
|
return all.map((p) => ({ id: p.id }));
|
|
@@ -742,10 +755,55 @@ export const ProductPage = Prerender(
|
|
|
742
755
|
if (!product.published) return ctx.passthrough();
|
|
743
756
|
return <Product data={product} />;
|
|
744
757
|
},
|
|
745
|
-
{ passthrough: true },
|
|
746
758
|
);
|
|
747
759
|
```
|
|
748
760
|
|
|
761
|
+
### Build-Time Environment Bindings
|
|
762
|
+
|
|
763
|
+
Prerender handlers can access platform bindings (KV, D1, R2) at build time when `buildEnv` is configured in the Vite plugin:
|
|
764
|
+
|
|
765
|
+
```ts
|
|
766
|
+
// vite.config.ts
|
|
767
|
+
import { rango } from "@rangojs/router/vite";
|
|
768
|
+
|
|
769
|
+
rango({ preset: "cloudflare", buildEnv: "auto" });
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
With `buildEnv: "auto"`, the plugin calls `wrangler.getPlatformProxy()` to provide local bindings. Handlers then access `ctx.env` during build:
|
|
773
|
+
|
|
774
|
+
```tsx
|
|
775
|
+
export const BlogPosts = Prerender<{ slug: string }>(
|
|
776
|
+
async (ctx) => {
|
|
777
|
+
const rows = await ctx.env.DB.prepare("SELECT slug FROM posts").all();
|
|
778
|
+
return rows.map((r) => ({ slug: r.slug }));
|
|
779
|
+
},
|
|
780
|
+
async (ctx) => {
|
|
781
|
+
const post = await ctx.env.DB.prepare("SELECT * FROM posts WHERE slug = ?")
|
|
782
|
+
.bind(ctx.params.slug)
|
|
783
|
+
.first();
|
|
784
|
+
return <BlogPost post={post} />;
|
|
785
|
+
},
|
|
786
|
+
);
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
`buildEnv` also accepts a factory function or plain object:
|
|
790
|
+
|
|
791
|
+
```ts
|
|
792
|
+
// Custom factory
|
|
793
|
+
rango({
|
|
794
|
+
buildEnv: async (ctx) => {
|
|
795
|
+
const { getPlatformProxy } = await import("wrangler");
|
|
796
|
+
const proxy = await getPlatformProxy();
|
|
797
|
+
return { env: proxy.env, dispose: proxy.dispose };
|
|
798
|
+
},
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
// Plain object (Node.js)
|
|
802
|
+
rango({ buildEnv: { DATABASE_URL: process.env.DATABASE_URL } });
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
Build-time env applies to both production builds and dev on-demand prerender. Without `buildEnv`, accessing `ctx.env` in a Prerender handler throws with a clear error.
|
|
806
|
+
|
|
749
807
|
## Theme
|
|
750
808
|
|
|
751
809
|
### Router Configuration
|
package/dist/bin/rango.js
CHANGED
|
@@ -218,7 +218,8 @@ function findTsFiles(dir, filter) {
|
|
|
218
218
|
for (const entry of entries) {
|
|
219
219
|
const fullPath = join(dir, entry.name);
|
|
220
220
|
if (entry.isDirectory()) {
|
|
221
|
-
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
221
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".") || entry.name === "dist" || entry.name === "build" || entry.name === "coverage")
|
|
222
|
+
continue;
|
|
222
223
|
results.push(...findTsFiles(fullPath, filter));
|
|
223
224
|
} else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".tsx") || entry.name.endsWith(".js") || entry.name.endsWith(".jsx")) && !entry.name.includes(".gen.")) {
|
|
224
225
|
if (filter && !filter(fullPath)) continue;
|