@rangojs/router 0.19.1 → 0.21.0

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 (185) hide show
  1. package/dist/bin/rango.js +26 -14
  2. package/dist/types/browser/event-controller.d.ts +32 -0
  3. package/dist/types/browser/history-state.d.ts +16 -4
  4. package/dist/types/browser/navigation-transaction.d.ts +7 -0
  5. package/dist/types/browser/rango-state.d.ts +3 -1
  6. package/dist/types/browser/react/context.d.ts +11 -0
  7. package/dist/types/browser/react/location-state-shared.d.ts +84 -10
  8. package/dist/types/browser/react/location-state.d.ts +7 -2
  9. package/dist/types/browser/react/subscribe-to-nothing.d.ts +7 -0
  10. package/dist/types/cache/cache-scope.d.ts +4 -5
  11. package/dist/types/cache/cf/cf-cache-store.d.ts +27 -6
  12. package/dist/types/cache/cf/cf-cache-types.d.ts +12 -4
  13. package/dist/types/cache/handle-snapshot.d.ts +36 -50
  14. package/dist/types/cache/index.d.ts +2 -0
  15. package/dist/types/cache/shell-snapshot.d.ts +19 -3
  16. package/dist/types/cache/types.d.ts +21 -10
  17. package/dist/types/cache/vercel/vercel-cache-store.d.ts +28 -16
  18. package/dist/types/client-urls/navigation.d.ts +7 -1
  19. package/dist/types/client-urls/optimistic-location.d.ts +10 -4
  20. package/dist/types/handles/deferred-resolution.d.ts +11 -1
  21. package/dist/types/prerender/build-shell-capture.d.ts +8 -6
  22. package/dist/types/router/match-middleware/cache-lookup.d.ts +1 -1
  23. package/dist/types/router/navigation-snapshot.d.ts +8 -1
  24. package/dist/types/router/router-interfaces.d.ts +2 -1
  25. package/dist/types/router/router-options.d.ts +17 -7
  26. package/dist/types/router/segment-resolution/loader-cache.d.ts +21 -9
  27. package/dist/types/router-versions.d.ts +39 -0
  28. package/dist/types/rsc/handler-context.d.ts +5 -0
  29. package/dist/types/rsc/shell-build-manifest.d.ts +3 -2
  30. package/dist/types/rsc/types.d.ts +4 -6
  31. package/dist/types/server/build-version-table.d.ts +44 -0
  32. package/dist/types/server/handle-store.d.ts +87 -46
  33. package/dist/types/server/request-context.d.ts +22 -8
  34. package/dist/types/ssr/entry-preload-priority.d.ts +69 -0
  35. package/dist/types/ssr/index.d.ts +1 -0
  36. package/dist/types/ssr/preinit-client-references.d.ts +17 -5
  37. package/dist/types/testing/build-versions.d.ts +32 -0
  38. package/dist/types/testing/dom.entry.d.ts +1 -1
  39. package/dist/types/testing/flight.entry.d.ts +1 -1
  40. package/dist/types/testing/index.d.ts +2 -0
  41. package/dist/types/testing/internal/seed-vars.d.ts +7 -2
  42. package/dist/types/testing/location-state-key.d.ts +5 -1
  43. package/dist/types/testing/render-route.d.ts +77 -6
  44. package/dist/types/testing/serve-shell-request.d.ts +21 -0
  45. package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
  46. package/dist/types/types/handler-context.d.ts +8 -5
  47. package/dist/types/vite/discovery/build-versions.d.ts +393 -0
  48. package/dist/types/vite/discovery/installed-packages.d.ts +26 -0
  49. package/dist/types/vite/discovery/router-versions-phase.d.ts +52 -0
  50. package/dist/types/vite/discovery/shell-prerender-phase.d.ts +7 -17
  51. package/dist/types/vite/discovery/state.d.ts +14 -0
  52. package/dist/types/vite/encryption-key.d.ts +18 -0
  53. package/dist/types/vite/plugin-types.d.ts +47 -6
  54. package/dist/types/vite/plugins/{version-injector.d.ts → entry-bootstrap-injector.d.ts} +4 -6
  55. package/dist/types/vite/plugins/expose-ids/export-analysis.d.ts +1 -0
  56. package/dist/types/vite/plugins/expose-ids/router-transform.d.ts +14 -0
  57. package/dist/types/vite/plugins/stable-rsc-output.d.ts +51 -0
  58. package/dist/types/vite/plugins/version-plugin.d.ts +9 -11
  59. package/dist/types/vite/plugins/virtual-entries.d.ts +21 -2
  60. package/dist/types/vite/router-discovery.d.ts +6 -0
  61. package/dist/types/vite/utils/client-chunks.d.ts +24 -2
  62. package/dist/types/vite/utils/compare-strings.d.ts +7 -0
  63. package/dist/types/vite/utils/package-resolution.d.ts +8 -0
  64. package/dist/types/vite/utils/prerender-utils.d.ts +2 -0
  65. package/dist/vite/index.js +1544 -420
  66. package/package.json +1 -2
  67. package/skills/bundle-analysis/SKILL.md +1 -1
  68. package/skills/cache-guide/SKILL.md +84 -20
  69. package/skills/caching/SKILL.md +16 -5
  70. package/skills/client-urls/SKILL.md +16 -0
  71. package/skills/cloudflare/SKILL.md +2 -1
  72. package/skills/comparison/references/framework-comparison.md +16 -12
  73. package/skills/hooks/SKILL.md +3 -0
  74. package/skills/hooks/handle-and-actions.md +6 -0
  75. package/skills/hooks/navigation.md +28 -0
  76. package/skills/hooks/state.md +209 -8
  77. package/skills/hooks/urls.md +40 -1
  78. package/skills/host-router/SKILL.md +13 -0
  79. package/skills/intercept/SKILL.md +6 -0
  80. package/skills/loader/SKILL.md +19 -1
  81. package/skills/middleware/SKILL.md +2 -0
  82. package/skills/ppr/SKILL.md +119 -40
  83. package/skills/prerender/SKILL.md +7 -3
  84. package/skills/rango/SKILL.md +8 -7
  85. package/skills/router-setup/SKILL.md +23 -3
  86. package/skills/testing/SKILL.md +30 -26
  87. package/skills/testing/client-components.md +193 -8
  88. package/skills/testing/handles.md +2 -0
  89. package/skills/testing/loader.md +1 -1
  90. package/skills/testing/middleware.md +1 -1
  91. package/skills/testing/render-handler.md +18 -18
  92. package/skills/testing/serve-shell-request.md +63 -14
  93. package/skills/testing/server-actions.md +17 -17
  94. package/skills/testing/server-tree.md +1 -1
  95. package/skills/typesafety/generated-files-and-cli.md +1 -1
  96. package/skills/use-cache/SKILL.md +16 -5
  97. package/skills/vercel/SKILL.md +3 -3
  98. package/src/bin/rango.ts +1 -1
  99. package/src/browser/event-controller.ts +75 -2
  100. package/src/browser/history-state.ts +39 -17
  101. package/src/browser/navigation-bridge.ts +41 -18
  102. package/src/browser/navigation-transaction.ts +15 -10
  103. package/src/browser/partial-update.ts +10 -2
  104. package/src/browser/rango-state.ts +3 -1
  105. package/src/browser/react/Link.tsx +2 -3
  106. package/src/browser/react/NavigationProvider.tsx +25 -1
  107. package/src/browser/react/context.ts +13 -0
  108. package/src/browser/react/location-state-shared.ts +200 -34
  109. package/src/browser/react/location-state.ts +40 -75
  110. package/src/browser/react/subscribe-to-nothing.ts +7 -0
  111. package/src/browser/react/use-handle.ts +20 -1
  112. package/src/browser/rsc-router.tsx +33 -11
  113. package/src/browser/server-action-bridge.ts +17 -1
  114. package/src/cache/cache-scope.ts +18 -8
  115. package/src/cache/cf/cf-cache-store.ts +75 -55
  116. package/src/cache/cf/cf-cache-types.ts +12 -4
  117. package/src/cache/handle-snapshot.ts +69 -87
  118. package/src/cache/index.ts +4 -0
  119. package/src/cache/shell-snapshot.ts +35 -5
  120. package/src/cache/types.ts +21 -10
  121. package/src/cache/vercel/vercel-cache-store.ts +48 -20
  122. package/src/client-urls/client-root.tsx +1 -0
  123. package/src/client-urls/navigation.ts +10 -0
  124. package/src/client-urls/optimistic-location.ts +10 -4
  125. package/src/handles/deferred-resolution.ts +31 -0
  126. package/src/prerender/build-shell-capture.ts +11 -9
  127. package/src/router/manifest.ts +2 -0
  128. package/src/router/match-middleware/cache-lookup.ts +11 -18
  129. package/src/router/navigation-snapshot.ts +25 -6
  130. package/src/router/request-classification.ts +15 -12
  131. package/src/router/router-interfaces.ts +2 -1
  132. package/src/router/router-options.ts +17 -7
  133. package/src/router/segment-resolution/loader-cache.ts +95 -60
  134. package/src/router-versions.ts +60 -0
  135. package/src/rsc/full-payload.ts +6 -2
  136. package/src/rsc/handler-context.ts +5 -0
  137. package/src/rsc/handler.ts +14 -4
  138. package/src/rsc/rsc-rendering.ts +12 -1
  139. package/src/rsc/shell-build-manifest.ts +10 -7
  140. package/src/rsc/shell-capture.ts +36 -26
  141. package/src/rsc/types.ts +4 -6
  142. package/src/server/build-version-table.ts +115 -0
  143. package/src/server/handle-store.ts +344 -127
  144. package/src/server/request-context.ts +62 -11
  145. package/src/ssr/entry-preload-priority.ts +308 -0
  146. package/src/ssr/index.tsx +46 -9
  147. package/src/ssr/preinit-client-references.ts +17 -5
  148. package/src/ssr/ssr-root.tsx +16 -4
  149. package/src/testing/build-versions.ts +64 -0
  150. package/src/testing/dispatch.ts +6 -0
  151. package/src/testing/dom.entry.ts +1 -0
  152. package/src/testing/flight.entry.ts +1 -0
  153. package/src/testing/index.ts +3 -0
  154. package/src/testing/internal/context.ts +2 -1
  155. package/src/testing/internal/seed-vars.ts +14 -2
  156. package/src/testing/location-state-key.ts +18 -8
  157. package/src/testing/render-handler.ts +2 -1
  158. package/src/testing/render-route.tsx +277 -43
  159. package/src/testing/serve-shell-request.ts +80 -11
  160. package/src/testing/vitest-stubs/version.ts +4 -1
  161. package/src/types/handler-context.ts +8 -5
  162. package/src/vite/discovery/build-versions.ts +1281 -0
  163. package/src/vite/discovery/installed-packages.ts +159 -0
  164. package/src/vite/discovery/prerender-collection.ts +38 -1
  165. package/src/vite/discovery/router-versions-phase.ts +336 -0
  166. package/src/vite/discovery/shell-prerender-phase.ts +28 -38
  167. package/src/vite/discovery/state.ts +19 -0
  168. package/src/vite/discovery/virtual-module-codegen.ts +7 -2
  169. package/src/vite/encryption-key.ts +101 -9
  170. package/src/vite/plugin-types.ts +48 -6
  171. package/src/vite/plugins/{version-injector.ts → entry-bootstrap-injector.ts} +7 -22
  172. package/src/vite/plugins/expose-ids/export-analysis.ts +1 -1
  173. package/src/vite/plugins/expose-ids/router-transform.ts +36 -15
  174. package/src/vite/plugins/expose-internal-ids.ts +12 -3
  175. package/src/vite/plugins/stable-rsc-output.ts +147 -0
  176. package/src/vite/plugins/version-plugin.ts +19 -24
  177. package/src/vite/plugins/version.d.ts +17 -2
  178. package/src/vite/plugins/virtual-entries.ts +40 -7
  179. package/src/vite/rango.ts +30 -3
  180. package/src/vite/router-discovery.ts +82 -13
  181. package/src/vite/utils/client-chunks.ts +84 -14
  182. package/src/vite/utils/compare-strings.ts +9 -0
  183. package/src/vite/utils/package-resolution.ts +9 -0
  184. package/src/vite/utils/prerender-utils.ts +4 -1
  185. package/src/vite/utils/shared-utils.ts +1 -1
