@rangojs/router 0.0.0-experimental.49 → 0.0.0-experimental.4fba1c4c

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 (272) hide show
  1. package/README.md +196 -43
  2. package/dist/bin/rango.js +269 -96
  3. package/dist/testing/vitest.js +48 -0
  4. package/dist/vite/index.js +2659 -883
  5. package/dist/vite/index.js.bak +5448 -0
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +57 -11
  8. package/skills/breadcrumbs/SKILL.md +3 -1
  9. package/skills/bundle-analysis/SKILL.md +159 -0
  10. package/skills/cache-guide/SKILL.md +243 -21
  11. package/skills/caching/SKILL.md +118 -2
  12. package/skills/composability/SKILL.md +27 -2
  13. package/skills/document-cache/SKILL.md +78 -55
  14. package/skills/handler-use/SKILL.md +364 -0
  15. package/skills/hooks/SKILL.md +229 -20
  16. package/skills/host-router/SKILL.md +45 -20
  17. package/skills/i18n/SKILL.md +276 -0
  18. package/skills/intercept/SKILL.md +46 -4
  19. package/skills/layout/SKILL.md +28 -7
  20. package/skills/links/SKILL.md +249 -17
  21. package/skills/loader/SKILL.md +273 -53
  22. package/skills/middleware/SKILL.md +49 -12
  23. package/skills/migrate-nextjs/SKILL.md +562 -0
  24. package/skills/migrate-react-router/SKILL.md +769 -0
  25. package/skills/mime-routes/SKILL.md +27 -0
  26. package/skills/observability/SKILL.md +137 -0
  27. package/skills/parallel/SKILL.md +71 -6
  28. package/skills/prerender/SKILL.md +123 -100
  29. package/skills/rango/SKILL.md +242 -22
  30. package/skills/react-compiler/SKILL.md +168 -0
  31. package/skills/response-routes/SKILL.md +66 -9
  32. package/skills/route/SKILL.md +88 -4
  33. package/skills/router-setup/SKILL.md +90 -5
  34. package/skills/server-actions/SKILL.md +751 -0
  35. package/skills/streams-and-websockets/SKILL.md +283 -0
  36. package/skills/testing/SKILL.md +734 -0
  37. package/skills/typesafety/SKILL.md +329 -27
  38. package/skills/use-cache/SKILL.md +34 -5
  39. package/skills/view-transitions/SKILL.md +294 -0
  40. package/src/__augment-tests__/augment.ts +81 -0
  41. package/src/__augment-tests__/augmented.check.ts +117 -0
  42. package/src/__internal.ts +1 -1
  43. package/src/browser/action-coordinator.ts +53 -36
  44. package/src/browser/app-shell.ts +52 -0
  45. package/src/browser/app-version.ts +14 -0
  46. package/src/browser/event-controller.ts +86 -70
  47. package/src/browser/history-state.ts +21 -0
  48. package/src/browser/index.ts +3 -3
  49. package/src/browser/navigation-bridge.ts +101 -13
  50. package/src/browser/navigation-client.ts +125 -53
  51. package/src/browser/navigation-store.ts +75 -17
  52. package/src/browser/navigation-transaction.ts +10 -28
  53. package/src/browser/partial-update.ts +90 -30
  54. package/src/browser/prefetch/cache.ts +129 -21
  55. package/src/browser/prefetch/fetch.ts +156 -18
  56. package/src/browser/prefetch/queue.ts +92 -29
  57. package/src/browser/prefetch/resource-ready.ts +77 -0
  58. package/src/browser/rango-state.ts +53 -13
  59. package/src/browser/react/Link.tsx +72 -8
  60. package/src/browser/react/NavigationProvider.tsx +83 -33
  61. package/src/browser/react/context.ts +7 -2
  62. package/src/browser/react/filter-segment-order.ts +51 -7
  63. package/src/browser/react/index.ts +3 -0
  64. package/src/browser/react/location-state-shared.ts +175 -4
  65. package/src/browser/react/location-state.ts +39 -13
  66. package/src/browser/react/use-handle.ts +23 -64
  67. package/src/browser/react/use-navigation.ts +22 -2
  68. package/src/browser/react/use-params.ts +20 -8
  69. package/src/browser/react/use-reverse.ts +106 -0
  70. package/src/browser/react/use-router.ts +43 -10
  71. package/src/browser/react/use-segments.ts +11 -8
  72. package/src/browser/response-adapter.ts +25 -0
  73. package/src/browser/rsc-router.tsx +87 -22
  74. package/src/browser/scroll-restoration.ts +29 -19
  75. package/src/browser/segment-reconciler.ts +36 -14
  76. package/src/browser/segment-structure-assert.ts +2 -2
  77. package/src/browser/server-action-bridge.ts +31 -36
  78. package/src/browser/types.ts +48 -5
  79. package/src/build/collect-fallback-refs.ts +107 -0
  80. package/src/build/generate-manifest.ts +65 -40
  81. package/src/build/generate-route-types.ts +5 -0
  82. package/src/build/index.ts +2 -0
  83. package/src/build/route-trie.ts +52 -25
  84. package/src/build/route-types/codegen.ts +4 -4
  85. package/src/build/route-types/include-resolution.ts +9 -2
  86. package/src/build/route-types/per-module-writer.ts +7 -4
  87. package/src/build/route-types/router-processing.ts +266 -86
  88. package/src/build/route-types/scan-filter.ts +9 -2
  89. package/src/build/route-types/source-scan.ts +118 -0
  90. package/src/build/runtime-discovery.ts +9 -20
  91. package/src/cache/cache-scope.ts +74 -47
  92. package/src/cache/cf/cf-cache-store.ts +54 -13
  93. package/src/cache/taint.ts +55 -0
  94. package/src/client.rsc.tsx +3 -0
  95. package/src/client.tsx +94 -238
  96. package/src/context-var.ts +72 -2
  97. package/src/decode-loader-results.ts +36 -0
  98. package/src/errors.ts +30 -1
  99. package/src/handle.ts +65 -12
  100. package/src/host/index.ts +2 -2
  101. package/src/host/router.ts +129 -57
  102. package/src/host/types.ts +31 -2
  103. package/src/host/utils.ts +1 -1
  104. package/src/href-client.ts +140 -20
  105. package/src/index.rsc.ts +12 -5
  106. package/src/index.ts +61 -11
  107. package/src/loader-store.ts +500 -0
  108. package/src/loader.rsc.ts +21 -6
  109. package/src/loader.ts +3 -10
  110. package/src/missing-id-error.ts +68 -0
  111. package/src/outlet-context.ts +1 -1
  112. package/src/prerender/store.ts +5 -4
  113. package/src/prerender.ts +141 -80
  114. package/src/response-utils.ts +37 -0
  115. package/src/reverse.ts +65 -15
  116. package/src/route-content-wrapper.tsx +6 -28
  117. package/src/route-definition/dsl-helpers.ts +411 -261
  118. package/src/route-definition/helper-factories.ts +29 -139
  119. package/src/route-definition/helpers-types.ts +110 -34
  120. package/src/route-definition/index.ts +3 -0
  121. package/src/route-definition/redirect.ts +9 -1
  122. package/src/route-definition/resolve-handler-use.ts +155 -0
  123. package/src/route-definition/use-item-types.ts +32 -0
  124. package/src/route-types.ts +37 -41
  125. package/src/router/basename.ts +14 -0
  126. package/src/router/content-negotiation.ts +113 -1
  127. package/src/router/error-handling.ts +1 -1
  128. package/src/router/handler-context.ts +77 -38
  129. package/src/router/intercept-resolution.ts +13 -22
  130. package/src/router/lazy-includes.ts +8 -8
  131. package/src/router/loader-resolution.ts +174 -22
  132. package/src/router/manifest.ts +22 -13
  133. package/src/router/match-api.ts +128 -192
  134. package/src/router/match-handlers.ts +63 -20
  135. package/src/router/match-middleware/cache-lookup.ts +70 -97
  136. package/src/router/match-middleware/cache-store.ts +8 -2
  137. package/src/router/match-middleware/segment-resolution.ts +53 -0
  138. package/src/router/match-result.ts +103 -4
  139. package/src/router/metrics.ts +1 -1
  140. package/src/router/middleware-types.ts +21 -34
  141. package/src/router/middleware.ts +101 -89
  142. package/src/router/navigation-snapshot.ts +182 -0
  143. package/src/router/pattern-matching.ts +101 -17
  144. package/src/router/prerender-match.ts +110 -10
  145. package/src/router/preview-match.ts +32 -102
  146. package/src/router/request-classification.ts +286 -0
  147. package/src/router/revalidation.ts +58 -2
  148. package/src/router/route-snapshot.ts +245 -0
  149. package/src/router/router-interfaces.ts +77 -28
  150. package/src/router/router-options.ts +76 -11
  151. package/src/router/router-registry.ts +2 -5
  152. package/src/router/segment-resolution/fresh.ts +105 -13
  153. package/src/router/segment-resolution/helpers.ts +29 -24
  154. package/src/router/segment-resolution/revalidation.ts +236 -112
  155. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  156. package/src/router/substitute-pattern-params.ts +56 -0
  157. package/src/router/telemetry.ts +99 -0
  158. package/src/router/trie-matching.ts +18 -13
  159. package/src/router/types.ts +9 -0
  160. package/src/router/url-params.ts +49 -0
  161. package/src/router.ts +86 -22
  162. package/src/rsc/handler-context.ts +2 -2
  163. package/src/rsc/handler.ts +440 -381
  164. package/src/rsc/helpers.ts +91 -43
  165. package/src/rsc/index.ts +1 -1
  166. package/src/rsc/loader-fetch.ts +23 -3
  167. package/src/rsc/manifest-init.ts +5 -1
  168. package/src/rsc/origin-guard.ts +28 -10
  169. package/src/rsc/progressive-enhancement.ts +18 -2
  170. package/src/rsc/response-route-handler.ts +46 -53
  171. package/src/rsc/rsc-rendering.ts +41 -48
  172. package/src/rsc/runtime-warnings.ts +9 -10
  173. package/src/rsc/server-action.ts +25 -37
  174. package/src/rsc/ssr-setup.ts +18 -2
  175. package/src/rsc/types.ts +17 -3
  176. package/src/search-params.ts +4 -4
  177. package/src/segment-content-promise.ts +67 -0
  178. package/src/segment-loader-promise.ts +122 -0
  179. package/src/segment-system.tsx +132 -116
  180. package/src/serialize.ts +243 -0
  181. package/src/server/context.ts +190 -51
  182. package/src/server/cookie-store.ts +28 -4
  183. package/src/server/handle-store.ts +19 -0
  184. package/src/server/loader-registry.ts +9 -8
  185. package/src/server/request-context.ts +195 -57
  186. package/src/ssr/index.tsx +8 -1
  187. package/src/static-handler.ts +19 -7
  188. package/src/testing/cache-status.ts +166 -0
  189. package/src/testing/collect-handle.ts +63 -0
  190. package/src/testing/dispatch.ts +440 -0
  191. package/src/testing/dom.entry.ts +22 -0
  192. package/src/testing/e2e/fixture.ts +154 -0
  193. package/src/testing/e2e/index.ts +149 -0
  194. package/src/testing/e2e/matchers.ts +51 -0
  195. package/src/testing/e2e/page-helpers.ts +272 -0
  196. package/src/testing/e2e/parity.ts +306 -0
  197. package/src/testing/e2e/server.ts +183 -0
  198. package/src/testing/flight-matchers.ts +104 -0
  199. package/src/testing/flight-runtime.d.ts +21 -0
  200. package/src/testing/flight.entry.ts +22 -0
  201. package/src/testing/flight.ts +182 -0
  202. package/src/testing/generated-routes.ts +223 -0
  203. package/src/testing/index.ts +106 -0
  204. package/src/testing/internal/context.ts +304 -0
  205. package/src/testing/render-route.tsx +565 -0
  206. package/src/testing/run-loader.ts +341 -0
  207. package/src/testing/run-middleware.ts +179 -0
  208. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  209. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  210. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  211. package/src/testing/vitest-stubs/version.ts +5 -0
  212. package/src/testing/vitest.ts +183 -0
  213. package/src/types/cache-types.ts +4 -4
  214. package/src/types/global-namespace.ts +39 -26
  215. package/src/types/handler-context.ts +103 -67
  216. package/src/types/index.ts +1 -0
  217. package/src/types/loader-types.ts +41 -15
  218. package/src/types/request-scope.ts +126 -0
  219. package/src/types/route-entry.ts +12 -1
  220. package/src/types/segments.ts +36 -2
  221. package/src/urls/include-helper.ts +34 -67
  222. package/src/urls/index.ts +0 -3
  223. package/src/urls/path-helper-types.ts +50 -9
  224. package/src/urls/path-helper.ts +63 -63
  225. package/src/urls/pattern-types.ts +48 -19
  226. package/src/urls/response-types.ts +25 -22
  227. package/src/urls/type-extraction.ts +26 -116
  228. package/src/urls/urls-function.ts +1 -5
  229. package/src/use-loader.tsx +487 -44
  230. package/src/vite/debug.ts +185 -0
  231. package/src/vite/discovery/bundle-postprocess.ts +34 -37
  232. package/src/vite/discovery/discover-routers.ts +105 -51
  233. package/src/vite/discovery/discovery-errors.ts +194 -0
  234. package/src/vite/discovery/gate-state.ts +171 -0
  235. package/src/vite/discovery/prerender-collection.ts +188 -93
  236. package/src/vite/discovery/route-types-writer.ts +40 -84
  237. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  238. package/src/vite/discovery/state.ts +46 -4
  239. package/src/vite/discovery/virtual-module-codegen.ts +13 -23
  240. package/src/vite/index.ts +6 -0
  241. package/src/vite/plugin-types.ts +126 -4
  242. package/src/vite/plugins/cjs-to-esm.ts +8 -7
  243. package/src/vite/plugins/client-ref-dedup.ts +16 -0
  244. package/src/vite/plugins/client-ref-hashing.ts +28 -5
  245. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  246. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  247. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  248. package/src/vite/plugins/expose-action-id.ts +54 -30
  249. package/src/vite/plugins/expose-id-utils.ts +24 -8
  250. package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
  251. package/src/vite/plugins/expose-ids/handler-transform.ts +12 -35
  252. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
  253. package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
  254. package/src/vite/plugins/expose-internal-ids.ts +544 -317
  255. package/src/vite/plugins/performance-tracks.ts +92 -0
  256. package/src/vite/plugins/refresh-cmd.ts +88 -26
  257. package/src/vite/plugins/use-cache-transform.ts +65 -50
  258. package/src/vite/plugins/version-injector.ts +39 -23
  259. package/src/vite/plugins/version-plugin.ts +59 -2
  260. package/src/vite/plugins/virtual-entries.ts +2 -2
  261. package/src/vite/rango.ts +130 -26
  262. package/src/vite/router-discovery.ts +920 -129
  263. package/src/vite/utils/ast-handler-extract.ts +15 -15
  264. package/src/vite/utils/banner.ts +1 -1
  265. package/src/vite/utils/bundle-analysis.ts +4 -2
  266. package/src/vite/utils/client-chunks.ts +190 -0
  267. package/src/vite/utils/forward-user-plugins.ts +193 -0
  268. package/src/vite/utils/manifest-utils.ts +21 -5
  269. package/src/vite/utils/package-resolution.ts +41 -1
  270. package/src/vite/utils/prerender-utils.ts +38 -5
  271. package/src/vite/utils/shared-utils.ts +109 -27
  272. package/src/browser/action-response-classifier.ts +0 -99
