@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bdaf10aa
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 +8 -4
- package/README.md +303 -741
- package/dist/bin/rango.js +730 -184
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4344 -1335
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +86 -15
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +251 -24
- package/skills/caching/SKILL.md +375 -17
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +94 -18
- package/skills/layout/SKILL.md +62 -19
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +302 -54
- package/skills/middleware/SKILL.md +59 -16
- package/skills/migrate-nextjs/SKILL.md +745 -0
- package/skills/migrate-react-router/SKILL.md +153 -0
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +225 -10
- package/skills/ppr/SKILL.md +622 -0
- package/skills/prerender/SKILL.md +178 -124
- package/skills/rango/SKILL.md +318 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +172 -9
- package/skills/router-setup/SKILL.md +131 -11
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -616
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +1 -66
- 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/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +257 -158
- 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/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +132 -33
- package/src/browser/navigation-client.ts +218 -68
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +203 -80
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +241 -127
- package/src/browser/prefetch/cache.ts +271 -44
- package/src/browser/prefetch/fetch.ts +367 -40
- package/src/browser/prefetch/queue.ts +144 -23
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +121 -16
- package/src/browser/react/NavigationProvider.tsx +240 -122
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -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-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- 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 +99 -8
- package/src/browser/rsc-router.tsx +272 -80
- package/src/browser/scroll-restoration.ts +56 -22
- package/src/browser/segment-reconciler.ts +44 -7
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +244 -71
- package/src/browser/types.ts +136 -12
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +207 -158
- package/src/build/generate-route-types.ts +6 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +198 -41
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +464 -63
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +336 -110
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +454 -97
- package/src/cache/cache-scope.ts +235 -103
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2446 -170
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +144 -49
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +24 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +194 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1132 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +116 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +104 -34
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- 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 +100 -13
- package/src/index.ts +143 -19
- package/src/internal-debug.ts +11 -10
- 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/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +215 -86
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +485 -303
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +153 -77
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +53 -12
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +48 -21
- package/src/route-types.ts +37 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +130 -29
- package/src/router/handler-context.ts +83 -39
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +50 -24
- package/src/router/lazy-includes.ts +89 -63
- package/src/router/loader-resolution.ts +286 -56
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +105 -56
- package/src/router/match-api.ts +178 -218
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +66 -22
- package/src/router/match-middleware/cache-lookup.ts +214 -263
- package/src/router/match-middleware/cache-store.ts +105 -50
- 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 +128 -44
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +301 -177
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +203 -58
- package/src/router/preview-match.ts +35 -103
- package/src/router/request-classification.ts +291 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +256 -0
- package/src/router/router-context.ts +11 -29
- package/src/router/router-interfaces.ts +146 -35
- package/src/router/router-options.ts +202 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +301 -78
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +156 -39
- package/src/router/segment-resolution/loader-mask.ts +60 -0
- package/src/router/segment-resolution/loader-snapshot.ts +259 -0
- package/src/router/segment-resolution/mask-nested.ts +83 -0
- package/src/router/segment-resolution/revalidation.ts +477 -385
- 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 +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +8 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +210 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +682 -508
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +127 -31
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +138 -15
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +509 -73
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +287 -113
- package/src/rsc/shell-capture.ts +1190 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +62 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +167 -0
- package/src/segment-system.tsx +449 -132
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +367 -61
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +38 -46
- package/src/server/request-context.ts +558 -173
- package/src/ssr/index.tsx +491 -174
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -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 +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -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 +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- 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 +234 -82
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +137 -14
- package/src/urls/include-helper.ts +40 -75
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +102 -23
- package/src/urls/path-helper.ts +62 -111
- package/src/urls/pattern-types.ts +84 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +346 -89
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +214 -132
- 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 +57 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +15 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +234 -62
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- 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 +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +553 -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 +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +46 -37
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +353 -303
- package/src/vite/router-discovery.ts +1090 -166
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- 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/directive-prologue.ts +40 -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 +98 -38
- package/src/vite/utils/shared-utils.ts +144 -44
- 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/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
package/src/vite/rango.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { type PluginOption } from "vite";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { exposeActionId } from "./plugins/expose-action-id.js";
|
|
5
5
|
import {
|
|
@@ -12,27 +12,46 @@ import { VIRTUAL_IDS } from "./plugins/virtual-entries.js";
|
|
|
12
12
|
import {
|
|
13
13
|
getExcludeDeps,
|
|
14
14
|
getPackageAliases,
|
|
15
|
+
getPublishedPackageName,
|
|
16
|
+
getVendorAliases,
|
|
15
17
|
} from "./utils/package-resolution.js";
|
|
16
18
|
import {
|
|
17
|
-
createScanFilter,
|
|
18
19
|
findRouterFiles,
|
|
20
|
+
findHostRouterFiles,
|
|
19
21
|
} from "../build/generate-route-types.js";
|
|
20
22
|
import { createVersionPlugin } from "./plugins/version-plugin.js";
|
|
21
23
|
import {
|
|
22
|
-
|
|
24
|
+
sharedRolldownOptions,
|
|
23
25
|
createVirtualEntriesPlugin,
|
|
26
|
+
normalizeHostRouterEntry,
|
|
24
27
|
onwarn,
|
|
25
28
|
getManualChunks,
|
|
26
29
|
} from "./utils/shared-utils.js";
|
|
30
|
+
import {
|
|
31
|
+
resolveClientChunks,
|
|
32
|
+
type ClientChunkContext,
|
|
33
|
+
} from "./utils/client-chunks.js";
|
|
27
34
|
import type {
|
|
28
35
|
RangoOptions,
|
|
29
36
|
RangoNodeOptions,
|
|
30
|
-
|
|
37
|
+
RangoVercelOptions,
|
|
31
38
|
} from "./plugin-types.js";
|
|
39
|
+
import { createVercelOutputPlugin } from "./plugins/vercel-output.js";
|
|
32
40
|
import { printBanner, rangoVersion } from "./utils/banner.js";
|
|
33
41
|
import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
34
42
|
import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
|
|
35
43
|
import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
44
|
+
import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
45
|
+
import { createRangoDebugger, NS } from "./debug.js";
|
|
46
|
+
|
|
47
|
+
const debugConfig = createRangoDebugger(NS.config);
|
|
48
|
+
|
|
49
|
+
// The leading-directive 'use client' sniff is shared with version-plugin's
|
|
50
|
+
// getClientModuleSignature so the two cannot drift. Imported for local use by the
|
|
51
|
+
// HMR transform below and re-exported because the E8 sniff test imports it from
|
|
52
|
+
// this module.
|
|
53
|
+
import { hasUseClientDirective } from "./utils/directive-prologue.js";
|
|
54
|
+
export { hasUseClientDirective };
|
|
36
55
|
|
|
37
56
|
/**
|
|
38
57
|
* Vite plugin for @rangojs/router.
|
|
@@ -43,7 +62,7 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
|
43
62
|
* @example Node.js (default)
|
|
44
63
|
* ```ts
|
|
45
64
|
* export default defineConfig({
|
|
46
|
-
* plugins: [react(), rango(
|
|
65
|
+
* plugins: [react(), rango()],
|
|
47
66
|
* });
|
|
48
67
|
* ```
|
|
49
68
|
*
|
|
@@ -59,37 +78,69 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
|
59
78
|
* ```
|
|
60
79
|
*/
|
|
61
80
|
export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
81
|
+
const rangoStart = performance.now();
|
|
62
82
|
const resolvedOptions: RangoOptions = options ?? { preset: "node" };
|
|
63
83
|
const preset = resolvedOptions.preset ?? "node";
|
|
64
84
|
const showBanner = resolvedOptions.banner ?? true;
|
|
85
|
+
const clientChunksOption = resolvedOptions.clientChunks ?? true;
|
|
86
|
+
const useBuiltInClientChunks = clientChunksOption === true;
|
|
87
|
+
const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
|
|
88
|
+
? { fallbackRefs: new Set<string>() }
|
|
89
|
+
: undefined;
|
|
90
|
+
const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
|
|
91
|
+
debugConfig?.("rango(%s) setup start", preset);
|
|
65
92
|
|
|
66
93
|
const plugins: PluginOption[] = [];
|
|
67
94
|
|
|
68
|
-
// Get package resolution info (workspace vs npm install)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
// Get package resolution info (workspace vs npm install).
|
|
96
|
+
// Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
|
|
97
|
+
// itself injects into optimizeDeps.include) to absolute paths resolved from
|
|
98
|
+
// this package — so strict-pnpm consumers don't hit "Failed to resolve
|
|
99
|
+
// dependency" warnings when those deps aren't hoisted to their app root.
|
|
100
|
+
const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
|
|
101
|
+
const excludeDeps = [
|
|
102
|
+
...getExcludeDeps(),
|
|
103
|
+
// plugin-rsc itself injects these into the client env's
|
|
104
|
+
// optimizeDeps.include, which overrides exclude for the dep's own
|
|
105
|
+
// pre-bundle entry. What exclude still controls is how *other*
|
|
106
|
+
// pre-bundled deps treat imports of these specs (external vs inlined)
|
|
107
|
+
// via esbuildCjsExternalPlugin. The cjs-to-esm transform in
|
|
108
|
+
// plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
|
|
109
|
+
// where client.browser's bare include fails to resolve and Vite ends up
|
|
110
|
+
// serving the raw CJS file at dev-serve time.
|
|
111
|
+
"@vitejs/plugin-rsc/browser",
|
|
112
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
// Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
|
|
116
|
+
// B from A's location. We anchor transitive deps (rsc-html-stream,
|
|
117
|
+
// @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
|
|
118
|
+
// these aren't visible at the app root — can still pre-bundle them.
|
|
119
|
+
const pkg = getPublishedPackageName();
|
|
120
|
+
const nested = (spec: string) => `${pkg} > ${spec}`;
|
|
121
|
+
|
|
122
|
+
// Mutable ref for the served entry path (node/vercel presets only). Populated
|
|
123
|
+
// by the auto-discover config() hook using Vite's resolved root. `kind` selects
|
|
124
|
+
// the RSC entry template: "router" wraps a single createRouter() app in
|
|
125
|
+
// createRSCHandler; "host" wraps a createHostRouter() instance and serves it
|
|
126
|
+
// via hostRouter.match().
|
|
127
|
+
const routerRef: { path: string | undefined; kind: "router" | "host" } = {
|
|
128
|
+
path: undefined,
|
|
129
|
+
kind: "router",
|
|
130
|
+
};
|
|
131
|
+
// Explicit host-router entry (node/vercel `hostRouter` option), root-relative.
|
|
132
|
+
const explicitHostRouter =
|
|
133
|
+
preset !== "cloudflare"
|
|
134
|
+
? (resolvedOptions as RangoNodeOptions | RangoVercelOptions).hostRouter
|
|
135
|
+
: undefined;
|
|
79
136
|
|
|
80
137
|
// Build-time prerendering is enabled for both presets.
|
|
81
138
|
// Collection runs in-process via the RSC dev environment runner during discoverRouters().
|
|
82
139
|
const prerenderEnabled = true;
|
|
83
140
|
|
|
84
141
|
if (preset === "cloudflare") {
|
|
85
|
-
// Cloudflare preset: configure entries for cloudflare worker setup
|
|
86
|
-
// Router is not needed here - worker.rsc.tsx imports it directly
|
|
87
|
-
|
|
88
|
-
// Dynamically import @vitejs/plugin-rsc
|
|
89
142
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
90
143
|
|
|
91
|
-
// Only client and ssr entries - rsc entry is handled by cloudflare plugin
|
|
92
|
-
// Always use virtual modules for cloudflare preset
|
|
93
144
|
const finalEntries: { client: string; ssr: string } = {
|
|
94
145
|
client: VIRTUAL_IDS.browser,
|
|
95
146
|
ssr: VIRTUAL_IDS.ssr,
|
|
@@ -100,16 +151,21 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
100
151
|
enforce: "pre",
|
|
101
152
|
|
|
102
153
|
config() {
|
|
103
|
-
// Configure environments for cloudflare deployment
|
|
104
154
|
return {
|
|
105
|
-
// Exclude rsc-router modules from optimization to prevent module duplication
|
|
106
|
-
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
107
155
|
optimizeDeps: {
|
|
108
156
|
exclude: excludeDeps,
|
|
109
|
-
|
|
157
|
+
rolldownOptions: sharedRolldownOptions,
|
|
110
158
|
},
|
|
111
159
|
resolve: {
|
|
112
160
|
alias: rangoAliases,
|
|
161
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
162
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
163
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
164
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
165
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
166
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
167
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
168
|
+
dedupe: ["react", "react-dom"],
|
|
113
169
|
},
|
|
114
170
|
build: {
|
|
115
171
|
rollupOptions: { onwarn },
|
|
@@ -118,30 +174,22 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
118
174
|
client: {
|
|
119
175
|
build: {
|
|
120
176
|
rollupOptions: {
|
|
177
|
+
onwarn,
|
|
121
178
|
output: {
|
|
122
179
|
manualChunks: getManualChunks,
|
|
123
180
|
},
|
|
124
181
|
},
|
|
125
182
|
},
|
|
126
|
-
// Pre-bundle rsc-html-stream to prevent discovery during first request
|
|
127
|
-
// Exclude rsc-router modules to ensure same Context instance
|
|
128
183
|
optimizeDeps: {
|
|
129
|
-
include: ["rsc-html-stream/client"],
|
|
184
|
+
include: [nested("rsc-html-stream/client")],
|
|
130
185
|
exclude: excludeDeps,
|
|
131
|
-
|
|
186
|
+
rolldownOptions: sharedRolldownOptions,
|
|
132
187
|
},
|
|
133
188
|
},
|
|
134
189
|
ssr: {
|
|
135
|
-
// Build SSR inside RSC directory so wrangler can deploy self-contained dist/rsc
|
|
136
190
|
build: {
|
|
137
191
|
outDir: "./dist/rsc/ssr",
|
|
138
192
|
},
|
|
139
|
-
resolve: {
|
|
140
|
-
// Ensure single React instance in SSR child environment
|
|
141
|
-
dedupe: ["react", "react-dom"],
|
|
142
|
-
},
|
|
143
|
-
// Pre-bundle SSR entry and React for proper module linking with childEnvironments
|
|
144
|
-
// All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
145
193
|
optimizeDeps: {
|
|
146
194
|
entries: [finalEntries.ssr],
|
|
147
195
|
include: [
|
|
@@ -151,26 +199,27 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
151
199
|
"react-dom/static.edge",
|
|
152
200
|
"react/jsx-runtime",
|
|
153
201
|
"react/jsx-dev-runtime",
|
|
154
|
-
"rsc-html-stream/server",
|
|
155
|
-
|
|
202
|
+
nested("rsc-html-stream/server"),
|
|
203
|
+
nested(
|
|
204
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
205
|
+
),
|
|
156
206
|
],
|
|
157
207
|
exclude: excludeDeps,
|
|
158
|
-
|
|
208
|
+
rolldownOptions: sharedRolldownOptions,
|
|
159
209
|
},
|
|
160
210
|
},
|
|
161
211
|
rsc: {
|
|
162
|
-
// RSC environment needs exclude list and esbuild options
|
|
163
|
-
// Exclude rsc-router modules to prevent createContext in RSC environment
|
|
164
212
|
optimizeDeps: {
|
|
165
|
-
// Pre-bundle all RSC deps to prevent late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
166
213
|
include: [
|
|
167
214
|
"react",
|
|
168
215
|
"react/jsx-runtime",
|
|
169
216
|
"react/jsx-dev-runtime",
|
|
170
|
-
|
|
217
|
+
nested(
|
|
218
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
219
|
+
),
|
|
171
220
|
],
|
|
172
221
|
exclude: excludeDeps,
|
|
173
|
-
|
|
222
|
+
rolldownOptions: sharedRolldownOptions,
|
|
174
223
|
},
|
|
175
224
|
},
|
|
176
225
|
},
|
|
@@ -191,232 +240,253 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
191
240
|
});
|
|
192
241
|
|
|
193
242
|
plugins.push(createVirtualEntriesPlugin(finalEntries));
|
|
194
|
-
|
|
195
|
-
// Add RSC plugin with cloudflare-specific options
|
|
196
|
-
// Note: loadModuleDevProxy should NOT be used with childEnvironments
|
|
197
|
-
// since SSR runs in workerd alongside RSC
|
|
243
|
+
plugins.push(performanceTracksPlugin());
|
|
198
244
|
plugins.push(
|
|
199
245
|
rsc({
|
|
200
246
|
entries: finalEntries,
|
|
201
247
|
serverHandler: false,
|
|
248
|
+
clientChunks,
|
|
202
249
|
}) as PluginOption,
|
|
203
250
|
);
|
|
204
|
-
|
|
205
|
-
// Deduplicate client references from third-party packages in dev mode.
|
|
206
|
-
// Prevents module duplication when server components import "use client"
|
|
207
|
-
// packages that are also imported directly by client components.
|
|
208
251
|
plugins.push(clientRefDedup());
|
|
209
252
|
} else {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
//
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
253
|
+
plugins.push({
|
|
254
|
+
name: "@rangojs/router:auto-discover",
|
|
255
|
+
config(userConfig) {
|
|
256
|
+
if (routerRef.path) return;
|
|
257
|
+
const root = userConfig.root
|
|
258
|
+
? resolve(process.cwd(), userConfig.root)
|
|
259
|
+
: process.cwd();
|
|
260
|
+
const toRootRelative = (abs: string) =>
|
|
261
|
+
(abs.startsWith(root)
|
|
262
|
+
? "./" + abs.slice(root.length + 1)
|
|
263
|
+
: abs
|
|
264
|
+
).replaceAll("\\", "/");
|
|
265
|
+
const bulletList = (files: string[]) =>
|
|
266
|
+
files.map((f) => " - " + toRootRelative(f)).join("\n");
|
|
267
|
+
|
|
268
|
+
// 1. Explicit host entry wins: serve the createHostRouter() instance.
|
|
269
|
+
if (explicitHostRouter) {
|
|
270
|
+
routerRef.path = normalizeHostRouterEntry(
|
|
271
|
+
explicitHostRouter,
|
|
272
|
+
root,
|
|
273
|
+
existsSync,
|
|
274
|
+
);
|
|
275
|
+
routerRef.kind = "host";
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// 2. A createHostRouter() file means this is a multi-app host deploy:
|
|
280
|
+
// serve it via the host entry. Checked BEFORE single-router discovery,
|
|
281
|
+
// because a host app may compose just one createRouter() sub-app plus
|
|
282
|
+
// host middleware / domain rules / inline .map() routes -- and a lone
|
|
283
|
+
// sub-app must not shadow the host entry (it would bypass
|
|
284
|
+
// hostRouter.match()).
|
|
285
|
+
const hostCandidates = findHostRouterFiles(root);
|
|
286
|
+
if (hostCandidates.length === 1) {
|
|
287
|
+
const hostPath = toRootRelative(hostCandidates[0]);
|
|
288
|
+
// Auto-detection preempts single-router discovery, so name the winning
|
|
289
|
+
// file: a stale prototype still containing `createHostRouter(` would
|
|
290
|
+
// otherwise silently become the served entry in place of the app.
|
|
291
|
+
// eslint-disable-next-line no-console
|
|
292
|
+
console.info(
|
|
293
|
+
`[rango] Serving host router entry ${hostPath} (auto-detected). ` +
|
|
294
|
+
`Set the \`hostRouter\` option to override.`,
|
|
295
|
+
);
|
|
296
|
+
routerRef.path = hostPath;
|
|
297
|
+
routerRef.kind = "host";
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (hostCandidates.length > 1) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`[rango] Multiple host routers found:\n${bulletList(hostCandidates)}\n\n` +
|
|
303
|
+
`Set the \`hostRouter\` option to the entry to serve, e.g. rango({ preset: "${preset}", hostRouter: "./src/worker.rsc.tsx" }).`,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// 3. No host entry: single createRouter() app.
|
|
308
|
+
const candidates = findRouterFiles(root);
|
|
309
|
+
if (candidates.length === 1) {
|
|
310
|
+
routerRef.path = toRootRelative(candidates[0]);
|
|
311
|
+
routerRef.kind = "router";
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (candidates.length > 1) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`[rango] Multiple routers found:\n${bulletList(candidates)}\n\n` +
|
|
317
|
+
`If this is a multi-app host router, export a createHostRouter() instance and set the \`hostRouter\` option (e.g. rango({ preset: "${preset}", hostRouter: "./src/worker.rsc.tsx" })), or use preset: "cloudflare" where you own the worker entry.`,
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const finalEntries = {
|
|
324
|
+
client: VIRTUAL_IDS.browser,
|
|
325
|
+
ssr: VIRTUAL_IDS.ssr,
|
|
326
|
+
rsc: VIRTUAL_IDS.rsc,
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
330
|
+
|
|
331
|
+
let hasWarnedDuplicate = false;
|
|
332
|
+
|
|
333
|
+
plugins.push({
|
|
334
|
+
name: "@rangojs/router:rsc-integration",
|
|
335
|
+
enforce: "pre",
|
|
336
|
+
|
|
337
|
+
config(_userConfig, configEnv) {
|
|
338
|
+
// Fold NODE_ENV for the vercel preset's build. The cloudflare plugin
|
|
339
|
+
// does this automatically and node apps do it themselves; vercel has no
|
|
340
|
+
// platform plugin, so without this React's CJS dev branch survives and
|
|
341
|
+
// doubles the SSR/RSC bundle (Bundle Hygiene rule #2). Only the exact
|
|
342
|
+
// `process.env.NODE_ENV` token is replaced.
|
|
343
|
+
const vercelDefine =
|
|
344
|
+
preset === "vercel" && configEnv.command === "build"
|
|
345
|
+
? { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
346
|
+
: undefined;
|
|
347
|
+
// The vercel preset's deployed function has no node_modules, so the
|
|
348
|
+
// server bundles must be fully self-contained. Bundle every dependency
|
|
349
|
+
// into the rsc + ssr builds instead of externalizing them (the node
|
|
350
|
+
// default, which only works because `vite preview` runs where
|
|
351
|
+
// node_modules exists). node: builtins stay external automatically.
|
|
352
|
+
//
|
|
353
|
+
// BUILD ONLY. In `vite dev` this must NOT apply: noExternal forces every
|
|
354
|
+
// server dependency through the RSC/SSR dev module runners, which cannot
|
|
355
|
+
// load many CJS packages (pg, mysql2, most SDKs, @vercel/functions) and
|
|
356
|
+
// crashes the dev server -- while the same app runs fine under
|
|
357
|
+
// preset: "node" and in the production build. Gating on `build` restores
|
|
358
|
+
// node-preset dev semantics (deps externalized to Node's require).
|
|
359
|
+
const vercelServerEnv =
|
|
360
|
+
preset === "vercel" && configEnv.command === "build"
|
|
361
|
+
? { resolve: { noExternal: true as const } }
|
|
362
|
+
: undefined;
|
|
363
|
+
return {
|
|
364
|
+
...(vercelDefine ? { define: vercelDefine } : {}),
|
|
365
|
+
optimizeDeps: {
|
|
366
|
+
exclude: excludeDeps,
|
|
367
|
+
rolldownOptions: sharedRolldownOptions,
|
|
368
|
+
},
|
|
369
|
+
build: {
|
|
370
|
+
rollupOptions: { onwarn },
|
|
371
|
+
},
|
|
372
|
+
resolve: {
|
|
373
|
+
alias: rangoAliases,
|
|
374
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
375
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
376
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
377
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
378
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
379
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
380
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
381
|
+
dedupe: ["react", "react-dom"],
|
|
382
|
+
},
|
|
383
|
+
environments: {
|
|
384
|
+
client: {
|
|
385
|
+
build: {
|
|
386
|
+
rollupOptions: {
|
|
387
|
+
onwarn,
|
|
388
|
+
output: {
|
|
389
|
+
manualChunks: getManualChunks,
|
|
306
390
|
},
|
|
307
391
|
},
|
|
308
|
-
// Always exclude rsc-router modules, conditionally add virtual entry
|
|
309
|
-
optimizeDeps: {
|
|
310
|
-
// Pre-bundle React and rsc-html-stream to prevent late discovery
|
|
311
|
-
// triggering ERR_OUTDATED_OPTIMIZED_DEP on cold starts
|
|
312
|
-
include: [
|
|
313
|
-
"react",
|
|
314
|
-
"react-dom",
|
|
315
|
-
"react/jsx-runtime",
|
|
316
|
-
"react/jsx-dev-runtime",
|
|
317
|
-
"rsc-html-stream/client",
|
|
318
|
-
],
|
|
319
|
-
exclude: excludeDeps,
|
|
320
|
-
esbuildOptions: sharedEsbuildOptions,
|
|
321
|
-
...(useVirtualClient && {
|
|
322
|
-
// Tell Vite to scan the virtual entry for dependencies
|
|
323
|
-
entries: [VIRTUAL_IDS.browser],
|
|
324
|
-
}),
|
|
325
|
-
},
|
|
326
392
|
},
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
},
|
|
359
|
-
},
|
|
360
|
-
}),
|
|
393
|
+
optimizeDeps: {
|
|
394
|
+
include: [
|
|
395
|
+
"react",
|
|
396
|
+
"react-dom",
|
|
397
|
+
"react/jsx-runtime",
|
|
398
|
+
"react/jsx-dev-runtime",
|
|
399
|
+
nested("rsc-html-stream/client"),
|
|
400
|
+
],
|
|
401
|
+
exclude: excludeDeps,
|
|
402
|
+
rolldownOptions: sharedRolldownOptions,
|
|
403
|
+
entries: [VIRTUAL_IDS.browser],
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
ssr: {
|
|
407
|
+
...(vercelServerEnv ?? {}),
|
|
408
|
+
optimizeDeps: {
|
|
409
|
+
entries: [VIRTUAL_IDS.ssr],
|
|
410
|
+
include: [
|
|
411
|
+
"react",
|
|
412
|
+
"react-dom",
|
|
413
|
+
"react-dom/server.edge",
|
|
414
|
+
"react-dom/static.edge",
|
|
415
|
+
"react/jsx-runtime",
|
|
416
|
+
"react/jsx-dev-runtime",
|
|
417
|
+
nested(
|
|
418
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
419
|
+
),
|
|
420
|
+
],
|
|
421
|
+
exclude: excludeDeps,
|
|
422
|
+
rolldownOptions: sharedRolldownOptions,
|
|
423
|
+
},
|
|
361
424
|
},
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
425
|
+
rsc: {
|
|
426
|
+
...(vercelServerEnv ?? {}),
|
|
427
|
+
optimizeDeps: {
|
|
428
|
+
entries: [VIRTUAL_IDS.rsc],
|
|
429
|
+
include: [
|
|
430
|
+
"react",
|
|
431
|
+
"react/jsx-runtime",
|
|
432
|
+
"react/jsx-dev-runtime",
|
|
433
|
+
nested(
|
|
434
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
435
|
+
),
|
|
436
|
+
],
|
|
437
|
+
// Vite 8 does not propagate the top-level optimizeDeps.exclude
|
|
438
|
+
// (set in config()) to non-client envs, so the rsc env must set
|
|
439
|
+
// it explicitly — mirroring the node ssr env and the cloudflare
|
|
440
|
+
// rsc env. Without it a strict-pnpm npm-installed app can try to
|
|
441
|
+
// pre-bundle the router's own subpath entries and fail.
|
|
442
|
+
exclude: excludeDeps,
|
|
443
|
+
rolldownOptions: sharedRolldownOptions,
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
configResolved(config) {
|
|
451
|
+
if (showBanner) {
|
|
452
|
+
const mode =
|
|
453
|
+
config.command === "serve"
|
|
454
|
+
? process.argv.includes("preview")
|
|
455
|
+
? "preview"
|
|
456
|
+
: "dev"
|
|
457
|
+
: "build";
|
|
458
|
+
printBanner(
|
|
459
|
+
mode,
|
|
460
|
+
preset === "vercel" ? "vercel" : "node",
|
|
461
|
+
rangoVersion,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const rscMinimalCount = config.plugins.filter(
|
|
466
|
+
(p) => p.name === "rsc:minimal",
|
|
467
|
+
).length;
|
|
468
|
+
|
|
469
|
+
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
470
|
+
hasWarnedDuplicate = true;
|
|
471
|
+
console.warn(
|
|
472
|
+
"[rango] Duplicate @vitejs/plugin-rsc detected. " +
|
|
473
|
+
"Remove rsc() from your vite config — rango() includes it automatically.",
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
|
|
480
|
+
plugins.push(performanceTracksPlugin());
|
|
481
|
+
plugins.push(
|
|
482
|
+
rsc({
|
|
483
|
+
entries: finalEntries,
|
|
484
|
+
clientChunks,
|
|
485
|
+
}) as PluginOption,
|
|
486
|
+
);
|
|
406
487
|
plugins.push(clientRefDedup());
|
|
407
488
|
}
|
|
408
489
|
|
|
409
|
-
// Fix HMR for "use client" components.
|
|
410
|
-
//
|
|
411
|
-
// @vitejs/plugin-rsc's hotUpdate returns undefined for "use client" files
|
|
412
|
-
// in the RSC environment. Vite then tries to propagate through the RSC
|
|
413
|
-
// module graph, but the proxy module has no import.meta.hot.accept()
|
|
414
|
-
// boundary, causing a full page reload. The client env would handle it
|
|
415
|
-
// fine via React Refresh, but the RSC env's full-reload arrives first.
|
|
416
|
-
//
|
|
417
|
-
// Fix: in the RSC env, return [] for "use client" files to signal
|
|
418
|
-
// "handled, nothing to propagate". The client env is left alone so
|
|
419
|
-
// React Refresh processes the update normally.
|
|
420
490
|
plugins.push({
|
|
421
491
|
name: "@rangojs/router:client-component-hmr",
|
|
422
492
|
hotUpdate(ctx) {
|
|
@@ -435,76 +505,56 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
435
505
|
|
|
436
506
|
try {
|
|
437
507
|
const source = readFileSync(file, "utf-8");
|
|
438
|
-
|
|
439
|
-
if (
|
|
440
|
-
trimmed.startsWith('"use client"') ||
|
|
441
|
-
trimmed.startsWith("'use client'")
|
|
442
|
-
) {
|
|
443
|
-
// Consume the update in RSC/SSR envs. The proxy module was already
|
|
444
|
-
// re-transformed by the RSC plugin's hotUpdate. Without this, Vite
|
|
445
|
-
// tries to propagate through the RSC/SSR module graph where the proxy
|
|
446
|
-
// has no import.meta.hot.accept() boundary, triggering a full reload.
|
|
447
|
-
// The actual component update is handled by React Refresh in the
|
|
448
|
-
// client environment.
|
|
508
|
+
if (hasUseClientDirective(source)) {
|
|
449
509
|
return [];
|
|
450
510
|
}
|
|
451
|
-
} catch {
|
|
452
|
-
// File deleted/moved during HMR, let default handling proceed
|
|
453
|
-
}
|
|
511
|
+
} catch {}
|
|
454
512
|
},
|
|
455
513
|
});
|
|
456
514
|
|
|
457
515
|
plugins.push(exposeActionId());
|
|
458
|
-
|
|
459
|
-
// "use cache" directive transform (enforce: "post"):
|
|
460
|
-
// Wraps exports with registerCachedFunction() for function-level caching.
|
|
461
516
|
plugins.push(useCacheTransform());
|
|
462
|
-
|
|
463
|
-
// Consolidated plugin for create* ID injection (enforce: "post"):
|
|
464
|
-
// loaders, handles, location state, and prerender handlers.
|
|
465
517
|
plugins.push(exposeInternalIds());
|
|
466
|
-
|
|
467
|
-
// Router ID injection runs at normal priority (no enforce) to avoid
|
|
468
|
-
// changing Vite's dep optimization timing.
|
|
469
518
|
plugins.push(exposeRouterId());
|
|
470
|
-
|
|
471
|
-
// Add version virtual module plugin for cache invalidation
|
|
472
519
|
plugins.push(createVersionPlugin());
|
|
473
520
|
|
|
474
|
-
// Entry path for discovery: user-specified value (if any) or undefined.
|
|
475
|
-
// Auto-discovered path is passed separately via routerRef.
|
|
476
|
-
// Cloudflare preset: deferred to configResolved (read from resolved Vite env config).
|
|
477
521
|
const discoveryEntryPath =
|
|
478
522
|
preset !== "cloudflare" ? routerRef.path : undefined;
|
|
479
|
-
// Ref for deferred auto-discovery (node preset only, undefined for cloudflare)
|
|
480
523
|
const discoveryRouterRef = preset !== "cloudflare" ? routerRef : undefined;
|
|
481
524
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
// lazily in configResolved). For node preset without a custom entry, the router file
|
|
485
|
-
// must NOT be transformed — injecting routes-manifest there creates a circular dependency.
|
|
486
|
-
const injectorEntryPath =
|
|
487
|
-
rscEntryPath ?? (preset === "cloudflare" ? undefined : null);
|
|
488
|
-
if (injectorEntryPath !== null) {
|
|
489
|
-
plugins.push(createVersionInjectorPlugin(injectorEntryPath));
|
|
525
|
+
if (preset === "cloudflare") {
|
|
526
|
+
plugins.push(createVersionInjectorPlugin(undefined));
|
|
490
527
|
}
|
|
491
528
|
|
|
492
|
-
// Transform CJS vendor files to ESM for browser compatibility
|
|
493
|
-
// optimizeDeps.include doesn't work because the file is loaded after initial optimization
|
|
494
529
|
plugins.push(createCjsToEsmPlugin());
|
|
495
|
-
|
|
496
|
-
// Router discovery plugin for build-time manifest generation.
|
|
497
|
-
// For cloudflare, the entry is resolved lazily in configResolved from the RSC environment.
|
|
498
|
-
// For node, discoveryRouterRef provides the auto-discovered path when not user-specified.
|
|
499
530
|
plugins.push(
|
|
500
531
|
createRouterDiscoveryPlugin(discoveryEntryPath, {
|
|
501
532
|
routerPathRef: discoveryRouterRef,
|
|
502
533
|
enableBuildPrerender: prerenderEnabled,
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
534
|
+
buildEnv: options?.buildEnv,
|
|
535
|
+
preset,
|
|
536
|
+
prerenderOnError: options?.prerender?.onError,
|
|
537
|
+
discovery: options?.discovery,
|
|
538
|
+
clientChunkCtx,
|
|
506
539
|
}),
|
|
507
540
|
);
|
|
508
541
|
|
|
542
|
+
// Vercel preset: assemble .vercel/output from dist/ after the build. Pushed
|
|
543
|
+
// last so its buildApp (order "post") hook runs after the discovery plugin's
|
|
544
|
+
// rsc-env postprocess. buildApp fires once after the whole multi-environment
|
|
545
|
+
// build, so dist/ is complete (closeBundle is unusable here -- it fires per
|
|
546
|
+
// environment, twice for ssr; see the plugin's own note).
|
|
547
|
+
if (preset === "vercel") {
|
|
548
|
+
plugins.push(
|
|
549
|
+
createVercelOutputPlugin(resolvedOptions as RangoVercelOptions),
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
debugConfig?.(
|
|
554
|
+
"rango(%s) setup done: %d plugin(s) (%sms)",
|
|
555
|
+
preset,
|
|
556
|
+
plugins.length,
|
|
557
|
+
(performance.now() - rangoStart).toFixed(1),
|
|
558
|
+
);
|
|
509
559
|
return plugins;
|
|
510
560
|
}
|