@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
|
@@ -8,30 +8,26 @@ export function normalizePath(p: string): string {
|
|
|
8
8
|
return p.split(path.sep).join("/");
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Generate a short hash for an ID.
|
|
13
|
-
* Uses first 8 chars of SHA-256 hash for uniqueness while keeping IDs short.
|
|
14
|
-
* Appends export name for easier debugging in production: "abc123#ExportName"
|
|
15
|
-
*/
|
|
16
11
|
export function hashId(filePath: string, exportName: string): string {
|
|
17
12
|
const input = `${filePath}#${exportName}`;
|
|
18
13
|
const hash = crypto.createHash("sha256").update(input).digest("hex");
|
|
19
14
|
return `${hash.slice(0, 8)}#${exportName}`;
|
|
20
15
|
}
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
export function makeStubId(
|
|
18
|
+
filePath: string,
|
|
19
|
+
exportName: string,
|
|
20
|
+
isBuild: boolean,
|
|
21
|
+
): string {
|
|
22
|
+
return isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
26
25
|
export function hashInlineId(
|
|
27
26
|
filePath: string,
|
|
28
|
-
|
|
29
|
-
index
|
|
27
|
+
fnName: string,
|
|
28
|
+
index: number,
|
|
30
29
|
): string {
|
|
31
|
-
const input =
|
|
32
|
-
index !== undefined && index > 0
|
|
33
|
-
? `${filePath}:${lineNumber}:${index}`
|
|
34
|
-
: `${filePath}:${lineNumber}`;
|
|
30
|
+
const input = `${filePath}:${fnName}:${index}`;
|
|
35
31
|
return crypto.createHash("sha256").update(input).digest("hex").slice(0, 8);
|
|
36
32
|
}
|
|
37
33
|
|
|
@@ -45,11 +41,6 @@ export interface DetectedImports {
|
|
|
45
41
|
any: boolean;
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
/**
|
|
49
|
-
* Build a map from local binding name to exported names by walking
|
|
50
|
-
* ExportNamedDeclaration nodes. Handles `export const X`, `export { X }`,
|
|
51
|
-
* and `export { X as Y }`. Skips re-exports (`export { X } from "..."`).
|
|
52
|
-
*/
|
|
53
44
|
export function buildExportMap(program: any): Map<string, string[]> {
|
|
54
45
|
const exportMap = new Map<string, string[]>();
|
|
55
46
|
|
|
@@ -89,10 +80,6 @@ export function buildExportMap(program: any): Map<string, string[]> {
|
|
|
89
80
|
return exportMap;
|
|
90
81
|
}
|
|
91
82
|
|
|
92
|
-
/**
|
|
93
|
-
* Single-pass detection of all create* imports from @rangojs/router.
|
|
94
|
-
* Returns which create functions are imported so we can skip unnecessary transforms.
|
|
95
|
-
*/
|
|
96
83
|
export function detectImports(code: string): DetectedImports {
|
|
97
84
|
// Extract all import declarations from @rangojs/router in one scan
|
|
98
85
|
const importPattern =
|
|
@@ -119,7 +106,6 @@ export function detectImports(code: string): DetectedImports {
|
|
|
119
106
|
if (/\bcreateRouter\b/.test(imports)) result.router = true;
|
|
120
107
|
}
|
|
121
108
|
|
|
122
|
-
// createRouter has a stricter check: only from "@rangojs/router" (not sub-paths)
|
|
123
109
|
if (result.router) {
|
|
124
110
|
result.router =
|
|
125
111
|
/import\s*\{[^}]*\bcreateRouter\b[^}]*\}\s*from\s*["']@rangojs\/router["']/.test(
|
|
@@ -138,11 +124,6 @@ export function detectImports(code: string): DetectedImports {
|
|
|
138
124
|
return result;
|
|
139
125
|
}
|
|
140
126
|
|
|
141
|
-
/**
|
|
142
|
-
* Skip past a string literal, template literal, or comment starting at pos.
|
|
143
|
-
* Returns the index after the closing delimiter, or pos if not at a
|
|
144
|
-
* string/comment start. Handles escape sequences and nested ${} in templates.
|
|
145
|
-
*/
|
|
146
127
|
export function skipStringOrComment(code: string, pos: number): number {
|
|
147
128
|
const ch = code[pos];
|
|
148
129
|
|
|
@@ -200,11 +181,6 @@ export function skipStringOrComment(code: string, pos: number): number {
|
|
|
200
181
|
return pos;
|
|
201
182
|
}
|
|
202
183
|
|
|
203
|
-
/**
|
|
204
|
-
* Find the matching closing paren starting after an already-opened paren.
|
|
205
|
-
* Skips strings, template literals, and comments so parens inside them
|
|
206
|
-
* don't affect depth tracking. Returns the index after the closing paren.
|
|
207
|
-
*/
|
|
208
184
|
export function findMatchingParen(code: string, startPos: number): number {
|
|
209
185
|
let depth = 1;
|
|
210
186
|
let i = startPos;
|
|
@@ -221,10 +197,6 @@ export function findMatchingParen(code: string, startPos: number): number {
|
|
|
221
197
|
return i;
|
|
222
198
|
}
|
|
223
199
|
|
|
224
|
-
/**
|
|
225
|
-
* Count the number of top-level arguments in a function call.
|
|
226
|
-
* Skips nested parens, brackets, braces, strings, and comments.
|
|
227
|
-
*/
|
|
228
200
|
export function countArgs(
|
|
229
201
|
code: string,
|
|
230
202
|
startPos: number,
|
|
@@ -238,7 +210,16 @@ export function countArgs(
|
|
|
238
210
|
while (i < endPos) {
|
|
239
211
|
const skipped = skipStringOrComment(code, i);
|
|
240
212
|
if (skipped > i) {
|
|
241
|
-
|
|
213
|
+
// A comment is transparent: `createHandle(/* meta */)` has ZERO real
|
|
214
|
+
// arguments, so a comment-only region must NOT set hasContent (else the
|
|
215
|
+
// fallback path would count it as 1 arg and inject `, "id"` over an elided
|
|
216
|
+
// first slot — a syntax error). A string/template literal IS content.
|
|
217
|
+
const ch = code[i];
|
|
218
|
+
const isComment =
|
|
219
|
+
ch === "/" &&
|
|
220
|
+
i + 1 < code.length &&
|
|
221
|
+
(code[i + 1] === "/" || code[i + 1] === "*");
|
|
222
|
+
if (!isComment) hasContent = true;
|
|
242
223
|
i = skipped;
|
|
243
224
|
continue;
|
|
244
225
|
}
|
|
@@ -260,10 +241,6 @@ export function countArgs(
|
|
|
260
241
|
return hasContent ? argCount + 1 : 0;
|
|
261
242
|
}
|
|
262
243
|
|
|
263
|
-
/**
|
|
264
|
-
* Find the end of a statement: skip whitespace and optional semicolon after
|
|
265
|
-
* a closing paren position.
|
|
266
|
-
*/
|
|
267
244
|
export function findStatementEnd(code: string, pos: number): number {
|
|
268
245
|
let i = pos;
|
|
269
246
|
while (i < code.length && /\s/.test(code[i])) {
|
|
@@ -275,48 +252,81 @@ export function findStatementEnd(code: string, pos: number): number {
|
|
|
275
252
|
return i;
|
|
276
253
|
}
|
|
277
254
|
|
|
278
|
-
|
|
279
|
-
* Simple depth-counter paren matching. Does NOT skip strings/comments.
|
|
280
|
-
* Used by loader and handle transforms where the simpler approach suffices.
|
|
281
|
-
* Returns the index after the closing paren.
|
|
282
|
-
*/
|
|
283
|
-
export function findClosingParen(code: string, startPos: number): number {
|
|
284
|
-
let depth = 1;
|
|
285
|
-
let i = startPos;
|
|
286
|
-
while (i < code.length && depth > 0) {
|
|
287
|
-
if (code[i] === "(") depth++;
|
|
288
|
-
if (code[i] === ")") depth--;
|
|
289
|
-
i++;
|
|
290
|
-
}
|
|
291
|
-
return i;
|
|
292
|
-
}
|
|
255
|
+
export { escapeRegExp } from "../../regex-escape.js";
|
|
293
256
|
|
|
294
257
|
/**
|
|
295
|
-
*
|
|
296
|
-
*
|
|
258
|
+
* Given an index pointing just past a `create*` callee identifier, return the
|
|
259
|
+
* index of the call's opening `(`, accounting for an optional generic type
|
|
260
|
+
* argument list `<...>` with arbitrarily nested `<>`. Returns -1 when the next
|
|
261
|
+
* non-trivia token is neither `<` nor `(` (i.e. not a call site).
|
|
262
|
+
*
|
|
263
|
+
* Replaces the single-level `<[^>]*>` regex assumption, which stopped at the
|
|
264
|
+
* first `>` and so never reached `(` for `createRouter<Config<Env>>(`.
|
|
265
|
+
*
|
|
266
|
+
* Whitespace, comments, and strings between the callee and `(` are skipped via
|
|
267
|
+
* skipStringOrComment. The `<...>` scan only balances angle brackets; it does
|
|
268
|
+
* not attempt to parse full TS type syntax (sufficient for locating the paren).
|
|
297
269
|
*/
|
|
298
|
-
export function
|
|
270
|
+
export function findCallParenAfterGenerics(
|
|
299
271
|
code: string,
|
|
300
|
-
|
|
301
|
-
endPos: number,
|
|
272
|
+
afterCalleeIndex: number,
|
|
302
273
|
): number {
|
|
303
|
-
let
|
|
304
|
-
|
|
305
|
-
|
|
274
|
+
let i = afterCalleeIndex;
|
|
275
|
+
// Skip leading whitespace/comments/strings before `<` or `(`.
|
|
276
|
+
while (i < code.length) {
|
|
277
|
+
const skipped = skipStringOrComment(code, i);
|
|
278
|
+
if (skipped > i) {
|
|
279
|
+
i = skipped;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (/\s/.test(code[i])) {
|
|
283
|
+
i++;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
306
288
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
289
|
+
if (i >= code.length) return -1;
|
|
290
|
+
|
|
291
|
+
if (code[i] === "(") return i;
|
|
292
|
+
|
|
293
|
+
if (code[i] === "<") {
|
|
294
|
+
let depth = 0;
|
|
295
|
+
while (i < code.length) {
|
|
296
|
+
const skipped = skipStringOrComment(code, i);
|
|
297
|
+
if (skipped > i) {
|
|
298
|
+
i = skipped;
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
const ch = code[i];
|
|
302
|
+
if (ch === "<") {
|
|
303
|
+
depth++;
|
|
304
|
+
} else if (ch === ">") {
|
|
305
|
+
depth--;
|
|
306
|
+
if (depth === 0) {
|
|
307
|
+
i++;
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
i++;
|
|
312
|
+
}
|
|
313
|
+
if (depth !== 0) return -1;
|
|
314
|
+
// After the balanced generic list, skip trivia and expect `(`.
|
|
315
|
+
while (i < code.length) {
|
|
316
|
+
const skipped = skipStringOrComment(code, i);
|
|
317
|
+
if (skipped > i) {
|
|
318
|
+
i = skipped;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (/\s/.test(code[i])) {
|
|
322
|
+
i++;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
break;
|
|
318
326
|
}
|
|
327
|
+
if (i < code.length && code[i] === "(") return i;
|
|
328
|
+
return -1;
|
|
319
329
|
}
|
|
320
330
|
|
|
321
|
-
return
|
|
331
|
+
return -1;
|
|
322
332
|
}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { parseAst } from "vite";
|
|
2
|
+
import {
|
|
3
|
+
findMatchingParen,
|
|
4
|
+
countArgs,
|
|
5
|
+
findStatementEnd,
|
|
6
|
+
buildExportMap,
|
|
7
|
+
escapeRegExp,
|
|
8
|
+
findCallParenAfterGenerics,
|
|
9
|
+
} from "../expose-id-utils.js";
|
|
10
|
+
import { codeMatchIndices } from "../../../build/route-types/source-scan.js";
|
|
11
|
+
import type { CreateExportBinding } from "./types.js";
|
|
12
|
+
|
|
13
|
+
export function isExportOnlyFile(
|
|
14
|
+
code: string,
|
|
15
|
+
bindings: CreateExportBinding[],
|
|
16
|
+
): boolean {
|
|
17
|
+
if (bindings.length === 0) return false;
|
|
18
|
+
|
|
19
|
+
const knownLocals = new Set<string>();
|
|
20
|
+
const knownExports = new Set<string>();
|
|
21
|
+
for (const b of bindings) {
|
|
22
|
+
knownLocals.add(b.localName);
|
|
23
|
+
for (const e of b.exportNames) knownExports.add(e);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (/export\s*\*/.test(code)) return false;
|
|
27
|
+
|
|
28
|
+
const declExportPattern =
|
|
29
|
+
/export\s+(const|let|var|function|class|default)\s+(\w+)/g;
|
|
30
|
+
let match: RegExpExecArray | null;
|
|
31
|
+
while ((match = declExportPattern.exec(code)) !== null) {
|
|
32
|
+
if (!knownExports.has(match[2])) return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const specExportPattern = /export\s*\{([^}]+)\}/g;
|
|
36
|
+
while ((match = specExportPattern.exec(code)) !== null) {
|
|
37
|
+
const specifiers = match[1]
|
|
38
|
+
.split(",")
|
|
39
|
+
.map((s) => s.trim())
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
for (const spec of specifiers) {
|
|
42
|
+
const m = spec.match(
|
|
43
|
+
/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/,
|
|
44
|
+
);
|
|
45
|
+
if (!m) continue;
|
|
46
|
+
const local = m[1];
|
|
47
|
+
if (!knownLocals.has(local)) return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Matches the callee identifier only. The optional generic argument list
|
|
55
|
+
// (which may be nested, e.g. createLoader<A<B>>(...)) and the call paren are
|
|
56
|
+
// resolved per match via findCallParenAfterGenerics, so a nested `>` no longer
|
|
57
|
+
// defeats the scan the way `<[^>]*>` did (it stopped at the first `>`).
|
|
58
|
+
function createCallPattern(fnNames: string[]): RegExp {
|
|
59
|
+
return new RegExp(`\\b(?:${fnNames.map(escapeRegExp).join("|")})\\b`, "g");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Byte offsets of every create*-call site in real code: a callee-identifier
|
|
64
|
+
* match that is actually followed by a call `(` (after an optional nested
|
|
65
|
+
* generic list). Non-call references (type positions, the import specifier
|
|
66
|
+
* itself) yield -1 from findCallParenAfterGenerics and are dropped.
|
|
67
|
+
*/
|
|
68
|
+
function createCallStartIndices(code: string, fnNames: string[]): number[] {
|
|
69
|
+
return codeMatchIndices(code, createCallPattern(fnNames)).filter(
|
|
70
|
+
(index) =>
|
|
71
|
+
findCallParenAfterGenerics(
|
|
72
|
+
code,
|
|
73
|
+
index + matchedNameLength(code, index),
|
|
74
|
+
) !== -1,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Length of the identifier match at `index` (run of identifier chars).
|
|
79
|
+
function matchedNameLength(code: string, index: number): number {
|
|
80
|
+
let i = index;
|
|
81
|
+
while (i < code.length && /[A-Za-z0-9_$]/.test(code[i])) i++;
|
|
82
|
+
return i - index;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function countCreateCallsForNames(
|
|
86
|
+
code: string,
|
|
87
|
+
fnNames: string[],
|
|
88
|
+
): number {
|
|
89
|
+
return createCallStartIndices(code, fnNames).length;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function offsetToLineColumn(
|
|
93
|
+
code: string,
|
|
94
|
+
index: number,
|
|
95
|
+
): { line: number; column: number } {
|
|
96
|
+
let line = 1;
|
|
97
|
+
let lineStart = 0;
|
|
98
|
+
const end = Math.min(index, code.length);
|
|
99
|
+
for (let i = 0; i < end; i++) {
|
|
100
|
+
if (code[i] === "\n") {
|
|
101
|
+
line++;
|
|
102
|
+
lineStart = i + 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { line, column: index - lineStart + 1 };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function findUnsupportedCreateCallSites(
|
|
109
|
+
code: string,
|
|
110
|
+
fnNames: string[],
|
|
111
|
+
supportedBindings: CreateExportBinding[],
|
|
112
|
+
): Array<{ line: number; column: number }> {
|
|
113
|
+
const supported = new Set(supportedBindings.map((b) => b.callExprStart));
|
|
114
|
+
return createCallStartIndices(code, fnNames)
|
|
115
|
+
.filter((index) => !supported.has(index))
|
|
116
|
+
.map((index) => offsetToLineColumn(code, index));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getImportedFnNames(
|
|
120
|
+
code: string,
|
|
121
|
+
importedName: string,
|
|
122
|
+
): string[] {
|
|
123
|
+
const importPattern =
|
|
124
|
+
/import\s*\{([^}]*)\}\s*from\s*["']@rangojs\/router(?:\/[^"']*)?["']/g;
|
|
125
|
+
|
|
126
|
+
const localNames = new Set<string>();
|
|
127
|
+
let match: RegExpExecArray | null;
|
|
128
|
+
|
|
129
|
+
while ((match = importPattern.exec(code)) !== null) {
|
|
130
|
+
const specList = match[1]
|
|
131
|
+
.split(",")
|
|
132
|
+
.map((s) => s.trim())
|
|
133
|
+
.filter(Boolean);
|
|
134
|
+
|
|
135
|
+
for (const spec of specList) {
|
|
136
|
+
const m = spec.match(
|
|
137
|
+
/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/,
|
|
138
|
+
);
|
|
139
|
+
if (!m) continue;
|
|
140
|
+
const imported = m[1];
|
|
141
|
+
const local = m[2] || imported;
|
|
142
|
+
if (imported === importedName) {
|
|
143
|
+
localNames.add(local);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const names = Array.from(localNames);
|
|
149
|
+
return names.length > 0 ? names : [importedName];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function getCalledIdentifierFromCall(callExpr: any): string | null {
|
|
153
|
+
const callee = callExpr?.callee;
|
|
154
|
+
if (callee?.type === "Identifier") return callee.name;
|
|
155
|
+
if (
|
|
156
|
+
callee?.type === "TSInstantiationExpression" &&
|
|
157
|
+
callee.expression?.type === "Identifier"
|
|
158
|
+
) {
|
|
159
|
+
return callee.expression.name;
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function unwrapSignatureWrappedCall(init: any, fnNameSet: Set<string>): any {
|
|
165
|
+
if (init?.type !== "CallExpression") return init;
|
|
166
|
+
const directId = getCalledIdentifierFromCall(init);
|
|
167
|
+
if (directId && fnNameSet.has(directId)) return init;
|
|
168
|
+
const firstArg = init.arguments?.[0];
|
|
169
|
+
if (firstArg?.type === "CallExpression") {
|
|
170
|
+
const innerId = getCalledIdentifierFromCall(firstArg);
|
|
171
|
+
if (innerId && fnNameSet.has(innerId)) return firstArg;
|
|
172
|
+
}
|
|
173
|
+
return init;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function collectCreateExportBindingsFallback(
|
|
177
|
+
code: string,
|
|
178
|
+
fnNames: string[],
|
|
179
|
+
): CreateExportBinding[] {
|
|
180
|
+
const alternation = fnNames.map(escapeRegExp).join("|");
|
|
181
|
+
const exportConstPattern = new RegExp(
|
|
182
|
+
`export\\s+const\\s+(\\w+)\\s*=\\s*(?:${alternation})\\s*(?:<[^>]*>)?\\s*\\(`,
|
|
183
|
+
"g",
|
|
184
|
+
);
|
|
185
|
+
const localDeclPattern = new RegExp(
|
|
186
|
+
`\\bconst\\s+(\\w+)\\s*=\\s*((?:${alternation})\\s*(?:<[^>]*>)?\\s*\\()`,
|
|
187
|
+
"g",
|
|
188
|
+
);
|
|
189
|
+
const exportSpecPattern = /export\s*\{([^}]+)\}/g;
|
|
190
|
+
|
|
191
|
+
const exportMap = new Map<string, string[]>();
|
|
192
|
+
const pushExport = (local: string, exported: string) => {
|
|
193
|
+
const list = exportMap.get(local);
|
|
194
|
+
if (list) {
|
|
195
|
+
if (!list.includes(exported)) list.push(exported);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
exportMap.set(local, [exported]);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
let match: RegExpExecArray | null;
|
|
202
|
+
while ((match = exportConstPattern.exec(code)) !== null) {
|
|
203
|
+
pushExport(match[1], match[1]);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
while ((match = exportSpecPattern.exec(code)) !== null) {
|
|
207
|
+
const specifiers = match[1]
|
|
208
|
+
.split(",")
|
|
209
|
+
.map((s) => s.trim())
|
|
210
|
+
.filter(Boolean);
|
|
211
|
+
for (const specifier of specifiers) {
|
|
212
|
+
const specMatch = specifier.match(
|
|
213
|
+
/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/,
|
|
214
|
+
);
|
|
215
|
+
if (!specMatch) continue;
|
|
216
|
+
const local = specMatch[1];
|
|
217
|
+
const exported = specMatch[2] || local;
|
|
218
|
+
pushExport(local, exported);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const bindings: CreateExportBinding[] = [];
|
|
223
|
+
while ((match = localDeclPattern.exec(code)) !== null) {
|
|
224
|
+
const localName = match[1];
|
|
225
|
+
const exportNames = exportMap.get(localName) ?? [];
|
|
226
|
+
if (exportNames.length === 0) continue;
|
|
227
|
+
|
|
228
|
+
const openParenPos = match.index + match[0].length - 1;
|
|
229
|
+
const closeParenPos = findMatchingParen(code, openParenPos + 1) - 1;
|
|
230
|
+
if (closeParenPos <= openParenPos) continue;
|
|
231
|
+
|
|
232
|
+
bindings.push({
|
|
233
|
+
localName,
|
|
234
|
+
exportNames,
|
|
235
|
+
callExprStart: match.index + match[0].length - match[2].length,
|
|
236
|
+
callOpenParenPos: openParenPos,
|
|
237
|
+
callCloseParenPos: closeParenPos,
|
|
238
|
+
argCount: countArgs(code, openParenPos + 1, closeParenPos),
|
|
239
|
+
statementEnd: findStatementEnd(code, closeParenPos + 1),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return bindings;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function collectCreateExportBindings(
|
|
247
|
+
code: string,
|
|
248
|
+
fnNames: string[],
|
|
249
|
+
program?: any,
|
|
250
|
+
): CreateExportBinding[] {
|
|
251
|
+
if (!program) {
|
|
252
|
+
try {
|
|
253
|
+
program = parseAst(code, { lang: "tsx" });
|
|
254
|
+
} catch {
|
|
255
|
+
return collectCreateExportBindingsFallback(code, fnNames);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const exportMap = buildExportMap(program);
|
|
260
|
+
const fnNameSet = new Set(fnNames);
|
|
261
|
+
const bindings: CreateExportBinding[] = [];
|
|
262
|
+
|
|
263
|
+
const collectFromVarDecl = (varDecl: any, statementEnd: number) => {
|
|
264
|
+
if (varDecl?.type !== "VariableDeclaration" || varDecl.kind !== "const") {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
for (const decl of varDecl.declarations ?? []) {
|
|
269
|
+
// Unwrap a Fast Refresh signature wrapper (`_s(createLoader(...), ...)`)
|
|
270
|
+
// so injection targets the inner create* call. Falls back to decl.init.
|
|
271
|
+
const callExpr = unwrapSignatureWrappedCall(decl?.init, fnNameSet);
|
|
272
|
+
const calledIdentifier = getCalledIdentifierFromCall(callExpr);
|
|
273
|
+
if (
|
|
274
|
+
decl?.id?.type !== "Identifier" ||
|
|
275
|
+
callExpr?.type !== "CallExpression" ||
|
|
276
|
+
!calledIdentifier ||
|
|
277
|
+
!fnNameSet.has(calledIdentifier)
|
|
278
|
+
) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const localName = decl.id.name;
|
|
283
|
+
const exportNames = exportMap.get(localName) ?? [];
|
|
284
|
+
if (exportNames.length === 0) continue;
|
|
285
|
+
|
|
286
|
+
const callEnd = callExpr.end as number;
|
|
287
|
+
const calleeEnd = callExpr.callee.end as number;
|
|
288
|
+
|
|
289
|
+
let openParenPos = -1;
|
|
290
|
+
for (let i = calleeEnd; i < callEnd; i++) {
|
|
291
|
+
if (code[i] === "(") {
|
|
292
|
+
openParenPos = i;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (openParenPos === -1) continue;
|
|
297
|
+
|
|
298
|
+
const closeParenPos = findMatchingParen(code, openParenPos + 1) - 1;
|
|
299
|
+
if (closeParenPos <= openParenPos) continue;
|
|
300
|
+
|
|
301
|
+
bindings.push({
|
|
302
|
+
localName,
|
|
303
|
+
exportNames,
|
|
304
|
+
callExprStart: callExpr.start as number,
|
|
305
|
+
callOpenParenPos: openParenPos,
|
|
306
|
+
callCloseParenPos: closeParenPos,
|
|
307
|
+
argCount: callExpr.arguments?.length ?? 0,
|
|
308
|
+
statementEnd,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
for (const node of program.body ?? []) {
|
|
314
|
+
if (node?.type === "VariableDeclaration") {
|
|
315
|
+
collectFromVarDecl(node, node.end as number);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (
|
|
320
|
+
node?.type === "ExportNamedDeclaration" &&
|
|
321
|
+
node.declaration?.type === "VariableDeclaration"
|
|
322
|
+
) {
|
|
323
|
+
collectFromVarDecl(node.declaration, node.end as number);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (bindings.length === 0) {
|
|
328
|
+
return collectCreateExportBindingsFallback(code, fnNames);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return bindings;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export function buildUnsupportedShapeWarning(
|
|
335
|
+
filePath: string,
|
|
336
|
+
fnName: string,
|
|
337
|
+
sites: Array<{ line: number; column: number }> = [],
|
|
338
|
+
): string {
|
|
339
|
+
const lines = [`[rango] Unsupported ${fnName} shape in "${filePath}".`];
|
|
340
|
+
|
|
341
|
+
if (sites.length === 1) {
|
|
342
|
+
const s = sites[0];
|
|
343
|
+
lines.push(
|
|
344
|
+
`The ${fnName}(...) call at ${filePath}:${s.line}:${s.column} has no stable $$id injected — it is not in a supported shape.`,
|
|
345
|
+
);
|
|
346
|
+
} else if (sites.length > 1) {
|
|
347
|
+
lines.push(
|
|
348
|
+
`These ${fnName}(...) calls have no stable $$id injected — they are not in a supported shape:`,
|
|
349
|
+
);
|
|
350
|
+
for (const s of sites) lines.push(` - ${filePath}:${s.line}:${s.column}`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
lines.push(
|
|
354
|
+
`Supported shapes are:`,
|
|
355
|
+
` - export const X = ${fnName}(...)`,
|
|
356
|
+
` - const X = ${fnName}(...); export { X }`,
|
|
357
|
+
` - const X = ${fnName}(...); export { X as Y }`,
|
|
358
|
+
`Potentially unsupported forms include:`,
|
|
359
|
+
` - export let/var X = ${fnName}(...)`,
|
|
360
|
+
` - inline ${fnName}(...) calls`,
|
|
361
|
+
);
|
|
362
|
+
return lines.join("\n");
|
|
363
|
+
}
|