@@ -68,6 +68,12 @@ export interface ClientChunkMeta {
68
68
  * strategy**. It splits app `"use client"` modules by **route id** — the segment
69
69
  * after a route-root directory (`routes`, `app`, `pages`, `features`, `handlers`,
70
70
  * …) — so `routes/dashboard/**` becomes `app-dashboard` at any nesting depth.
71
+ * The first marker in the path wins, except that an `app/` directly followed
72
+ * by another marker with a directory after it is treated as a source root:
73
+ * `app/routes/product/**` becomes `app-product`, while `app/dashboard/**`
74
+ * (Next-style), `app/components/**` and files directly in `app/routes/` stay
75
+ * `app-dashboard` / `app-components` / `app-routes`. The same route id under
76
+ * different markers is one group.
71
77
  * Where it finds NO route structure (a flat `src/components/`, or host sub-apps
72
78
  * already split by a dynamic `import()`), it inherits the default grouping
73
79
  * unchanged — so the shared `src/components` chunk stays shared and host apps do
@@ -79,10 +85,14 @@ export interface ClientChunkMeta {
79
85
  * back to the default grouping for that one module. Forwarded directly to
80
86
  * `@vitejs/plugin-rsc`'s `clientChunks`.
81
87
  *
82
- * Every module maps to exactly one group, so there is no byte duplication: a
83
- * component used by two routes lives in one group and is fetched whenever it
84
- * renders. Put genuinely shared client components OUTSIDE route directories so
85
- * they land in the shared group rather than one route's chunk.
88
+ * Every module maps to exactly one group, so there is no byte duplication. A
89
+ * group is also the loading unit: rendering any one member downloads the whole
90
+ * group's chunk, every other member included. A component used by two routes
91
+ * lives in one group, and rendering it on either route fetches that entire
92
+ * group. Put genuinely shared client components OUTSIDE route directories so
93
+ * they land in the shared group rather than one route's chunk, and keep an
94
+ * always-rendered component (a layout header) out of a large group.
95
+ * `DEBUG=rango:chunks vite build` logs each group's module count and size.
86
96
  *
87
97
  * @default true
88
98
  */
@@ -114,14 +124,18 @@ interface RangoBaseOptions {
114
124
  * - `"preinit"` (**default**): client-reference chunks render as EXECUTING
115
125
  * `<script type="module" async>` tags hoisted into `<head>` (upgrading
116
126
  * plugin-rsc's modulepreload hints in place), and the browser entry ships
117
- * as Fizz `bootstrapModules` — a head `modulepreload fetchpriority=low`
118
- * hint plus the executing end-of-shell `id="_R_"` module script. Chunk
127
+ * as Fizz `bootstrapModules` — a `modulepreload` hint after the head
128
+ * chunk scripts (default priority; Fizz's `fetchpriority=low` is dropped,
129
+ * #1025)
130
+ * plus the executing end-of-shell `id="_R_"` module script. Chunk
119
131
  * execution overlaps body streaming instead of waiting for the hydration
120
132
  * import walk; under PPR everything lands in the stored shell prelude.
121
133
  * - `"preload"`: the previous behavior — `<link rel="modulepreload">` hints
122
134
  * only, entry as an inline `import()` script at end of shell. Chunks
123
135
  * fetch+compile early but execute only when hydration imports them.
124
136
  *
137
+ * Any other value throws when the generated SSR entry is built.
138
+ *
125
139
  * Build-only for the chunk half: plugin-rsc resolves no JS deps per client
126
140
  * reference in dev, so dev documents carry no head chunk scripts in either
127
141
  * mode (the bootstrap conversion does apply in dev). Trades and upstream
@@ -199,6 +213,33 @@ interface RangoBaseOptions {
199
213
  prerender?: {
200
214
  onError?: "fail" | "warn";
201
215
  };
216
+ /**
217
+ * The key inline server actions encrypt their bound arguments with:
218
+ * base64-encoded 32 bytes (`openssl rand -base64 32`). Pass it from the
219
+ * environment, never as a literal in the config file:
220
+ *
221
+ * ```ts
222
+ * rango({ encryptionKey: process.env.RANGO_ENCRYPTION_KEY })
223
+ * ```
224
+ *
225
+ * Why set it: the key is part of the cache version of every router whose
226
+ * server code encrypts with it, because a payload cached under one key
227
+ * carries arguments another key cannot decrypt. Without a stable key rango
228
+ * generates one per build, so those routers get a new version, and a cleared
229
+ * cache, on every deploy. With a stable key their cache survives a deploy
230
+ * that does not change their server code. It also lets a build decrypt
231
+ * arguments an earlier build encrypted (a cached or prerendered payload, an
232
+ * open tab).
233
+ *
234
+ * Validated when `rango()` is called: a value that is not base64 or does not
235
+ * decode to an AES key size (16, 24 or 32 bytes) throws. `undefined` (the
236
+ * variable is unset) falls back to the `RANGO_ENCRYPTION_KEY` environment
237
+ * variable, then to a generated key. Rotating the key clears the cache of
238
+ * the routers that use it.
239
+ *
240
+ * @default process.env.RANGO_ENCRYPTION_KEY, else a key generated per build
241
+ */
242
+ encryptionKey?: string;
202
243
  }
203
244
  /**
204
245
  * Options for Node.js deployment (default)
@@ -1,10 +1,8 @@
1
1
  import type { Plugin } from "vite";
2
2
  /**
3
- * Plugin that auto-injects VERSION, routes-manifest, and loader-manifest into
4
- * custom entry.rsc files. If a custom entry.rsc file uses createRSCHandler but
5
- * doesn't pass version, this transform adds the import and property
6
- * automatically. It also ensures the routes-manifest and loader-manifest
7
- * virtual modules are always imported.
3
+ * Plugin that auto-injects the routes-manifest and loader-manifest imports
4
+ * into a custom entry.rsc file (the Cloudflare preset, where the consumer owns
5
+ * the worker entry).
8
6
  *
9
7
  * The loader-manifest import is what makes fetchable loaders resolvable on a
10
8
  * custom worker entry. The virtual RSC entry (getVirtualEntryRSC) imports the
@@ -18,4 +16,4 @@ import type { Plugin } from "vite";
18
16
  * manifest, hence the production-only failure this fixes.
19
17
  * @internal
20
18
  */
21
- export declare function createVersionInjectorPlugin(rscEntryPath: string | undefined): Plugin;
19
+ export declare function createEntryBootstrapInjectorPlugin(rscEntryPath: string | undefined): Plugin;
@@ -1,5 +1,6 @@
1
1
  import type { CreateExportBinding } from "./types.js";
2
2
  export declare function isExportOnlyFile(code: string, bindings: CreateExportBinding[]): boolean;
3
+ export declare function createCallPattern(fnNames: string[]): RegExp;
3
4
  export declare function countCreateCallsForNames(code: string, fnNames: string[]): number;
4
5
  export declare function offsetToLineColumn(code: string, index: number): {
5
6
  line: number;
@@ -1,5 +1,19 @@
1
1
  import type { Plugin } from "vite";
2
2
  import MagicString from "magic-string";
3
+ /**
4
+ * A router's `$$id`: a hash of its root-relative file and of its position
5
+ * among the file's createRouter() calls.
6
+ *
7
+ * Not of the call's line. `code` is TS-transformed, and a dev server keeps
8
+ * comments there that a build drops, so a line of `code` gave build-time
9
+ * discovery and the bundle different ids for any router with a comment above
10
+ * it (e2e/test-app, tests/cloudflare-basic): the build registered the lazy
11
+ * route manifest under an id no running router had. And a line of the file as
12
+ * written changes with every blank line or comment added above the call,
13
+ * which renamed the state cookie, the route manifest chunk and the router's
14
+ * cache versions for an edit that changed nothing.
15
+ */
16
+ export declare function routerId(filePath: string, callIndex: number): string;
3
17
  export declare function transformRouter(code: string, filePath: string, routerFnNames: string[], absolutePath?: string, warn?: (message: string) => void): {
4
18
  code: string;
5
19
  map: ReturnType<MagicString["generateMap"]>;
@@ -0,0 +1,51 @@
1
+ import { type Plugin } from "vite";
2
+ /** One property of an object literal, by its position in the source. */
3
+ export interface LiteralProperty {
4
+ readonly key: string;
5
+ /** Range of the whole property, key included. */
6
+ readonly start: number;
7
+ readonly end: number;
8
+ /** The value's AST node. */
9
+ readonly value: any;
10
+ }
11
+ /**
12
+ * The properties of an object-literal AST node, or undefined when it is not an
13
+ * object literal of plain keys (a spread, a computed key).
14
+ */
15
+ export declare function literalProperties(object: any): LiteralProperty[] | undefined;
16
+ /**
17
+ * The properties of a module's `export default { ... }`, or undefined when
18
+ * the module does not parse or is not that shape. plugin-rsc generates its
19
+ * registries (the server-reference map, the assets manifest) in this form.
20
+ */
21
+ export declare function defaultExportProperties(code: string): LiteralProperty[] | undefined;
22
+ /**
23
+ * Return `code` with the properties of its default-exported object literal
24
+ * sorted by key, or undefined when there is nothing to reorder (or the module
25
+ * is not that shape).
26
+ */
27
+ export declare function sortDefaultExportProperties(code: string): string | undefined;
28
+ /**
29
+ * Return `code` with its default import of plugin-rsc's assets manifest
30
+ * renamed to {@link ASSETS_MANIFEST_BINDING}, or undefined when there is
31
+ * nothing to rename (no such import under a generated name, or the module
32
+ * uses the canonical name for something else).
33
+ */
34
+ export declare function canonicalAssetsManifestBinding(code: string): string | undefined;
35
+ /**
36
+ * Removes two run-to-run differences from plugin-rsc 0.5.35's build output.
37
+ * The cache versions hash these bytes (discovery/build-versions.ts).
38
+ *
39
+ * 1. Property order of the server-reference map. plugin-rsc writes it in the
40
+ * order its transforms first saw each `"use server"` module
41
+ * (`ServerReferencesManager.claimMap`), which varies with the concurrent
42
+ * scan builds (e2e/test-app: 2 of 2 consecutive builds differed). Sorted
43
+ * here so a minified server build, where stripServerReferenceMap finds no
44
+ * region comments, still hashes the same bytes.
45
+ * 2. Local name of the assets-manifest import. plugin-rsc imports the manifest
46
+ * under three names; the bundler merges them into one import per chunk and
47
+ * keeps a different one from build to build (the cache-versions fixture:
48
+ * 1 of 10 concurrent builds). One name in, one name out.
49
+ * @internal
50
+ */
51
+ export declare function stableRscOutput(): Plugin;
@@ -1,18 +1,16 @@
1
1
  import { type Plugin } from "vite";
2
2
  /**
3
- * Plugin providing rsc-router:version virtual module.
4
- * Exports VERSION that changes when RSC modules change (dev) or at build time (production).
3
+ * Plugin providing the `@rangojs/router:version` virtual module.
5
4
  *
6
- * The version is used for:
7
- * 1. Cache invalidation - CFCacheStore uses VERSION to invalidate stale cache
8
- * 2. Version mismatch detection - client sends version, server reloads on mismatch
5
+ * Dev: exports a VERSION stamp used for both versions of every router. It
6
+ * updates when the server starts and when an RSC module changes via HMR (the
7
+ * version module is invalidated). Client-only HMR changes do not update it:
8
+ * they do not affect server-rendered content or cached RSC payloads.
9
9
  *
10
- * In dev mode, the version updates when:
11
- * - Server starts (initial version)
12
- * - RSC modules change via HMR (triggers version module invalidation)
13
- *
14
- * Client-only HMR changes don't update the version since they don't affect
15
- * server-rendered content or cached RSC payloads.
10
+ * Build: exports a placeholder for the per-router versions table. The module
11
+ * holds nothing that varies between builds; the table is written into the
12
+ * built chunk after the server output is hashed (the buildApp post hook in
13
+ * router-discovery.ts). See docs/design/per-app-cache-version.md.
16
14
  * @internal
17
15
  */
18
16
  export declare function createVersionPlugin(): Plugin;
@@ -5,7 +5,9 @@ export declare const VIRTUAL_ENTRY_BROWSER: string;
5
5
  * option: "preinit" (default) installs the client-reference preinit hook and
6
6
  * threads `getClientEntryUrl` so Fizz emits `bootstrapModules`;
7
7
  * "preload" omits the hook and uses the deprecated inline
8
- * `loadBootstrapScriptContent` bootstrap.
8
+ * `loadBootstrapScriptContent` bootstrap. Any other value throws: an unknown
9
+ * string such as "prenit" used to run as "preinit" silently
10
+ * (`headScripts !== "preload"` since #694).
9
11
  */
10
12
  export declare function getVirtualEntrySSR(headScripts?: HeadScriptsOption, progressiveChunkSize?: number): string;
11
13
  /**
@@ -20,7 +22,7 @@ export declare function getVirtualEntrySSR(headScripts?: HeadScriptsOption, prog
20
22
  * registered for the _rsc_loader endpoint and fail in production.
21
23
  *
22
24
  * Single source of truth: both the generated virtual RSC entry below and the
23
- * custom-entry injector (version-injector) consume this list, so a new
25
+ * custom-entry injector (entry-bootstrap-injector) consume this list, so a new
24
26
  * bootstrap manifest cannot be added to one path and forgotten on the other.
25
27
  * That exact drift (loader-manifest present here but missing from the injector)
26
28
  * is what left fetchable loaders unresolved on custom worker entries.
@@ -34,4 +36,21 @@ export declare const VIRTUAL_IDS: {
34
36
  readonly rsc: "virtual:rsc-router/entry.rsc.js";
35
37
  readonly version: "@rangojs/router:version";
36
38
  };
39
+ /** Dev: one stamp for both versions of every router, bumped on RSC edits. */
37
40
  export declare function getVirtualVersionContent(version: string): string;
41
+ /**
42
+ * Free identifier the production version module ships in place of the table.
43
+ * The versions are hashes of the built server code, so they cannot be part of
44
+ * it: the buildApp post hook (router-discovery.ts) replaces this token in the
45
+ * written chunk once the hashes are final (runRouterVersionsPhase,
46
+ * discovery/router-versions-phase.ts). An unreplaced token throws a ReferenceError
47
+ * when the module evaluates, so a build that skipped the step cannot serve
48
+ * with a constant version.
49
+ */
50
+ export declare const ROUTER_VERSIONS_PLACEHOLDER = "__RANGO_ROUTER_VERSIONS__";
51
+ /**
52
+ * Production: byte-identical in every build, so it never moves the hashes it
53
+ * is later filled with. VERSION is the whole-build document version (the
54
+ * table's "*" entry).
55
+ */
56
+ export declare function getVirtualBuildVersionContent(): string;
@@ -35,6 +35,12 @@ export declare function createTempRscServer(state: DiscoveryState, options?: {
35
35
  */
36
36
  realSsrEntry?: boolean;
37
37
  }): Promise<ViteDevServer>;
38
+ import type { BuildEnvOption, BuildEnvFactoryContext, BuildEnvResult } from "./plugin-types.js";
39
+ /**
40
+ * Resolve the buildEnv option into a concrete { env, dispose? } result.
41
+ * Handles all four input shapes: false, "auto", factory, plain object.
42
+ */
43
+ export declare function resolveBuildEnv(option: BuildEnvOption | undefined, factoryCtx: BuildEnvFactoryContext): Promise<BuildEnvResult | null>;
38
44
  /**
39
45
  * Plugin that discovers router instances at dev/build time via the RSC environment.
40
46
  *
@@ -1,4 +1,6 @@
1
+ import type { Plugin } from "vite";
1
2
  import type { ClientChunkMeta, ClientChunks } from "../plugin-types.js";
3
+ import { type Debugger } from "../debug.js";
2
4
  /** The callback shape @vitejs/plugin-rsc's `clientChunks` option accepts. */
3
5
  export type RscClientChunksFn = (meta: ClientChunkMeta) => string | undefined;
4
6
  /**
@@ -36,8 +38,11 @@ export interface ClientChunkContext {
36
38
  * 1. Shared runtime (React / router / node_modules) -> `undefined` (never split).
37
39
  * 2. A registered error/notFound fallback (`ctx.fallbackRefs`) -> `app-fallback`,
38
40
  * regardless of location, so the error UI is decoupled from the happy path.
39
- * 3. A {@link ROUTE_ROOT_DIRS} marker with a directory after it -> key on that
40
- * next segment (the route id), robust to any nesting depth.
41
+ * 3. The first {@link ROUTE_ROOT_DIRS} marker with a directory after it -> key on
42
+ * that next segment (the route id), robust to any nesting depth. A
43
+ * {@link SOURCE_ROOT_DIRS} marker (`app`) directly followed by another marker
44
+ * with a directory after it defers to that inner marker:
45
+ * `app/routes/<id>/…` -> `app-<id>`, while `app/<segment>/…` -> `app-<segment>`.
41
46
  * 4. Otherwise `undefined` (inherit the default `serverChunk` grouping).
42
47
  */
43
48
  export declare function directoryClientChunks(meta: ClientChunkMeta, ctx?: ClientChunkContext): string | undefined;
@@ -53,3 +58,20 @@ export declare function directoryClientChunks(meta: ClientChunkMeta, ctx?: Clien
53
58
  * fallback refinement does not apply — the consumer owns the grouping).
54
59
  */
55
60
  export declare function resolveClientChunks(option: ClientChunks | undefined, ctx?: ClientChunkContext): RscClientChunksFn | undefined;
61
+ /** @vitejs/plugin-rsc's client-reference map; its group modules sit under it. */
62
+ export declare const CLIENT_REFERENCES_MODULE_ID = "\0virtual:vite-rsc/client-references";
63
+ /**
64
+ * Build-end group report under `DEBUG=rango:chunks`: one line per client
65
+ * reference group with its client-reference count and the size of the group's
66
+ * own chunk (code split into shared chunks such as `react`/`router` is not
67
+ * counted). A group is the loading unit (plugin-rsc imports the group's virtual
68
+ * module to resolve any one member), so a large group that an always-rendered
69
+ * component belongs to is downloaded on every route; this line makes that
70
+ * visible. Covers every group, including ones named by a custom `clientChunks`
71
+ * function or by plugin-rsc's default `serverChunk` grouping. `undefined` when
72
+ * the namespace is off, so a normal build does not register it. Group names are
73
+ * printed with NUL escaped: plugin-rsc's default group is named
74
+ * `facade:\0virtual:…`, and a raw NUL makes `grep` treat the output as binary
75
+ * and drop that line, usually the largest group. `log` is injectable for tests.
76
+ */
77
+ export declare function clientChunksReport(log?: Debugger | undefined): Plugin | undefined;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Code-unit order, the same on every machine. Generated modules and the cache
3
+ * version inputs are sorted with it: `localeCompare` depends on the build
4
+ * machine's ICU data, and build output has to be byte-identical across machines
5
+ * (discovery/build-versions.ts hashes it).
6
+ */
7
+ export declare function compareStrings(a: string, b: string): number;
@@ -3,4 +3,12 @@ export declare function isInstalledFromNpm(): boolean;
3
3
  export declare function isWorkspaceDevelopment(): boolean;
4
4
  export declare function getExcludeDeps(): string[];
5
5
  export declare function getPackageAliases(): Record<string, string>;
6
+ /**
7
+ * @vitejs/plugin-rsc puts these vendor specifiers in `optimizeDeps.include`,
8
+ * and Vite resolves them from the app root, where pnpm's strict layout does
9
+ * not link the plugin unless the app lists it (#1050). Aliased to the copy
10
+ * the router resolves, which therefore also wins over an app's own
11
+ * @vitejs/plugin-rsc. Must hold every vendor entry the plugin includes:
12
+ * optimize-deps-vendor-resolution.test.ts checks the resolved config.
13
+ */
6
14
  export declare function getVendorAliases(): Record<string, string>;
@@ -18,6 +18,8 @@ export declare function notifyOnError(registry: Map<string, any>, error: unknown
18
18
  * URL / handler name for the log line; `elapsed` is the per-entry duration string.
19
19
  */
20
20
  export declare function resolvePrerenderError(registry: Map<string, any>, error: any, onError: "fail" | "warn", label: string, elapsed: string, phase: "prerender" | "static", routeKey?: string, pathname?: string): void;
21
+ /** Build scratch space, relative to the project root. Never shipped. */
22
+ export declare const RANGO_BUILD_DIR = "node_modules/.rangojs-router-build";
21
23
  export declare function resetStagedBuildAssets(projectRoot: string): void;
22
24
  /**
23
25
  * Write one content-hashed `export default <value>;` asset module into `dir`