@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.141
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 +17 -0
- package/README.md +432 -7
- package/dist/bin/rango.js +2073 -213
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +7258 -2714
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +140 -67
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +487 -0
- package/skills/caching/SKILL.md +357 -25
- 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 +246 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -10
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +207 -15
- package/skills/layout/SKILL.md +146 -6
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +616 -54
- package/skills/middleware/SKILL.md +217 -37
- package/skills/migrate-nextjs/SKILL.md +611 -0
- package/skills/migrate-react-router/SKILL.md +927 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +194 -0
- package/skills/parallel/SKILL.md +284 -3
- package/skills/ppr/SKILL.md +293 -0
- package/skills/prerender/SKILL.md +437 -52
- package/skills/rango/SKILL.md +369 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +263 -121
- package/skills/route/SKILL.md +350 -21
- package/skills/router-setup/SKILL.md +246 -33
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +126 -222
- 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 +9 -8
- package/skills/typesafety/SKILL.md +532 -103
- package/skills/use-cache/SKILL.md +367 -0
- 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 +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- 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 +293 -202
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +245 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +184 -118
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +412 -364
- package/src/browser/prefetch/cache.ts +359 -0
- package/src/browser/prefetch/fetch.ts +452 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +275 -68
- package/src/browser/react/NavigationProvider.tsx +265 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +300 -72
- package/src/browser/scroll-restoration.ts +138 -50
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +223 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +252 -161
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +225 -42
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +60 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +525 -0
- package/src/cache/cache-scope.ts +298 -332
- 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 +2508 -158
- 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 +17 -17
- package/src/cache/document-cache.ts +199 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +111 -0
- package/src/cache/index.ts +24 -35
- package/src/cache/memory-segment-store.ts +363 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +248 -0
- package/src/cache/shell-snapshot.ts +368 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +222 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1113 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- 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 +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +173 -35
- package/src/index.ts +241 -73
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +460 -26
- 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 +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +505 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +263 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +245 -0
- package/src/router/handler-context.ts +377 -125
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +59 -28
- package/src/router/lazy-includes.ts +254 -0
- package/src/router/loader-resolution.ts +421 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +131 -57
- package/src/router/match-api.ts +167 -246
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +505 -441
- 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 +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +547 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +278 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +246 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +554 -0
- package/src/router/router-options.ts +779 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +772 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +250 -0
- package/src/router/segment-resolution/loader-mask.ts +44 -0
- package/src/router/segment-resolution/revalidation.ts +1331 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- 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 +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +781 -2378
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +905 -1142
- package/src/rsc/helpers.ts +275 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +502 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +527 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +897 -0
- package/src/rsc/shell-serve.ts +124 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +349 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +459 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +310 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +848 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +443 -135
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -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 +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 +76 -98
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +44 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +280 -0
- package/src/urls/pattern-types.ts +160 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- 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 +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- 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 +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- 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/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- 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 +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type MagicString from "magic-string";
|
|
2
|
-
import { hashInlineId, buildExportMap } from "
|
|
3
|
-
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
// Types
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
2
|
+
import { hashInlineId, buildExportMap } from "../plugins/expose-id-utils.js";
|
|
7
3
|
|
|
8
4
|
/** Minimal ESTree Program node — avoids importing from `rollup` (not a direct dep). */
|
|
9
5
|
interface ProgramNode {
|
|
@@ -27,14 +23,14 @@ export interface HandlerCallSite {
|
|
|
27
23
|
export interface VirtualHandlerEntry {
|
|
28
24
|
originalModuleId: string;
|
|
29
25
|
imports: string[];
|
|
26
|
+
declarations: string[];
|
|
30
27
|
handlerCode: string;
|
|
31
28
|
exportName: string;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
31
|
function isDirectivePrologueStatement(node: any): boolean {
|
|
35
32
|
return (
|
|
36
|
-
node?.type === "ExpressionStatement" &&
|
|
37
|
-
typeof node.directive === "string"
|
|
33
|
+
node?.type === "ExpressionStatement" && typeof node.directive === "string"
|
|
38
34
|
);
|
|
39
35
|
}
|
|
40
36
|
|
|
@@ -48,7 +44,7 @@ function findImportInsertionPos(
|
|
|
48
44
|
): number {
|
|
49
45
|
let program: ProgramNode;
|
|
50
46
|
try {
|
|
51
|
-
program = parseAst(code, {
|
|
47
|
+
program = parseAst(code, { lang: "tsx" });
|
|
52
48
|
} catch {
|
|
53
49
|
return 0;
|
|
54
50
|
}
|
|
@@ -70,10 +66,6 @@ function findImportInsertionPos(
|
|
|
70
66
|
return insertionPos;
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// AST walking helper
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
|
|
77
69
|
/**
|
|
78
70
|
* Recursively walk an ESTree AST node, calling `enter` on each node.
|
|
79
71
|
* Parent is passed for context.
|
|
@@ -99,7 +91,11 @@ function walkNode(
|
|
|
99
91
|
walkNode(item, node, ancestors, enter);
|
|
100
92
|
}
|
|
101
93
|
}
|
|
102
|
-
} else if (
|
|
94
|
+
} else if (
|
|
95
|
+
child &&
|
|
96
|
+
typeof child === "object" &&
|
|
97
|
+
typeof child.type === "string"
|
|
98
|
+
) {
|
|
103
99
|
walkNode(child, node, ancestors, enter);
|
|
104
100
|
}
|
|
105
101
|
}
|
|
@@ -107,10 +103,6 @@ function walkNode(
|
|
|
107
103
|
ancestors.pop();
|
|
108
104
|
}
|
|
109
105
|
|
|
110
|
-
// ---------------------------------------------------------------------------
|
|
111
|
-
// AST analysis
|
|
112
|
-
// ---------------------------------------------------------------------------
|
|
113
|
-
|
|
114
106
|
/**
|
|
115
107
|
* Parse the file with Vite's parseAst and find all calls to `fnName`.
|
|
116
108
|
* Distinguishes between `export const X = fnName(...)` (exportInfo set)
|
|
@@ -123,7 +115,7 @@ export function findHandlerCalls(
|
|
|
123
115
|
): HandlerCallSite[] {
|
|
124
116
|
let program: ProgramNode;
|
|
125
117
|
try {
|
|
126
|
-
program = parseAst(code, {
|
|
118
|
+
program = parseAst(code, { lang: "tsx" });
|
|
127
119
|
} catch {
|
|
128
120
|
return [];
|
|
129
121
|
}
|
|
@@ -158,8 +150,10 @@ export function findHandlerCalls(
|
|
|
158
150
|
|
|
159
151
|
if (parent?.type === "VariableDeclarator" && parent.init === node) {
|
|
160
152
|
// ancestors: [..., ExportNamedDecl, VarDecl, VarDeclarator, CallExpr]
|
|
161
|
-
const grandParent =
|
|
162
|
-
|
|
153
|
+
const grandParent =
|
|
154
|
+
ancestors.length >= 3 ? ancestors[ancestors.length - 3] : null;
|
|
155
|
+
const greatGrandParent =
|
|
156
|
+
ancestors.length >= 4 ? ancestors[ancestors.length - 4] : null;
|
|
163
157
|
|
|
164
158
|
if (
|
|
165
159
|
grandParent?.type === "VariableDeclaration" &&
|
|
@@ -233,7 +227,7 @@ export function getImportedLocalNames(
|
|
|
233
227
|
parseAst: (code: string, options?: any) => ProgramNode,
|
|
234
228
|
): Set<string> {
|
|
235
229
|
try {
|
|
236
|
-
const program = parseAst(code, {
|
|
230
|
+
const program = parseAst(code, { lang: "tsx" });
|
|
237
231
|
return getImportedLocalNamesFromProgram(program, importedName);
|
|
238
232
|
} catch {
|
|
239
233
|
return new Set<string>();
|
|
@@ -250,7 +244,7 @@ export function extractImportDeclarations(
|
|
|
250
244
|
): string[] {
|
|
251
245
|
let program: ProgramNode;
|
|
252
246
|
try {
|
|
253
|
-
program = parseAst(code, {
|
|
247
|
+
program = parseAst(code, { lang: "tsx" });
|
|
254
248
|
} catch {
|
|
255
249
|
return [];
|
|
256
250
|
}
|
|
@@ -264,9 +258,168 @@ export function extractImportDeclarations(
|
|
|
264
258
|
return imports;
|
|
265
259
|
}
|
|
266
260
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Check if an expression AST subtree is "inert" -- safe to evaluate eagerly
|
|
263
|
+
* without referencing import bindings. Inert expressions contain only literals,
|
|
264
|
+
* arrays/objects of inert values, template literals with inert expressions,
|
|
265
|
+
* and unary/binary operators on inert operands.
|
|
266
|
+
*
|
|
267
|
+
* Function/arrow expressions are NOT inert (they're lazy -- handled separately).
|
|
268
|
+
* Identifiers and member expressions are NOT inert (may reference imports).
|
|
269
|
+
*
|
|
270
|
+
* This check prevents TDZ errors when declarations are moved to virtual
|
|
271
|
+
* modules that end up in separate Rollup chunks with circular dependencies.
|
|
272
|
+
*/
|
|
273
|
+
function isInertExpression(node: any): boolean {
|
|
274
|
+
if (!node) return false;
|
|
275
|
+
switch (node.type) {
|
|
276
|
+
case "Literal":
|
|
277
|
+
return true;
|
|
278
|
+
case "TemplateLiteral":
|
|
279
|
+
return (node.expressions ?? []).every((e: any) => isInertExpression(e));
|
|
280
|
+
case "ArrayExpression":
|
|
281
|
+
return (node.elements ?? []).every(
|
|
282
|
+
(e: any) => e === null || isInertExpression(e),
|
|
283
|
+
);
|
|
284
|
+
case "ObjectExpression":
|
|
285
|
+
return (node.properties ?? []).every((p: any) => {
|
|
286
|
+
// A spread inside an object (`{ ...x }`) is inert iff `x` is inert.
|
|
287
|
+
if (p.type === "SpreadElement" || p.type === "RestElement") {
|
|
288
|
+
return isInertExpression(p.argument);
|
|
289
|
+
}
|
|
290
|
+
return (
|
|
291
|
+
p.type === "Property" &&
|
|
292
|
+
(!p.computed || isInertExpression(p.key)) &&
|
|
293
|
+
isInertExpression(p.value)
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
case "UnaryExpression":
|
|
297
|
+
return isInertExpression(node.argument);
|
|
298
|
+
case "BinaryExpression":
|
|
299
|
+
return isInertExpression(node.left) && isInertExpression(node.right);
|
|
300
|
+
case "LogicalExpression":
|
|
301
|
+
return isInertExpression(node.left) && isInertExpression(node.right);
|
|
302
|
+
case "ConditionalExpression":
|
|
303
|
+
return (
|
|
304
|
+
isInertExpression(node.test) &&
|
|
305
|
+
isInertExpression(node.consequent) &&
|
|
306
|
+
isInertExpression(node.alternate)
|
|
307
|
+
);
|
|
308
|
+
case "SpreadElement":
|
|
309
|
+
return isInertExpression(node.argument);
|
|
310
|
+
default:
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Check if a variable declarator's init is safe for inclusion in a virtual
|
|
317
|
+
* module. Safe initializers are:
|
|
318
|
+
* 1. Function/arrow expressions (body is lazy, no TDZ risk)
|
|
319
|
+
* 2. Inert expressions (no identifier references, no TDZ risk)
|
|
320
|
+
*
|
|
321
|
+
* Declarations that reference identifiers at the top level (e.g.
|
|
322
|
+
* `const VT = React.Fragment`) are NOT safe -- when the virtual module
|
|
323
|
+
* is bundled into a separate Rollup chunk, circular chunk dependencies
|
|
324
|
+
* can cause "Cannot access X before initialization" TDZ errors.
|
|
325
|
+
*/
|
|
326
|
+
function isSafeDeclaratorInit(init: any): boolean {
|
|
327
|
+
if (!init) return true; // `let x;` with no init is safe
|
|
328
|
+
if (
|
|
329
|
+
init.type === "ArrowFunctionExpression" ||
|
|
330
|
+
init.type === "FunctionExpression"
|
|
331
|
+
) {
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
return isInertExpression(init);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Check if all declarators in a VariableDeclaration have safe initializers
|
|
339
|
+
* and none is a handler call (Static/Prerender).
|
|
340
|
+
*/
|
|
341
|
+
function isSafeVariableDeclaration(
|
|
342
|
+
node: any,
|
|
343
|
+
handlerNames: Set<string>,
|
|
344
|
+
): boolean {
|
|
345
|
+
if (node.type !== "VariableDeclaration") return false;
|
|
346
|
+
return node.declarations.every(
|
|
347
|
+
(d: any) =>
|
|
348
|
+
isSafeDeclaratorInit(d.init) &&
|
|
349
|
+
!(
|
|
350
|
+
d.init?.type === "CallExpression" &&
|
|
351
|
+
d.init.callee?.type === "Identifier" &&
|
|
352
|
+
handlerNames.has(d.init.callee.name)
|
|
353
|
+
),
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Extract module-level declarations that are safe for inclusion in virtual
|
|
359
|
+
* modules. "Safe" means the declaration can be eagerly evaluated without
|
|
360
|
+
* referencing import bindings, preventing TDZ errors in separate chunks.
|
|
361
|
+
*
|
|
362
|
+
* Included: function declarations, arrow/function expression inits, and
|
|
363
|
+
* variable inits that are inert (pure literals, arrays, objects).
|
|
364
|
+
* Excluded: declarations that reference identifiers at init time (may
|
|
365
|
+
* reference imports causing TDZ), handler call declarations (circular),
|
|
366
|
+
* class declarations (field initializers can reference imports).
|
|
367
|
+
*
|
|
368
|
+
* Strips export keywords so declarations work as plain locals.
|
|
369
|
+
* Rollup tree-shakes unused declarations from virtual modules.
|
|
370
|
+
*/
|
|
371
|
+
export function extractModuleLevelDeclarations(
|
|
372
|
+
code: string,
|
|
373
|
+
parseAst: (code: string, options?: any) => ProgramNode,
|
|
374
|
+
handlerNames: Set<string>,
|
|
375
|
+
): string[] {
|
|
376
|
+
let program: ProgramNode;
|
|
377
|
+
try {
|
|
378
|
+
program = parseAst(code, { lang: "tsx" });
|
|
379
|
+
} catch {
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const declarations: string[] = [];
|
|
384
|
+
for (const node of program.body as any[]) {
|
|
385
|
+
// Skip imports (handled by extractImportDeclarations)
|
|
386
|
+
if (node.type === "ImportDeclaration") continue;
|
|
387
|
+
|
|
388
|
+
// VariableDeclaration -- include only if all declarators are safe
|
|
389
|
+
if (node.type === "VariableDeclaration") {
|
|
390
|
+
if (isSafeVariableDeclaration(node, handlerNames)) {
|
|
391
|
+
declarations.push(code.slice(node.start, node.end));
|
|
392
|
+
}
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// FunctionDeclaration -- always safe (body is lazy)
|
|
397
|
+
if (node.type === "FunctionDeclaration") {
|
|
398
|
+
declarations.push(code.slice(node.start, node.end));
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// ExportNamedDeclaration with a declaration inside -- strip the export
|
|
403
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration) {
|
|
404
|
+
const decl = node.declaration;
|
|
405
|
+
if (decl.type === "VariableDeclaration") {
|
|
406
|
+
if (isSafeVariableDeclaration(decl, handlerNames)) {
|
|
407
|
+
declarations.push(code.slice(decl.start, decl.end));
|
|
408
|
+
}
|
|
409
|
+
} else if (decl.type === "FunctionDeclaration") {
|
|
410
|
+
declarations.push(code.slice(decl.start, decl.end));
|
|
411
|
+
}
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Skip: ClassDeclaration (field initializers can reference imports),
|
|
416
|
+
// ExportDefaultDeclaration, ExportAllDeclaration,
|
|
417
|
+
// ExportNamedDeclaration without declaration (re-exports),
|
|
418
|
+
// ExpressionStatement (side effects), etc.
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return declarations;
|
|
422
|
+
}
|
|
270
423
|
|
|
271
424
|
/**
|
|
272
425
|
* Transform inline handler calls by extracting them into virtual modules.
|
|
@@ -295,19 +448,30 @@ export function transformInlineHandlers(
|
|
|
295
448
|
|
|
296
449
|
const imports = extractImportDeclarations(code, parseAst);
|
|
297
450
|
|
|
298
|
-
//
|
|
299
|
-
|
|
451
|
+
// Collect local names for both Static and Prerender to exclude their
|
|
452
|
+
// declarations from virtual modules (avoids circular extraction).
|
|
453
|
+
const staticNames = getImportedLocalNames(code, "Static", parseAst);
|
|
454
|
+
const prerenderNames = getImportedLocalNames(code, "Prerender", parseAst);
|
|
455
|
+
const handlerNames = new Set([...staticNames, ...prerenderNames]);
|
|
456
|
+
const declarations = extractModuleLevelDeclarations(
|
|
457
|
+
code,
|
|
458
|
+
parseAst,
|
|
459
|
+
handlerNames,
|
|
460
|
+
);
|
|
300
461
|
|
|
301
462
|
// Collect all import statements to prepend
|
|
302
463
|
const importStatements: string[] = [];
|
|
303
464
|
|
|
304
|
-
for (const site of inlineSites) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
465
|
+
for (const [siteIndex, site] of inlineSites.entries()) {
|
|
466
|
+
// Key the extracted handler on its source-order index (per fnName), NOT its
|
|
467
|
+
// line number. The id flows into BOTH the export name and the virtual module
|
|
468
|
+
// path (which hashId hashes for the runtime $$id), and line numbers shift
|
|
469
|
+
// between the prerender and production build contexts. The index is invariant
|
|
470
|
+
// to those shifts, keeping the prerender manifest key == the runtime id.
|
|
471
|
+
const hash = hashInlineId(filePath, fnName, siteIndex);
|
|
309
472
|
const exportName = `__sh_${hash}`;
|
|
310
|
-
const
|
|
473
|
+
const idSuffix = `${filePath}:${fnName}:${siteIndex}`;
|
|
474
|
+
const virtualId = `\0${virtualPrefix}${idSuffix}`;
|
|
311
475
|
|
|
312
476
|
// Extract the full handler call expression text
|
|
313
477
|
const handlerCode = code.slice(site.callStart, site.callEnd);
|
|
@@ -316,6 +480,7 @@ export function transformInlineHandlers(
|
|
|
316
480
|
virtualRegistry.set(virtualId, {
|
|
317
481
|
originalModuleId: moduleId,
|
|
318
482
|
imports,
|
|
483
|
+
declarations,
|
|
319
484
|
handlerCode,
|
|
320
485
|
exportName,
|
|
321
486
|
});
|
|
@@ -324,10 +489,8 @@ export function transformInlineHandlers(
|
|
|
324
489
|
s.overwrite(site.callStart, site.callEnd, exportName);
|
|
325
490
|
|
|
326
491
|
// Build the import specifier for this virtual module
|
|
327
|
-
const importId = `${virtualPrefix}${
|
|
328
|
-
importStatements.push(
|
|
329
|
-
`import { ${exportName} } from "${importId}";`,
|
|
330
|
-
);
|
|
492
|
+
const importId = `${virtualPrefix}${idSuffix}`;
|
|
493
|
+
importStatements.push(`import { ${exportName} } from "${importId}";`);
|
|
331
494
|
}
|
|
332
495
|
|
|
333
496
|
// Insert imports after directive prologue + existing import block
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import packageJson from "../../../package.json";
|
|
2
|
+
|
|
3
|
+
export const rangoVersion: string = packageJson.version;
|
|
4
|
+
|
|
5
|
+
let _bannerPrinted = false;
|
|
6
|
+
|
|
7
|
+
export function printBanner(
|
|
8
|
+
mode: "dev" | "build" | "preview",
|
|
9
|
+
preset: string,
|
|
10
|
+
version: string,
|
|
11
|
+
): void {
|
|
12
|
+
if (_bannerPrinted) return;
|
|
13
|
+
_bannerPrinted = true;
|
|
14
|
+
|
|
15
|
+
// ANSI codes
|
|
16
|
+
const dim = "\x1b[2m";
|
|
17
|
+
const bold = "\x1b[1m";
|
|
18
|
+
const reset = "\x1b[0m";
|
|
19
|
+
|
|
20
|
+
const banner = `
|
|
21
|
+
${dim} ✦ ✦ ✧. . .${reset}
|
|
22
|
+
${dim} ╱${reset} ${bold}╔═╗${reset}${dim} * ╱ ✦ *${reset}
|
|
23
|
+
${dim} ${reset}${bold}║ ║${reset} ${bold}╔═╗${reset}${dim} * ✧. ╱${reset}
|
|
24
|
+
${dim} ${reset}${bold}╔╗ ║ ║ ║ ║${reset}${dim} * ╱${reset}
|
|
25
|
+
${dim} ${reset}${bold}║║ ║ ║ ║ ║ ╦═╗╔═╗╔╗╔╔═╗╔═╗${reset}${dim} ✧ ✦${reset}
|
|
26
|
+
${dim} ${reset}${bold}║║ ║ ╠═╝ ║ ╠╦╝╠═╣║║║║ ╦║ ║${reset}${dim} * ✧${reset}
|
|
27
|
+
${dim} ${reset}${bold}║╚═╝ ╔═══╝ ╩╚═╩ ╩╝╚╝╚═╝╚═╝${reset}${dim} ✦ . *${reset}
|
|
28
|
+
${dim} ${reset}${bold}╚══╗ ║${reset}${dim} * RSC Wrangler ✧ ✦${reset}
|
|
29
|
+
${dim} * ${reset}${bold}║ ║${reset}${dim} * ✧. ╱${reset}
|
|
30
|
+
${dim} ${reset}${bold}═══╝ ╚════${reset}${dim} ✦ *${reset}
|
|
31
|
+
|
|
32
|
+
v${version} · ${preset} · ${mode}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
console.log(banner);
|
|
36
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
skipStringOrComment,
|
|
3
|
+
escapeRegExp,
|
|
4
|
+
} from "../plugins/expose-id-utils.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Find matching close paren in bundled code using depth counting.
|
|
8
|
+
* Uses skipStringOrComment to correctly handle template literals, comments, and nested strings.
|
|
9
|
+
* @internal Exported for testing only.
|
|
10
|
+
*/
|
|
11
|
+
export function findMatchingParenInBundle(
|
|
12
|
+
code: string,
|
|
13
|
+
openParenPos: number,
|
|
14
|
+
): number {
|
|
15
|
+
let depth = 1;
|
|
16
|
+
let pos = openParenPos;
|
|
17
|
+
while (pos < code.length && depth > 0) {
|
|
18
|
+
const skipped = skipStringOrComment(code, pos);
|
|
19
|
+
if (skipped > pos) {
|
|
20
|
+
pos = skipped;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (code[pos] === "(") depth++;
|
|
24
|
+
else if (code[pos] === ")") depth--;
|
|
25
|
+
pos++;
|
|
26
|
+
}
|
|
27
|
+
return depth === 0 ? pos : -1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Scan a bundled chunk for handler exports and extract their names + $$id values.
|
|
32
|
+
* Optionally detects passthrough flag. @internal Exported for testing only.
|
|
33
|
+
*/
|
|
34
|
+
export function extractHandlerExportsFromChunk(
|
|
35
|
+
chunkCode: string,
|
|
36
|
+
handlerModules: Map<string, string[]>,
|
|
37
|
+
fnName: string,
|
|
38
|
+
detectPassthrough: boolean,
|
|
39
|
+
): Array<{ name: string; handlerId: string; passthrough: boolean }> {
|
|
40
|
+
const handlers: Array<{
|
|
41
|
+
name: string;
|
|
42
|
+
handlerId: string;
|
|
43
|
+
passthrough: boolean;
|
|
44
|
+
}> = [];
|
|
45
|
+
|
|
46
|
+
for (const [, handlerNames] of handlerModules) {
|
|
47
|
+
for (const name of handlerNames) {
|
|
48
|
+
const eName = escapeRegExp(name);
|
|
49
|
+
const idPattern = new RegExp(
|
|
50
|
+
`(?<![a-zA-Z0-9_])${eName}\\.\\$\\$id\\s*=\\s*"([^"]+)"`,
|
|
51
|
+
);
|
|
52
|
+
const match = chunkCode.match(idPattern);
|
|
53
|
+
if (!match) continue;
|
|
54
|
+
|
|
55
|
+
let isPassthrough = false;
|
|
56
|
+
if (detectPassthrough) {
|
|
57
|
+
const eFnName = escapeRegExp(fnName);
|
|
58
|
+
const callStartRe = new RegExp(
|
|
59
|
+
`(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`,
|
|
60
|
+
);
|
|
61
|
+
const callStart = callStartRe.exec(chunkCode);
|
|
62
|
+
if (callStart) {
|
|
63
|
+
const afterOpen = callStart.index + callStart[0].length;
|
|
64
|
+
const closePos = findMatchingParenInBundle(chunkCode, afterOpen);
|
|
65
|
+
if (closePos !== -1) {
|
|
66
|
+
const callBody = chunkCode.slice(callStart.index, closePos);
|
|
67
|
+
isPassthrough = /passthrough\s*:\s*(!0|true)/.test(callBody); // !0 is minified true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
handlers.push({ name, handlerId: match[1], passthrough: isPassthrough });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return handlers;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Evict handler code from a bundled chunk, replacing full call expressions with stubs.
|
|
80
|
+
* Returns the modified code and bytes saved, or null if no changes were made.
|
|
81
|
+
* @internal Exported for testing only.
|
|
82
|
+
*/
|
|
83
|
+
export function evictHandlerCode(
|
|
84
|
+
code: string,
|
|
85
|
+
exports: Array<{ name: string; handlerId: string; passthrough?: boolean }>,
|
|
86
|
+
fnName: string,
|
|
87
|
+
brand: string,
|
|
88
|
+
): { code: string; savedBytes: number } | null {
|
|
89
|
+
const originalSize = Buffer.byteLength(code);
|
|
90
|
+
let modified = code;
|
|
91
|
+
|
|
92
|
+
const eFnName = escapeRegExp(fnName);
|
|
93
|
+
for (const { name, handlerId, passthrough } of exports) {
|
|
94
|
+
if (passthrough) continue;
|
|
95
|
+
|
|
96
|
+
const eName = escapeRegExp(name);
|
|
97
|
+
// Match const/let/var: Rolldown (Vite 8) emits top-level bindings in the
|
|
98
|
+
// non-minified RSC bundle as `var`, whereas Rollup used `const`.
|
|
99
|
+
const callStartRe = new RegExp(
|
|
100
|
+
`(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`,
|
|
101
|
+
);
|
|
102
|
+
const startMatch = callStartRe.exec(modified);
|
|
103
|
+
if (!startMatch) continue;
|
|
104
|
+
|
|
105
|
+
const afterOpen = startMatch.index + startMatch[0].length;
|
|
106
|
+
const closePos = findMatchingParenInBundle(modified, afterOpen);
|
|
107
|
+
if (closePos === -1) continue;
|
|
108
|
+
|
|
109
|
+
let rangeEnd = closePos;
|
|
110
|
+
while (rangeEnd < modified.length && /\s/.test(modified[rangeEnd]))
|
|
111
|
+
rangeEnd++;
|
|
112
|
+
if (modified[rangeEnd] === ";") rangeEnd++;
|
|
113
|
+
|
|
114
|
+
const matched = modified.slice(startMatch.index, rangeEnd);
|
|
115
|
+
if (!matched.includes(handlerId)) continue;
|
|
116
|
+
|
|
117
|
+
const stub = `const ${name} = { __brand: "${brand}", $$id: "${handlerId}" };`;
|
|
118
|
+
modified =
|
|
119
|
+
modified.slice(0, startMatch.index) + stub + modified.slice(rangeEnd);
|
|
120
|
+
|
|
121
|
+
modified = modified.replace(
|
|
122
|
+
new RegExp(`\\n${eName}\\.\\$\\$id\\s*=\\s*"[^"]+";`),
|
|
123
|
+
"",
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (modified === code) return null;
|
|
128
|
+
return {
|
|
129
|
+
code: modified,
|
|
130
|
+
savedBytes: originalSize - Buffer.byteLength(modified),
|
|
131
|
+
};
|
|
132
|
+
}
|