@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
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import MagicString from "magic-string";
|
|
2
|
+
import { makeStubId } from "../expose-id-utils.js";
|
|
3
|
+
import type { HandlerTransformConfig, CreateExportBinding } from "./types.js";
|
|
4
|
+
import { isExportOnlyFile } from "./export-analysis.js";
|
|
5
|
+
|
|
6
|
+
export function transformHandles(
|
|
7
|
+
bindings: CreateExportBinding[],
|
|
8
|
+
s: MagicString,
|
|
9
|
+
filePath: string,
|
|
10
|
+
isBuild: boolean,
|
|
11
|
+
): boolean {
|
|
12
|
+
let hasChanges = false;
|
|
13
|
+
for (const binding of bindings) {
|
|
14
|
+
const exportName = binding.exportNames[0];
|
|
15
|
+
|
|
16
|
+
const handleId = makeStubId(filePath, exportName, isBuild);
|
|
17
|
+
|
|
18
|
+
// Branch on the AST-derived argCount, not a string-trim of the raw arg
|
|
19
|
+
// slice. A comment-only arg list (`createHandle(/* meta */)`) trims to
|
|
20
|
+
// non-empty but is zero real arguments; injecting `, "id"` would emit
|
|
21
|
+
// `createHandle(/* meta */, "id")` — an elided first arg / syntax error.
|
|
22
|
+
let paramInjection: string;
|
|
23
|
+
if (binding.argCount === 0) {
|
|
24
|
+
paramInjection = `undefined, "${handleId}"`;
|
|
25
|
+
} else {
|
|
26
|
+
paramInjection = `, "${handleId}"`;
|
|
27
|
+
}
|
|
28
|
+
s.appendLeft(binding.callCloseParenPos, paramInjection);
|
|
29
|
+
|
|
30
|
+
const propInjection = `\n${binding.localName}.$$id = "${handleId}";`;
|
|
31
|
+
s.appendRight(binding.statementEnd, propInjection);
|
|
32
|
+
hasChanges = true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return hasChanges;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function transformLocationState(
|
|
39
|
+
bindings: CreateExportBinding[],
|
|
40
|
+
s: MagicString,
|
|
41
|
+
filePath: string,
|
|
42
|
+
isBuild: boolean,
|
|
43
|
+
): boolean {
|
|
44
|
+
let hasChanges = false;
|
|
45
|
+
for (const binding of bindings) {
|
|
46
|
+
const exportName = binding.exportNames[0];
|
|
47
|
+
|
|
48
|
+
const stateKey = makeStubId(filePath, exportName, isBuild);
|
|
49
|
+
|
|
50
|
+
// Key is injected as a property assignment (not as a function argument).
|
|
51
|
+
// This allows createLocationState to accept options like { flash: true }
|
|
52
|
+
// without conflicting with key injection.
|
|
53
|
+
const propInjection = `\n${binding.localName}.__rsc_ls_key = "__rsc_ls_${stateKey}";`;
|
|
54
|
+
s.appendRight(binding.statementEnd, propInjection);
|
|
55
|
+
hasChanges = true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return hasChanges;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function generateWholeFileStubs(
|
|
62
|
+
cfg: HandlerTransformConfig,
|
|
63
|
+
bindings: CreateExportBinding[],
|
|
64
|
+
code: string,
|
|
65
|
+
filePath: string,
|
|
66
|
+
isBuild: boolean,
|
|
67
|
+
): { code: string; map: null } | null {
|
|
68
|
+
if (!isExportOnlyFile(code, bindings)) return null;
|
|
69
|
+
|
|
70
|
+
const exportNames = bindings.flatMap((b) => b.exportNames);
|
|
71
|
+
const stubs = exportNames.map((name) => {
|
|
72
|
+
const handlerId = makeStubId(filePath, name, isBuild);
|
|
73
|
+
return `export const ${name} = { __brand: "${cfg.brand}", $$id: "${handlerId}" };`;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return { code: stubs.join("\n") + "\n", map: null };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function stubHandlerExprs(
|
|
80
|
+
cfg: HandlerTransformConfig,
|
|
81
|
+
bindings: CreateExportBinding[],
|
|
82
|
+
s: MagicString,
|
|
83
|
+
filePath: string,
|
|
84
|
+
isBuild: boolean,
|
|
85
|
+
): boolean {
|
|
86
|
+
let hasChanges = false;
|
|
87
|
+
for (const binding of bindings) {
|
|
88
|
+
const exportName = binding.exportNames[0];
|
|
89
|
+
const handlerId = makeStubId(filePath, exportName, isBuild);
|
|
90
|
+
|
|
91
|
+
s.overwrite(
|
|
92
|
+
binding.callExprStart,
|
|
93
|
+
binding.callCloseParenPos + 1,
|
|
94
|
+
`{ __brand: "${cfg.brand}", $$id: "${handlerId}" }`,
|
|
95
|
+
);
|
|
96
|
+
hasChanges = true;
|
|
97
|
+
}
|
|
98
|
+
return hasChanges;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function transformHandlerIds(
|
|
102
|
+
cfg: HandlerTransformConfig,
|
|
103
|
+
bindings: CreateExportBinding[],
|
|
104
|
+
s: MagicString,
|
|
105
|
+
filePath: string,
|
|
106
|
+
isBuild: boolean,
|
|
107
|
+
): boolean {
|
|
108
|
+
let hasChanges = false;
|
|
109
|
+
for (const binding of bindings) {
|
|
110
|
+
const exportName = binding.exportNames[0];
|
|
111
|
+
|
|
112
|
+
const handlerId = makeStubId(filePath, exportName, isBuild);
|
|
113
|
+
|
|
114
|
+
let paramInjection: string;
|
|
115
|
+
if (binding.argCount === 0) {
|
|
116
|
+
paramInjection = `undefined, "${handlerId}"`;
|
|
117
|
+
} else if (binding.argCount === 1) {
|
|
118
|
+
paramInjection = `, undefined, "${handlerId}"`;
|
|
119
|
+
} else {
|
|
120
|
+
paramInjection = `, "${handlerId}"`;
|
|
121
|
+
}
|
|
122
|
+
s.appendLeft(binding.callCloseParenPos, paramInjection);
|
|
123
|
+
|
|
124
|
+
const propInjection = `\n${binding.localName}.$$id = "${handlerId}";`;
|
|
125
|
+
s.appendRight(binding.statementEnd, propInjection);
|
|
126
|
+
hasChanges = true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return hasChanges;
|
|
130
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type MagicString from "magic-string";
|
|
2
|
+
import { makeStubId } from "../expose-id-utils.js";
|
|
3
|
+
import type { CreateExportBinding } from "./types.js";
|
|
4
|
+
import { isExportOnlyFile } from "./export-analysis.js";
|
|
5
|
+
|
|
6
|
+
export function hasCreateLoaderImport(code: string): boolean {
|
|
7
|
+
return /import\s*\{[^}]*\bcreateLoader\b[^}]*\}\s*from\s*["']@rangojs\/router(?:\/server)?["']/.test(
|
|
8
|
+
code,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function generateClientLoaderStubs(
|
|
13
|
+
bindings: CreateExportBinding[],
|
|
14
|
+
code: string,
|
|
15
|
+
filePath: string,
|
|
16
|
+
isBuild: boolean,
|
|
17
|
+
): { code: string; map?: undefined } | null {
|
|
18
|
+
if (!isExportOnlyFile(code, bindings)) return null;
|
|
19
|
+
|
|
20
|
+
const lines: string[] = [];
|
|
21
|
+
|
|
22
|
+
for (const binding of bindings) {
|
|
23
|
+
// Aliases share the primary export's id (matches the server side, which
|
|
24
|
+
// registers only exportNames[0] in the loader registry, and the mixed-type
|
|
25
|
+
// whole-file path). Emitting a distinct makeStubId per alias would make a
|
|
26
|
+
// client component importing the alias fetch an id absent from the server
|
|
27
|
+
// registry, so the fetchable-loader request would 404.
|
|
28
|
+
const primaryName = binding.exportNames[0];
|
|
29
|
+
const loaderId = makeStubId(filePath, primaryName, isBuild);
|
|
30
|
+
lines.push(
|
|
31
|
+
`export const ${primaryName} = { __brand: "loader", $$id: "${loaderId}" };`,
|
|
32
|
+
);
|
|
33
|
+
for (const alias of binding.exportNames.slice(1)) {
|
|
34
|
+
lines.push(`export const ${alias} = ${primaryName};`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return { code: lines.join("\n") + "\n" };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function transformLoaders(
|
|
42
|
+
bindings: CreateExportBinding[],
|
|
43
|
+
s: MagicString,
|
|
44
|
+
filePath: string,
|
|
45
|
+
isBuild: boolean,
|
|
46
|
+
): boolean {
|
|
47
|
+
let hasChanges = false;
|
|
48
|
+
|
|
49
|
+
for (const binding of bindings) {
|
|
50
|
+
const exportName = binding.exportNames[0];
|
|
51
|
+
|
|
52
|
+
const loaderId = makeStubId(filePath, exportName, isBuild);
|
|
53
|
+
|
|
54
|
+
const paramInjection =
|
|
55
|
+
binding.argCount === 1 ? `, undefined, "${loaderId}"` : `, "${loaderId}"`;
|
|
56
|
+
s.appendLeft(binding.callCloseParenPos, paramInjection);
|
|
57
|
+
|
|
58
|
+
const propInjection = `\n${binding.localName}.$$id = "${loaderId}";`;
|
|
59
|
+
s.appendRight(binding.statementEnd, propInjection);
|
|
60
|
+
hasChanges = true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return hasChanges;
|
|
64
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import MagicString from "magic-string";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import {
|
|
6
|
+
normalizePath,
|
|
7
|
+
findMatchingParen,
|
|
8
|
+
findCallParenAfterGenerics,
|
|
9
|
+
skipStringOrComment,
|
|
10
|
+
} from "../expose-id-utils.js";
|
|
11
|
+
import { escapeRegExp } from "../../../regex-escape.js";
|
|
12
|
+
import {
|
|
13
|
+
getImportedFnNames,
|
|
14
|
+
buildUnsupportedShapeWarning,
|
|
15
|
+
} from "./export-analysis.js";
|
|
16
|
+
import { codeMatchIndices } from "../../../build/route-types/source-scan.js";
|
|
17
|
+
import { createRangoDebugger, createCounter, NS } from "../../debug.js";
|
|
18
|
+
|
|
19
|
+
const debug = createRangoDebugger(NS.transform);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Advance past leading whitespace and a single leading line/block comment so a
|
|
23
|
+
* `createRouter(/* opts *\/ { ... })` call still resolves to its `{`. Only the
|
|
24
|
+
* first comment-or-whitespace run is skipped (enough for the common prefix
|
|
25
|
+
* case); a non-trivia token after it stops the scan.
|
|
26
|
+
*/
|
|
27
|
+
function skipLeadingTrivia(code: string, start: number, end: number): number {
|
|
28
|
+
let i = start;
|
|
29
|
+
while (i < end) {
|
|
30
|
+
const skipped = skipStringOrComment(code, i);
|
|
31
|
+
// skipStringOrComment only advances for strings/comments, not whitespace.
|
|
32
|
+
if (skipped > i) {
|
|
33
|
+
i = skipped;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (/\s/.test(code[i])) {
|
|
37
|
+
i++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
return i;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function transformRouter(
|
|
46
|
+
code: string,
|
|
47
|
+
filePath: string,
|
|
48
|
+
routerFnNames: string[],
|
|
49
|
+
absolutePath?: string,
|
|
50
|
+
warn?: (message: string) => void,
|
|
51
|
+
): { code: string; map: ReturnType<MagicString["generateMap"]> } | null {
|
|
52
|
+
// Match only the callee identifier; the generic list (which may be nested,
|
|
53
|
+
// e.g. createRouter<Config<Env>>(...)) and the opening paren are located
|
|
54
|
+
// separately via findCallParenAfterGenerics so a nested `>` does not defeat
|
|
55
|
+
// the scan (a `<[^>]*>` regex stopped at the first `>`).
|
|
56
|
+
const pat = new RegExp(
|
|
57
|
+
`\\b(?:${routerFnNames.map(escapeRegExp).join("|")})\\b`,
|
|
58
|
+
"g",
|
|
59
|
+
);
|
|
60
|
+
let match: RegExpExecArray | null;
|
|
61
|
+
const s = new MagicString(code);
|
|
62
|
+
let changed = false;
|
|
63
|
+
const unsupportedSites: Array<{ line: number; column: number }> = [];
|
|
64
|
+
|
|
65
|
+
// Compute the import path for the generated route names file.
|
|
66
|
+
// filePath is relative to project root (e.g., "src/router.tsx")
|
|
67
|
+
const basename = path.basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
|
|
68
|
+
const routeNamesImport = `./${basename}.named-routes.gen.js`;
|
|
69
|
+
const routeNamesVar = `__rsc_rn`;
|
|
70
|
+
|
|
71
|
+
// Only inject at call sites in REAL code, not inside comments or string
|
|
72
|
+
// literals — e.g. a `createRouter({ ... })` snippet in a JSDoc example must
|
|
73
|
+
// not get a `$$id`/`.named-routes.gen` import injected. The sibling analysis
|
|
74
|
+
// path (export-analysis.ts) already uses this same comment/string-aware scan;
|
|
75
|
+
// the raw `pat.exec(code)` loop below would otherwise match in comments too.
|
|
76
|
+
const codeOffsets = new Set(codeMatchIndices(code, pat));
|
|
77
|
+
pat.lastIndex = 0;
|
|
78
|
+
|
|
79
|
+
while ((match = pat.exec(code)) !== null) {
|
|
80
|
+
if (!codeOffsets.has(match.index)) continue;
|
|
81
|
+
const callStart = match.index;
|
|
82
|
+
const calleeEnd = match.index + match[0].length;
|
|
83
|
+
|
|
84
|
+
// Resolve the call's opening paren, skipping an optional (possibly nested)
|
|
85
|
+
// generic argument list. A non-call reference (e.g. a bare identifier or a
|
|
86
|
+
// type position) yields -1 and is skipped.
|
|
87
|
+
const parenPos = findCallParenAfterGenerics(code, calleeEnd);
|
|
88
|
+
if (parenPos === -1) continue;
|
|
89
|
+
|
|
90
|
+
const closeParen = findMatchingParen(code, parenPos + 1);
|
|
91
|
+
const callArgs = code.slice(parenPos + 1, closeParen);
|
|
92
|
+
|
|
93
|
+
// Skip ONLY a call we already injected into. The injected marker is the
|
|
94
|
+
// unique `$$routeNames: <var>` property; a bare `$$id` substring check
|
|
95
|
+
// would also match a user value/comment that merely contains the text
|
|
96
|
+
// "$$id" (e.g. `createRouter({ meta: { note: "see $$id docs" } })`),
|
|
97
|
+
// silently dropping named-route wiring for a legitimate config.
|
|
98
|
+
if (callArgs.includes(`$$routeNames: ${routeNamesVar}`)) continue;
|
|
99
|
+
|
|
100
|
+
const sourceFilePath = absolutePath ?? filePath;
|
|
101
|
+
const lineNumber = code.slice(0, callStart).split("\n").length;
|
|
102
|
+
const hash = createHash("sha256")
|
|
103
|
+
.update(`${filePath}:${lineNumber}`)
|
|
104
|
+
.digest("hex")
|
|
105
|
+
.slice(0, 8);
|
|
106
|
+
const injected = ` $$id: "${hash}", $$sourceFile: "${sourceFilePath}", $$routeNames: ${routeNamesVar},`;
|
|
107
|
+
|
|
108
|
+
// Skip a leading comment/whitespace run so `createRouter(/* c *\/ {...})`
|
|
109
|
+
// and a newline-then-comment prefix still resolve to the object literal.
|
|
110
|
+
// findMatchingParen returns one past the close `)`, so the matching paren
|
|
111
|
+
// sits at closeParen - 1 and empty args resolve to that `)`.
|
|
112
|
+
const argsContentStart = skipLeadingTrivia(code, parenPos + 1, closeParen);
|
|
113
|
+
const firstArgChar = code[argsContentStart];
|
|
114
|
+
|
|
115
|
+
if (firstArgChar === "{") {
|
|
116
|
+
changed = true;
|
|
117
|
+
s.appendRight(argsContentStart + 1, injected);
|
|
118
|
+
} else if (argsContentStart >= closeParen - 1) {
|
|
119
|
+
// Empty args: createRouter(). Wrap a fresh config object.
|
|
120
|
+
changed = true;
|
|
121
|
+
s.appendRight(parenPos + 1, `{${injected} }`);
|
|
122
|
+
} else {
|
|
123
|
+
// Unsupported argument shape (bare identifier, spread, call, etc.). No
|
|
124
|
+
// stable $$id can be injected here. Record it so the plugin can warn —
|
|
125
|
+
// and crucially do NOT mark changed, so a dead named-routes.gen import is
|
|
126
|
+
// not prepended for a call we never touched.
|
|
127
|
+
const lastNl = code.lastIndexOf("\n", callStart - 1);
|
|
128
|
+
const column = callStart - (lastNl + 1) + 1;
|
|
129
|
+
unsupportedSites.push({ line: lineNumber, column });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (unsupportedSites.length > 0 && warn) {
|
|
134
|
+
warn(
|
|
135
|
+
buildUnsupportedShapeWarning(filePath, "createRouter", unsupportedSites),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!changed) return null;
|
|
140
|
+
|
|
141
|
+
s.prepend(
|
|
142
|
+
`import { NamedRoutes as ${routeNamesVar} } from "${routeNamesImport}";\n`,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
code: s.toString(),
|
|
147
|
+
map: s.generateMap({ hires: true }),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Inject stable $$id into createRouter() calls at compile time.
|
|
153
|
+
* This must be a separate plugin without enforce:"post" because running
|
|
154
|
+
* at "post" priority changes Vite's dep optimization timing and can cause
|
|
155
|
+
* ERR_OUTDATED_OPTIMIZED_DEP / React dual-instance issues.
|
|
156
|
+
*/
|
|
157
|
+
export function exposeRouterId(): Plugin {
|
|
158
|
+
let projectRoot = "";
|
|
159
|
+
const counter = createCounter(debug, "expose-router-id");
|
|
160
|
+
return {
|
|
161
|
+
name: "@rangojs/router:expose-router-id",
|
|
162
|
+
configResolved(config) {
|
|
163
|
+
projectRoot = config.root;
|
|
164
|
+
},
|
|
165
|
+
buildEnd() {
|
|
166
|
+
counter?.flush();
|
|
167
|
+
},
|
|
168
|
+
transform(code, id) {
|
|
169
|
+
if (!code.includes("createRouter")) return null;
|
|
170
|
+
if (
|
|
171
|
+
!/import\s*\{[^}]*\bcreateRouter\b[^}]*\}\s*from\s*["']@rangojs\/router(?:\/server)?["']/.test(
|
|
172
|
+
code,
|
|
173
|
+
)
|
|
174
|
+
) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
if (id.includes("node_modules")) return null;
|
|
178
|
+
|
|
179
|
+
const start = counter ? performance.now() : 0;
|
|
180
|
+
try {
|
|
181
|
+
const filePath = normalizePath(path.relative(projectRoot, id));
|
|
182
|
+
const routerFnNames = getImportedFnNames(code, "createRouter");
|
|
183
|
+
const warn =
|
|
184
|
+
typeof this.warn === "function"
|
|
185
|
+
? (message: string) => this.warn(message)
|
|
186
|
+
: undefined;
|
|
187
|
+
return transformRouter(
|
|
188
|
+
code,
|
|
189
|
+
filePath,
|
|
190
|
+
routerFnNames,
|
|
191
|
+
normalizePath(id),
|
|
192
|
+
warn,
|
|
193
|
+
);
|
|
194
|
+
} finally {
|
|
195
|
+
counter?.record(id, performance.now() - start);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface HandlerTransformConfig {
|
|
2
|
+
fnName: string;
|
|
3
|
+
brand: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface CreateExportBinding {
|
|
7
|
+
localName: string;
|
|
8
|
+
exportNames: string[];
|
|
9
|
+
callExprStart: number;
|
|
10
|
+
callOpenParenPos: number;
|
|
11
|
+
callCloseParenPos: number;
|
|
12
|
+
argCount: number;
|
|
13
|
+
statementEnd: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface StrictCreateTransformConfig {
|
|
17
|
+
fnName: "createLoader" | "createHandle" | "createLocationState";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const PRERENDER_CONFIG: HandlerTransformConfig = {
|
|
21
|
+
fnName: "Prerender",
|
|
22
|
+
brand: "prerenderHandler",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const STATIC_CONFIG: HandlerTransformConfig = {
|
|
26
|
+
fnName: "Static",
|
|
27
|
+
brand: "staticHandler",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const STRICT_CREATE_CONFIGS: StrictCreateTransformConfig[] = [
|
|
31
|
+
{ fnName: "createLoader" },
|
|
32
|
+
{ fnName: "createHandle" },
|
|
33
|
+
{ fnName: "createLocationState" },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
export interface ExposeInternalIdsApi {
|
|
37
|
+
/** Tracks absolute module IDs that contain prerender handler exports.
|
|
38
|
+
* key: absolute module ID (filesystem path)
|
|
39
|
+
* value: array of export names (e.g., ["ArticlesIndex", "ArticleDetail"]) */
|
|
40
|
+
prerenderHandlerModules: Map<string, string[]>;
|
|
41
|
+
/** Tracks absolute module IDs that contain static handler exports.
|
|
42
|
+
* key: absolute module ID (filesystem path)
|
|
43
|
+
* value: array of export names (e.g., ["DocsNav", "DocShell"]) */
|
|
44
|
+
staticHandlerModules: Map<string, string[]>;
|
|
45
|
+
}
|