package/src/vite/rango.ts CHANGED
@@ -12,20 +12,30 @@ import { VIRTUAL_IDS } from "./plugins/virtual-entries.js";
12
12
  import {
13
13
  getExcludeDeps,
14
14
  getPackageAliases,
15
+ getPublishedPackageName,
16
+ getVendorAliases,
15
17
  } from "./utils/package-resolution.js";
16
18
  import { findRouterFiles } from "../build/generate-route-types.js";
17
19
  import { createVersionPlugin } from "./plugins/version-plugin.js";
18
20
  import {
19
- sharedEsbuildOptions,
21
+ sharedRolldownOptions,
20
22
  createVirtualEntriesPlugin,
21
23
  onwarn,
22
24
  getManualChunks,
23
25
  } from "./utils/shared-utils.js";
26
+ import {
27
+ resolveClientChunks,
28
+ type ClientChunkContext,
29
+ } from "./utils/client-chunks.js";
24
30
  import type { RangoOptions } from "./plugin-types.js";
25
31
  import { printBanner, rangoVersion } from "./utils/banner.js";
26
32
  import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
27
33
  import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
28
34
  import { createRouterDiscoveryPlugin } from "./router-discovery.js";
35
+ import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
36
+ import { createRangoDebugger, NS } from "./debug.js";
37
+
38
+ const debugConfig = createRangoDebugger(NS.config);
29
39
 
