@rangojs/router 0.22.1 → 0.23.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 (179) hide show
  1. package/dist/bin/rango.js +8 -3
  2. package/dist/testing/vitest.js +31 -1
  3. package/dist/types/browser/defer.d.ts +48 -0
  4. package/dist/types/browser/document-revealed.d.ts +17 -0
  5. package/dist/types/browser/event-controller.d.ts +7 -1
  6. package/dist/types/browser/navigation-transaction.d.ts +21 -7
  7. package/dist/types/browser/partial-update.d.ts +34 -5
  8. package/dist/types/browser/react/NavigationProvider.d.ts +13 -3
  9. package/dist/types/browser/react/filter-segment-order.d.ts +7 -0
  10. package/dist/types/browser/response-adapter.d.ts +7 -0
  11. package/dist/types/browser/types.d.ts +19 -9
  12. package/dist/types/browser/validate-redirect-origin.d.ts +11 -0
  13. package/dist/types/build/generate-route-types.d.ts +1 -1
  14. package/dist/types/build/route-types/router-processing.d.ts +1 -1
  15. package/dist/types/build/route-types/scan-filter.d.ts +16 -2
  16. package/dist/types/cache/cf/cf-cache-store.d.ts +16 -1
  17. package/dist/types/cache/cf/cf-cache-types.d.ts +23 -2
  18. package/dist/types/client-urls/client-urls.d.ts +1 -1
  19. package/dist/types/client-urls/hoisted-revalidate.d.ts +13 -0
  20. package/dist/types/client-urls/navigation.d.ts +0 -37
  21. package/dist/types/client-urls/revalidate-registry.d.ts +4 -0
  22. package/dist/types/client-urls/server-projection.d.ts +29 -1
  23. package/dist/types/client-urls/types.d.ts +34 -69
  24. package/dist/types/client.d.ts +0 -1
  25. package/dist/types/errors.d.ts +5 -0
  26. package/dist/types/handles/deferred-resolution.d.ts +2 -1
  27. package/dist/types/handles/pushed-by.d.ts +23 -0
  28. package/dist/types/loader-store.d.ts +8 -0
  29. package/dist/types/prefetch-markers.d.ts +11 -0
  30. package/dist/types/route-definition/helpers-types.d.ts +27 -0
  31. package/dist/types/router/is-action.d.ts +2 -1
  32. package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -2
  33. package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +241 -0
  34. package/dist/types/server/context.d.ts +21 -1
  35. package/dist/types/server/handle-store.d.ts +9 -1
  36. package/dist/types/server/request-context.d.ts +14 -1
  37. package/dist/types/server.d.ts +1 -0
  38. package/dist/types/testing/flight.entry.d.ts +1 -1
  39. package/dist/types/testing/index.d.ts +3 -3
  40. package/dist/types/testing/internal/action-id.d.ts +10 -1
  41. package/dist/types/testing/internal/client-urls-projection.d.ts +16 -0
  42. package/dist/types/testing/internal/test-action.d.ts +8 -0
  43. package/dist/types/testing/run-loader.d.ts +2 -1
  44. package/dist/types/testing/run-revalidate.d.ts +74 -0
  45. package/dist/types/testing/run-transition-when.d.ts +2 -3
  46. package/dist/types/testing/serve-shell-request.d.ts +38 -0
  47. package/dist/types/testing/vitest.d.ts +11 -0
  48. package/dist/types/types/boundaries.d.ts +9 -0
  49. package/dist/types/types/handler-context.d.ts +14 -0
  50. package/dist/types/types/loader-types.d.ts +30 -0
  51. package/dist/types/types/segments.d.ts +21 -4
  52. package/dist/types/urls/path-helper-types.d.ts +25 -4
  53. package/dist/types/urls/type-extraction.d.ts +6 -2
  54. package/dist/types/vite/discovery/discover-routers.d.ts +9 -0
  55. package/dist/types/vite/discovery/state.d.ts +11 -4
  56. package/dist/types/vite/plugins/client-urls-revalidate-hoist.d.ts +54 -0
  57. package/dist/types/vite/plugins/hoist/literal.d.ts +83 -0
  58. package/dist/types/vite/plugins/hoist/scope.d.ts +40 -0
  59. package/dist/types/vite/plugins/hoist/source.d.ts +41 -0
  60. package/dist/types/vite/plugins/transition-when-hoist.d.ts +8 -11
  61. package/dist/types/vite/router-discovery.d.ts +10 -0
  62. package/dist/vite/index.js +842 -308
  63. package/package.json +1 -1
  64. package/skills/caching/SKILL.md +42 -5
  65. package/skills/catalog.json +2 -2
  66. package/skills/client-urls/SKILL.md +113 -24
  67. package/skills/cloudflare/SKILL.md +14 -9
  68. package/skills/hooks/SKILL.md +11 -3
  69. package/skills/links/SKILL.md +24 -0
  70. package/skills/loader/SKILL.md +192 -1
  71. package/skills/migrate-nextjs/SKILL.md +2 -2
  72. package/skills/migrate-react-router/SKILL.md +10 -7
  73. package/skills/migrate-react-router/data-and-actions.md +1 -1
  74. package/skills/ppr/SKILL.md +13 -0
  75. package/skills/prerender/SKILL.md +22 -8
  76. package/skills/rango/SKILL.md +12 -6
  77. package/skills/route/SKILL.md +139 -0
  78. package/skills/testing/SKILL.md +3 -2
  79. package/skills/testing/client-components.md +1 -1
  80. package/skills/testing/predicates.md +67 -32
  81. package/skills/testing/serve-shell-request.md +88 -18
  82. package/skills/testing/setup.md +2 -2
  83. package/skills/typesafety/route-types.md +2 -2
  84. package/skills/view-transitions/SKILL.md +26 -0
  85. package/src/browser/defer.ts +82 -0
  86. package/src/browser/document-revealed.ts +52 -0
  87. package/src/browser/event-controller.ts +43 -32
  88. package/src/browser/navigation-bridge.ts +64 -14
  89. package/src/browser/navigation-client.ts +48 -36
  90. package/src/browser/navigation-store.ts +13 -0
  91. package/src/browser/navigation-transaction.ts +25 -8
  92. package/src/browser/partial-update.ts +528 -135
  93. package/src/browser/prefetch/fetch.ts +2 -1
  94. package/src/browser/react/NavigationProvider.tsx +47 -28
  95. package/src/browser/react/filter-segment-order.ts +13 -2
  96. package/src/browser/response-adapter.ts +20 -0
  97. package/src/browser/rsc-router.tsx +17 -45
  98. package/src/browser/server-action-bridge.ts +19 -63
  99. package/src/browser/types.ts +19 -9
  100. package/src/browser/validate-redirect-origin.ts +16 -0
  101. package/src/build/generate-route-types.ts +1 -0
  102. package/src/build/route-types/router-processing.ts +3 -6
  103. package/src/build/route-types/scan-filter.ts +37 -10
  104. package/src/cache/cf/cf-cache-store.ts +59 -21
  105. package/src/cache/cf/cf-cache-types.ts +24 -2
  106. package/src/cache/document-cache.ts +22 -1
  107. package/src/client-urls/client-urls.ts +22 -6
  108. package/src/client-urls/hoisted-revalidate.ts +25 -0
  109. package/src/client-urls/navigation.ts +0 -96
  110. package/src/client-urls/revalidate-registry.ts +30 -0
  111. package/src/client-urls/server-projection.ts +151 -65
  112. package/src/client-urls/types.ts +39 -71
  113. package/src/client.tsx +9 -5
  114. package/src/errors.ts +15 -0
  115. package/src/handles/deferred-resolution.ts +28 -5
  116. package/src/handles/pushed-by.ts +122 -0
  117. package/src/loader-store.ts +18 -7
  118. package/src/prefetch-markers.ts +13 -0
  119. package/src/route-content-wrapper.tsx +18 -4
  120. package/src/route-definition/dsl-helpers.ts +27 -4
  121. package/src/route-definition/helpers-types.ts +27 -1
  122. package/src/router/intercept-resolution.ts +6 -4
  123. package/src/router/is-action.ts +2 -1
  124. package/src/router/loader-resolution.ts +83 -4
  125. package/src/router/match-api.ts +36 -1
  126. package/src/router/match-middleware/background-revalidation.ts +11 -1
  127. package/src/router/match-middleware/cache-lookup.ts +29 -6
  128. package/src/router/match-middleware/cache-store.ts +17 -1
  129. package/src/router/match-result.ts +14 -2
  130. package/src/router/navigation-snapshot.ts +2 -1
  131. package/src/router/segment-resolution/fresh.ts +22 -18
  132. package/src/router/segment-resolution/loader-cache.ts +2 -1
  133. package/src/router/segment-resolution/loader-mask.ts +5 -3
  134. package/src/router/segment-resolution/prefetch-deferral.ts +543 -0
  135. package/src/router/segment-resolution/revalidation.ts +169 -60
  136. package/src/rsc/rsc-rendering.ts +50 -7
  137. package/src/rsc/shell-capture.ts +2 -1
  138. package/src/segment-loader-promise.ts +23 -20
  139. package/src/segment-system.tsx +60 -26
  140. package/src/server/context.ts +39 -5
  141. package/src/server/handle-store.ts +104 -8
  142. package/src/server/request-context.ts +21 -1
  143. package/src/server.ts +4 -0
  144. package/src/testing/action-form.ts +2 -11
  145. package/src/testing/e2e/page-helpers.ts +3 -1
  146. package/src/testing/flight.entry.ts +1 -0
  147. package/src/testing/index.ts +6 -3
  148. package/src/testing/internal/action-id.ts +16 -1
  149. package/src/testing/internal/client-urls-projection.ts +70 -0
  150. package/src/testing/internal/test-action.ts +25 -0
  151. package/src/testing/run-loader.ts +2 -1
  152. package/src/testing/run-revalidate.ts +142 -0
  153. package/src/testing/run-transition-when.ts +7 -8
  154. package/src/testing/serve-shell-request.ts +116 -6
  155. package/src/testing/vitest.ts +67 -1
  156. package/src/types/boundaries.ts +12 -0
  157. package/src/types/handler-context.ts +14 -0
  158. package/src/types/loader-types.ts +30 -0
  159. package/src/types/segments.ts +26 -4
  160. package/src/urls/path-helper-types.ts +27 -5
  161. package/src/urls/type-extraction.ts +30 -10
  162. package/src/use-loader.tsx +18 -13
  163. package/src/vite/discovery/client-urls-projection.ts +20 -21
  164. package/src/vite/discovery/discover-routers.ts +94 -26
  165. package/src/vite/discovery/state.ts +20 -4
  166. package/src/vite/discovery/virtual-module-codegen.ts +22 -17
  167. package/src/vite/plugins/client-urls-revalidate-hoist.ts +564 -0
  168. package/src/vite/plugins/hoist/literal.ts +417 -0
  169. package/src/vite/plugins/hoist/scope.ts +370 -0
  170. package/src/vite/plugins/hoist/source.ts +84 -0
  171. package/src/vite/plugins/transition-when-hoist.ts +113 -779
  172. package/src/vite/rango.ts +2 -0
  173. package/src/vite/router-discovery.ts +93 -32
  174. package/dist/types/client-urls/revalidate-chain.d.ts +0 -33
  175. package/dist/types/client-urls/revalidation-protocol.d.ts +0 -25
  176. package/dist/types/testing/run-client-revalidate.d.ts +0 -43
  177. package/src/client-urls/revalidate-chain.ts +0 -83
  178. package/src/client-urls/revalidation-protocol.ts +0 -56
  179. package/src/testing/run-client-revalidate.ts +0 -92
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Literal-level helpers shared by the build-time predicate hoists
3
+ * (transition-when-hoist.ts moves a `when` from a server module into a
4
+ * "use client" one; client-urls-revalidate-hoist.ts moves a `revalidate()`
5
+ * from a "use client" module into a server one): finding a urls-callback
6
+ * helper's calls, the lexical-capture check, and the free imports a literal
7
+ * re-emits in its new module.
8
+ */
9
+ import { type ImportBinding, type Node, type Reference, type Scope } from "./scope.js";
10
+ /** The offset after the directive prologue (0 when there is none). */
11
+ export declare function directivePrologueEnd(program: Node): number;
12
+ export declare function parseLang(file: string): "ts" | "tsx" | "jsx";
13
+ export declare function unwrapExpression(node: Node): Node;
14
+ export declare function isFunctionLiteral(node: Node): boolean;
15
+ export declare function propertyKeyIs(prop: Node, name: string): boolean;
16
+ /** Which helper calls {@link findHelperCalls} looks for. */
17
+ interface HelperCallSpec {
18
+ /** Module specifiers the builder (and a direct helper import) come from. */
19
+ readonly sources: ReadonlySet<string>;
20
+ /** The builder export whose callback's first parameter hands out `helper`. */
21
+ readonly builder: string;
22
+ readonly helper: string;
23
+ /** A direct import of `helper` from `sources` counts too. */
24
+ readonly directImport: boolean;
25
+ }
26
+ interface HelperCall {
27
+ readonly call: Node;
28
+ readonly scope: Scope;
29
+ }
30
+ /**
31
+ * Every call of `spec.helper` the builder's callback hands out: destructured,
32
+ * renamed or as `helpers.<helper>`, at any depth of the callback, plus a
33
+ * direct import when `spec.directImport`. A builder is recognised by its
34
+ * import (named, renamed, or through a namespace); any other function of the
35
+ * same name is left alone.
36
+ */
37
+ export declare function findHelperCalls(program: Node, scopeOf: Map<Node, Scope>, moduleScope: Scope, imports: Map<string, ImportBinding>, spec: HelperCallSpec): HelperCall[];
38
+ /**
39
+ * What a lexical-capture error says, per hoist direction. `lexical` explains
40
+ * each construct (`this`, `arguments`, `super`, `new.target`); `captureHint`
41
+ * and `loadsHint` follow every capture and module-load message;
42
+ * `importMetaWhy`, `importMetaMemberWhy` and `dynamicImportWhy` explain the
43
+ * module-loading expressions.
44
+ */
45
+ export interface LexicalCaptureMessages {
46
+ readonly lexical: Readonly<Record<string, string>>;
47
+ readonly captureHint: string;
48
+ readonly loadsHint: string;
49
+ readonly importMetaWhy: string;
50
+ readonly importMetaMemberWhy: string;
51
+ readonly dynamicImportWhy: string;
52
+ }
53
+ /**
54
+ * The first use in a literal of a lexical context it would lose when hoisted
55
+ * (`this`, `arguments`, `super`, `new.target` of an enclosing function or
56
+ * object), or of a module-loading expression the build cannot check
57
+ * (`import()`, `import.meta` other than `import.meta.env`). A nested
58
+ * non-arrow function (or class body) owns its `this`/`arguments`, so uses
59
+ * inside one are fine; a method literal owns them too, but its `super`
60
+ * loses the object it was defined on.
61
+ */
62
+ export declare function findLexicalCapture(literal: Node, references: readonly Reference[], code: string, messages: LexicalCaptureMessages): {
63
+ node: Node;
64
+ detail: string;
65
+ } | null;
66
+ /** The free references of a literal, by what they resolve to. */
67
+ interface FreeReferences {
68
+ /** Import local name -> whether any use is a value use. */
69
+ readonly imports: Map<string, boolean>;
70
+ /** Value references to a binding declared outside the literal that is not an import. */
71
+ readonly bindings: readonly Reference[];
72
+ /** References declared nowhere (window, URL, console, ...). */
73
+ readonly globals: readonly Reference[];
74
+ }
75
+ /** Every reference inside `literal` to something declared outside it. */
76
+ export declare function collectFreeReferences(literal: Node, references: readonly Reference[], moduleScope: Scope, imports: Map<string, ImportBinding>): FreeReferences;
77
+ /**
78
+ * Re-emit the imports a literal uses, grouped per source, type-only uses as
79
+ * `import type`. `checkValueImport` runs first for each value use and throws
80
+ * to reject one.
81
+ */
82
+ export declare function emitImports(used: Map<string, boolean>, imports: Map<string, ImportBinding>, checkValueImport: (local: string, binding: ImportBinding) => Promise<void> | void): Promise<string[]>;
83
+ export {};
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Scope analysis shared by the build-time predicate hoists
3
+ * (transition-when-hoist.ts, client-urls-revalidate-hoist.ts): a module's
4
+ * scope tree, every identifier reference, and its imports. Enough of ES
5
+ * scoping for the free-variable analysis of one literal.
6
+ */
7
+ export type Node = any;
8
+ export interface ImportBinding {
9
+ readonly source: string;
10
+ /** "default", "*", or the imported name. */
11
+ readonly imported: string;
12
+ readonly typeOnly: boolean;
13
+ }
14
+ export declare class Scope {
15
+ readonly parent: Scope | null;
16
+ readonly isFunction: boolean;
17
+ readonly node: Node;
18
+ readonly declarations: Set<string>;
19
+ constructor(parent: Scope | null, isFunction: boolean, node: Node);
20
+ nearestFunction(): Scope;
21
+ lookup(name: string): Scope | null;
22
+ }
23
+ export interface Reference {
24
+ readonly node: Node;
25
+ readonly scope: Scope;
26
+ readonly typeOnly: boolean;
27
+ }
28
+ export declare const TYPE_KEYS: ReadonlySet<string>;
29
+ /**
30
+ * Scope tree and every identifier reference of a module, TS type positions
31
+ * flagged. Enough of ES scoping for free-variable analysis of one literal:
32
+ * var hoists to the function scope, let/const/class to the block, function
33
+ * declarations to their block.
34
+ */
35
+ export declare function analyzeScopes(program: Node): {
36
+ moduleScope: Scope;
37
+ references: Reference[];
38
+ scopeOf: Map<Node, Scope>;
39
+ };
40
+ export declare function collectImports(program: Node): Map<string, ImportBinding>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Source reading shared by the build-time predicate hoists
3
+ * (transition-when-hoist.ts, client-urls-revalidate-hoist.ts): which ids are
4
+ * source files, reading one off disk, resolving an import to the file it
5
+ * names, and the "emitted or disk" lookup behind their `?rango-*` modules.
6
+ */
7
+ /** A file path (query already stripped) a hoist transform may rewrite. */
8
+ export declare const SOURCE_FILE_RE: RegExp;
9
+ export declare function readSource(file: string): Promise<string | null>;
10
+ /** The part of a plugin context {@link resolveSourceTarget} needs. */
11
+ export interface SourceResolver {
12
+ resolve(source: string, importer?: string): Promise<{
13
+ id: string;
14
+ external?: boolean | string;
15
+ } | null>;
16
+ }
17
+ /**
18
+ * The file `source` names when imported from `importer`, query stripped, or
19
+ * null when it is external or virtual. `skipNodeModules` also yields null for
20
+ * a dependency: transition-when-hoist only looks for `import "server-only"`
21
+ * in project files, while client-urls-revalidate-hoist must see the
22
+ * "use client" directive of a package's modules too.
23
+ */
24
+ export declare function resolveSourceTarget(ctx: SourceResolver, source: string, importer: string, options: {
25
+ readonly skipNodeModules: boolean;
26
+ }): Promise<string | null>;
27
+ /** What a hoist's RSC transform emitted for a file, and the disk source it saw. */
28
+ export interface EmittedEntry<T> {
29
+ readonly disk: string | null;
30
+ readonly value: T;
31
+ }
32
+ export declare function recordEmitted<T>(emitted: Map<string, EmittedEntry<T>>, file: string, value: T): Promise<void>;
33
+ /**
34
+ * What a `?rango-*` load serves for `hoistedFile`: the transform's emission
35
+ * when it saw the current disk source (or the file is gone), else
36
+ * `rehoist(disk)`. The transform hoists the pipeline code, which an earlier
37
+ * plugin may have changed, so re-hoisting the disk source is the fallback only
38
+ * for an environment loading before the RSC transform ran or for an edit the
39
+ * RSC environment has not re-transformed yet. Undefined when neither exists.
40
+ */
41
+ export declare function loadEmittedOrDisk<T>(emitted: ReadonlyMap<string, EmittedEntry<T>>, hoistedFile: string, rehoist: (disk: string) => Promise<T | undefined>): Promise<T | undefined>;
@@ -2,14 +2,14 @@ import type { Plugin } from "vite";
2
2
  import MagicString from "magic-string";
