@rangojs/router 0.0.0-experimental.9c9afef3 → 0.0.0-experimental.a014d2b7
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 -0
- package/README.md +245 -49
- package/dist/bin/rango.js +440 -133
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3373 -1176
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +68 -14
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +64 -2
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +224 -32
- package/skills/caching/SKILL.md +279 -17
- package/skills/composability/SKILL.md +27 -3
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +4 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +250 -30
- package/skills/host-router/SKILL.md +83 -23
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +87 -18
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +235 -9
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +771 -0
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +77 -7
- package/skills/prerender/SKILL.md +172 -125
- package/skills/rango/SKILL.md +251 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +123 -48
- package/skills/route/SKILL.md +70 -5
- package/skills/router-setup/SKILL.md +65 -8
- package/skills/scripts/SKILL.md +179 -0
- 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 +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 +129 -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 +84 -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/typesafety/SKILL.md +322 -29
- package/skills/use-cache/SKILL.md +57 -14
- 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 +192 -150
- 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/navigation-bridge.ts +131 -30
- package/src/browser/navigation-client.ts +186 -100
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +157 -74
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +165 -112
- package/src/browser/prefetch/cache.ts +205 -62
- package/src/browser/prefetch/fetch.ts +347 -39
- package/src/browser/prefetch/queue.ts +42 -8
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +102 -15
- package/src/browser/react/NavigationProvider.tsx +295 -119
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/deferred-handle-resolution.ts +75 -0
- 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 +114 -24
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +222 -72
- package/src/browser/types.ts +102 -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 +65 -40
- package/src/build/generate-route-types.ts +5 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +165 -36
- 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 +125 -24
- 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 +260 -94
- 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 +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +29 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +224 -41
- package/src/cache/cache-scope.ts +188 -82
- package/src/cache/cache-tag.ts +103 -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 +1989 -378
- 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 +6 -16
- package/src/cache/document-cache.ts +89 -21
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +10 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +9 -17
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +37 -100
- package/src/client.rsc.tsx +44 -21
- package/src/client.tsx +119 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +196 -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 +70 -22
- package/src/handles/MetaTags.tsx +62 -19
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +37 -8
- package/src/handles/is-thenable.ts +19 -0
- package/src/handles/meta.ts +51 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -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 +99 -13
- package/src/index.ts +139 -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 +198 -82
- package/src/redirect-origin.ts +100 -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 +461 -304
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +143 -69
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +51 -10
- 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 +0 -16
- 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 +44 -23
- package/src/router/handler-context.ts +52 -31
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +48 -24
- package/src/router/lazy-includes.ts +15 -52
- package/src/router/loader-resolution.ts +268 -56
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +40 -42
- package/src/router/match-api.ts +124 -204
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +170 -276
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +45 -14
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +87 -39
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -140
- package/src/router/middleware.ts +266 -169
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +132 -90
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prerender-match.ts +195 -56
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +3 -28
- package/src/router/router-interfaces.ts +115 -35
- package/src/router/router-options.ts +172 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +162 -84
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +76 -39
- package/src/router/segment-resolution/revalidation.ts +351 -321
- 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 +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +161 -199
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +163 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +157 -54
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +655 -529
- 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 +122 -31
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +131 -14
- package/src/rsc/redirect-guard.ts +99 -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 +109 -74
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +287 -115
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +29 -9
- 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 +149 -0
- package/src/segment-system.tsx +236 -202
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +224 -52
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +38 -46
- package/src/server/request-context.ts +401 -173
- package/src/ssr/index.tsx +24 -16
- 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 +701 -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 +183 -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 +581 -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 +20 -58
- 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 +125 -71
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +40 -11
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +12 -7
- package/src/types/segments.ts +136 -15
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +68 -18
- 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 -19
- 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 +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 -4
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +6 -0
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +178 -5
- 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 +48 -95
- 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 +64 -170
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +39 -25
- package/src/vite/rango.ts +118 -114
- package/src/vite/router-discovery.ts +941 -142
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- 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 +81 -34
- package/src/vite/utils/shared-utils.ts +92 -42
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/debug-channel.ts +0 -93
- 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,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PluginOption } from "vite";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { exposeActionId } from "./plugins/expose-action-id.js";
|
|
@@ -12,21 +12,37 @@ 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 { findRouterFiles } from "../build/generate-route-types.js";
|
|
17
19
|
import { createVersionPlugin } from "./plugins/version-plugin.js";
|
|
18
20
|
import {
|
|
19
|
-
|
|
21
|
+
sharedRolldownOptions,
|
|
20
22
|
createVirtualEntriesPlugin,
|
|
21
23
|
onwarn,
|
|
22
24
|
getManualChunks,
|
|
23
25
|
} from "./utils/shared-utils.js";
|
|
26
|
+
import {
|
|
27
|
+
resolveClientChunks,
|
|
28
|
+
type ClientChunkContext,
|
|
29
|
+
} from "./utils/client-chunks.js";
|
|
24
30
|
import type { RangoOptions } from "./plugin-types.js";
|
|
25
31
|
import { printBanner, rangoVersion } from "./utils/banner.js";
|
|
26
32
|
import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
27
33
|
import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
|
|
28
34
|
import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
29
35
|
import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
36
|
+
import { createRangoDebugger, NS } from "./debug.js";
|
|
37
|
+
|
|
38
|
+
const debugConfig = createRangoDebugger(NS.config);
|
|
39
|
+
|
|
40
|
+
// The leading-directive 'use client' sniff is shared with version-plugin's
|
|
41
|
+
// getClientModuleSignature so the two cannot drift. Imported for local use by the
|
|
42
|
+
// HMR transform below and re-exported because the E8 sniff test imports it from
|
|
43
|
+
// this module.
|
|
44
|
+
import { hasUseClientDirective } from "./utils/directive-prologue.js";
|
|
45
|
+
export { hasUseClientDirective };
|
|
30
46
|
|
|
31
47
|
/**
|
|
32
48
|
* Vite plugin for @rangojs/router.
|
|
@@ -53,15 +69,46 @@ import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
|
53
69
|
* ```
|
|
54
70
|
*/
|
|
55
71
|
export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
72
|
+
const rangoStart = performance.now();
|
|
56
73
|
const resolvedOptions: RangoOptions = options ?? { preset: "node" };
|
|
57
74
|
const preset = resolvedOptions.preset ?? "node";
|
|
58
75
|
const showBanner = resolvedOptions.banner ?? true;
|
|
76
|
+
const clientChunksOption = resolvedOptions.clientChunks ?? true;
|
|
77
|
+
const useBuiltInClientChunks = clientChunksOption === true;
|
|
78
|
+
const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
|
|
79
|
+
? { fallbackRefs: new Set<string>() }
|
|
80
|
+
: undefined;
|
|
81
|
+
const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
|
|
82
|
+
debugConfig?.("rango(%s) setup start", preset);
|
|
59
83
|
|
|
60
84
|
const plugins: PluginOption[] = [];
|
|
61
85
|
|
|
62
|
-
// Get package resolution info (workspace vs npm install)
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
// Get package resolution info (workspace vs npm install).
|
|
87
|
+
// Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
|
|
88
|
+
// itself injects into optimizeDeps.include) to absolute paths resolved from
|
|
89
|
+
// this package — so strict-pnpm consumers don't hit "Failed to resolve
|
|
90
|
+
// dependency" warnings when those deps aren't hoisted to their app root.
|
|
91
|
+
const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
|
|
92
|
+
const excludeDeps = [
|
|
93
|
+
...getExcludeDeps(),
|
|
94
|
+
// plugin-rsc itself injects these into the client env's
|
|
95
|
+
// optimizeDeps.include, which overrides exclude for the dep's own
|
|
96
|
+
// pre-bundle entry. What exclude still controls is how *other*
|
|
97
|
+
// pre-bundled deps treat imports of these specs (external vs inlined)
|
|
98
|
+
// via esbuildCjsExternalPlugin. The cjs-to-esm transform in
|
|
99
|
+
// plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
|
|
100
|
+
// where client.browser's bare include fails to resolve and Vite ends up
|
|
101
|
+
// serving the raw CJS file at dev-serve time.
|
|
102
|
+
"@vitejs/plugin-rsc/browser",
|
|
103
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
// Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
|
|
107
|
+
// B from A's location. We anchor transitive deps (rsc-html-stream,
|
|
108
|
+
// @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
|
|
109
|
+
// these aren't visible at the app root — can still pre-bundle them.
|
|
110
|
+
const pkg = getPublishedPackageName();
|
|
111
|
+
const nested = (spec: string) => `${pkg} > ${spec}`;
|
|
65
112
|
|
|
66
113
|
// Mutable ref for router path (node preset only).
|
|
67
114
|
// Set immediately when user-specified, or populated by the auto-discover
|
|
@@ -73,14 +120,8 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
73
120
|
const prerenderEnabled = true;
|
|
74
121
|
|
|
75
122
|
if (preset === "cloudflare") {
|
|
76
|
-
// Cloudflare preset: configure entries for cloudflare worker setup
|
|
77
|
-
// Router is not needed here - worker.rsc.tsx imports it directly
|
|
78
|
-
|
|
79
|
-
// Dynamically import @vitejs/plugin-rsc
|
|
80
123
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
81
124
|
|
|
82
|
-
// Only client and ssr entries - rsc entry is handled by cloudflare plugin
|
|
83
|
-
// Always use virtual modules for cloudflare preset
|
|
84
125
|
const finalEntries: { client: string; ssr: string } = {
|
|
85
126
|
client: VIRTUAL_IDS.browser,
|
|
86
127
|
ssr: VIRTUAL_IDS.ssr,
|
|
@@ -91,16 +132,21 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
91
132
|
enforce: "pre",
|
|
92
133
|
|
|
93
134
|
config() {
|
|
94
|
-
// Configure environments for cloudflare deployment
|
|
95
135
|
return {
|
|
96
|
-
// Exclude rsc-router modules from optimization to prevent module duplication
|
|
97
|
-
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
98
136
|
optimizeDeps: {
|
|
99
137
|
exclude: excludeDeps,
|
|
100
|
-
|
|
138
|
+
rolldownOptions: sharedRolldownOptions,
|
|
101
139
|
},
|
|
102
140
|
resolve: {
|
|
103
141
|
alias: rangoAliases,
|
|
142
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
143
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
144
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
145
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
146
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
147
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
148
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
149
|
+
dedupe: ["react", "react-dom"],
|
|
104
150
|
},
|
|
105
151
|
build: {
|
|
106
152
|
rollupOptions: { onwarn },
|
|
@@ -109,30 +155,22 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
109
155
|
client: {
|
|
110
156
|
build: {
|
|
111
157
|
rollupOptions: {
|
|
158
|
+
onwarn,
|
|
112
159
|
output: {
|
|
113
160
|
manualChunks: getManualChunks,
|
|
114
161
|
},
|
|
115
162
|
},
|
|
116
163
|
},
|
|
117
|
-
// Pre-bundle rsc-html-stream to prevent discovery during first request
|
|
118
|
-
// Exclude rsc-router modules to ensure same Context instance
|
|
119
164
|
optimizeDeps: {
|
|
120
|
-
include: ["rsc-html-stream/client"],
|
|
165
|
+
include: [nested("rsc-html-stream/client")],
|
|
121
166
|
exclude: excludeDeps,
|
|
122
|
-
|
|
167
|
+
rolldownOptions: sharedRolldownOptions,
|
|
123
168
|
},
|
|
124
169
|
},
|
|
125
170
|
ssr: {
|
|
126
|
-
// Build SSR inside RSC directory so wrangler can deploy self-contained dist/rsc
|
|
127
171
|
build: {
|
|
128
172
|
outDir: "./dist/rsc/ssr",
|
|
129
173
|
},
|
|
130
|
-
resolve: {
|
|
131
|
-
// Ensure single React instance in SSR child environment
|
|
132
|
-
dedupe: ["react", "react-dom"],
|
|
133
|
-
},
|
|
134
|
-
// Pre-bundle SSR entry and React for proper module linking with childEnvironments
|
|
135
|
-
// All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
136
174
|
optimizeDeps: {
|
|
137
175
|
entries: [finalEntries.ssr],
|
|
138
176
|
include: [
|
|
@@ -142,26 +180,27 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
142
180
|
"react-dom/static.edge",
|
|
143
181
|
"react/jsx-runtime",
|
|
144
182
|
"react/jsx-dev-runtime",
|
|
145
|
-
"rsc-html-stream/server",
|
|
146
|
-
|
|
183
|
+
nested("rsc-html-stream/server"),
|
|
184
|
+
nested(
|
|
185
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
186
|
+
),
|
|
147
187
|
],
|
|
148
188
|
exclude: excludeDeps,
|
|
149
|
-
|
|
189
|
+
rolldownOptions: sharedRolldownOptions,
|
|
150
190
|
},
|
|
151
191
|
},
|
|
152
192
|
rsc: {
|
|
153
|
-
// RSC environment needs exclude list and esbuild options
|
|
154
|
-
// Exclude rsc-router modules to prevent createContext in RSC environment
|
|
155
193
|
optimizeDeps: {
|
|
156
|
-
// Pre-bundle all RSC deps to prevent late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
157
194
|
include: [
|
|
158
195
|
"react",
|
|
159
196
|
"react/jsx-runtime",
|
|
160
197
|
"react/jsx-dev-runtime",
|
|
161
|
-
|
|
198
|
+
nested(
|
|
199
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
200
|
+
),
|
|
162
201
|
],
|
|
163
202
|
exclude: excludeDeps,
|
|
164
|
-
|
|
203
|
+
rolldownOptions: sharedRolldownOptions,
|
|
165
204
|
},
|
|
166
205
|
},
|
|
167
206
|
},
|
|
@@ -182,23 +221,16 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
182
221
|
});
|
|
183
222
|
|
|
184
223
|
plugins.push(createVirtualEntriesPlugin(finalEntries));
|
|
185
|
-
|
|
186
|
-
// Add RSC plugin with cloudflare-specific options
|
|
187
|
-
// Note: loadModuleDevProxy should NOT be used with childEnvironments
|
|
188
|
-
// since SSR runs in workerd alongside RSC
|
|
224
|
+
plugins.push(performanceTracksPlugin());
|
|
189
225
|
plugins.push(
|
|
190
226
|
rsc({
|
|
191
227
|
entries: finalEntries,
|
|
192
228
|
serverHandler: false,
|
|
229
|
+
clientChunks,
|
|
193
230
|
}) as PluginOption,
|
|
194
231
|
);
|
|
195
|
-
|
|
196
|
-
// Deduplicate client references from third-party packages in dev mode.
|
|
197
|
-
// Prevents module duplication when server components import "use client"
|
|
198
|
-
// packages that are also imported directly by client components.
|
|
199
232
|
plugins.push(clientRefDedup());
|
|
200
233
|
} else {
|
|
201
|
-
// Auto-discover router using Vite's resolved root (not process.cwd())
|
|
202
234
|
plugins.push({
|
|
203
235
|
name: "@rangojs/router:auto-discover",
|
|
204
236
|
config(userConfig) {
|
|
@@ -219,20 +251,17 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
219
251
|
" - " + (f.startsWith(root) ? f.slice(root.length + 1) : f),
|
|
220
252
|
)
|
|
221
253
|
.join("\n");
|
|
222
|
-
throw new Error(`[
|
|
254
|
+
throw new Error(`[rango] Multiple routers found:\n${list}`);
|
|
223
255
|
}
|
|
224
|
-
// 0 found: routerRef.path stays undefined, warn at startup via discovery plugin
|
|
225
256
|
},
|
|
226
257
|
});
|
|
227
258
|
|
|
228
|
-
// Always use virtual entries for client, ssr, and rsc
|
|
229
259
|
const finalEntries = {
|
|
230
260
|
client: VIRTUAL_IDS.browser,
|
|
231
261
|
ssr: VIRTUAL_IDS.ssr,
|
|
232
262
|
rsc: VIRTUAL_IDS.rsc,
|
|
233
263
|
};
|
|
234
264
|
|
|
235
|
-
// Dynamically import @vitejs/plugin-rsc
|
|
236
265
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
237
266
|
|
|
238
267
|
let hasWarnedDuplicate = false;
|
|
@@ -245,18 +274,27 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
245
274
|
return {
|
|
246
275
|
optimizeDeps: {
|
|
247
276
|
exclude: excludeDeps,
|
|
248
|
-
|
|
277
|
+
rolldownOptions: sharedRolldownOptions,
|
|
249
278
|
},
|
|
250
279
|
build: {
|
|
251
280
|
rollupOptions: { onwarn },
|
|
252
281
|
},
|
|
253
282
|
resolve: {
|
|
254
283
|
alias: rangoAliases,
|
|
284
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
285
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
286
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
287
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
288
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
289
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
290
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
291
|
+
dedupe: ["react", "react-dom"],
|
|
255
292
|
},
|
|
256
293
|
environments: {
|
|
257
294
|
client: {
|
|
258
295
|
build: {
|
|
259
296
|
rollupOptions: {
|
|
297
|
+
onwarn,
|
|
260
298
|
output: {
|
|
261
299
|
manualChunks: getManualChunks,
|
|
262
300
|
},
|
|
@@ -268,10 +306,10 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
268
306
|
"react-dom",
|
|
269
307
|
"react/jsx-runtime",
|
|
270
308
|
"react/jsx-dev-runtime",
|
|
271
|
-
"rsc-html-stream/client",
|
|
309
|
+
nested("rsc-html-stream/client"),
|
|
272
310
|
],
|
|
273
311
|
exclude: excludeDeps,
|
|
274
|
-
|
|
312
|
+
rolldownOptions: sharedRolldownOptions,
|
|
275
313
|
entries: [VIRTUAL_IDS.browser],
|
|
276
314
|
},
|
|
277
315
|
},
|
|
@@ -285,10 +323,12 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
285
323
|
"react-dom/static.edge",
|
|
286
324
|
"react/jsx-runtime",
|
|
287
325
|
"react/jsx-dev-runtime",
|
|
288
|
-
|
|
326
|
+
nested(
|
|
327
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
328
|
+
),
|
|
289
329
|
],
|
|
290
330
|
exclude: excludeDeps,
|
|
291
|
-
|
|
331
|
+
rolldownOptions: sharedRolldownOptions,
|
|
292
332
|
},
|
|
293
333
|
},
|
|
294
334
|
rsc: {
|
|
@@ -298,9 +338,17 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
298
338
|
"react",
|
|
299
339
|
"react/jsx-runtime",
|
|
300
340
|
"react/jsx-dev-runtime",
|
|
301
|
-
|
|
341
|
+
nested(
|
|
342
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
343
|
+
),
|
|
302
344
|
],
|
|
303
|
-
|
|
345
|
+
// Vite 8 does not propagate the top-level optimizeDeps.exclude
|
|
346
|
+
// (set in config()) to non-client envs, so the rsc env must set
|
|
347
|
+
// it explicitly — mirroring the node ssr env and the cloudflare
|
|
348
|
+
// rsc env. Without it a strict-pnpm npm-installed app can try to
|
|
349
|
+
// pre-bundle the router's own subpath entries and fail.
|
|
350
|
+
exclude: excludeDeps,
|
|
351
|
+
rolldownOptions: sharedRolldownOptions,
|
|
304
352
|
},
|
|
305
353
|
},
|
|
306
354
|
},
|
|
@@ -325,39 +373,24 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
325
373
|
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
326
374
|
hasWarnedDuplicate = true;
|
|
327
375
|
console.warn(
|
|
328
|
-
"[
|
|
376
|
+
"[rango] Duplicate @vitejs/plugin-rsc detected. " +
|
|
329
377
|
"Remove rsc() from your vite config — rango() includes it automatically.",
|
|
330
378
|
);
|
|
331
379
|
}
|
|
332
380
|
},
|
|
333
381
|
});
|
|
334
382
|
|
|
335
|
-
// Add virtual entries plugin (RSC entry generated lazily from routerRef)
|
|
336
383
|
plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
|
|
337
|
-
|
|
384
|
+
plugins.push(performanceTracksPlugin());
|
|
338
385
|
plugins.push(
|
|
339
386
|
rsc({
|
|
340
387
|
entries: finalEntries,
|
|
388
|
+
clientChunks,
|
|
341
389
|
}) as PluginOption,
|
|
342
390
|
);
|
|
343
|
-
|
|
344
|
-
// Deduplicate client references from third-party packages in dev mode.
|
|
345
|
-
// Prevents module duplication when server components import "use client"
|
|
346
|
-
// packages that are also imported directly by client components.
|
|
347
391
|
plugins.push(clientRefDedup());
|
|
348
392
|
}
|
|
349
393
|
|
|
350
|
-
// Fix HMR for "use client" components.
|
|
351
|
-
//
|
|
352
|
-
// @vitejs/plugin-rsc's hotUpdate returns undefined for "use client" files
|
|
353
|
-
// in the RSC environment. Vite then tries to propagate through the RSC
|
|
354
|
-
// module graph, but the proxy module has no import.meta.hot.accept()
|
|
355
|
-
// boundary, causing a full page reload. The client env would handle it
|
|
356
|
-
// fine via React Refresh, but the RSC env's full-reload arrives first.
|
|
357
|
-
//
|
|
358
|
-
// Fix: in the RSC env, return [] for "use client" files to signal
|
|
359
|
-
// "handled, nothing to propagate". The client env is left alone so
|
|
360
|
-
// React Refresh processes the update normally.
|
|
361
394
|
plugins.push({
|
|
362
395
|
name: "@rangojs/router:client-component-hmr",
|
|
363
396
|
hotUpdate(ctx) {
|
|
@@ -376,74 +409,45 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
376
409
|
|
|
377
410
|
try {
|
|
378
411
|
const source = readFileSync(file, "utf-8");
|
|
379
|
-
|
|
380
|
-
if (
|
|
381
|
-
trimmed.startsWith('"use client"') ||
|
|
382
|
-
trimmed.startsWith("'use client'")
|
|
383
|
-
) {
|
|
384
|
-
// Consume the update in RSC/SSR envs. The proxy module was already
|
|
385
|
-
// re-transformed by the RSC plugin's hotUpdate. Without this, Vite
|
|
386
|
-
// tries to propagate through the RSC/SSR module graph where the proxy
|
|
387
|
-
// has no import.meta.hot.accept() boundary, triggering a full reload.
|
|
388
|
-
// The actual component update is handled by React Refresh in the
|
|
389
|
-
// client environment.
|
|
412
|
+
if (hasUseClientDirective(source)) {
|
|
390
413
|
return [];
|
|
391
414
|
}
|
|
392
|
-
} catch {
|
|
393
|
-
// File deleted/moved during HMR, let default handling proceed
|
|
394
|
-
}
|
|
415
|
+
} catch {}
|
|
395
416
|
},
|
|
396
417
|
});
|
|
397
418
|
|
|
398
419
|
plugins.push(exposeActionId());
|
|
399
|
-
|
|
400
|
-
// "use cache" directive transform (enforce: "post"):
|
|
401
|
-
// Wraps exports with registerCachedFunction() for function-level caching.
|
|
402
420
|
plugins.push(useCacheTransform());
|
|
403
|
-
|
|
404
|
-
// Consolidated plugin for create* ID injection (enforce: "post"):
|
|
405
|
-
// loaders, handles, location state, and prerender handlers.
|
|
406
421
|
plugins.push(exposeInternalIds());
|
|
407
|
-
|
|
408
|
-
// Router ID injection runs at normal priority (no enforce) to avoid
|
|
409
|
-
// changing Vite's dep optimization timing.
|
|
410
422
|
plugins.push(exposeRouterId());
|
|
411
|
-
|
|
412
|
-
// Add version virtual module plugin for cache invalidation
|
|
413
423
|
plugins.push(createVersionPlugin());
|
|
414
424
|
|
|
415
|
-
// Entry path for discovery: user-specified value (if any) or undefined.
|
|
416
|
-
// Auto-discovered path is passed separately via routerRef.
|
|
417
|
-
// Cloudflare preset: deferred to configResolved (read from resolved Vite env config).
|
|
418
425
|
const discoveryEntryPath =
|
|
419
426
|
preset !== "cloudflare" ? routerRef.path : undefined;
|
|
420
|
-
// Ref for deferred auto-discovery (node preset only, undefined for cloudflare)
|
|
421
427
|
const discoveryRouterRef = preset !== "cloudflare" ? routerRef : undefined;
|
|
422
428
|
|
|
423
|
-
// Version injector: auto-injects VERSION and routes-manifest into the RSC entry.
|
|
424
|
-
// For cloudflare preset, the entry is resolved lazily in configResolved.
|
|
425
|
-
// For node preset, the virtual entry already includes these imports.
|
|
426
429
|
if (preset === "cloudflare") {
|
|
427
430
|
plugins.push(createVersionInjectorPlugin(undefined));
|
|
428
431
|
}
|
|
429
432
|
|
|
430
|
-
// Transform CJS vendor files to ESM for browser compatibility
|
|
431
|
-
// optimizeDeps.include doesn't work because the file is loaded after initial optimization
|
|
432
433
|
plugins.push(createCjsToEsmPlugin());
|
|
433
|
-
|
|
434
|
-
// Router discovery plugin for build-time manifest generation.
|
|
435
|
-
// For cloudflare, the entry is resolved lazily in configResolved from the RSC environment.
|
|
436
|
-
// For node, discoveryRouterRef provides the auto-discovered path when not user-specified.
|
|
437
434
|
plugins.push(
|
|
438
435
|
createRouterDiscoveryPlugin(discoveryEntryPath, {
|
|
439
436
|
routerPathRef: discoveryRouterRef,
|
|
440
437
|
enableBuildPrerender: prerenderEnabled,
|
|
441
|
-
|
|
438
|
+
buildEnv: options?.buildEnv,
|
|
439
|
+
preset,
|
|
440
|
+
prerenderOnError: options?.prerender?.onError,
|
|
441
|
+
discovery: options?.discovery,
|
|
442
|
+
clientChunkCtx,
|
|
442
443
|
}),
|
|
443
444
|
);
|
|
444
445
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
446
|
+
debugConfig?.(
|
|
447
|
+
"rango(%s) setup done: %d plugin(s) (%sms)",
|
|
448
|
+
preset,
|
|
449
|
+
plugins.length,
|
|
450
|
+
(performance.now() - rangoStart).toFixed(1),
|
|
451
|
+
);
|
|
448
452
|
return plugins;
|
|
449
453
|
}
|