30
40
  /**
31
41
  * Vite plugin for @rangojs/router.
@@ -52,15 +62,57 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
52
62
  * ```
53
63
  */
54
64
  export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
65
+ const rangoStart = performance.now();
55
66
  const resolvedOptions: RangoOptions = options ?? { preset: "node" };
56
67
  const preset = resolvedOptions.preset ?? "node";
57
68
  const showBanner = resolvedOptions.banner ?? true;
69
+ // Client-chunking strategy (per-route/per-feature splitting of the browser
70
+ // bundle). Defaults to the built-in directory strategy (`true`) pre-1.0; pass
71
+ // `clientChunks: false` to opt out. Resolved once and forwarded to
72
+ // @vitejs/plugin-rsc in both presets. The built-in strategy only splits where it
73
+ // recognizes a route structure, so this default is a no-op for flat / host-split
74
+ // apps and never duplicates the shared runtime.
75
+ const clientChunksOption = resolvedOptions.clientChunks ?? true;
76
+ // Shared context the built-in strategy reads at build time: the production
77
+ // hashes of registered error/notFound fallback modules (-> app-fallback).
78
+ // Populated by the discovery plugin in buildStart, before the client build
79
+ // invokes the strategy. Only wired when the built-in strategy is active; a
80
+ // custom function owns its own grouping.
81
+ const useBuiltInClientChunks = clientChunksOption === true;
82
+ const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
83
+ ? { fallbackRefs: new Set<string>() }
84
+ : undefined;
85
+ const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
86
+ debugConfig?.("rango(%s) setup start", preset);
58
87
 