3
3
  /** Specifiers that can never load in the browser. */
4
4
  export declare function isServerOnlySpecifier(source: string): boolean;
5
- export interface HoistTransitionWhenDeps {
5
+ interface HoistTransitionWhenDeps {
6
6
  /**
7
7
  * Whether an import the literal re-emits is server-only beyond its
8
8
  * specifier (the plugin resolves it and looks for `import "server-only"`).
9
9
  */
10
10
  isServerOnlyImport?(source: string): Promise<boolean> | boolean;
11
11
  }
12
- export interface HoistTransitionWhenResult {
12
+ interface HoistTransitionWhenResult {
13
13
  readonly code: string;
14
14
  readonly map: ReturnType<MagicString["generateMap"]>;
15
15
  /** Virtual module source per hoisted literal, by index. */
@@ -32,14 +32,11 @@ export declare function parseHoistedWhenId(id: string): {
32
32
  * evaluated) and serves the `?rango-when=N` modules in every environment
33
33
  * (RSC, SSR and client all load them).
34
34
  *
35
- * `load` serves the modules the transform emitted, not a re-hoist of the file
36
- * on disk: the transform hoists the pipeline code, which an earlier plugin
37
- * may have changed, so re-hoisting the disk source can number the literals
38
- * differently and serve the wrong one for index N. The disk source is the
39
- * fallback only when the transform has not seen the current file: an
40
- * environment loading before the RSC transform ran (the order environments
41
- * ask in is not fixed), or an edit the RSC environment has not re-transformed
42
- * yet (serving the last transform would then be stale). The map is per
43
- * plugin instance, so every environment of one dev server or build shares it.
35
+ * `load` serves the modules the transform emitted (loadEmittedOrDisk), not a
36
+ * re-hoist of the file on disk: re-hoisting a disk source an earlier plugin
37
+ * changed can number the literals differently and serve the wrong one for
38
+ * index N. The map is per plugin instance, so every environment of one dev
39
+ * server or build shares it.
44
40
  */
45
41
  export declare function transitionWhenHoistPlugin(): Plugin;
42
+ export {};
@@ -8,6 +8,16 @@
8
8
  import type { Plugin, ViteDevServer } from "vite";
9
9
  import { VIRTUAL_ROUTES_MANIFEST_ID, type DiscoveryState, type PluginOptions } from "./discovery/state.js";
10
10
  export { VIRTUAL_ROUTES_MANIFEST_ID };
11
+ /** The slice of a Vite environment module graph the route-file watcher reads. */
12
+ interface ModulesByFileGraph {
13
+ getModulesByFile(file: string): ReadonlySet<unknown> | undefined;
14
+ }
15
+ /**
16
+ * Whether the dev route-file watcher ignores `file`: it sits in a directory
17
+ * every discovery scan skips (isInSkippedScanDir) and the RSC graph has not
18
+ * loaded it. See docs/manifests.md, "A reload no file of the app asked for".
19
+ */
20
+ export declare function isFileOutsideApp(root: string, file: string, rscGraph: ModulesByFileGraph | undefined): boolean;
11
21
  /**
12
22
  * Create a minimal Vite server for router discovery.
13
23
  *