@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.
Files changed (93) hide show
  1. package/README.md +76 -18
  2. package/dist/bin/rango.js +2 -1
  3. package/dist/vite/index.js +507 -192
  4. package/dist/vite/index.js.bak +5448 -0
  5. package/package.json +3 -3
  6. package/skills/handler-use/SKILL.md +362 -0
  7. package/skills/intercept/SKILL.md +20 -0
  8. package/skills/layout/SKILL.md +22 -0
  9. package/skills/middleware/SKILL.md +32 -3
  10. package/skills/migrate-nextjs/SKILL.md +560 -0
  11. package/skills/migrate-react-router/SKILL.md +764 -0
  12. package/skills/parallel/SKILL.md +59 -0
  13. package/skills/prerender/SKILL.md +110 -68
  14. package/skills/rango/SKILL.md +24 -22
  15. package/skills/route/SKILL.md +24 -0
  16. package/src/__internal.ts +1 -1
  17. package/src/browser/navigation-bridge.ts +21 -2
  18. package/src/browser/navigation-client.ts +34 -6
  19. package/src/browser/partial-update.ts +14 -2
  20. package/src/browser/prefetch/cache.ts +16 -6
  21. package/src/browser/prefetch/fetch.ts +60 -4
  22. package/src/browser/react/Link.tsx +25 -2
  23. package/src/browser/react/use-handle.ts +9 -58
  24. package/src/browser/scroll-restoration.ts +10 -8
  25. package/src/browser/segment-reconciler.ts +36 -14
  26. package/src/build/generate-manifest.ts +3 -6
  27. package/src/build/route-trie.ts +50 -24
  28. package/src/build/route-types/scan-filter.ts +8 -1
  29. package/src/client.tsx +84 -230
  30. package/src/handle.ts +40 -0
  31. package/src/index.rsc.ts +3 -1
  32. package/src/index.ts +46 -6
  33. package/src/prerender/store.ts +5 -4
  34. package/src/prerender.ts +138 -77
  35. package/src/reverse.ts +25 -1
  36. package/src/route-definition/dsl-helpers.ts +194 -32
  37. package/src/route-definition/helpers-types.ts +61 -14
  38. package/src/route-definition/index.ts +3 -0
  39. package/src/route-definition/resolve-handler-use.ts +149 -0
  40. package/src/route-types.ts +18 -0
  41. package/src/router/content-negotiation.ts +100 -1
  42. package/src/router/handler-context.ts +46 -6
  43. package/src/router/lazy-includes.ts +5 -5
  44. package/src/router/loader-resolution.ts +147 -19
  45. package/src/router/manifest.ts +12 -7
  46. package/src/router/match-api.ts +124 -189
  47. package/src/router/match-middleware/cache-lookup.ts +24 -7
  48. package/src/router/match-middleware/segment-resolution.ts +53 -0
  49. package/src/router/match-result.ts +82 -4
  50. package/src/router/navigation-snapshot.ts +182 -0
  51. package/src/router/prerender-match.ts +108 -8
  52. package/src/router/preview-match.ts +30 -102
  53. package/src/router/request-classification.ts +310 -0
  54. package/src/router/route-snapshot.ts +245 -0
  55. package/src/router/router-interfaces.ts +11 -0
  56. package/src/router/segment-resolution/fresh.ts +59 -2
  57. package/src/router/segment-resolution/revalidation.ts +79 -6
  58. package/src/router.ts +13 -1
  59. package/src/rsc/handler.ts +468 -377
  60. package/src/rsc/loader-fetch.ts +23 -3
  61. package/src/rsc/progressive-enhancement.ts +10 -2
  62. package/src/rsc/rsc-rendering.ts +5 -1
  63. package/src/rsc/server-action.ts +6 -0
  64. package/src/rsc/ssr-setup.ts +1 -1
  65. package/src/rsc/types.ts +1 -0
  66. package/src/segment-content-promise.ts +67 -0
  67. package/src/segment-loader-promise.ts +122 -0
  68. package/src/segment-system.tsx +11 -61
  69. package/src/server/context.ts +40 -4
  70. package/src/server/handle-store.ts +19 -0
  71. package/src/server/request-context.ts +125 -3
  72. package/src/static-handler.ts +18 -6
  73. package/src/types/handler-context.ts +12 -2
  74. package/src/types/loader-types.ts +32 -4
  75. package/src/types/route-entry.ts +12 -1
  76. package/src/types/segments.ts +1 -1
  77. package/src/urls/include-helper.ts +24 -14
  78. package/src/urls/path-helper-types.ts +39 -6
  79. package/src/urls/path-helper.ts +47 -12
  80. package/src/urls/response-types.ts +16 -6
  81. package/src/use-loader.tsx +77 -5
  82. package/src/vite/discovery/bundle-postprocess.ts +30 -33
  83. package/src/vite/discovery/prerender-collection.ts +128 -74
  84. package/src/vite/discovery/state.ts +13 -4
  85. package/src/vite/index.ts +4 -0
  86. package/src/vite/plugin-types.ts +60 -5
  87. package/src/vite/plugins/expose-id-utils.ts +12 -0
  88. package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
  89. package/src/vite/plugins/expose-internal-ids.ts +257 -40
  90. package/src/vite/plugins/refresh-cmd.ts +88 -26
  91. package/src/vite/rango.ts +2 -1
  92. package/src/vite/router-discovery.ts +178 -37
  93. 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, urls } from "@rangojs/router";
95
- import { Document } from "./document";
94
+ import { createRouter } from "@rangojs/router";
96
95
 
97
- const blogPatterns = urls(({ path }) => [
98
- path("/", BlogIndexPage, { name: "index" }),
99
- path("/:slug", BlogPostPage, { name: "post" }),
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({ document: Document }).routes(urlpatterns);
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 ProductPage = Prerender(
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
- With `passthrough: true`, known params are served from the build-time cache and unknown params fall through to live rendering.
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
- Handlers can also skip individual param sets with `ctx.passthrough()`, deferring them to the live handler at runtime:
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 ProductPage = Prerender(
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(".")) continue;
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;