59
88
  const plugins: PluginOption[] = [];
60
89
 
61
- // Get package resolution info (workspace vs npm install)
62
- const rangoAliases = getPackageAliases();
63
- const excludeDeps = getExcludeDeps();
90
+ // Get package resolution info (workspace vs npm install).
91
+ // Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
92
+ // itself injects into optimizeDeps.include) to absolute paths resolved from
93
+ // this package — so strict-pnpm consumers don't hit "Failed to resolve
94
+ // dependency" warnings when those deps aren't hoisted to their app root.
95
+ const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
96
+ const excludeDeps = [
97
+ ...getExcludeDeps(),
98
+ // plugin-rsc itself injects these into the client env's
99
+ // optimizeDeps.include, which overrides exclude for the dep's own
100
+ // pre-bundle entry. What exclude still controls is how *other*
101
+ // pre-bundled deps treat imports of these specs (external vs inlined)
102
+ // via esbuildCjsExternalPlugin. The cjs-to-esm transform in
103
+ // plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
104
+ // where client.browser's bare include fails to resolve and Vite ends up
105
+ // serving the raw CJS file at dev-serve time.
106
+ "@vitejs/plugin-rsc/browser",
107
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
108
+ ];
109
+
110
+ // Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
111
+ // B from A's location. We anchor transitive deps (rsc-html-stream,
112
+ // @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
113
+ // these aren't visible at the app root — can still pre-bundle them.
114
+ const pkg = getPublishedPackageName();
115
+ const nested = (spec: string) => `${pkg} > ${spec}`;
64
116
 
