@rangojs/router 0.0.0-experimental.31 → 0.0.0-experimental.3232cd17
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/AGENTS.md +4 -0
- package/README.md +198 -44
- package/dist/bin/rango.js +287 -105
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3248 -1117
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +73 -21
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +107 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +245 -21
- package/skills/caching/SKILL.md +302 -6
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +270 -30
- package/skills/host-router/SKILL.md +82 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +294 -30
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +97 -5
- package/skills/router-setup/SKILL.md +90 -5
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +120 -0
- package/skills/typesafety/SKILL.md +329 -27
- package/skills/use-cache/SKILL.md +36 -5
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +67 -40
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +86 -147
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +148 -19
- package/src/browser/navigation-client.ts +187 -67
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/partial-update.ts +123 -94
- package/src/browser/prefetch/cache.ts +214 -36
- package/src/browser/prefetch/fetch.ts +260 -38
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +126 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +93 -11
- package/src/browser/react/NavigationProvider.tsx +115 -34
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +46 -11
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +52 -1
- package/src/browser/rsc-router.tsx +215 -76
- package/src/browser/scroll-restoration.ts +46 -39
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -50
- package/src/browser/types.ts +95 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +278 -96
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +149 -43
- package/src/cache/cache-scope.ts +148 -81
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2550 -93
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +78 -27
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +52 -26
- package/src/index.ts +100 -38
- package/src/internal-debug.ts +2 -4
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +437 -274
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +113 -37
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +52 -10
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -17
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +45 -22
- package/src/router/handler-context.ts +83 -41
- package/src/router/intercept-resolution.ts +25 -23
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +213 -30
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +121 -205
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +27 -6
- package/src/router/match-middleware/cache-lookup.ts +205 -249
- package/src/router/match-middleware/cache-store.ts +45 -32
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +104 -40
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +173 -143
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +192 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +6 -28
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +242 -75
- package/src/router/segment-resolution/helpers.ts +64 -25
- package/src/router/segment-resolution/loader-cache.ts +41 -37
- package/src/router/segment-resolution/revalidation.ts +456 -372
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +4 -1
- package/src/router/segment-wrappers.ts +2 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +134 -43
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -383
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +30 -3
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +56 -54
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -67
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +25 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +272 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +309 -61
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +348 -128
- package/src/ssr/index.tsx +23 -15
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +233 -81
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +37 -14
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +192 -99
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +51 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +187 -69
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +49 -98
- package/src/vite/plugins/expose-id-utils.ts +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +41 -20
- package/src/vite/plugins/virtual-entries.ts +2 -17
- package/src/vite/rango.ts +257 -289
- package/src/vite/router-discovery.ts +930 -140
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +27 -29
- package/src/vite/utils/shared-utils.ts +92 -42
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -22,6 +22,32 @@ export function markSelfGenWrite(
|
|
|
22
22
|
export function consumeSelfGenWrite(
|
|
23
23
|
state: DiscoveryState,
|
|
24
24
|
filePath: string,
|
|
25
|
+
): boolean {
|
|
26
|
+
return checkSelfGenWrite(state, filePath, true);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Non-consuming variant. Used by the `handleHotUpdate` plugin hook to
|
|
31
|
+
* suppress vite's HMR cascade for our own gen-file writes WITHOUT
|
|
32
|
+
* consuming the entry — `consumeSelfGenWrite` (called later from the
|
|
33
|
+
* chokidar `change` handler in `handleRouteFileChange`) still needs to
|
|
34
|
+
* see and consume the same entry to short-circuit our regen path.
|
|
35
|
+
*
|
|
36
|
+
* Both hooks fire for the same file change event:
|
|
37
|
+
* - `handleHotUpdate` runs first (vite's HMR pipeline).
|
|
38
|
+
* - chokidar `change` callback runs after (filesystem watcher).
|
|
39
|
+
*/
|
|
40
|
+
export function peekSelfGenWrite(
|
|
41
|
+
state: DiscoveryState,
|
|
42
|
+
filePath: string,
|
|
43
|
+
): boolean {
|
|
44
|
+
return checkSelfGenWrite(state, filePath, false);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function checkSelfGenWrite(
|
|
48
|
+
state: DiscoveryState,
|
|
49
|
+
filePath: string,
|
|
50
|
+
consume: boolean,
|
|
25
51
|
): boolean {
|
|
26
52
|
const info = state.selfWrittenGenFiles.get(filePath);
|
|
27
53
|
if (!info) return false;
|
|
@@ -33,7 +59,7 @@ export function consumeSelfGenWrite(
|
|
|
33
59
|
const current = readFileSync(filePath, "utf-8");
|
|
34
60
|
const currentHash = createHash("sha256").update(current).digest("hex");
|
|
35
61
|
if (currentHash === info.hash) {
|
|
36
|
-
state.selfWrittenGenFiles.delete(filePath);
|
|
62
|
+
if (consume) state.selfWrittenGenFiles.delete(filePath);
|
|
37
63
|
return true;
|
|
38
64
|
}
|
|
39
65
|
// Hash mismatch: file was changed externally. Keep the entry so a
|
|
@@ -13,11 +13,25 @@ export const VIRTUAL_ROUTES_MANIFEST_ID = "virtual:rsc-router/routes-manifest";
|
|
|
13
13
|
export interface PluginOptions {
|
|
14
14
|
enableBuildPrerender?: boolean;
|
|
15
15
|
staticRouteTypesGeneration?: boolean;
|
|
16
|
-
include?: string[];
|
|
17
|
-
exclude?: string[];
|
|
18
16
|
// Mutable ref for deferred auto-discovery (node preset).
|
|
19
17
|
// The auto-discover config() hook populates this before configResolved.
|
|
20
18
|
routerPathRef?: { path?: string };
|
|
19
|
+
/** Build-time env option from rango() config. */
|
|
20
|
+
buildEnv?: import("../plugin-types.js").BuildEnvOption;
|
|
21
|
+
/** Deployment preset (needed for buildEnv "auto" resolution). */
|
|
22
|
+
preset?: "node" | "cloudflare" | "vercel";
|
|
23
|
+
/**
|
|
24
|
+
* Route-discovery scan filter (glob include/exclude) from rango() config.
|
|
25
|
+
* Compiled into `DiscoveryState.scanFilter` once `projectRoot` is known.
|
|
26
|
+
*/
|
|
27
|
+
discovery?: { include?: string[]; exclude?: string[] };
|
|
28
|
+
/**
|
|
29
|
+
* Shared context the built-in clientChunks strategy reads. Discovery populates
|
|
30
|
+
* it (registered fallback hashes + single-router name) before the client build
|
|
31
|
+
* invokes the strategy. Present only when the built-in strategy is active
|
|
32
|
+
* (`clientChunks: true`/default); undefined for `false` or a custom function.
|
|
33
|
+
*/
|
|
34
|
+
clientChunkCtx?: import("../utils/client-chunks.js").ClientChunkContext;
|
|
21
35
|
}
|
|
22
36
|
|
|
23
37
|
export interface PrecomputedEntry {
|
|
@@ -43,6 +57,21 @@ export interface DiscoveryState {
|
|
|
43
57
|
projectRoot: string;
|
|
44
58
|
isBuildMode: boolean;
|
|
45
59
|
userResolveAlias: any;
|
|
60
|
+
/**
|
|
61
|
+
* Data-only slice of the user's resolved config (resolve.* incl. native
|
|
62
|
+
* tsconfigPaths, define, oxc) mirrored into the discovery temp server so it
|
|
63
|
+
* resolves and transforms modules the same way the real environment does.
|
|
64
|
+
* See `utils/forward-user-plugins.ts`.
|
|
65
|
+
*/
|
|
66
|
+
userRunnerConfig:
|
|
67
|
+
| import("../utils/forward-user-plugins.js").ForwardedRunnerConfig
|
|
68
|
+
| undefined;
|
|
69
|
+
/**
|
|
70
|
+
* User resolution plugins (resolveId/load), stripped to their resolution
|
|
71
|
+
* surface, forwarded into the discovery temp server. Lets third-party
|
|
72
|
+
* resolvers such as vite-tsconfig-paths participate in discovery.
|
|
73
|
+
*/
|
|
74
|
+
userResolvePlugins: import("vite").Plugin[];
|
|
46
75
|
scanFilter: ScanFilter | undefined;
|
|
47
76
|
cachedRouterFiles: string[] | undefined;
|
|
48
77
|
opts: PluginOptions | undefined;
|
|
@@ -58,8 +87,8 @@ export interface DiscoveryState {
|
|
|
58
87
|
|
|
59
88
|
prerenderManifestEntries: Record<string, string> | null;
|
|
60
89
|
staticManifestEntries: Record<string, string> | null;
|
|
61
|
-
|
|
62
|
-
|
|
90
|
+
handlerChunkInfoMap: Map<string, ChunkInfo>;
|
|
91
|
+
staticHandlerChunkInfoMap: Map<string, ChunkInfo>;
|
|
63
92
|
rscEntryFileName: string | null;
|
|
64
93
|
resolvedPrerenderModules: Map<string, string[]> | undefined;
|
|
65
94
|
resolvedStaticModules: Map<string, string[]> | undefined;
|
|
@@ -69,6 +98,19 @@ export interface DiscoveryState {
|
|
|
69
98
|
devServer: any;
|
|
70
99
|
selfWrittenGenFiles: Map<string, { at: number; hash: string }>;
|
|
71
100
|
SELF_WRITE_WINDOW_MS: number;
|
|
101
|
+
|
|
102
|
+
/** Resolved build-time env bindings (set during buildStart/configureServer). */
|
|
103
|
+
resolvedBuildEnv?: Record<string, unknown>;
|
|
104
|
+
/** Cleanup function for build-time env resources (e.g., miniflare). */
|
|
105
|
+
buildEnvDispose?: (() => Promise<void> | void) | null;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Set when the most recent HMR re-discovery threw. Cleared on the next
|
|
109
|
+
* successful discovery. Surfaced via debug logs so we can detect "manifest
|
|
110
|
+
* frozen at last-good after error → user fix in non-route file → no
|
|
111
|
+
* rediscovery trigger" scenarios.
|
|
112
|
+
*/
|
|
113
|
+
lastDiscoveryError?: { message: string; at: number } | null;
|
|
72
114
|
}
|
|
73
115
|
|
|
74
116
|
export function createDiscoveryState(
|
|
@@ -80,6 +122,8 @@ export function createDiscoveryState(
|
|
|
80
122
|
projectRoot: "",
|
|
81
123
|
isBuildMode: false,
|
|
82
124
|
userResolveAlias: undefined,
|
|
125
|
+
userRunnerConfig: undefined,
|
|
126
|
+
userResolvePlugins: [],
|
|
83
127
|
scanFilter: undefined,
|
|
84
128
|
cachedRouterFiles: undefined,
|
|
85
129
|
opts,
|
|
@@ -95,8 +139,8 @@ export function createDiscoveryState(
|
|
|
95
139
|
|
|
96
140
|
prerenderManifestEntries: null,
|
|
97
141
|
staticManifestEntries: null,
|
|
98
|
-
|
|
99
|
-
|
|
142
|
+
handlerChunkInfoMap: new Map(),
|
|
143
|
+
staticHandlerChunkInfoMap: new Map(),
|
|
100
144
|
rscEntryFileName: null,
|
|
101
145
|
resolvedPrerenderModules: undefined,
|
|
102
146
|
resolvedStaticModules: undefined,
|
|
@@ -106,5 +150,6 @@ export function createDiscoveryState(
|
|
|
106
150
|
devServer: null,
|
|
107
151
|
selfWrittenGenFiles: new Map(),
|
|
108
152
|
SELF_WRITE_WINDOW_MS: 5_000,
|
|
153
|
+
lastDiscoveryError: null,
|
|
109
154
|
};
|
|
110
155
|
}
|
|
@@ -49,7 +49,6 @@ export function generateRoutesManifestModule(state: DiscoveryState): string {
|
|
|
49
49
|
);
|
|
50
50
|
genFileVars.push(varName);
|
|
51
51
|
} else {
|
|
52
|
-
// Routers without sourceFile: inline their manifest data directly
|
|
53
52
|
routersWithoutGenFile.push({
|
|
54
53
|
id: entry.id,
|
|
55
54
|
manifest: entry.routeManifest,
|
|
@@ -58,7 +57,7 @@ export function generateRoutesManifestModule(state: DiscoveryState): string {
|
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
const lines = [
|
|
61
|
-
`import { setCachedManifest,
|
|
60
|
+
`import { setCachedManifest, setRouterManifest, registerRouterManifestLoader, clearAllRouterData } from "@rangojs/router/server";`,
|
|
62
61
|
...genFileImports,
|
|
63
62
|
// Clear stale per-router cached data (manifest, trie, precomputed entries)
|
|
64
63
|
// before re-populating. In Cloudflare dev mode, program reloads re-evaluate
|
|
@@ -68,14 +67,12 @@ export function generateRoutesManifestModule(state: DiscoveryState): string {
|
|
|
68
67
|
`clearAllRouterData();`,
|
|
69
68
|
];
|
|
70
69
|
|
|
71
|
-
// Flatten NamedRoutes entries: search schema objects -> plain string paths
|
|
72
70
|
if (genFileVars.length > 0) {
|
|
73
71
|
lines.push(
|
|
74
72
|
`function __flat(r) { const o = {}; for (const [k, v] of Object.entries(r)) o[k] = typeof v === "string" ? v : v.path; return o; }`,
|
|
75
73
|
);
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
// Build the merged manifest from gen file imports + inlined data
|
|
79
76
|
if (genFileVars.length === 1 && routersWithoutGenFile.length === 0) {
|
|
80
77
|
lines.push(`setCachedManifest(__flat(${genFileVars[0]}));`);
|
|
81
78
|
} else {
|
|
@@ -86,7 +83,6 @@ export function generateRoutesManifestModule(state: DiscoveryState): string {
|
|
|
86
83
|
lines.push(`setCachedManifest({ ${parts.join(", ")} });`);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
|
-
// Set per-router manifests
|
|
90
86
|
let genVarIdx = 0;
|
|
91
87
|
for (const entry of state.perRouterManifests) {
|
|
92
88
|
if (entry.sourceFile) {
|
|
@@ -101,31 +97,19 @@ export function generateRoutesManifestModule(state: DiscoveryState): string {
|
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
lines.push(
|
|
117
|
-
`setPrecomputedEntries(${jsonParseExpression(state.mergedPrecomputedEntries)});`,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
if (state.mergedRouteTrie) {
|
|
121
|
-
lines.push(
|
|
122
|
-
`setRouteTrie(${jsonParseExpression(state.mergedRouteTrie)});`,
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
100
|
+
// Per-router trie and precomputedEntries are NOT inlined eagerly.
|
|
101
|
+
// They live in the per-router lazy chunks (generatePerRouterModule) and
|
|
102
|
+
// are loaded via ensureRouterManifest(routerId), which is awaited before
|
|
103
|
+
// every request in router.fetch() and before findMatch is reached.
|
|
104
|
+
// Inlining the merged versions here would duplicate the per-router data
|
|
105
|
+
// (the merged trie/precomputedEntries equal the per-router data for
|
|
106
|
+
// single-router apps; for multi-router, the merged trie is dead code
|
|
107
|
+
// because find-match.ts only consumes per-router tries).
|
|
108
|
+
//
|
|
109
|
+
// In dev mode, the handler also falls back to Phase 2 regex matching
|
|
110
|
+
// against live router.urlpatterns, which is always correct after a
|
|
111
|
+
// program reload.
|
|
126
112
|
|
|
127
|
-
// Register lazy loaders for per-router manifest modules.
|
|
128
|
-
// Each import() uses a static string literal so Rollup creates separate chunks.
|
|
129
113
|
for (const routerId of state.perRouterManifestDataMap.keys()) {
|
|
130
114
|
lines.push(
|
|
131
115
|
`registerRouterManifestLoader(${JSON.stringify(routerId)}, () => import(${JSON.stringify(VIRTUAL_ROUTES_MANIFEST_ID + "/" + routerId)}));`,
|
|
@@ -139,9 +123,6 @@ export function generateRoutesManifestModule(state: DiscoveryState): string {
|
|
|
139
123
|
return lines.join("\n");
|
|
140
124
|
}
|
|
141
125
|
|
|
142
|
-
// No manifest: either discovery hasn't completed or no runner (Cloudflare dev).
|
|
143
|
-
// Still inject __PRERENDER_DEV_URL so the prerender store can fetch on-demand.
|
|
144
|
-
// Re-resolve origin now since the server is listening by module load time.
|
|
145
126
|
if (!state.isBuildMode) {
|
|
146
127
|
const origin =
|
|
147
128
|
state.devServerOrigin ||
|
|
@@ -170,7 +151,6 @@ export function generatePerRouterModule(
|
|
|
170
151
|
const lines: string[] = [];
|
|
171
152
|
|
|
172
153
|
if (routerEntry?.sourceFile) {
|
|
173
|
-
// Import manifest from the gen file so HMR auto-propagates
|
|
174
154
|
const routerDir = dirname(routerEntry.sourceFile);
|
|
175
155
|
const routerBasename = basename(routerEntry.sourceFile).replace(
|
|
176
156
|
/\.(tsx?|jsx?)$/,
|
|
@@ -199,5 +179,5 @@ export function generatePerRouterModule(
|
|
|
199
179
|
`export const precomputedEntries = ${jsonParseExpression(entries)};`,
|
|
200
180
|
);
|
|
201
181
|
}
|
|
202
|
-
return lines.join("\n") || "
|
|
182
|
+
return lines.join("\n") || "";
|
|
203
183
|
}
|
package/src/vite/index.ts
CHANGED
|
@@ -12,5 +12,13 @@ export { poke } from "./plugins/refresh-cmd.js";
|
|
|
12
12
|
export type {
|
|
13
13
|
RangoNodeOptions,
|
|
14
14
|
RangoCloudflareOptions,
|
|
15
|
+
RangoVercelOptions,
|
|
16
|
+
VercelPresetOptions,
|
|
15
17
|
RangoOptions,
|
|
18
|
+
ClientChunks,
|
|
19
|
+
ClientChunkMeta,
|
|
20
|
+
BuildEnvOption,
|
|
21
|
+
BuildEnvFactory,
|
|
22
|
+
BuildEnvFactoryContext,
|
|
23
|
+
BuildEnvResult,
|
|
16
24
|
} from "./plugin-types.js";
|
package/src/vite/plugin-types.ts
CHANGED
|
@@ -1,39 +1,112 @@
|
|
|
1
|
+
// -- Build-time environment types -------------------------------------------
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
+
* Context passed to a buildEnv factory function.
|
|
5
|
+
* Provides Vite config details for conditional env setup.
|
|
4
6
|
*/
|
|
5
|
-
export interface
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export interface BuildEnvFactoryContext {
|
|
8
|
+
/** Vite project root directory. */
|
|
9
|
+
root: string;
|
|
10
|
+
/** Vite mode (e.g. "development", "production"). */
|
|
11
|
+
mode: string;
|
|
12
|
+
/** Vite command ("serve" for dev, "build" for production). */
|
|
13
|
+
command: "serve" | "build";
|
|
14
|
+
/** Router deployment preset. */
|
|
15
|
+
preset: "node" | "cloudflare" | "vercel";
|
|
16
|
+
}
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Factory function that creates build-time environment bindings.
|
|
20
|
+
* Called once at plugin startup. Return `dispose` to clean up resources.
|
|
21
|
+
*/
|
|
22
|
+
export type BuildEnvFactory = (
|
|
23
|
+
ctx: BuildEnvFactoryContext,
|
|
24
|
+
) => Promise<BuildEnvResult> | BuildEnvResult;
|
|
17
25
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Result of resolving build-time environment bindings.
|
|
28
|
+
*/
|
|
29
|
+
export interface BuildEnvResult {
|
|
30
|
+
/** Environment bindings available to Prerender/Static handlers via ctx.env. */
|
|
31
|
+
env: Record<string, unknown>;
|
|
32
|
+
/** Called after build completes to clean up resources (e.g., miniflare). */
|
|
33
|
+
dispose?: () => Promise<void> | void;
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
/**
|
|
26
|
-
*
|
|
37
|
+
* Build-time environment configuration for Prerender and Static handlers.
|
|
38
|
+
*
|
|
39
|
+
* - `false` (default): no build-time env, `ctx.env` throws.
|
|
40
|
+
* - `"auto"`: calls `wrangler.getPlatformProxy()` (cloudflare preset only).
|
|
41
|
+
* - Object: used directly as `ctx.env` during build.
|
|
42
|
+
* - Factory: called once at startup, must return `{ env, dispose? }`.
|
|
27
43
|
*/
|
|
28
|
-
export
|
|
44
|
+
export type BuildEnvOption =
|
|
45
|
+
| false
|
|
46
|
+
| "auto"
|
|
47
|
+
| Record<string, unknown>
|
|
48
|
+
| BuildEnvFactory;
|
|
49
|
+
|
|
50
|
+
// -- Client chunking --------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Metadata for one client ("use client") module, passed to a {@link ClientChunks}
|
|
54
|
+
* function. Mirrors the shape `@vitejs/plugin-rsc` passes to its own
|
|
55
|
+
* `clientChunks` option.
|
|
56
|
+
*/
|
|
57
|
+
export interface ClientChunkMeta {
|
|
58
|
+
/** Absolute module id of the "use client" file. */
|
|
59
|
+
id: string;
|
|
60
|
+
/** Normalized (posix) module id — convenient for path-based matching. */
|
|
61
|
+
normalizedId: string;
|
|
29
62
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
63
|
+
* The RSC/server chunk that statically imports this client reference. This is
|
|
64
|
+
* the key used for the default grouping when no override is supplied: a single
|
|
65
|
+
* router that statically imports every route yields ONE `serverChunk`, hence
|
|
66
|
+
* one client chunk for all routes.
|
|
33
67
|
*/
|
|
34
|
-
|
|
68
|
+
serverChunk: string;
|
|
35
69
|
}
|
|
36
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Controls how client ("use client") components are grouped into browser
|
|
73
|
+
* chunks, i.e. per-route / per-feature code splitting of the client bundle.
|
|
74
|
+
*
|
|
75
|
+
* Without splitting, a single router ships ONE client chunk containing every
|
|
76
|
+
* route's client components (and their CSS) — navigating to one route downloads
|
|
77
|
+
* every other route's client code. (Host sub-apps loaded via a dynamic `import()`
|
|
78
|
+
* are the exception: each forms its own chunk.) This option controls how that
|
|
79
|
+
* monolith is split.
|
|
80
|
+
*
|
|
81
|
+
* Behavior branches:
|
|
82
|
+
* - `true` / omitted (**default**, pre-1.0): Rango's built-in **directory
|
|
83
|
+
* strategy**. It splits app `"use client"` modules by **route id** — the segment
|
|
84
|
+
* after a route-root directory (`routes`, `app`, `pages`, `features`, `handlers`,
|
|
85
|
+
* …) — so `routes/dashboard/**` becomes `app-dashboard` at any nesting depth.
|
|
86
|
+
* Where it finds NO route structure (a flat `src/components/`, or host sub-apps
|
|
87
|
+
* already split by a dynamic `import()`), it inherits the default grouping
|
|
88
|
+
* unchanged — so the shared `src/components` chunk stays shared and host apps do
|
|
89
|
+
* not leak across each other. Shared runtime (React, the router, `node_modules`)
|
|
90
|
+
* is never split.
|
|
91
|
+
* - `false`: opt out — inherit `@vitejs/plugin-rsc`'s default grouping everywhere
|
|
92
|
+
* (one chunk per router / per host sub-app).
|
|
93
|
+
* - function: full override. Return a chunk group name, or `undefined` to fall
|
|
94
|
+
* back to the default grouping for that one module. Forwarded directly to
|
|
95
|
+
* `@vitejs/plugin-rsc`'s `clientChunks`.
|
|
96
|
+
*
|
|
97
|
+
* Every module maps to exactly one group, so there is no byte duplication: a
|
|
98
|
+
* component used by two routes lives in one group and is fetched whenever it
|
|
99
|
+
* renders. Put genuinely shared client components OUTSIDE route directories so
|
|
100
|
+
* they land in the shared group rather than one route's chunk.
|
|
101
|
+
*
|
|
102
|
+
* @default true
|
|
103
|
+
*/
|
|
104
|
+
export type ClientChunks =
|
|
105
|
+
| boolean
|
|
106
|
+
| ((meta: ClientChunkMeta) => string | undefined);
|
|
107
|
+
|
|
108
|
+
// -- Plugin options ---------------------------------------------------------
|
|
109
|
+
|
|
37
110
|
/**
|
|
38
111
|
* Base options shared by all presets
|
|
39
112
|
*/
|
|
@@ -45,27 +118,27 @@ interface RangoBaseOptions {
|
|
|
45
118
|
banner?: boolean;
|
|
46
119
|
|
|
47
120
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
121
|
+
* Group client ("use client") components into browser chunks for per-route /
|
|
122
|
+
* per-feature code splitting. On by default (pre-1.0); pass `false` to opt out.
|
|
123
|
+
* See {@link ClientChunks}.
|
|
124
|
+
*
|
|
51
125
|
* @default true
|
|
52
126
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Glob patterns for files to include in route type scanning.
|
|
57
|
-
* Only files matching at least one pattern will be scanned.
|
|
58
|
-
* Patterns are relative to the project root.
|
|
59
|
-
* When unset, all .ts/.tsx files are scanned.
|
|
60
|
-
*/
|
|
61
|
-
include?: string[];
|
|
127
|
+
clientChunks?: ClientChunks;
|
|
62
128
|
|
|
63
129
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
130
|
+
* Filter which files route discovery scans, by glob. Paths are matched
|
|
131
|
+
* root-relative (e.g. `src/routes/**`). `include` restricts discovery to
|
|
132
|
+
* matching files; `exclude` removes matches (the defaults cover tests, dist,
|
|
133
|
+
* coverage, etc.). Mirrors the CLI's `--include`/`--exclude`.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* rango({ discovery: { include: ["src/routes/**"] } })
|
|
67
137
|
*/
|
|
68
|
-
|
|
138
|
+
discovery?: {
|
|
139
|
+
include?: string[];
|
|
140
|
+
exclude?: string[];
|
|
141
|
+
};
|
|
69
142
|
}
|
|
70
143
|
|
|
71
144
|
/**
|
|
@@ -78,36 +151,15 @@ export interface RangoNodeOptions extends RangoBaseOptions {
|
|
|
78
151
|
preset?: "node";
|
|
79
152
|
|
|
80
153
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* When omitted, auto-discovers the router by scanning for files containing
|
|
85
|
-
* `createRouter`. If exactly one is found, it is used automatically.
|
|
86
|
-
* If multiple are found, an error is thrown with the list of candidates.
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```ts
|
|
90
|
-
* rango({ router: './src/router.tsx' })
|
|
91
|
-
* // or simply:
|
|
92
|
-
* rango()
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
router?: string;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* RSC plugin configuration. By default, rsc-router includes @vitejs/plugin-rsc
|
|
99
|
-
* with sensible defaults.
|
|
100
|
-
*
|
|
101
|
-
* Entry files (browser, ssr, rsc) are optional - if they don't exist,
|
|
102
|
-
* virtual defaults are used.
|
|
154
|
+
* Environment bindings available to Prerender and Static handlers at build
|
|
155
|
+
* time via `ctx.env`. Shared across all prerender invocations for the build.
|
|
103
156
|
*
|
|
104
|
-
* -
|
|
105
|
-
*
|
|
106
|
-
* - Pass `false` to disable (for manual @vitejs/plugin-rsc configuration)
|
|
157
|
+
* `"auto"` is Cloudflare-only (it resolves the wrangler platform proxy), so it
|
|
158
|
+
* is not accepted on the Node preset — pass an object or a factory instead.
|
|
107
159
|
*
|
|
108
|
-
* @default
|
|
160
|
+
* @default false
|
|
109
161
|
*/
|
|
110
|
-
|
|
162
|
+
buildEnv?: Exclude<BuildEnvOption, "auto">;
|
|
111
163
|
}
|
|
112
164
|
|
|
113
165
|
/**
|
|
@@ -117,15 +169,81 @@ export interface RangoCloudflareOptions extends RangoBaseOptions {
|
|
|
117
169
|
/**
|
|
118
170
|
* Deployment preset for Cloudflare Workers.
|
|
119
171
|
* When using cloudflare preset:
|
|
120
|
-
* - @vitejs/plugin-rsc
|
|
172
|
+
* - @vitejs/plugin-rsc IS still added by rango(), but with `serverHandler: false`
|
|
173
|
+
* (the cloudflare plugin owns the RSC worker/server entry); only `client` and
|
|
174
|
+
* `ssr` virtual entries are configured, no rsc entry
|
|
121
175
|
* - Your worker entry (e.g., worker.rsc.tsx) imports the router directly
|
|
122
176
|
* - Browser and SSR use virtual entries
|
|
123
177
|
* - Build-time manifest generation is auto-detected from the resolved RSC environment config
|
|
124
178
|
*/
|
|
125
179
|
preset: "cloudflare";
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Environment bindings available to Prerender and Static handlers at build
|
|
183
|
+
* time via `ctx.env`. Shared across all prerender invocations for the build.
|
|
184
|
+
*
|
|
185
|
+
* `"auto"` resolves the Cloudflare platform proxy via wrangler
|
|
186
|
+
* `getPlatformProxy()`.
|
|
187
|
+
*
|
|
188
|
+
* @default false
|
|
189
|
+
*/
|
|
190
|
+
buildEnv?: BuildEnvOption;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Per-function knobs for the Vercel deployment, written into the generated
|
|
195
|
+
* `.vc-config.json` (and `config.json` for `functionName`).
|
|
196
|
+
*/
|
|
197
|
+
export interface VercelPresetOptions {
|
|
198
|
+
/** Node runtime for the function. @default "nodejs22.x" */
|
|
199
|
+
runtime?: string;
|
|
200
|
+
/** Max execution time in seconds. @default 30 */
|
|
201
|
+
maxDuration?: number;
|
|
202
|
+
/** Function memory in MB (platform default when omitted). */
|
|
203
|
+
memory?: number;
|
|
204
|
+
/** Regions to pin the function to (platform default when omitted). */
|
|
205
|
+
regions?: string[];
|
|
206
|
+
/**
|
|
207
|
+
* Function name — the `<name>.func` directory and the `config.json` route
|
|
208
|
+
* destination. @default "index"
|
|
209
|
+
*/
|
|
210
|
+
functionName?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Options for Vercel Functions deployment.
|
|
215
|
+
*
|
|
216
|
+
* Builds like the node preset (Vercel runs Node Functions, not Workers): rango
|
|
217
|
+
* owns the RSC entry, `process.env.NODE_ENV` is folded for the build, and after
|
|
218
|
+
* the build a `.vercel/output` directory (Build Output API v3) is assembled from
|
|
219
|
+
* `dist/` — a single streaming Node Function plus the static client assets. The
|
|
220
|
+
* app must install `@vercel/functions` (used by `VercelCacheStore` and the
|
|
221
|
+
* generated function launcher).
|
|
222
|
+
*/
|
|
223
|
+
export interface RangoVercelOptions extends RangoBaseOptions {
|
|
224
|
+
/**
|
|
225
|
+
* Deployment preset for Vercel Functions.
|
|
226
|
+
*/
|
|
227
|
+
preset: "vercel";
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Environment bindings available to Prerender and Static handlers at build
|
|
231
|
+
* time via `ctx.env`. `"auto"` is Cloudflare-only; pass an object or a factory.
|
|
232
|
+
*
|
|
233
|
+
* @default false
|
|
234
|
+
*/
|
|
235
|
+
buildEnv?: Exclude<BuildEnvOption, "auto">;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Vercel function configuration written into the Build Output.
|
|
239
|
+
*/
|
|
240
|
+
vercel?: VercelPresetOptions;
|
|
126
241
|
}
|
|
127
242
|
|
|
128
243
|
/**
|
|
129
244
|
* Options for rango() Vite plugin
|
|
130
245
|
*/
|
|
131
|
-
export type RangoOptions =
|
|
246
|
+
export type RangoOptions =
|
|
247
|
+
| RangoNodeOptions
|
|
248
|
+
| RangoCloudflareOptions
|
|
249
|
+
| RangoVercelOptions;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from "vite";
|
|
2
|
+
import { createRangoDebugger, NS } from "../debug.js";
|
|
3
|
+
|
|
4
|
+
const debug = createRangoDebugger(NS.transform);
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* Transform CJS vendor files from @vitejs/plugin-rsc to ESM for browser compatibility.
|
|
@@ -9,78 +12,65 @@ export function createCjsToEsmPlugin(): Plugin {
|
|
|
9
12
|
name: "@rangojs/router:cjs-to-esm",
|
|
10
13
|
enforce: "pre",
|
|
11
14
|
transform(code, id) {
|
|
12
|
-
const cleanId = id.split("?")[0];
|
|
15
|
+
const cleanId = id.split("?")[0].replaceAll("\\", "/");
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
cleanId.includes("vendor/react-server-dom/client.browser.js") ||
|
|
17
|
-
cleanId.includes("vendor\\react-server-dom\\client.browser.js")
|
|
18
|
-
) {
|
|
17
|
+
if (cleanId.includes("vendor/react-server-dom/client.browser.js")) {
|
|
19
18
|
const isProd = process.env.NODE_ENV === "production";
|
|
20
19
|
const cjsFile = isProd
|
|
21
20
|
? "./cjs/react-server-dom-webpack-client.browser.production.js"
|
|
22
21
|
: "./cjs/react-server-dom-webpack-client.browser.development.js";
|
|
23
22
|
|
|
23
|
+
debug?.("cjs-to-esm entry redirect %s", id);
|
|
24
24
|
return {
|
|
25
25
|
code: `export * from "${cjsFile}";`,
|
|
26
26
|
map: null,
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// Transform the actual CJS files to ESM
|
|
31
30
|
if (
|
|
32
|
-
|
|
33
|
-
cleanId.includes("vendor\\react-server-dom\\cjs\\")) &&
|
|
31
|
+
cleanId.includes("vendor/react-server-dom/cjs/") &&
|
|
34
32
|
cleanId.includes("client.browser")
|
|
35
33
|
) {
|
|
36
34
|
let transformed = code;
|
|
37
35
|
|
|
38
|
-
// Extract the license comment to preserve it
|
|
39
36
|
const licenseMatch = transformed.match(/^\/\*\*[\s\S]*?\*\//);
|
|
40
37
|
const license = licenseMatch ? licenseMatch[0] : "";
|
|
41
38
|
if (license) {
|
|
42
39
|
transformed = transformed.slice(license.length);
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
// Remove "use strict" (both dev and prod have this)
|
|
46
42
|
transformed = transformed.replace(/^\s*["']use strict["'];\s*/, "");
|
|
47
43
|
|
|
48
|
-
// Remove the conditional IIFE wrapper (development only)
|
|
49
44
|
transformed = transformed.replace(
|
|
50
45
|
/^\s*["']production["']\s*!==\s*process\.env\.NODE_ENV\s*&&\s*\(function\s*\(\)\s*\{/,
|
|
51
46
|
"",
|
|
52
47
|
);
|
|
53
48
|
|
|
54
|
-
// Remove the closing of the conditional IIFE at the end (development only)
|
|
55
49
|
transformed = transformed.replace(/\}\)\(\);?\s*$/, "");
|
|
56
50
|
|
|
57
|
-
// Replace require('react') and require('react-dom') with imports (development)
|
|
58
51
|
transformed = transformed.replace(
|
|
59
52
|
/var\s+React\s*=\s*require\s*\(\s*["']react["']\s*\)\s*,[\s\n]+ReactDOM\s*=\s*require\s*\(\s*["']react-dom["']\s*\)\s*,/g,
|
|
60
53
|
'import React from "react";\nimport ReactDOM from "react-dom";\nvar ',
|
|
61
54
|
);
|
|
62
55
|
|
|
63
|
-
// Replace require('react-dom') only (production - doesn't import React)
|
|
64
56
|
transformed = transformed.replace(
|
|
65
57
|
/var\s+ReactDOM\s*=\s*require\s*\(\s*["']react-dom["']\s*\)\s*,/g,
|
|
66
58
|
'import ReactDOM from "react-dom";\nvar ',
|
|
67
59
|
);
|
|
68
60
|
|
|
69
|
-
// Transform exports.xyz = function() to export function xyz()
|
|
70
61
|
transformed = transformed.replace(
|
|
71
62
|
/exports\.(\w+)\s*=\s*function\s*\(/g,
|
|
72
63
|
"export function $1(",
|
|
73
64
|
);
|
|
74
65
|
|
|
75
|
-
// Transform exports.xyz = value to export const xyz = value
|
|
76
66
|
transformed = transformed.replace(
|
|
77
67
|
/exports\.(\w+)\s*=/g,
|
|
78
68
|
"export const $1 =",
|
|
79
69
|
);
|
|
80
70
|
|
|
81
|
-
// Reconstruct with license at the top
|
|
82
71
|
transformed = license + "\n" + transformed;
|
|
83
72
|
|
|
73
|
+
debug?.("cjs-to-esm body rewrite %s", id);
|
|
84
74
|
return {
|
|
85
75
|
code: transformed,
|
|
86
76
|
map: null,
|