@rangojs/router 0.16.0 → 0.18.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.
- package/README.md +255 -89
- package/dist/testing/vitest.js +252 -0
- package/dist/types/browser/cookie-name.d.ts +6 -0
- package/dist/types/browser/history-state.d.ts +16 -0
- package/dist/types/browser/navigation-transaction.d.ts +6 -0
- package/dist/types/browser/partial-update.d.ts +11 -0
- package/dist/types/browser/react/ScrollRestoration.d.ts +6 -6
- package/dist/types/browser/rsc-router.d.ts +1 -1
- package/dist/types/browser/scroll-restoration.d.ts +7 -0
- package/dist/types/cache/cache-exec-scope.d.ts +18 -1
- package/dist/types/cache/cache-key-utils.d.ts +17 -2
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +132 -19
- package/dist/types/cache/cache-tag.d.ts +92 -7
- package/dist/types/cache/cf/cf-base64.d.ts +6 -0
- package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
- package/dist/types/cache/cf/cf-cache-store.d.ts +185 -44
- package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
- package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +34 -0
- package/dist/types/cache/handle-capture.d.ts +41 -3
- package/dist/types/cache/handle-snapshot.d.ts +54 -13
- package/dist/types/cache/index.d.ts +1 -0
- package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
- package/dist/types/cache/segment-codec.d.ts +10 -3
- package/dist/types/cache/shell-memo.d.ts +178 -0
- package/dist/types/cache/shell-snapshot.d.ts +110 -21
- package/dist/types/cache/tag-invalidation.d.ts +30 -3
- package/dist/types/cache/taint.d.ts +1 -1
- package/dist/types/cache/types.d.ts +220 -44
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +111 -13
- package/dist/types/client.d.ts +4 -4
- package/dist/types/client.rsc.d.ts +4 -5
- package/dist/types/components/DefaultDocument.d.ts +5 -2
- package/dist/types/context-var.d.ts +6 -5
- package/dist/types/escape-script.d.ts +1 -1
- package/dist/types/handles/MetaTags.d.ts +5 -4
- package/dist/types/handles/Scripts.d.ts +8 -7
- package/dist/types/handles/meta.d.ts +2 -2
- package/dist/types/handles/script.d.ts +17 -16
- package/dist/types/href-client.d.ts +1 -1
- package/dist/types/html.d.ts +12 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +3 -2
- package/dist/types/loader-store.d.ts +7 -4
- package/dist/types/prerender/build-shell-capture.d.ts +11 -4
- package/dist/types/reverse.d.ts +36 -4
- package/dist/types/route-definition/dsl-helpers.d.ts +3 -3
- package/dist/types/route-definition/helpers-types.d.ts +33 -9
- package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
- package/dist/types/route-types.d.ts +1 -1
- package/dist/types/router/debug-manifest.d.ts +3 -2
- package/dist/types/router/error-handling.d.ts +20 -0
- package/dist/types/router/handler-context.d.ts +6 -0
- package/dist/types/router/instrument.d.ts +8 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +46 -5
- package/dist/types/router/middleware-types.d.ts +9 -3
- package/dist/types/router/router-context.d.ts +3 -1
- package/dist/types/router/router-interfaces.d.ts +24 -2
- package/dist/types/router/router-options.d.ts +8 -5
- package/dist/types/router/segment-resolution/fresh.d.ts +10 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +66 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +9 -19
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +23 -12
- package/dist/types/router/segment-resolution/mask-nested.d.ts +67 -26
- package/dist/types/router/segment-resolution/revalidation.d.ts +6 -2
- package/dist/types/router/segment-wrappers.d.ts +1 -1
- package/dist/types/rsc/full-payload.d.ts +14 -0
- package/dist/types/rsc/handler.d.ts +1 -1
- package/dist/types/rsc/response-route-handler.d.ts +1 -1
- package/dist/types/rsc/rsc-rendering.d.ts +1 -2
- package/dist/types/rsc/shell-build-manifest.d.ts +8 -0
- package/dist/types/rsc/shell-capture-constants.d.ts +61 -6
- package/dist/types/rsc/shell-capture.d.ts +151 -19
- package/dist/types/rsc/shell-serve.d.ts +140 -17
- package/dist/types/rsc/ssr-setup.d.ts +6 -6
- package/dist/types/rsc/types.d.ts +17 -0
- package/dist/types/server/context.d.ts +139 -15
- package/dist/types/server/cookie-store.d.ts +21 -0
- package/dist/types/server/handle-store.d.ts +26 -2
- package/dist/types/server/request-context.d.ts +182 -53
- package/dist/types/ssr/index.d.ts +24 -0
- package/dist/types/ssr/ssr-root.d.ts +9 -8
- package/dist/types/static-handler.d.ts +4 -1
- package/dist/types/testing/flight.entry.d.ts +7 -0
- package/dist/types/testing/generated-routes.d.ts +2 -2
- package/dist/types/testing/internal/context.d.ts +1 -1
- package/dist/types/testing/render-route.d.ts +32 -6
- package/dist/types/testing/run-loader.d.ts +18 -3
- package/dist/types/testing/serve-shell-request.d.ts +132 -0
- package/dist/types/testing/shell-status.d.ts +23 -10
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +28 -5
- package/dist/types/testing/vitest.d.ts +35 -1
- package/dist/types/theme/ThemeScript.d.ts +3 -3
- package/dist/types/types/cache-types.d.ts +14 -10
- package/dist/types/types/handler-context.d.ts +28 -1
- package/dist/types/types/loader-types.d.ts +8 -6
- package/dist/types/urls/pattern-types.d.ts +22 -18
- package/dist/types/urls/response-types.d.ts +3 -12
- package/dist/types/use-loader.d.ts +12 -3
- package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
- package/dist/types/vite/rango.d.ts +1 -1
- package/dist/types/vite/router-discovery.d.ts +29 -2
- package/dist/vite/index.js +1420 -1348
- package/package.json +2 -2
- package/skills/api-client/SKILL.md +22 -10
- package/skills/breadcrumbs/SKILL.md +75 -22
- package/skills/bundle-analysis/SKILL.md +22 -22
- package/skills/cache-guide/SKILL.md +306 -124
- package/skills/caching/SKILL.md +530 -98
- package/skills/catalog.json +16 -16
- package/skills/client-urls/SKILL.md +65 -38
- package/skills/cloudflare/SKILL.md +87 -20
- package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
- package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
- package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
- package/skills/comparison/SKILL.md +5 -0
- package/skills/comparison/references/framework-comparison.md +75 -57
- package/skills/composability/SKILL.md +38 -29
- package/skills/css/SKILL.md +10 -13
- package/skills/debug-manifest/SKILL.md +74 -31
- package/skills/defer-hydration/SKILL.md +52 -31
- package/skills/deployment-caching/SKILL.md +11 -3
- package/skills/document-cache/SKILL.md +98 -28
- package/skills/fonts/SKILL.md +16 -8
- package/skills/handler-use/SKILL.md +55 -17
- package/skills/hooks/SKILL.md +28 -20
- package/skills/hooks/data.md +23 -3
- package/skills/hooks/handle-and-actions.md +34 -17
- package/skills/hooks/navigation.md +39 -10
- package/skills/hooks/outlets.md +13 -6
- package/skills/hooks/state.md +39 -15
- package/skills/hooks/urls.md +7 -5
- package/skills/host-router/SKILL.md +64 -12
- package/skills/i18n/SKILL.md +60 -34
- package/skills/intercept/SKILL.md +161 -26
- package/skills/layout/SKILL.md +106 -50
- package/skills/links/SKILL.md +51 -19
- package/skills/loader/SKILL.md +386 -128
- package/skills/middleware/SKILL.md +129 -26
- package/skills/migrate-nextjs/SKILL.md +156 -70
- package/skills/migrate-nextjs/backend-host-swap.md +5 -2
- package/skills/migrate-react-router/SKILL.md +51 -39
- package/skills/migrate-react-router/component-migration.md +28 -7
- package/skills/migrate-react-router/data-and-actions.md +21 -6
- package/skills/migrate-react-router/route-mapping.md +19 -10
- package/skills/mime-routes/SKILL.md +12 -7
- package/skills/observability/SKILL.md +92 -14
- package/skills/parallel/SKILL.md +88 -47
- package/skills/ppr/SKILL.md +866 -379
- package/skills/prerender/SKILL.md +210 -108
- package/skills/rango/SKILL.md +115 -65
- package/skills/react-compiler/SKILL.md +6 -5
- package/skills/response-routes/SKILL.md +133 -25
- package/skills/route/SKILL.md +170 -60
- package/skills/router-setup/SKILL.md +420 -240
- package/skills/scripts/SKILL.md +39 -21
- package/skills/server-actions/SKILL.md +231 -59
- package/skills/shell-manifest/SKILL.md +28 -14
- package/skills/streams-and-websockets/SKILL.md +32 -14
- package/skills/tailwind/SKILL.md +37 -33
- package/skills/testing/SKILL.md +73 -33
- package/skills/testing/cache-prerender.md +60 -33
- package/skills/testing/client-components.md +59 -6
- package/skills/testing/e2e-parity.md +12 -2
- package/skills/testing/flight.md +19 -11
- package/skills/testing/handles.md +8 -5
- package/skills/testing/loader.md +26 -6
- package/skills/testing/middleware.md +8 -3
- package/skills/testing/predicates.md +120 -0
- package/skills/testing/render-handler.md +70 -22
- package/skills/testing/response-routes.md +11 -4
- package/skills/testing/reverse-and-types.md +20 -14
- package/skills/testing/serve-shell-request.md +188 -0
- package/skills/testing/server-actions.md +12 -3
- package/skills/testing/server-tree.md +9 -0
- package/skills/testing/setup.md +9 -5
- package/skills/theme/SKILL.md +155 -30
- package/skills/typesafety/SKILL.md +20 -9
- package/skills/typesafety/env-and-bindings.md +137 -50
- package/skills/typesafety/generated-files-and-cli.md +26 -14
- package/skills/typesafety/params-and-search.md +44 -19
- package/skills/typesafety/route-types.md +50 -14
- package/skills/use-cache/SKILL.md +224 -83
- package/skills/vercel/SKILL.md +35 -13
- package/skills/view-transitions/SKILL.md +42 -21
- package/src/__augment-tests__/augmented.check.ts +26 -1
- package/src/browser/cookie-name.ts +23 -0
- package/src/browser/history-state.ts +23 -0
- package/src/browser/index.ts +2 -2
- package/src/browser/navigation-bridge.ts +3 -4
- package/src/browser/navigation-transaction.ts +22 -2
- package/src/browser/partial-update.ts +35 -25
- package/src/browser/react/ScrollRestoration.tsx +6 -6
- package/src/browser/rsc-router.tsx +6 -1
- package/src/browser/scroll-restoration.ts +53 -6
- package/src/cache/cache-exec-scope.ts +37 -4
- package/src/cache/cache-key-utils.ts +23 -8
- package/src/cache/cache-policy.ts +22 -0
- package/src/cache/cache-runtime.ts +264 -68
- package/src/cache/cache-scope.ts +419 -43
- package/src/cache/cache-tag.ts +375 -11
- package/src/cache/cf/cf-base64.ts +36 -4
- package/src/cache/cf/cf-cache-constants.ts +12 -0
- package/src/cache/cf/cf-cache-store.ts +990 -348
- package/src/cache/cf/cf-cache-types.ts +32 -4
- package/src/cache/cf/cf-shell-frame.ts +258 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +143 -39
- package/src/cache/document-cache.ts +15 -0
- package/src/cache/handle-capture.ts +90 -10
- package/src/cache/handle-snapshot.ts +133 -28
- package/src/cache/index.ts +2 -0
- package/src/cache/isolate-tag-memo.ts +308 -0
- package/src/cache/segment-codec.ts +26 -7
- package/src/cache/shell-memo.ts +341 -0
- package/src/cache/shell-snapshot.ts +217 -27
- package/src/cache/tag-invalidation.ts +108 -22
- package/src/cache/taint.ts +1 -1
- package/src/cache/types.ts +225 -44
- package/src/cache/vercel/vercel-cache-store.ts +545 -61
- package/src/client.rsc.tsx +10 -9
- package/src/client.tsx +5 -4
- package/src/components/DefaultDocument.tsx +7 -2
- package/src/context-var.ts +6 -5
- package/src/escape-script.ts +1 -1
- package/src/handles/MetaTags.tsx +13 -11
- package/src/handles/Scripts.tsx +11 -10
- package/src/handles/meta.ts +2 -2
- package/src/handles/script.ts +17 -16
- package/src/href-client.ts +1 -1
- package/src/html.ts +12 -0
- package/src/index.rsc.ts +5 -0
- package/src/index.ts +1 -0
- package/src/loader-store.ts +7 -4
- package/src/prerender/build-shell-capture.ts +73 -22
- package/src/reverse.ts +44 -4
- package/src/route-definition/dsl-helpers.ts +121 -33
- package/src/route-definition/helpers-types.ts +33 -9
- package/src/route-definition/resolve-handler-use.ts +121 -6
- package/src/route-types.ts +0 -3
- package/src/router/debug-manifest.ts +10 -2
- package/src/router/error-handling.ts +51 -15
- package/src/router/handler-context.ts +71 -28
- package/src/router/instrument.ts +54 -2
- package/src/router/intercept-resolution.ts +141 -43
- package/src/router/loader-resolution.ts +115 -39
- package/src/router/match-api.ts +40 -26
- package/src/router/match-handlers.ts +5 -0
- package/src/router/match-middleware/background-revalidation.ts +161 -96
- package/src/router/match-middleware/cache-lookup.ts +110 -10
- package/src/router/match-middleware/cache-store.ts +48 -101
- package/src/router/middleware-types.ts +9 -6
- package/src/router/middleware.ts +75 -13
- package/src/router/prerender-match.ts +59 -19
- package/src/router/route-snapshot.ts +11 -1
- package/src/router/router-context.ts +2 -0
- package/src/router/router-interfaces.ts +25 -2
- package/src/router/router-options.ts +8 -5
- package/src/router/segment-resolution/fresh.ts +62 -21
- package/src/router/segment-resolution/helpers.ts +4 -2
- package/src/router/segment-resolution/loader-cache.ts +407 -76
- package/src/router/segment-resolution/loader-mask.ts +12 -22
- package/src/router/segment-resolution/loader-snapshot.ts +208 -56
- package/src/router/segment-resolution/mask-nested.ts +138 -44
- package/src/router/segment-resolution/revalidation.ts +61 -16
- package/src/router/segment-wrappers.ts +4 -0
- package/src/rsc/full-payload.ts +25 -1
- package/src/rsc/handler.ts +14 -2
- package/src/rsc/progressive-enhancement.ts +3 -2
- package/src/rsc/render-pipeline.ts +3 -0
- package/src/rsc/response-cache-serve.ts +9 -6
- package/src/rsc/response-route-handler.ts +11 -3
- package/src/rsc/rsc-rendering.ts +608 -225
- package/src/rsc/shell-build-manifest.ts +27 -9
- package/src/rsc/shell-capture-constants.ts +73 -6
- package/src/rsc/shell-capture.ts +1068 -296
- package/src/rsc/shell-serve.ts +316 -34
- package/src/rsc/ssr-setup.ts +14 -8
- package/src/rsc/types.ts +18 -0
- package/src/server/context.ts +300 -32
- package/src/server/cookie-store.ts +87 -61
- package/src/server/handle-store.ts +232 -7
- package/src/server/request-context.ts +297 -67
- package/src/ssr/index.tsx +136 -44
- package/src/ssr/ssr-root.tsx +9 -8
- package/src/static-handler.ts +4 -1
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/flight.entry.ts +14 -0
- package/src/testing/generated-routes.ts +2 -2
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/internal/flight-client-globals.ts +7 -5
- package/src/testing/render-route.tsx +85 -24
- package/src/testing/run-loader.ts +68 -6
- package/src/testing/serve-shell-request.ts +378 -0
- package/src/testing/shell-status.ts +34 -12
- package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
- package/src/testing/vitest.ts +62 -1
- package/src/theme/ThemeProvider.tsx +7 -6
- package/src/theme/ThemeScript.tsx +3 -3
- package/src/types/cache-types.ts +14 -10
- package/src/types/handler-context.ts +28 -1
- package/src/types/loader-types.ts +8 -6
- package/src/urls/pattern-types.ts +22 -18
- package/src/urls/response-types.ts +3 -23
- package/src/use-loader.tsx +12 -3
- package/src/vite/discovery/shell-prerender-phase.ts +9 -0
- package/src/vite/plugins/use-cache-transform.ts +118 -74
- package/src/vite/rango.ts +7 -3
- package/src/vite/router-discovery.ts +14 -4
|
@@ -16,14 +16,18 @@
|
|
|
16
16
|
* - transformHoistInlineDirective() for function-level hoisting
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import type { Plugin } from "vite";
|
|
19
|
+
import type { Plugin, Rollup } from "vite";
|
|
20
20
|
import type { ModuleExportMeta } from "@vitejs/plugin-rsc/transforms";
|
|
21
21
|
import path from "node:path";
|
|
22
|
-
import MagicString from "magic-string";
|
|
23
22
|
import { normalizePath, hashId } from "./expose-id-utils.js";
|
|
24
|
-
import {
|
|
23
|
+
import type { Counter } from "../debug.js";
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
// No static import of `magic-string` or `../debug.js` (the `debug` package):
|
|
26
|
+
// `rangoUseCacheTransform()` bundles this module into `dist/testing/vitest.js`,
|
|
27
|
+
// whose static imports are node builtins only, and every package it needs
|
|
28
|
+
// loads lazily, as `rangoUseClientTransform()`'s `vite` and plugin-rsc
|
|
29
|
+
// imports do. src/__tests__/installed-vitest-config.test.ts loads that file
|
|
30
|
+
// from a fixture holding only `package.json` and `dist/`.
|
|
27
31
|
|
|
28
32
|
const CACHE_RUNTIME_IMPORT = "@rangojs/router/cache-runtime";
|
|
29
33
|
|
|
@@ -33,12 +37,13 @@ const LAYOUT_TEMPLATE_PATTERN = /\/(layout|template)\.(tsx?|jsx?)$/;
|
|
|
33
37
|
|
|
34
38
|
export const USE_CACHE_DIRECTIVE_RE: RegExp = /^use cache(:\s*[\w-]+)?$/;
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
/**
|
|
41
|
+
* @param counter `rango:transform` timing counter, created by `rango()`
|
|
42
|
+
* (`createCounter` in ../debug.js); omitted when debugging is off.
|
|
43
|
+
*/
|
|
44
|
+
export function useCacheTransform(counter?: Counter): Plugin {
|
|
37
45
|
let projectRoot = "";
|
|
38
46
|
let isBuild = false;
|
|
39
|
-
let rscTransforms: typeof import("@vitejs/plugin-rsc/transforms") | null =
|
|
40
|
-
null;
|
|
41
|
-
const counter = createCounter(debug, "use-cache");
|
|
42
47
|
|
|
43
48
|
return {
|
|
44
49
|
name: "@rangojs/router:use-cache",
|
|
@@ -56,75 +61,15 @@ export function useCacheTransform(): Plugin {
|
|
|
56
61
|
async transform(code, id) {
|
|
57
62
|
// Only process in RSC environment
|
|
58
63
|
if (this.environment?.name !== "rsc") return;
|
|
59
|
-
|
|
60
|
-
// Quick bail: no "use cache" in source
|
|
61
|
-
if (!code.includes("use cache")) return;
|
|
62
|
-
|
|
63
|
-
// Skip node_modules and virtual modules
|
|
64
|
-
if (id.includes("/node_modules/") || id.startsWith("\0")) return;
|
|
65
|
-
|
|
66
|
-
// Only JS/TS files
|
|
67
|
-
if (!/\.(tsx?|jsx?|mjs)$/.test(id)) return;
|
|
64
|
+
if (!isUseCacheCandidate(code, id)) return;
|
|
68
65
|
|
|
69
66
|
const start = counter ? performance.now() : 0;
|
|
70
67
|
try {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
rscTransforms = await import("@vitejs/plugin-rsc/transforms");
|
|
74
|
-
} catch {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const {
|
|
80
|
-
hasDirective,
|
|
81
|
-
transformWrapExport,
|
|
82
|
-
transformHoistInlineDirective,
|
|
83
|
-
} = rscTransforms;
|
|
84
|
-
|
|
85
|
-
let ast: any;
|
|
86
|
-
try {
|
|
87
|
-
const { parseAst } = await import("vite");
|
|
88
|
-
ast = parseAst(code, { lang: "tsx" });
|
|
89
|
-
} catch {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// plugin-rsc 0.5.34 `matchDirective` does `stmt.directive.match(...)`
|
|
94
|
-
// after `"directive" in node`. Vite/oxc parseAst now emits
|
|
95
|
-
// `directive: null` on ordinary ExpressionStatements, so a file that
|
|
96
|
-
// mixes a `"use cache"` function with a sibling handler whose first
|
|
97
|
-
// statement is an expression throws and the wrap is dropped.
|
|
98
|
-
stripNullDirectiveFields(ast);
|
|
99
|
-
|
|
100
|
-
const filePath = normalizePath(path.relative(projectRoot, id));
|
|
101
|
-
const isLayoutOrTemplate = LAYOUT_TEMPLATE_PATTERN.test(id);
|
|
102
|
-
|
|
103
|
-
if (hasDirective(ast.body, "use cache")) {
|
|
104
|
-
return transformFileLevelUseCache(
|
|
105
|
-
code,
|
|
106
|
-
ast,
|
|
107
|
-
filePath,
|
|
108
|
-
id,
|
|
109
|
-
isBuild,
|
|
110
|
-
isLayoutOrTemplate,
|
|
111
|
-
transformWrapExport,
|
|
112
|
-
hasDirective,
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const functionResult = transformFunctionLevelUseCache(
|
|
117
|
-
code,
|
|
118
|
-
ast,
|
|
119
|
-
filePath,
|
|
120
|
-
id,
|
|
68
|
+
return await transformUseCache(code, id, {
|
|
69
|
+
root: projectRoot,
|
|
121
70
|
isBuild,
|
|
122
|
-
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
warnOnNearMissDirectives(ast, id, this.warn.bind(this));
|
|
126
|
-
|
|
127
|
-
if (functionResult) return functionResult;
|
|
71
|
+
warn: (message) => this.warn(message),
|
|
72
|
+
});
|
|
128
73
|
} finally {
|
|
129
74
|
counter?.record(id, performance.now() - start);
|
|
130
75
|
}
|
|
@@ -132,7 +77,105 @@ export function useCacheTransform(): Plugin {
|
|
|
132
77
|
};
|
|
133
78
|
}
|
|
134
79
|
|
|
135
|
-
|
|
80
|
+
/** Options for {@link transformUseCache}. */
|
|
81
|
+
export interface UseCacheTransformOptions {
|
|
82
|
+
/** Root the ids are relative to (Vite's `config.root`). */
|
|
83
|
+
root: string;
|
|
84
|
+
/** Build ids hash the path (`hashId`); dev ids are `<path>#<export>`. */
|
|
85
|
+
isBuild: boolean;
|
|
86
|
+
/** Sink for the near-miss directive warning. */
|
|
87
|
+
warn: (message: string) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Called when `@vitejs/plugin-rsc/transforms` fails to load; the module is
|
|
90
|
+
* then left unwrapped. The rango plugin omits it (skip silently).
|
|
91
|
+
*/
|
|
92
|
+
onTransformsError?: (error: unknown) => void;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Whether a module may carry a `"use cache"` directive the transform wraps. */
|
|
96
|
+
export function isUseCacheCandidate(code: string, id: string): boolean {
|
|
97
|
+
return (
|
|
98
|
+
// Quick bail: no "use cache" in source
|
|
99
|
+
code.includes("use cache") &&
|
|
100
|
+
// Skip node_modules and virtual modules
|
|
101
|
+
!id.includes("/node_modules/") &&
|
|
102
|
+
!id.startsWith("\0") &&
|
|
103
|
+
// Only JS/TS files
|
|
104
|
+
/\.(tsx?|jsx?|mjs)$/.test(id)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let rscTransforms: typeof import("@vitejs/plugin-rsc/transforms") | null = null;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Wrap a module's `"use cache"` functions with `registerCachedFunction`. The
|
|
112
|
+
* rango plugin runs it in the rsc environment; `rangoUseCacheTransform()`
|
|
113
|
+
* (testing/vitest.ts) runs it in a Vitest project, whose environment is `ssr`.
|
|
114
|
+
* Call it only for an {@link isUseCacheCandidate} module.
|
|
115
|
+
*/
|
|
116
|
+
export async function transformUseCache(
|
|
117
|
+
code: string,
|
|
118
|
+
id: string,
|
|
119
|
+
options: UseCacheTransformOptions,
|
|
120
|
+
): Promise<{ code: string; map: Rollup.ExistingRawSourceMap } | undefined> {
|
|
121
|
+
if (!rscTransforms) {
|
|
122
|
+
try {
|
|
123
|
+
rscTransforms = await import("@vitejs/plugin-rsc/transforms");
|
|
124
|
+
} catch (error) {
|
|
125
|
+
options.onTransformsError?.(error);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const { hasDirective, transformWrapExport, transformHoistInlineDirective } =
|
|
131
|
+
rscTransforms;
|
|
132
|
+
|
|
133
|
+
let ast: any;
|
|
134
|
+
try {
|
|
135
|
+
const { parseAst } = await import("vite");
|
|
136
|
+
ast = parseAst(code, { lang: "tsx" });
|
|
137
|
+
} catch {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// plugin-rsc 0.5.34 `matchDirective` does `stmt.directive.match(...)`
|
|
142
|
+
// after `"directive" in node`. Vite/oxc parseAst now emits
|
|
143
|
+
// `directive: null` on ordinary ExpressionStatements, so a file that
|
|
144
|
+
// mixes a `"use cache"` function with a sibling handler whose first
|
|
145
|
+
// statement is an expression throws and the wrap is dropped.
|
|
146
|
+
stripNullDirectiveFields(ast);
|
|
147
|
+
|
|
148
|
+
const filePath = normalizePath(path.relative(options.root, id));
|
|
149
|
+
const isLayoutOrTemplate = LAYOUT_TEMPLATE_PATTERN.test(id);
|
|
150
|
+
|
|
151
|
+
if (hasDirective(ast.body, "use cache")) {
|
|
152
|
+
return transformFileLevelUseCache(
|
|
153
|
+
code,
|
|
154
|
+
ast,
|
|
155
|
+
filePath,
|
|
156
|
+
id,
|
|
157
|
+
options.isBuild,
|
|
158
|
+
isLayoutOrTemplate,
|
|
159
|
+
transformWrapExport,
|
|
160
|
+
hasDirective,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const functionResult = transformFunctionLevelUseCache(
|
|
165
|
+
code,
|
|
166
|
+
ast,
|
|
167
|
+
filePath,
|
|
168
|
+
id,
|
|
169
|
+
options.isBuild,
|
|
170
|
+
transformHoistInlineDirective,
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
warnOnNearMissDirectives(ast, id, options.warn);
|
|
174
|
+
|
|
175
|
+
if (functionResult) return functionResult;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function transformFileLevelUseCache(
|
|
136
179
|
code: string,
|
|
137
180
|
ast: any,
|
|
138
181
|
filePath: string,
|
|
@@ -193,6 +236,7 @@ function transformFileLevelUseCache(
|
|
|
193
236
|
}
|
|
194
237
|
|
|
195
238
|
if (exportNames.length === 0) {
|
|
239
|
+
const { default: MagicString } = await import("magic-string");
|
|
196
240
|
const s = new MagicString(code);
|
|
197
241
|
const directive = findFileLevelDirective(ast);
|
|
198
242
|
if (directive) {
|
package/src/vite/rango.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
|
45
45
|
import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
|
|
46
46
|
import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
47
47
|
import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
48
|
-
import { createRangoDebugger, NS } from "./debug.js";
|
|
48
|
+
import { createCounter, createRangoDebugger, NS } from "./debug.js";
|
|
49
49
|
|
|
50
50
|
const debugConfig = createRangoDebugger(NS.config);
|
|
51
51
|
|
|
@@ -100,7 +100,7 @@ export { hasUseClientDirective };
|
|
|
100
100
|
* plugins: [
|
|
101
101
|
* react(),
|
|
102
102
|
* rango({ preset: 'cloudflare' }),
|
|
103
|
-
* cloudflare({ viteEnvironment: { name: 'rsc' } }),
|
|
103
|
+
* cloudflare({ viteEnvironment: { name: 'rsc', childEnvironments: ['ssr'] } }),
|
|
104
104
|
* ],
|
|
105
105
|
* });
|
|
106
106
|
* ```
|
|
@@ -565,7 +565,11 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
565
565
|
plugins.push(createLoaderDirectiveGuardPlugin());
|
|
566
566
|
plugins.push(createLoaderScanStubPlugin());
|
|
567
567
|
plugins.push(exposeActionId());
|
|
568
|
-
plugins.push(
|
|
568
|
+
plugins.push(
|
|
569
|
+
useCacheTransform(
|
|
570
|
+
createCounter(createRangoDebugger(NS.transform), "use-cache"),
|
|
571
|
+
),
|
|
572
|
+
);
|
|
569
573
|
plugins.push(exposeInternalIds());
|
|
570
574
|
plugins.push(exposeRouterId());
|
|
571
575
|
plugins.push(createVersionPlugin());
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* generation, virtual module codegen, and bundle post-processing.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { Plugin } from "vite";
|
|
9
|
+
import type { Plugin, ViteDevServer } from "vite";
|
|
10
10
|
import { createServer as createViteServer } from "vite";
|
|
11
11
|
import { resolve } from "node:path";
|
|
12
12
|
import { readFileSync } from "node:fs";
|
|
@@ -177,8 +177,9 @@ const injectedShellNotReadyPaths = new Set<string>();
|
|
|
177
177
|
* - Build: hashed IDs (forceBuild), hashClientRefs for production bundles
|
|
178
178
|
*
|
|
179
179
|
* Returns the ViteDevServer instance. Callers access .environments.rsc as needed.
|
|
180
|
+
* @internal Exported for tests.
|
|
180
181
|
*/
|
|
181
|
-
async function createTempRscServer(
|
|
182
|
+
export async function createTempRscServer(
|
|
182
183
|
state: DiscoveryState,
|
|
183
184
|
options: {
|
|
184
185
|
forceBuild?: boolean;
|
|
@@ -195,7 +196,7 @@ async function createTempRscServer(
|
|
|
195
196
|
*/
|
|
196
197
|
realSsrEntry?: boolean;
|
|
197
198
|
} = {},
|
|
198
|
-
) {
|
|
199
|
+
): Promise<ViteDevServer> {
|
|
199
200
|
// Install the Node ESM loader hook before any module evaluation so
|
|
200
201
|
// `cloudflare:*` specifiers in externalized/loader-delegated modules
|
|
201
202
|
// (e.g. packages plugin-rsc marks as external) resolve to stubs
|
|
@@ -216,7 +217,16 @@ async function createTempRscServer(
|
|
|
216
217
|
return createViteServer({
|
|
217
218
|
root: state.projectRoot,
|
|
218
219
|
configFile: false,
|
|
219
|
-
server: {
|
|
220
|
+
server: {
|
|
221
|
+
middlewareMode: true,
|
|
222
|
+
// Build mode: no file watching. buildStart installs the per-router tries
|
|
223
|
+
// into this realm and runShellPrerenderPhase reuses it after the bundles
|
|
224
|
+
// are written. A watched write in between (writeRouteTypesFiles' own
|
|
225
|
+
// <router>.named-routes.gen.ts, which every router file imports) can
|
|
226
|
+
// make Vite full-reload the RSC runner; the shell phase then matches in
|
|
227
|
+
// a fresh realm with no tries and a root path("/*") wins (#947).
|
|
228
|
+
...(options.forceBuild ? { watch: null } : {}),
|
|
229
|
+
},
|
|
220
230
|
appType: "custom",
|
|
221
231
|
logLevel: "silent",
|
|
222
232
|
resolve: resolveConfig,
|