65
117
  // Mutable ref for router path (node preset only).
66
118
  // Set immediately when user-specified, or populated by the auto-discover
@@ -96,10 +148,18 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
96
148
  // This ensures the same Context instance is used by both browser entry and RSC proxy modules
97
149
  optimizeDeps: {
98
150
  exclude: excludeDeps,
99
- esbuildOptions: sharedEsbuildOptions,
151
+ rolldownOptions: sharedRolldownOptions,
100
152
  },
101
153
  resolve: {
102
154
  alias: rangoAliases,
155
+ // Force a single React/React-DOM copy across all three RSC
156
+ // environments. RSC requires exactly one react/react-dom instance
157
+ // per environment runtime; consumer install topologies (pnpm
158
+ // strict layout, experimental React pins, third-party "use client"
159
+ // packages) can otherwise resolve duplicate copies, causing
160
+ // "Invalid hook call" / lost context. Child environments inherit
161
+ // this root dedupe, and Vite merges it with any consumer dedupe.
162
+ dedupe: ["react", "react-dom"],
103
163
  },
104
164
  build: {
105
165
  rollupOptions: { onwarn },
@@ -108,6 +168,14 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
108
168
  client: {
109
169
  build: {
110
170
  rollupOptions: {
171
+ // FILE_NAME_CONFLICT (and any other client-build warning) is
172
+ // emitted by the CLIENT environment build, which consults THIS
173
+ // env's onwarn -- Vite 8's environment builds do NOT propagate
174
+ // the top-level build.rollupOptions.onwarn into the client env.
175
+ // Wire it here so the suppression runs where the conflicts
176
+ // originate (the top-level handler is invoked 0x for these; the
177
+ // client-env handler is invoked for all of them).
178
+ onwarn,
111
179
  output: {
112
180
  manualChunks: getManualChunks,
113
181
  },
@@ -116,9 +184,9 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
116
184
  // Pre-bundle rsc-html-stream to prevent discovery during first request
117
185
  // Exclude rsc-router modules to ensure same Context instance
118
186
  optimizeDeps: {
119
- include: ["rsc-html-stream/client"],
187
+ include: [nested("rsc-html-stream/client")],
120
188
  exclude: excludeDeps,
121
- esbuildOptions: sharedEsbuildOptions,
189
+ rolldownOptions: sharedRolldownOptions,
122
190
  },
123
191
  },
124
192
  ssr: {
@@ -126,10 +194,6 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
126
194
  build: {
127
195
  outDir: "./dist/rsc/ssr",
128
196
  },
129
- resolve: {
130
- // Ensure single React instance in SSR child environment
131
- dedupe: ["react", "react-dom"],
132
- },
133
197
  // Pre-bundle SSR entry and React for proper module linking with childEnvironments
134
198
  // All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
135
199
  optimizeDeps: {
@@ -141,11 +205,13 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
141
205
  "react-dom/static.edge",
142
206
  "react/jsx-runtime",
143
207
  "react/jsx-dev-runtime",
144
- "rsc-html-stream/server",
145
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
208
+ nested("rsc-html-stream/server"),
209
+ nested(
210
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
211
+ ),
146
212
  ],
147
213
  exclude: excludeDeps,
148
- esbuildOptions: sharedEsbuildOptions,
214
+ rolldownOptions: sharedRolldownOptions,
149
215
  },
150
216
  },
151
217
  rsc: {
@@ -157,10 +223,12 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
157
223
  "react",
158
224
  "react/jsx-runtime",
159
225
  "react/jsx-dev-runtime",
160
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
226
+ nested(
227
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
228
+ ),
161
229
  ],
162
230
  exclude: excludeDeps,
163
- esbuildOptions: sharedEsbuildOptions,
231
+ rolldownOptions: sharedRolldownOptions,
164
232
  },
165
233
  },
