@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -4
- package/README.md +301 -797
- package/dist/bin/rango.js +603 -145
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3750 -1160
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +96 -24
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +12 -10
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +75 -19
- package/skills/layout/SKILL.md +40 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +25 -13
- package/skills/migrate-nextjs/SKILL.md +205 -20
- package/skills/migrate-react-router/SKILL.md +59 -670
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +40 -10
- package/skills/ppr/SKILL.md +616 -0
- package/skills/prerender/SKILL.md +72 -60
- package/skills/rango/SKILL.md +318 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +117 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +0 -65
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +144 -79
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +183 -144
- package/src/browser/prefetch/cache.ts +242 -77
- package/src/browser/prefetch/fetch.ts +325 -69
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +58 -20
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +17 -14
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +203 -154
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -21
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +421 -58
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2202 -372
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +180 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1127 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +33 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +67 -37
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +97 -12
- package/src/index.ts +98 -14
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +78 -10
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +65 -39
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +87 -59
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +27 -42
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +82 -59
- package/src/router/loader-resolution.ts +167 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +80 -55
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +69 -79
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +112 -67
- package/src/router/preview-match.ts +6 -2
- package/src/router/request-classification.ts +50 -69
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +115 -36
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +131 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +139 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +251 -0
- package/src/router/segment-resolution/revalidation.ts +272 -320
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +157 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +291 -217
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +124 -13
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +421 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +282 -116
- package/src/rsc/shell-capture.ts +1158 -0
- package/src/rsc/shell-serve.ts +150 -0
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +53 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +350 -149
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +208 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +395 -176
- package/src/ssr/index.tsx +458 -178
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +19 -64
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +63 -17
- package/src/urls/path-helper.ts +22 -106
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- 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 +8 -7
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- 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 +96 -68
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +45 -1
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +4 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +210 -10
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +236 -138
- package/src/vite/router-discovery.ts +927 -136
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +71 -43
- package/src/vite/utils/shared-utils.ts +142 -43
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
package/dist/bin/rango.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __esm = (fn, res) => function __init() {
|
|
5
|
-
|
|
4
|
+
var __esm = (fn, res, err) => function __init() {
|
|
5
|
+
if (err) throw err[0];
|
|
6
|
+
try {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
throw err = [e], e;
|
|
10
|
+
}
|
|
6
11
|
};
|
|
7
12
|
var __export = (target, all) => {
|
|
8
13
|
for (var name in all)
|
|
@@ -22,10 +27,10 @@ function extractParamsFromPattern(pattern) {
|
|
|
22
27
|
function formatRouteEntry(key, pattern, _params, search) {
|
|
23
28
|
const hasSearch = search && Object.keys(search).length > 0;
|
|
24
29
|
if (!hasSearch) {
|
|
25
|
-
return ` ${key}:
|
|
30
|
+
return ` ${key}: ${JSON.stringify(pattern)},`;
|
|
26
31
|
}
|
|
27
|
-
const searchBody = Object.entries(search).map(([k, v]) => `${k}:
|
|
28
|
-
return ` ${key}: { path:
|
|
32
|
+
const searchBody = Object.entries(search).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
|
|
33
|
+
return ` ${key}: { path: ${JSON.stringify(pattern)}, search: { ${searchBody} } },`;
|
|
29
34
|
}
|
|
30
35
|
var init_param_extraction = __esm({
|
|
31
36
|
"src/build/route-types/param-extraction.ts"() {
|
|
@@ -59,8 +64,8 @@ var init_ast_helpers = __esm({
|
|
|
59
64
|
|
|
60
65
|
// src/build/route-types/ast-route-extraction.ts
|
|
61
66
|
import ts2 from "typescript";
|
|
62
|
-
function extractRoutesFromSource(code) {
|
|
63
|
-
const sourceFile = ts2.createSourceFile(
|
|
67
|
+
function extractRoutesFromSource(code, sourceFileArg) {
|
|
68
|
+
const sourceFile = sourceFileArg ?? ts2.createSourceFile(
|
|
64
69
|
"input.tsx",
|
|
65
70
|
code,
|
|
66
71
|
ts2.ScriptTarget.Latest,
|
|
@@ -139,7 +144,7 @@ function generatePerModuleTypesSource(routes) {
|
|
|
139
144
|
const valid = routes.filter(({ name }) => {
|
|
140
145
|
if (!name || /["'\\`\n\r]/.test(name)) {
|
|
141
146
|
console.warn(
|
|
142
|
-
`[
|
|
147
|
+
`[rango] Skipping route with invalid name: ${JSON.stringify(name)}`
|
|
143
148
|
);
|
|
144
149
|
return false;
|
|
145
150
|
}
|
|
@@ -149,7 +154,7 @@ function generatePerModuleTypesSource(routes) {
|
|
|
149
154
|
for (const { name, pattern, params, search } of valid) {
|
|
150
155
|
if (deduped.has(name)) {
|
|
151
156
|
console.warn(
|
|
152
|
-
`[
|
|
157
|
+
`[rango] Duplicate route name "${name}" \u2014 keeping first definition`
|
|
153
158
|
);
|
|
154
159
|
continue;
|
|
155
160
|
}
|
|
@@ -185,9 +190,13 @@ export const NamedRoutes = {
|
|
|
185
190
|
${objectBody}
|
|
186
191
|
} as const;
|
|
187
192
|
|
|
193
|
+
// Aliased so the augmentation below does not pay a homomorphic mapped-type
|
|
194
|
+
// instantiation per route; \`as const\` already makes the members readonly.
|
|
195
|
+
type NamedRoutesShape = typeof NamedRoutes;
|
|
196
|
+
|
|
188
197
|
declare global {
|
|
189
|
-
namespace
|
|
190
|
-
interface GeneratedRouteMap extends
|
|
198
|
+
namespace Rango {
|
|
199
|
+
interface GeneratedRouteMap extends NamedRoutesShape {}
|
|
191
200
|
}
|
|
192
201
|
}
|
|
193
202
|
`;
|
|
@@ -211,7 +220,7 @@ function findTsFiles(dir, filter) {
|
|
|
211
220
|
entries = readdirSync(dir, { withFileTypes: true });
|
|
212
221
|
} catch (err) {
|
|
213
222
|
console.warn(
|
|
214
|
-
`[
|
|
223
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
215
224
|
);
|
|
216
225
|
return results;
|
|
217
226
|
}
|
|
@@ -238,6 +247,33 @@ var init_scan_filter = __esm({
|
|
|
238
247
|
import { readFileSync, existsSync } from "node:fs";
|
|
239
248
|
import { dirname, resolve } from "node:path";
|
|
240
249
|
import ts3 from "typescript";
|
|
250
|
+
function createScanMemo() {
|
|
251
|
+
return { files: /* @__PURE__ */ new Map(), blockSourceFiles: /* @__PURE__ */ new Map() };
|
|
252
|
+
}
|
|
253
|
+
function parseBlock(memo, block) {
|
|
254
|
+
if (memo) {
|
|
255
|
+
const cached = memo.blockSourceFiles.get(block);
|
|
256
|
+
if (cached) return cached;
|
|
257
|
+
}
|
|
258
|
+
const sf = ts3.createSourceFile(
|
|
259
|
+
"input.tsx",
|
|
260
|
+
block,
|
|
261
|
+
ts3.ScriptTarget.Latest,
|
|
262
|
+
true,
|
|
263
|
+
ts3.ScriptKind.TSX
|
|
264
|
+
);
|
|
265
|
+
if (memo) memo.blockSourceFiles.set(block, sf);
|
|
266
|
+
return sf;
|
|
267
|
+
}
|
|
268
|
+
function readSourceMemoized(memo, realPath) {
|
|
269
|
+
if (memo) {
|
|
270
|
+
const cached = memo.files.get(realPath);
|
|
271
|
+
if (cached !== void 0) return cached;
|
|
272
|
+
}
|
|
273
|
+
const source = readFileSync(realPath, "utf-8");
|
|
274
|
+
if (memo) memo.files.set(realPath, source);
|
|
275
|
+
return source;
|
|
276
|
+
}
|
|
241
277
|
function extractNamePrefixFromInclude(node) {
|
|
242
278
|
if (node.arguments.length >= 3) {
|
|
243
279
|
const thirdArg = node.arguments[2];
|
|
@@ -253,8 +289,98 @@ function extractNamePrefixFromInclude(node) {
|
|
|
253
289
|
}
|
|
254
290
|
return null;
|
|
255
291
|
}
|
|
256
|
-
function
|
|
257
|
-
const
|
|
292
|
+
function thenSelectsNonDefaultMember(expr) {
|
|
293
|
+
const findThenCall = (e) => {
|
|
294
|
+
if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression) && e.expression.name.text === "then") {
|
|
295
|
+
return e;
|
|
296
|
+
}
|
|
297
|
+
if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression)) {
|
|
298
|
+
return findThenCall(e.expression.expression);
|
|
299
|
+
}
|
|
300
|
+
if (ts3.isPropertyAccessExpression(e)) return findThenCall(e.expression);
|
|
301
|
+
if (ts3.isParenthesizedExpression(e)) return findThenCall(e.expression);
|
|
302
|
+
if (ts3.isAwaitExpression(e)) return findThenCall(e.expression);
|
|
303
|
+
return null;
|
|
304
|
+
};
|
|
305
|
+
const thenCall = findThenCall(expr);
|
|
306
|
+
if (!thenCall || thenCall.arguments.length === 0) return false;
|
|
307
|
+
const cb = thenCall.arguments[0];
|
|
308
|
+
if (!ts3.isArrowFunction(cb) && !ts3.isFunctionExpression(cb)) return false;
|
|
309
|
+
let ret;
|
|
310
|
+
if (ts3.isBlock(cb.body)) {
|
|
311
|
+
for (const stmt of cb.body.statements) {
|
|
312
|
+
if (ts3.isReturnStatement(stmt) && stmt.expression) {
|
|
313
|
+
ret = stmt.expression;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
ret = cb.body;
|
|
319
|
+
}
|
|
320
|
+
if (!ret) return false;
|
|
321
|
+
if (ts3.isPropertyAccessExpression(ret)) {
|
|
322
|
+
return ret.name.text !== "default";
|
|
323
|
+
}
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
function extractDynamicImportSpecifier(node) {
|
|
327
|
+
let body;
|
|
328
|
+
if (ts3.isArrowFunction(node) || ts3.isFunctionExpression(node)) {
|
|
329
|
+
body = node.body;
|
|
330
|
+
}
|
|
331
|
+
if (!body) return null;
|
|
332
|
+
let expr;
|
|
333
|
+
if (ts3.isBlock(body)) {
|
|
334
|
+
for (const stmt of body.statements) {
|
|
335
|
+
if (ts3.isReturnStatement(stmt) && stmt.expression) {
|
|
336
|
+
expr = stmt.expression;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
expr = body;
|
|
342
|
+
}
|
|
343
|
+
if (!expr) return null;
|
|
344
|
+
const findImportCall = (e) => {
|
|
345
|
+
if (ts3.isCallExpression(e) && e.expression.kind === ts3.SyntaxKind.ImportKeyword) {
|
|
346
|
+
return e;
|
|
347
|
+
}
|
|
348
|
+
if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression)) {
|
|
349
|
+
return findImportCall(e.expression.expression);
|
|
350
|
+
}
|
|
351
|
+
if (ts3.isPropertyAccessExpression(e)) return findImportCall(e.expression);
|
|
352
|
+
if (ts3.isParenthesizedExpression(e)) return findImportCall(e.expression);
|
|
353
|
+
if (ts3.isAwaitExpression(e)) return findImportCall(e.expression);
|
|
354
|
+
return null;
|
|
355
|
+
};
|
|
356
|
+
const importCall = findImportCall(expr);
|
|
357
|
+
if (!importCall || importCall.arguments.length === 0) return null;
|
|
358
|
+
if (thenSelectsNonDefaultMember(expr)) return null;
|
|
359
|
+
return getStringValue(importCall.arguments[0]);
|
|
360
|
+
}
|
|
361
|
+
function resolveDefaultExportTarget(code, sourceFile) {
|
|
362
|
+
let result = null;
|
|
363
|
+
function visit(node) {
|
|
364
|
+
if (result) return;
|
|
365
|
+
if (ts3.isExportAssignment(node) && !node.isExportEquals) {
|
|
366
|
+
const expr = node.expression;
|
|
367
|
+
if (ts3.isIdentifier(expr)) {
|
|
368
|
+
result = { variableName: expr.text };
|
|
369
|
+
} else if (ts3.isCallExpression(expr)) {
|
|
370
|
+
const callee = expr.expression;
|
|
371
|
+
if (ts3.isIdentifier(callee) && callee.text === "urls") {
|
|
372
|
+
result = { inlineBlock: expr.getText(sourceFile) };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
ts3.forEachChild(node, visit);
|
|
378
|
+
}
|
|
379
|
+
visit(sourceFile);
|
|
380
|
+
return result;
|
|
381
|
+
}
|
|
382
|
+
function extractIncludesWithDiagnostics(code, sourceFileArg) {
|
|
383
|
+
const sourceFile = sourceFileArg ?? ts3.createSourceFile(
|
|
258
384
|
"input.tsx",
|
|
259
385
|
code,
|
|
260
386
|
ts3.ScriptTarget.Latest,
|
|
@@ -278,12 +404,19 @@ function extractIncludesWithDiagnostics(code) {
|
|
|
278
404
|
}
|
|
279
405
|
const secondArg = node.arguments[1];
|
|
280
406
|
const namePrefix = extractNamePrefixFromInclude(node);
|
|
407
|
+
const dynamicImportSpec = extractDynamicImportSpecifier(secondArg);
|
|
281
408
|
if (ts3.isIdentifier(secondArg)) {
|
|
282
409
|
resolved.push({
|
|
283
410
|
pathPrefix,
|
|
284
411
|
variableName: secondArg.text,
|
|
285
412
|
namePrefix
|
|
286
413
|
});
|
|
414
|
+
} else if (dynamicImportSpec !== null) {
|
|
415
|
+
resolved.push({
|
|
416
|
+
pathPrefix,
|
|
417
|
+
moduleSpecifier: dynamicImportSpec,
|
|
418
|
+
namePrefix
|
|
419
|
+
});
|
|
287
420
|
} else if (ts3.isCallExpression(secondArg)) {
|
|
288
421
|
const callText = secondArg.expression.getText(sourceFile);
|
|
289
422
|
unresolvable.push({
|
|
@@ -308,7 +441,7 @@ function extractIncludesWithDiagnostics(code) {
|
|
|
308
441
|
return { resolved, unresolvable };
|
|
309
442
|
}
|
|
310
443
|
function resolveImportedVariable(code, localName) {
|
|
311
|
-
const importRegex = /import\s
|
|
444
|
+
const importRegex = /import\s*(?:[\w$]+\s*,\s*)?\{([^}]+)\}\s*from\s*["']([^"']+)["']/g;
|
|
312
445
|
let match;
|
|
313
446
|
while ((match = importRegex.exec(code)) !== null) {
|
|
314
447
|
const imports = match[1];
|
|
@@ -345,8 +478,8 @@ function resolveImportPath(importSpec, fromFile) {
|
|
|
345
478
|
}
|
|
346
479
|
return null;
|
|
347
480
|
}
|
|
348
|
-
function extractUrlsBlockForVariable(code, varName) {
|
|
349
|
-
const sourceFile = ts3.createSourceFile(
|
|
481
|
+
function extractUrlsBlockForVariable(code, varName, sourceFileArg) {
|
|
482
|
+
const sourceFile = sourceFileArg ?? ts3.createSourceFile(
|
|
350
483
|
"input.tsx",
|
|
351
484
|
code,
|
|
352
485
|
ts3.ScriptTarget.Latest,
|
|
@@ -368,67 +501,113 @@ function extractUrlsBlockForVariable(code, varName) {
|
|
|
368
501
|
visit(sourceFile);
|
|
369
502
|
return result;
|
|
370
503
|
}
|
|
371
|
-
function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut) {
|
|
504
|
+
function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut, memo) {
|
|
372
505
|
const routeMap = {};
|
|
373
|
-
const
|
|
506
|
+
const blockSourceFile = parseBlock(memo, block);
|
|
507
|
+
const localRoutes = extractRoutesFromSource(block, blockSourceFile);
|
|
374
508
|
for (const { name, pattern, search } of localRoutes) {
|
|
375
509
|
routeMap[name] = pattern;
|
|
376
510
|
if (search && searchSchemasOut) {
|
|
377
511
|
searchSchemasOut[name] = search;
|
|
378
512
|
}
|
|
379
513
|
}
|
|
380
|
-
const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
|
|
514
|
+
const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
|
|
515
|
+
block,
|
|
516
|
+
blockSourceFile
|
|
517
|
+
);
|
|
381
518
|
if (diagnosticsOut) {
|
|
382
519
|
for (const entry of unresolvable) {
|
|
383
520
|
diagnosticsOut.push({ ...entry, sourceFile: filePath });
|
|
384
521
|
}
|
|
385
522
|
}
|
|
386
|
-
for (const
|
|
523
|
+
for (const inc of includes) {
|
|
524
|
+
const { pathPrefix, namePrefix } = inc;
|
|
387
525
|
let childResult;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
const targetFile = resolveImportPath(imported.specifier, filePath);
|
|
526
|
+
if (inc.moduleSpecifier) {
|
|
527
|
+
const targetFile = resolveImportPath(inc.moduleSpecifier, filePath);
|
|
391
528
|
if (!targetFile) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
});
|
|
400
|
-
}
|
|
529
|
+
diagnosticsOut?.push({
|
|
530
|
+
pathPrefix,
|
|
531
|
+
namePrefix,
|
|
532
|
+
reason: "file-not-found",
|
|
533
|
+
sourceFile: filePath,
|
|
534
|
+
detail: `import("${inc.moduleSpecifier}") resolved to no file`
|
|
535
|
+
});
|
|
401
536
|
continue;
|
|
402
537
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
diagnosticsOut
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
538
|
+
let targetSource;
|
|
539
|
+
try {
|
|
540
|
+
targetSource = readSourceMemoized(memo, resolve(targetFile));
|
|
541
|
+
} catch (err) {
|
|
542
|
+
diagnosticsOut?.push({
|
|
543
|
+
pathPrefix,
|
|
544
|
+
namePrefix,
|
|
545
|
+
reason: "file-not-found",
|
|
546
|
+
sourceFile: filePath,
|
|
547
|
+
detail: `import("${inc.moduleSpecifier}") resolved to "${targetFile}" but reading it failed: ${err?.message ?? String(err)}`
|
|
548
|
+
});
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
const def = resolveDefaultExportTarget(
|
|
552
|
+
targetSource,
|
|
553
|
+
parseBlock(memo, targetSource)
|
|
413
554
|
);
|
|
414
|
-
if (!
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
});
|
|
423
|
-
}
|
|
555
|
+
if (!def) {
|
|
556
|
+
diagnosticsOut?.push({
|
|
557
|
+
pathPrefix,
|
|
558
|
+
namePrefix,
|
|
559
|
+
reason: "unresolvable-import",
|
|
560
|
+
sourceFile: filePath,
|
|
561
|
+
detail: `import("${inc.moduleSpecifier}") has no resolvable \`export default urls(...)\``
|
|
562
|
+
});
|
|
424
563
|
continue;
|
|
425
564
|
}
|
|
426
|
-
|
|
427
|
-
|
|
565
|
+
if (def.inlineBlock) {
|
|
566
|
+
childResult = buildCombinedRouteMapWithSearch(
|
|
567
|
+
targetFile,
|
|
568
|
+
void 0,
|
|
569
|
+
visited,
|
|
570
|
+
diagnosticsOut,
|
|
571
|
+
def.inlineBlock,
|
|
572
|
+
memo
|
|
573
|
+
);
|
|
574
|
+
} else {
|
|
575
|
+
const variableName = def.variableName;
|
|
576
|
+
const resolved = resolveIncludedVariable({
|
|
577
|
+
variableName,
|
|
578
|
+
resolutionFile: targetFile,
|
|
579
|
+
resolutionSource: targetSource,
|
|
580
|
+
reportFile: filePath,
|
|
581
|
+
memo,
|
|
582
|
+
visited,
|
|
583
|
+
diagnosticsOut,
|
|
584
|
+
pathPrefix,
|
|
585
|
+
namePrefix,
|
|
586
|
+
fileNotFoundDetail: (specifier) => `import("${inc.moduleSpecifier}") default re-exports "${variableName}" from "${specifier}", which resolved to no file`,
|
|
587
|
+
notFoundDetail: () => `import("${inc.moduleSpecifier}") default "${variableName}" not found in its imports or same-file scope`
|
|
588
|
+
});
|
|
589
|
+
if (!resolved) continue;
|
|
590
|
+
childResult = resolved;
|
|
591
|
+
}
|
|
592
|
+
} else if (inc.variableName) {
|
|
593
|
+
const variableName = inc.variableName;
|
|
594
|
+
const resolved = resolveIncludedVariable({
|
|
428
595
|
variableName,
|
|
596
|
+
resolutionFile: filePath,
|
|
597
|
+
resolutionSource: fullSource,
|
|
598
|
+
reportFile: filePath,
|
|
599
|
+
memo,
|
|
429
600
|
visited,
|
|
430
|
-
diagnosticsOut
|
|
431
|
-
|
|
601
|
+
diagnosticsOut,
|
|
602
|
+
pathPrefix,
|
|
603
|
+
namePrefix,
|
|
604
|
+
fileNotFoundDetail: (specifier) => `import "${specifier}" resolved to no file`,
|
|
605
|
+
notFoundDetail: () => `variable "${variableName}" not found in imports or same-file scope`
|
|
606
|
+
});
|
|
607
|
+
if (!resolved) continue;
|
|
608
|
+
childResult = resolved;
|
|
609
|
+
} else {
|
|
610
|
+
continue;
|
|
432
611
|
}
|
|
433
612
|
if (namePrefix === null) {
|
|
434
613
|
continue;
|
|
@@ -451,18 +630,77 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
451
630
|
}
|
|
452
631
|
return routeMap;
|
|
453
632
|
}
|
|
454
|
-
function
|
|
633
|
+
function resolveIncludedVariable(opts) {
|
|
634
|
+
const {
|
|
635
|
+
variableName,
|
|
636
|
+
resolutionFile,
|
|
637
|
+
resolutionSource,
|
|
638
|
+
reportFile,
|
|
639
|
+
memo,
|
|
640
|
+
visited,
|
|
641
|
+
diagnosticsOut,
|
|
642
|
+
pathPrefix,
|
|
643
|
+
namePrefix
|
|
644
|
+
} = opts;
|
|
645
|
+
const imported = resolveImportedVariable(resolutionSource, variableName);
|
|
646
|
+
if (imported) {
|
|
647
|
+
const targetFile = resolveImportPath(imported.specifier, resolutionFile);
|
|
648
|
+
if (!targetFile) {
|
|
649
|
+
diagnosticsOut?.push({
|
|
650
|
+
pathPrefix,
|
|
651
|
+
namePrefix,
|
|
652
|
+
reason: "file-not-found",
|
|
653
|
+
sourceFile: reportFile,
|
|
654
|
+
detail: opts.fileNotFoundDetail(imported.specifier)
|
|
655
|
+
});
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
658
|
+
return buildCombinedRouteMapWithSearch(
|
|
659
|
+
targetFile,
|
|
660
|
+
imported.exportedName,
|
|
661
|
+
visited,
|
|
662
|
+
diagnosticsOut,
|
|
663
|
+
void 0,
|
|
664
|
+
memo
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
const sameFileBlock = extractUrlsBlockForVariable(
|
|
668
|
+
resolutionSource,
|
|
669
|
+
variableName,
|
|
670
|
+
parseBlock(memo, resolutionSource)
|
|
671
|
+
);
|
|
672
|
+
if (!sameFileBlock) {
|
|
673
|
+
diagnosticsOut?.push({
|
|
674
|
+
pathPrefix,
|
|
675
|
+
namePrefix,
|
|
676
|
+
reason: "unresolvable-import",
|
|
677
|
+
sourceFile: reportFile,
|
|
678
|
+
detail: opts.notFoundDetail()
|
|
679
|
+
});
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
return buildCombinedRouteMapWithSearch(
|
|
683
|
+
resolutionFile,
|
|
684
|
+
variableName,
|
|
685
|
+
visited,
|
|
686
|
+
diagnosticsOut,
|
|
687
|
+
void 0,
|
|
688
|
+
memo
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock, memo) {
|
|
455
692
|
visited = visited ?? /* @__PURE__ */ new Set();
|
|
693
|
+
memo = memo ?? createScanMemo();
|
|
456
694
|
const realPath = resolve(filePath);
|
|
457
695
|
const key = variableName ? `${realPath}:${variableName}` : realPath;
|
|
458
696
|
if (visited.has(key)) {
|
|
459
|
-
console.warn(`[
|
|
697
|
+
console.warn(`[rango] Circular include detected, skipping: ${key}`);
|
|
460
698
|
return { routes: {}, searchSchemas: {} };
|
|
461
699
|
}
|
|
462
700
|
visited.add(key);
|
|
463
701
|
let source;
|
|
464
702
|
try {
|
|
465
|
-
source =
|
|
703
|
+
source = readSourceMemoized(memo, realPath);
|
|
466
704
|
} catch {
|
|
467
705
|
return { routes: {}, searchSchemas: {} };
|
|
468
706
|
}
|
|
@@ -470,7 +708,11 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
470
708
|
if (inlineBlock) {
|
|
471
709
|
block = inlineBlock;
|
|
472
710
|
} else if (variableName) {
|
|
473
|
-
const extracted = extractUrlsBlockForVariable(
|
|
711
|
+
const extracted = extractUrlsBlockForVariable(
|
|
712
|
+
source,
|
|
713
|
+
variableName,
|
|
714
|
+
parseBlock(memo, source)
|
|
715
|
+
);
|
|
474
716
|
if (!extracted) return { routes: {}, searchSchemas: {} };
|
|
475
717
|
block = extracted;
|
|
476
718
|
} else {
|
|
@@ -483,7 +725,8 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
483
725
|
realPath,
|
|
484
726
|
visited,
|
|
485
727
|
searchSchemas,
|
|
486
|
-
diagnosticsOut
|
|
728
|
+
diagnosticsOut,
|
|
729
|
+
memo
|
|
487
730
|
);
|
|
488
731
|
visited.delete(key);
|
|
489
732
|
return { routes, searchSchemas };
|
|
@@ -528,8 +771,16 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
528
771
|
let routes;
|
|
529
772
|
if (varNames.length > 0) {
|
|
530
773
|
routes = [];
|
|
774
|
+
const memo = createScanMemo();
|
|
531
775
|
for (const varName of varNames) {
|
|
532
|
-
const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
|
|
776
|
+
const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
|
|
777
|
+
filePath,
|
|
778
|
+
varName,
|
|
779
|
+
void 0,
|
|
780
|
+
void 0,
|
|
781
|
+
void 0,
|
|
782
|
+
memo
|
|
783
|
+
);
|
|
533
784
|
for (const [name, pattern] of Object.entries(routeMap)) {
|
|
534
785
|
const params = extractParamsFromPattern(pattern);
|
|
535
786
|
routes.push({
|
|
@@ -543,12 +794,12 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
543
794
|
} else {
|
|
544
795
|
routes = extractRoutesFromSource(source);
|
|
545
796
|
}
|
|
546
|
-
const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
|
|
797
|
+
const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
|
|
547
798
|
if (routes.length === 0) {
|
|
548
799
|
if (varNames.length > 0 && !existsSync2(genPath)) {
|
|
549
800
|
writeFileSync(genPath, generatePerModuleTypesSource([]));
|
|
550
801
|
console.log(
|
|
551
|
-
`[
|
|
802
|
+
`[rango] Generated route types (placeholder) -> ${genPath}`
|
|
552
803
|
);
|
|
553
804
|
}
|
|
554
805
|
return;
|
|
@@ -557,11 +808,11 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
557
808
|
const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
|
|
558
809
|
if (existing !== genSource) {
|
|
559
810
|
writeFileSync(genPath, genSource);
|
|
560
|
-
console.log(`[
|
|
811
|
+
console.log(`[rango] Generated route types -> ${genPath}`);
|
|
561
812
|
}
|
|
562
813
|
} catch (err) {
|
|
563
814
|
console.warn(
|
|
564
|
-
`[
|
|
815
|
+
`[rango] Failed to generate route types for ${filePath}: ${err.message}`
|
|
565
816
|
);
|
|
566
817
|
}
|
|
567
818
|
}
|
|
@@ -576,6 +827,131 @@ var init_per_module_writer = __esm({
|
|
|
576
827
|
}
|
|
577
828
|
});
|
|
578
829
|
|
|
830
|
+
// src/build/route-types/source-scan.ts
|
|
831
|
+
function isLineTerminator(ch) {
|
|
832
|
+
const c = ch.charCodeAt(0);
|
|
833
|
+
return c === 10 || c === 13 || c === 8232 || c === 8233;
|
|
834
|
+
}
|
|
835
|
+
function isRegexPositionAt(code, slashPos, prevChar) {
|
|
836
|
+
if (prevChar === void 0) return true;
|
|
837
|
+
if (prevChar === ")" || prevChar === "]" || prevChar === "}") return false;
|
|
838
|
+
if (!/[\w$]/.test(prevChar)) return true;
|
|
839
|
+
let k = slashPos - 1;
|
|
840
|
+
while (k >= 0 && /\s/.test(code[k])) k--;
|
|
841
|
+
const wordEnd = k + 1;
|
|
842
|
+
while (k >= 0 && /[\w$]/.test(code[k])) k--;
|
|
843
|
+
return REGEX_PRECEDING_KEYWORDS.has(code.slice(k + 1, wordEnd));
|
|
844
|
+
}
|
|
845
|
+
function makeCodeClassifier(code) {
|
|
846
|
+
const n = code.length;
|
|
847
|
+
let i = 0;
|
|
848
|
+
let skipStart = -1;
|
|
849
|
+
let skipEnd = -1;
|
|
850
|
+
let lastSig;
|
|
851
|
+
return (q) => {
|
|
852
|
+
if (q >= skipStart && q < skipEnd) return false;
|
|
853
|
+
while (i < n && i <= q) {
|
|
854
|
+
const c = code[i];
|
|
855
|
+
const d = i + 1 < n ? code[i + 1] : "";
|
|
856
|
+
let end = -1;
|
|
857
|
+
let transparent = false;
|
|
858
|
+
if (c === "/" && d === "/") {
|
|
859
|
+
let j = i + 2;
|
|
860
|
+
while (j < n && !isLineTerminator(code[j])) j++;
|
|
861
|
+
end = j;
|
|
862
|
+
transparent = true;
|
|
863
|
+
} else if (c === "/" && d === "*") {
|
|
864
|
+
let j = i + 2;
|
|
865
|
+
while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
|
|
866
|
+
end = Math.min(n, j + 2);
|
|
867
|
+
transparent = true;
|
|
868
|
+
} else if (c === '"' || c === "'" || c === "`") {
|
|
869
|
+
let j = i + 1;
|
|
870
|
+
while (j < n) {
|
|
871
|
+
if (code[j] === "\\") {
|
|
872
|
+
j += 2;
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
if (code[j] === c) {
|
|
876
|
+
j++;
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
j++;
|
|
880
|
+
}
|
|
881
|
+
end = j;
|
|
882
|
+
} else if (c === "/" && d !== "/" && d !== "*" && isRegexPositionAt(code, i, lastSig)) {
|
|
883
|
+
let j = i + 1;
|
|
884
|
+
let inClass = false;
|
|
885
|
+
let closed = false;
|
|
886
|
+
while (j < n && !isLineTerminator(code[j])) {
|
|
887
|
+
const r = code[j];
|
|
888
|
+
if (r === "\\") {
|
|
889
|
+
j += 2;
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
if (r === "[") inClass = true;
|
|
893
|
+
else if (r === "]") inClass = false;
|
|
894
|
+
else if (r === "/" && !inClass) {
|
|
895
|
+
j++;
|
|
896
|
+
closed = true;
|
|
897
|
+
break;
|
|
898
|
+
}
|
|
899
|
+
j++;
|
|
900
|
+
}
|
|
901
|
+
if (closed) {
|
|
902
|
+
while (j < n && /[a-z]/.test(code[j])) j++;
|
|
903
|
+
end = j;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (end >= 0) {
|
|
907
|
+
if (q < end) {
|
|
908
|
+
skipStart = i;
|
|
909
|
+
skipEnd = end;
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
i = end;
|
|
913
|
+
if (!transparent) lastSig = "x";
|
|
914
|
+
} else {
|
|
915
|
+
if (!/\s/.test(c)) lastSig = c;
|
|
916
|
+
i++;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return true;
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
function firstCodeMatchIndex(code, pattern) {
|
|
923
|
+
const inCode = makeCodeClassifier(code);
|
|
924
|
+
pattern.lastIndex = 0;
|
|
925
|
+
let m;
|
|
926
|
+
while ((m = pattern.exec(code)) !== null) {
|
|
927
|
+
if (inCode(m.index)) return m.index;
|
|
928
|
+
if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
|
|
929
|
+
}
|
|
930
|
+
return -1;
|
|
931
|
+
}
|
|
932
|
+
var REGEX_PRECEDING_KEYWORDS;
|
|
933
|
+
var init_source_scan = __esm({
|
|
934
|
+
"src/build/route-types/source-scan.ts"() {
|
|
935
|
+
"use strict";
|
|
936
|
+
REGEX_PRECEDING_KEYWORDS = /* @__PURE__ */ new Set([
|
|
937
|
+
"return",
|
|
938
|
+
"typeof",
|
|
939
|
+
"instanceof",
|
|
940
|
+
"in",
|
|
941
|
+
"of",
|
|
942
|
+
"new",
|
|
943
|
+
"delete",
|
|
944
|
+
"void",
|
|
945
|
+
"do",
|
|
946
|
+
"else",
|
|
947
|
+
"yield",
|
|
948
|
+
"await",
|
|
949
|
+
"case",
|
|
950
|
+
"throw"
|
|
951
|
+
]);
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
|
|
579
955
|
// src/build/route-types/router-processing.ts
|
|
580
956
|
import {
|
|
581
957
|
readFileSync as readFileSync3,
|
|
@@ -606,43 +982,50 @@ function countPublicRouteEntries(source) {
|
|
|
606
982
|
function isRoutableSourceFile(name) {
|
|
607
983
|
return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
|
|
608
984
|
}
|
|
609
|
-
function
|
|
985
|
+
function isExcludedScanDir(name) {
|
|
986
|
+
return name === "node_modules" || name === "dist" || name === "coverage" || name === "__tests__" || name === "__mocks__" || name.startsWith(".");
|
|
987
|
+
}
|
|
988
|
+
function findCallSiteFilesRecursive(dir, pattern, patternG, stopAtMatchDir, filter, results) {
|
|
610
989
|
let entries;
|
|
611
990
|
try {
|
|
612
991
|
entries = readdirSync2(dir, { withFileTypes: true });
|
|
613
992
|
} catch (err) {
|
|
614
993
|
console.warn(
|
|
615
|
-
`[
|
|
994
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
616
995
|
);
|
|
617
996
|
return;
|
|
618
997
|
}
|
|
619
998
|
const childDirs = [];
|
|
620
|
-
const
|
|
999
|
+
const matchesInDir = [];
|
|
621
1000
|
for (const entry of entries) {
|
|
622
1001
|
const fullPath = join2(dir, entry.name);
|
|
623
1002
|
if (entry.isDirectory()) {
|
|
624
|
-
if (entry.name
|
|
625
|
-
continue;
|
|
626
|
-
childDirs.push(fullPath);
|
|
1003
|
+
if (!isExcludedScanDir(entry.name)) childDirs.push(fullPath);
|
|
627
1004
|
continue;
|
|
628
1005
|
}
|
|
629
1006
|
if (!isRoutableSourceFile(entry.name)) continue;
|
|
630
1007
|
if (filter && !filter(fullPath)) continue;
|
|
631
1008
|
try {
|
|
632
1009
|
const source = readFileSync3(fullPath, "utf-8");
|
|
633
|
-
if (
|
|
634
|
-
|
|
1010
|
+
if (pattern.test(source) && firstCodeMatchIndex(source, patternG) >= 0) {
|
|
1011
|
+
matchesInDir.push(fullPath);
|
|
635
1012
|
}
|
|
636
1013
|
} catch {
|
|
637
1014
|
continue;
|
|
638
1015
|
}
|
|
639
1016
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
1017
|
+
results.push(...matchesInDir);
|
|
1018
|
+
if (!stopAtMatchDir || matchesInDir.length === 0) {
|
|
1019
|
+
for (const childDir of childDirs) {
|
|
1020
|
+
findCallSiteFilesRecursive(
|
|
1021
|
+
childDir,
|
|
1022
|
+
pattern,
|
|
1023
|
+
patternG,
|
|
1024
|
+
stopAtMatchDir,
|
|
1025
|
+
filter,
|
|
1026
|
+
results
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
646
1029
|
}
|
|
647
1030
|
}
|
|
648
1031
|
function findNestedRouterConflict(routerFiles) {
|
|
@@ -668,7 +1051,7 @@ function findNestedRouterConflict(routerFiles) {
|
|
|
668
1051
|
}
|
|
669
1052
|
return null;
|
|
670
1053
|
}
|
|
671
|
-
function formatNestedRouterConflictError(conflict, prefix = "[
|
|
1054
|
+
function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
|
|
672
1055
|
return `${prefix} Nested router roots are not supported.
|
|
673
1056
|
Router root: ${conflict.ancestor}
|
|
674
1057
|
Nested router: ${conflict.nested}
|
|
@@ -764,19 +1147,38 @@ function extractBasenameFromRouter(code) {
|
|
|
764
1147
|
visit(sourceFile);
|
|
765
1148
|
return result;
|
|
766
1149
|
}
|
|
767
|
-
function applyBasenameToRoutes(result,
|
|
1150
|
+
function applyBasenameToRoutes(result, basename) {
|
|
768
1151
|
const prefixed = {};
|
|
769
1152
|
for (const [name, pattern] of Object.entries(result.routes)) {
|
|
770
1153
|
if (pattern === "/") {
|
|
771
|
-
prefixed[name] =
|
|
772
|
-
} else if (
|
|
773
|
-
prefixed[name] =
|
|
1154
|
+
prefixed[name] = basename;
|
|
1155
|
+
} else if (basename.endsWith("/") && pattern.startsWith("/")) {
|
|
1156
|
+
prefixed[name] = basename + pattern.slice(1);
|
|
774
1157
|
} else {
|
|
775
|
-
prefixed[name] =
|
|
1158
|
+
prefixed[name] = basename + pattern;
|
|
776
1159
|
}
|
|
777
1160
|
}
|
|
778
1161
|
return { routes: prefixed, searchSchemas: result.searchSchemas };
|
|
779
1162
|
}
|
|
1163
|
+
function genFileTsPath(sourceFile) {
|
|
1164
|
+
const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
1165
|
+
return join2(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
|
|
1166
|
+
}
|
|
1167
|
+
function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
|
|
1168
|
+
if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
|
|
1169
|
+
return runtimeSchemas;
|
|
1170
|
+
}
|
|
1171
|
+
const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
|
|
1172
|
+
if (Object.keys(staticParsed.searchSchemas).length === 0) {
|
|
1173
|
+
return runtimeSchemas;
|
|
1174
|
+
}
|
|
1175
|
+
const filtered = {};
|
|
1176
|
+
for (const name of publicRouteNames) {
|
|
1177
|
+
const schema = staticParsed.searchSchemas[name];
|
|
1178
|
+
if (schema) filtered[name] = schema;
|
|
1179
|
+
}
|
|
1180
|
+
return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
|
|
1181
|
+
}
|
|
780
1182
|
function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
781
1183
|
let routerSource;
|
|
782
1184
|
try {
|
|
@@ -789,7 +1191,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
789
1191
|
return { routes: {}, searchSchemas: {} };
|
|
790
1192
|
}
|
|
791
1193
|
const rawBasename = extractBasenameFromRouter(routerSource);
|
|
792
|
-
const
|
|
1194
|
+
const basename = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
|
|
793
1195
|
let result;
|
|
794
1196
|
if (extraction.kind === "inline") {
|
|
795
1197
|
result = buildCombinedRouteMapWithSearch(
|
|
@@ -814,8 +1216,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
814
1216
|
result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
|
|
815
1217
|
}
|
|
816
1218
|
}
|
|
817
|
-
if (
|
|
818
|
-
result = applyBasenameToRoutes(result,
|
|
1219
|
+
if (basename) {
|
|
1220
|
+
result = applyBasenameToRoutes(result, basename);
|
|
819
1221
|
}
|
|
820
1222
|
return result;
|
|
821
1223
|
}
|
|
@@ -888,7 +1290,14 @@ function detectUnresolvableIncludesForUrlsFile(filePath) {
|
|
|
888
1290
|
}
|
|
889
1291
|
function findRouterFiles(root, filter) {
|
|
890
1292
|
const result = [];
|
|
891
|
-
|
|
1293
|
+
findCallSiteFilesRecursive(
|
|
1294
|
+
root,
|
|
1295
|
+
ROUTER_CALL_PATTERN,
|
|
1296
|
+
ROUTER_CALL_PATTERN_G,
|
|
1297
|
+
true,
|
|
1298
|
+
filter,
|
|
1299
|
+
result
|
|
1300
|
+
);
|
|
892
1301
|
return result;
|
|
893
1302
|
}
|
|
894
1303
|
function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
@@ -897,7 +1306,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
897
1306
|
if (existsSync3(oldCombinedPath)) {
|
|
898
1307
|
unlinkSync(oldCombinedPath);
|
|
899
1308
|
console.log(
|
|
900
|
-
`[
|
|
1309
|
+
`[rango] Removed stale combined route types: ${oldCombinedPath}`
|
|
901
1310
|
);
|
|
902
1311
|
}
|
|
903
1312
|
} catch {
|
|
@@ -919,18 +1328,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
919
1328
|
}
|
|
920
1329
|
if (!extractUrlsFromRouter(routerSource)) continue;
|
|
921
1330
|
}
|
|
922
|
-
const
|
|
923
|
-
/\.(tsx?|jsx?)$/,
|
|
924
|
-
""
|
|
925
|
-
);
|
|
926
|
-
const outPath = join2(
|
|
927
|
-
dirname2(routerFilePath),
|
|
928
|
-
`${routerBasename}.named-routes.gen.ts`
|
|
929
|
-
);
|
|
1331
|
+
const outPath = genFileTsPath(routerFilePath);
|
|
930
1332
|
const existing = existsSync3(outPath) ? readFileSync3(outPath, "utf-8") : null;
|
|
931
1333
|
if (Object.keys(result.routes).length === 0) {
|
|
932
1334
|
if (!existing) {
|
|
933
1335
|
const emptySource = generateRouteTypesSource({});
|
|
1336
|
+
opts?.onWrite?.(outPath, emptySource);
|
|
934
1337
|
writeFileSync2(outPath, emptySource);
|
|
935
1338
|
}
|
|
936
1339
|
continue;
|
|
@@ -950,22 +1353,25 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
950
1353
|
continue;
|
|
951
1354
|
}
|
|
952
1355
|
}
|
|
1356
|
+
opts?.onWrite?.(outPath, source);
|
|
953
1357
|
writeFileSync2(outPath, source);
|
|
954
1358
|
console.log(
|
|
955
|
-
`[
|
|
1359
|
+
`[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
|
|
956
1360
|
);
|
|
957
1361
|
}
|
|
958
1362
|
}
|
|
959
1363
|
}
|
|
960
|
-
var ROUTER_CALL_PATTERN;
|
|
1364
|
+
var ROUTER_CALL_PATTERN, ROUTER_CALL_PATTERN_G;
|
|
961
1365
|
var init_router_processing = __esm({
|
|
962
1366
|
"src/build/route-types/router-processing.ts"() {
|
|
963
1367
|
"use strict";
|
|
964
1368
|
init_codegen();
|
|
1369
|
+
init_source_scan();
|
|
965
1370
|
init_include_resolution();
|
|
966
1371
|
init_per_module_writer();
|
|
967
1372
|
init_route_name();
|
|
968
1373
|
ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
|
|
1374
|
+
ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
|
|
969
1375
|
}
|
|
970
1376
|
});
|
|
971
1377
|
|
|
@@ -1003,7 +1409,7 @@ import {
|
|
|
1003
1409
|
import { createElement, StrictMode } from "react";
|
|
1004
1410
|
import { hydrateRoot } from "react-dom/client";
|
|
1005
1411
|
import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
|
|
1006
|
-
import { initBrowserApp,
|
|
1412
|
+
import { initBrowserApp, Rango } from "@rangojs/router/browser";
|
|
1007
1413
|
|
|
1008
1414
|
async function initializeApp() {
|
|
1009
1415
|
const deps = {
|
|
@@ -1014,11 +1420,16 @@ async function initializeApp() {
|
|
|
1014
1420
|
createTemporaryReferenceSet,
|
|
1015
1421
|
};
|
|
1016
1422
|
|
|
1017
|
-
|
|
1423
|
+
// initBrowserApp resolves the initial payload and returns the browser app
|
|
1424
|
+
// context, including strictMode (default true) from createRouter. StrictMode
|
|
1425
|
+
// is the default; createRouter({ strictMode: false }) ships the opt-out in the
|
|
1426
|
+
// payload metadata. StrictMode emits no DOM, so toggling never changes markup.
|
|
1427
|
+
const { strictMode } = await initBrowserApp({ rscStream, deps });
|
|
1018
1428
|
|
|
1429
|
+
const app = createElement(Rango);
|
|
1019
1430
|
hydrateRoot(
|
|
1020
1431
|
document,
|
|
1021
|
-
createElement(StrictMode, null,
|
|
1432
|
+
strictMode === false ? app : createElement(StrictMode, null, app)
|
|
1022
1433
|
);
|
|
1023
1434
|
}
|
|
1024
1435
|
|
|
@@ -1026,9 +1437,14 @@ initializeApp().catch(console.error);
|
|
|
1026
1437
|
`.trim();
|
|
1027
1438
|
VIRTUAL_ENTRY_SSR = `
|
|
1028
1439
|
import { createFromReadableStream } from "@rangojs/router/internal/deps/ssr";
|
|
1029
|
-
import { renderToReadableStream } from "react-dom/server.edge";
|
|
1440
|
+
import { renderToReadableStream, resume } from "react-dom/server.edge";
|
|
1441
|
+
import { prerender } from "react-dom/static.edge";
|
|
1030
1442
|
import { injectRSCPayload } from "@rangojs/router/internal/deps/html-stream-server";
|
|
1031
|
-
import {
|
|
1443
|
+
import {
|
|
1444
|
+
createSSRHandler,
|
|
1445
|
+
createShellCaptureHandler,
|
|
1446
|
+
createShellResumeHandler,
|
|
1447
|
+
} from "@rangojs/router/ssr";
|
|
1032
1448
|
|
|
1033
1449
|
export const renderHTML = createSSRHandler({
|
|
1034
1450
|
createFromReadableStream,
|
|
@@ -1037,6 +1453,26 @@ export const renderHTML = createSSRHandler({
|
|
|
1037
1453
|
loadBootstrapScriptContent: () =>
|
|
1038
1454
|
import.meta.viteRsc.loadBootstrapScriptContent("index"),
|
|
1039
1455
|
});
|
|
1456
|
+
|
|
1457
|
+
export const captureShellHTML = createShellCaptureHandler({
|
|
1458
|
+
createFromReadableStream,
|
|
1459
|
+
renderToReadableStream,
|
|
1460
|
+
injectRSCPayload,
|
|
1461
|
+
prerender,
|
|
1462
|
+
resume,
|
|
1463
|
+
loadBootstrapScriptContent: () =>
|
|
1464
|
+
import.meta.viteRsc.loadBootstrapScriptContent("index"),
|
|
1465
|
+
});
|
|
1466
|
+
|
|
1467
|
+
export const resumeShellHTML = createShellResumeHandler({
|
|
1468
|
+
createFromReadableStream,
|
|
1469
|
+
renderToReadableStream,
|
|
1470
|
+
injectRSCPayload,
|
|
1471
|
+
prerender,
|
|
1472
|
+
resume,
|
|
1473
|
+
loadBootstrapScriptContent: () =>
|
|
1474
|
+
import.meta.viteRsc.loadBootstrapScriptContent("index"),
|
|
1475
|
+
});
|
|
1040
1476
|
`.trim();
|
|
1041
1477
|
VIRTUAL_IDS = {
|
|
1042
1478
|
browser: "virtual:rsc-router/entry.browser.js",
|
|
@@ -1047,12 +1483,37 @@ export const renderHTML = createSSRHandler({
|
|
|
1047
1483
|
}
|
|
1048
1484
|
});
|
|
1049
1485
|
|
|
1486
|
+
// src/vite/utils/directive-prologue.ts
|
|
1487
|
+
import { parseAst } from "vite";
|
|
1488
|
+
function hasUseClientDirective(source) {
|
|
1489
|
+
let program;
|
|
1490
|
+
try {
|
|
1491
|
+
program = parseAst(source, { lang: "tsx" });
|
|
1492
|
+
} catch {
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
for (const node of program.body ?? []) {
|
|
1496
|
+
if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
|
|
1497
|
+
if (node.expression.value === "use client") return true;
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
return false;
|
|
1503
|
+
}
|
|
1504
|
+
var init_directive_prologue = __esm({
|
|
1505
|
+
"src/vite/utils/directive-prologue.ts"() {
|
|
1506
|
+
"use strict";
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1050
1510
|
// src/vite/plugins/version-plugin.ts
|
|
1051
1511
|
var version_plugin_exports = {};
|
|
1052
1512
|
__export(version_plugin_exports, {
|
|
1053
|
-
createVersionPlugin: () => createVersionPlugin
|
|
1513
|
+
createVersionPlugin: () => createVersionPlugin,
|
|
1514
|
+
isViteDepCachePath: () => isViteDepCachePath
|
|
1054
1515
|
});
|
|
1055
|
-
import { parseAst } from "vite";
|
|
1516
|
+
import { parseAst as parseAst2 } from "vite";
|
|
1056
1517
|
function isCodeModule(id) {
|
|
1057
1518
|
return /\.(tsx?|jsx?)($|\?)/.test(id);
|
|
1058
1519
|
}
|
|
@@ -1060,23 +1521,13 @@ function normalizeModuleId(id) {
|
|
|
1060
1521
|
return id.split("?", 1)[0];
|
|
1061
1522
|
}
|
|
1062
1523
|
function getClientModuleSignature(source) {
|
|
1524
|
+
if (!hasUseClientDirective(source)) return void 0;
|
|
1063
1525
|
let program;
|
|
1064
1526
|
try {
|
|
1065
|
-
program =
|
|
1527
|
+
program = parseAst2(source, { lang: "tsx" });
|
|
1066
1528
|
} catch {
|
|
1067
1529
|
return void 0;
|
|
1068
1530
|
}
|
|
1069
|
-
let isUseClient = false;
|
|
1070
|
-
for (const node of program.body ?? []) {
|
|
1071
|
-
if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
|
|
1072
|
-
if (node.expression.value === "use client") {
|
|
1073
|
-
isUseClient = true;
|
|
1074
|
-
}
|
|
1075
|
-
continue;
|
|
1076
|
-
}
|
|
1077
|
-
break;
|
|
1078
|
-
}
|
|
1079
|
-
if (!isUseClient) return void 0;
|
|
1080
1531
|
const exports = /* @__PURE__ */ new Set();
|
|
1081
1532
|
let hasDefault = false;
|
|
1082
1533
|
let hasExportAll = false;
|
|
@@ -1145,11 +1596,12 @@ function createVersionPlugin() {
|
|
|
1145
1596
|
let currentVersion = buildVersion;
|
|
1146
1597
|
let isDev = false;
|
|
1147
1598
|
let server = null;
|
|
1599
|
+
let resolvedCacheDir;
|
|
1148
1600
|
const clientModuleSignatures = /* @__PURE__ */ new Map();
|
|
1149
1601
|
let versionCounter = 0;
|
|
1150
1602
|
const bumpVersion = (reason) => {
|
|
1151
1603
|
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
1152
|
-
console.log(`[
|
|
1604
|
+
console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
|
|
1153
1605
|
const rscEnv = server?.environments?.rsc;
|
|
1154
1606
|
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
1155
1607
|
"\0" + VIRTUAL_IDS.version
|
|
@@ -1163,6 +1615,7 @@ function createVersionPlugin() {
|
|
|
1163
1615
|
enforce: "pre",
|
|
1164
1616
|
configResolved(config) {
|
|
1165
1617
|
isDev = config.command === "serve";
|
|
1618
|
+
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
1166
1619
|
},
|
|
1167
1620
|
configureServer(devServer) {
|
|
1168
1621
|
server = devServer;
|
|
@@ -1199,11 +1652,11 @@ function createVersionPlugin() {
|
|
|
1199
1652
|
}
|
|
1200
1653
|
return null;
|
|
1201
1654
|
},
|
|
1202
|
-
// Track RSC module changes and update version
|
|
1203
1655
|
async hotUpdate(ctx) {
|
|
1204
1656
|
if (!isDev) return;
|
|
1205
1657
|
const isRscModule = this.environment?.name === "rsc";
|
|
1206
1658
|
if (!isRscModule) return;
|
|
1659
|
+
if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
|
|
1207
1660
|
if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
|
|
1208
1661
|
return;
|
|
1209
1662
|
}
|
|
@@ -1233,10 +1686,22 @@ function createVersionPlugin() {
|
|
|
1233
1686
|
}
|
|
1234
1687
|
};
|
|
1235
1688
|
}
|
|
1689
|
+
function isViteDepCachePath(filePath, cacheDir) {
|
|
1690
|
+
if (!filePath) return false;
|
|
1691
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
1692
|
+
if (cacheDir) {
|
|
1693
|
+
const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1694
|
+
if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
|
|
1695
|
+
return true;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
|
|
1699
|
+
}
|
|
1236
1700
|
var init_version_plugin = __esm({
|
|
1237
1701
|
"src/vite/plugins/version-plugin.ts"() {
|
|
1238
1702
|
"use strict";
|
|
1239
1703
|
init_virtual_entries();
|
|
1704
|
+
init_directive_prologue();
|
|
1240
1705
|
}
|
|
1241
1706
|
});
|
|
1242
1707
|
|
|
@@ -1278,7 +1743,7 @@ var runtime_discovery_exports = {};
|
|
|
1278
1743
|
__export(runtime_discovery_exports, {
|
|
1279
1744
|
discoverAndWriteRouteTypes: () => discoverAndWriteRouteTypes
|
|
1280
1745
|
});
|
|
1281
|
-
import {
|
|
1746
|
+
import { resolve as resolve3 } from "node:path";
|
|
1282
1747
|
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1283
1748
|
async function discoverAndWriteRouteTypes(opts) {
|
|
1284
1749
|
let createViteServer;
|
|
@@ -1364,7 +1829,10 @@ async function discoverAndWriteRouteTypes(opts) {
|
|
|
1364
1829
|
let routerMountIndex = 0;
|
|
1365
1830
|
for (const [id, router] of registry) {
|
|
1366
1831
|
if (!router.urlpatterns) continue;
|
|
1367
|
-
const manifest = generateManifest(
|
|
1832
|
+
const manifest = await generateManifest(
|
|
1833
|
+
router.urlpatterns,
|
|
1834
|
+
routerMountIndex
|
|
1835
|
+
);
|
|
1368
1836
|
routerMountIndex++;
|
|
1369
1837
|
const rawManifest = manifest.routeManifest;
|
|
1370
1838
|
const routeManifest = {};
|
|
@@ -1388,22 +1856,12 @@ This means createRouter() stack trace parsing matched an internal frame.
|
|
|
1388
1856
|
Set an explicit \`id\` on createRouter() or check the call site.`
|
|
1389
1857
|
);
|
|
1390
1858
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
if (schema) filtered[name] = schema;
|
|
1398
|
-
}
|
|
1399
|
-
if (Object.keys(filtered).length > 0) {
|
|
1400
|
-
routeSearchSchemas = filtered;
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
const routerDir = dirname3(sourceFile);
|
|
1405
|
-
const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
1406
|
-
const outPath = join3(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
1859
|
+
routeSearchSchemas = resolveSearchSchemas(
|
|
1860
|
+
Object.keys(routeManifest),
|
|
1861
|
+
routeSearchSchemas,
|
|
1862
|
+
sourceFile
|
|
1863
|
+
);
|
|
1864
|
+
const outPath = genFileTsPath(sourceFile);
|
|
1407
1865
|
const source = generateRouteTypesSource(
|
|
1408
1866
|
routeManifest,
|
|
1409
1867
|
routeSearchSchemas && Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : void 0
|
|
@@ -1440,7 +1898,7 @@ var init_runtime_discovery = __esm({
|
|
|
1440
1898
|
|
|
1441
1899
|
// src/bin/rango.ts
|
|
1442
1900
|
init_generate_route_types();
|
|
1443
|
-
import { resolve as resolve4, dirname as
|
|
1901
|
+
import { resolve as resolve4, dirname as dirname3 } from "node:path";
|
|
1444
1902
|
import { readFileSync as readFileSync5, statSync, existsSync as existsSync5 } from "node:fs";
|
|
1445
1903
|
var [command, ...rawArgs] = process.argv.slice(2);
|
|
1446
1904
|
if (command === "generate") {
|
|
@@ -1511,12 +1969,12 @@ Examples:
|
|
|
1511
1969
|
);
|
|
1512
1970
|
}
|
|
1513
1971
|
function findProjectRoot(fromPath) {
|
|
1514
|
-
let dir =
|
|
1515
|
-
while (dir !==
|
|
1972
|
+
let dir = dirname3(resolve4(fromPath));
|
|
1973
|
+
while (dir !== dirname3(dir)) {
|
|
1516
1974
|
if (existsSync5(resolve4(dir, "package.json")) || existsSync5(resolve4(dir, "vite.config.ts")) || existsSync5(resolve4(dir, "vite.config.js"))) {
|
|
1517
1975
|
return dir;
|
|
1518
1976
|
}
|
|
1519
|
-
dir =
|
|
1977
|
+
dir = dirname3(dir);
|
|
1520
1978
|
}
|
|
1521
1979
|
return process.cwd();
|
|
1522
1980
|
}
|