166
234
  },
@@ -182,6 +250,9 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
182
250
 
183
251
  plugins.push(createVirtualEntriesPlugin(finalEntries));
184
252
 
253
+ // Dev-only: RSDW client patch for React Performance Tracks
254
+ plugins.push(performanceTracksPlugin());
255
+
185
256
  // Add RSC plugin with cloudflare-specific options
186
257
  // Note: loadModuleDevProxy should NOT be used with childEnvironments
187
258
  // since SSR runs in workerd alongside RSC
@@ -189,6 +260,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
189
260
  rsc({
190
261
  entries: finalEntries,
191
262
  serverHandler: false,
263
+ clientChunks,
192
264
  }) as PluginOption,
193
265
  );
194
266
 
@@ -218,7 +290,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
218
290
  " - " + (f.startsWith(root) ? f.slice(root.length + 1) : f),
219
291
  )
220
292
  .join("\n");
221
- throw new Error(`[rsc-router] Multiple routers found:\n${list}`);
293
+ throw new Error(`[rango] Multiple routers found:\n${list}`);
222
294
  }
223
295
  // 0 found: routerRef.path stays undefined, warn at startup via discovery plugin
224
296
  },
@@ -244,18 +316,34 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
244
316
  return {
245
317
  optimizeDeps: {
246
318
  exclude: excludeDeps,
247
- esbuildOptions: sharedEsbuildOptions,
319
+ rolldownOptions: sharedRolldownOptions,
248
320
  },
249
321
  build: {
250
322
  rollupOptions: { onwarn },
251
323
  },
252
324
  resolve: {
253
325
  alias: rangoAliases,
326
+ // Force a single React/React-DOM copy across all three RSC
327
+ // environments. RSC requires exactly one react/react-dom instance
328
+ // per environment runtime; consumer install topologies (pnpm
329
+ // strict layout, experimental React pins, third-party "use client"
330
+ // packages) can otherwise resolve duplicate copies, causing
331
+ // "Invalid hook call" / lost context. Child environments inherit
332
+ // this root dedupe, and Vite merges it with any consumer dedupe.
333
+ dedupe: ["react", "react-dom"],
254
334
  },
255
335
  environments: {
256
336
  client: {
257
337
  build: {
258
338
  rollupOptions: {
339
+ // FILE_NAME_CONFLICT (and any other client-build warning) is
340
+ // emitted by the CLIENT environment build, which consults THIS
341
+ // env's onwarn -- Vite 8's environment builds do NOT propagate
342
+ // the top-level build.rollupOptions.onwarn into the client env.
343
+ // Wire it here so the suppression runs where the conflicts
344
+ // originate (the top-level handler is invoked 0x for these; the
345
+ // client-env handler is invoked for all of them).
346
+ onwarn,
259
347
  output: {
260
348
  manualChunks: getManualChunks,
261
349
  },
@@ -267,10 +355,10 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
267
355
  "react-dom",
268
356
  "react/jsx-runtime",
269
357
  "react/jsx-dev-runtime",
270
- "rsc-html-stream/client",
358
+ nested("rsc-html-stream/client"),
271
359
  ],
272
360
  exclude: excludeDeps,
273
- esbuildOptions: sharedEsbuildOptions,
361
+ rolldownOptions: sharedRolldownOptions,
274
362
  entries: [VIRTUAL_IDS.browser],
275
363
  },
276
364
  },
@@ -284,10 +372,12 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
284
372
  "react-dom/static.edge",
285
373
  "react/jsx-runtime",
286
374
  "react/jsx-dev-runtime",
287
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
375
+ nested(
376
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
377
+ ),
288
378
  ],
289
379
  exclude: excludeDeps,
290
- esbuildOptions: sharedEsbuildOptions,
380
+ rolldownOptions: sharedRolldownOptions,
291
381
  },
292
382
  },
293
383
  rsc: {
@@ -297,9 +387,11 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
297
387
  "react",
298
388
  "react/jsx-runtime",
299
389
  "react/jsx-dev-runtime",
300
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
390
+ nested(
391
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
392
+ ),
301
393
  ],
302
- esbuildOptions: sharedEsbuildOptions,
394
+ rolldownOptions: sharedRolldownOptions,
303
395
  },
304
396
  },
305
397
  },
@@ -324,7 +416,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
324
416
  if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
325
417
  hasWarnedDuplicate = true;
326
418
  console.warn(
327
- "[rsc-router] Duplicate @vitejs/plugin-rsc detected. " +
419
+ "[rango] Duplicate @vitejs/plugin-rsc detected. " +
328
420
  "Remove rsc() from your vite config — rango() includes it automatically.",
329
421
  );
330
422
  }
@@ -334,9 +426,13 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
334
426
  // Add virtual entries plugin (RSC entry generated lazily from routerRef)
335
427
  plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
336
428
 
429
+ // Dev-only: RSDW client patch for React Performance Tracks
430
+ plugins.push(performanceTracksPlugin());
431
+
337
432
  plugins.push(
338
433
  rsc({
339
434
  entries: finalEntries,
435
+ clientChunks,
340
436
  }) as PluginOption,
341
437
  );
342
438
 
@@ -437,9 +533,17 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
437
533
  createRouterDiscoveryPlugin(discoveryEntryPath, {
438
534
  routerPathRef: discoveryRouterRef,
439
535
  enableBuildPrerender: prerenderEnabled,
440
- staticRouteTypesGeneration: resolvedOptions.staticRouteTypesGeneration,
536
+ buildEnv: options?.buildEnv,
537
+ preset,
538
+ clientChunkCtx,
441
539
  }),
442
540
  );
443
541
 
542
+ debugConfig?.(
543
+ "rango(%s) setup done: %d plugin(s) (%sms)",
544
+ preset,
545
+ plugins.length,
546
+ (performance.now() - rangoStart).toFixed(1),
547
+ );
444
548
  return plugins;
445
549
  }