@rangojs/router 0.0.0-experimental.eb0645d3 → 0.0.0-experimental.f1468e3c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -0
- package/README.md +126 -16
- package/dist/bin/rango.js +319 -95
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +2724 -1053
- package/package.json +68 -14
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +64 -2
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +224 -32
- package/skills/caching/SKILL.md +279 -17
- package/skills/composability/SKILL.md +27 -3
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +4 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +11 -9
- package/skills/hooks/SKILL.md +243 -29
- package/skills/host-router/SKILL.md +83 -23
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +68 -19
- package/skills/layout/SKILL.md +13 -9
- package/skills/links/SKILL.md +190 -23
- package/skills/loader/SKILL.md +235 -9
- package/skills/middleware/SKILL.md +18 -10
- package/skills/migrate-nextjs/SKILL.md +43 -19
- package/skills/migrate-react-router/SKILL.md +8 -2
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +18 -7
- package/skills/prerender/SKILL.md +65 -60
- package/skills/rango/SKILL.md +251 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +115 -48
- package/skills/route/SKILL.md +46 -5
- package/skills/router-setup/SKILL.md +30 -8
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/typesafety/SKILL.md +322 -29
- package/skills/use-cache/SKILL.md +57 -14
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +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 +192 -150
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +121 -84
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +115 -67
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +147 -128
- package/src/browser/prefetch/cache.ts +107 -56
- package/src/browser/prefetch/fetch.ts +204 -34
- package/src/browser/prefetch/queue.ts +6 -3
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +30 -7
- package/src/browser/react/NavigationProvider.tsx +283 -118
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/deferred-handle-resolution.ts +75 -0
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +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 +10 -5
- package/src/browser/react/use-params.ts +11 -11
- 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 +91 -24
- package/src/browser/scroll-restoration.ts +30 -17
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +214 -55
- package/src/browser/types.ts +80 -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 +60 -35
- package/src/build/generate-route-types.ts +2 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +117 -14
- 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 +117 -23
- 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 +55 -28
- 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 +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +29 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +224 -41
- package/src/cache/cache-scope.ts +188 -82
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +1989 -378
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +89 -21
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +10 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +9 -17
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +37 -100
- package/src/client.rsc.tsx +44 -21
- package/src/client.tsx +36 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +31 -23
- package/src/handles/MetaTags.tsx +62 -19
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +37 -8
- package/src/handles/is-thenable.ts +19 -0
- package/src/handles/meta.ts +51 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +96 -12
- package/src/index.ts +94 -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 +61 -6
- 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 +34 -0
- package/src/reverse.ts +65 -40
- 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 +82 -55
- 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 +0 -16
- 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 +44 -23
- package/src/router/handler-context.ts +27 -43
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +10 -47
- package/src/router/loader-resolution.ts +155 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +18 -29
- package/src/router/match-api.ts +9 -24
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +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 +44 -74
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +247 -166
- package/src/router/navigation-snapshot.ts +0 -51
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +85 -94
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prerender-match.ts +104 -65
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +28 -62
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +0 -1
- package/src/router/router-context.ts +3 -28
- package/src/router/router-interfaces.ts +83 -35
- package/src/router/router-options.ts +136 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +97 -84
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +76 -39
- package/src/router/segment-resolution/revalidation.ts +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 +56 -0
- package/src/router/telemetry-otel.ts +161 -199
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +162 -64
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +0 -5
- package/src/router.ts +110 -55
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +264 -220
- package/src/rsc/helpers.ts +100 -6
- 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 +28 -41
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +117 -11
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +88 -188
- package/src/rsc/rsc-rendering.ts +98 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +281 -117
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +23 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +31 -4
- package/src/segment-system.tsx +254 -143
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +163 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +287 -178
- package/src/ssr/index.tsx +21 -16
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +701 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +581 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +20 -58
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +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 +6 -50
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +9 -56
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +29 -12
- package/src/urls/path-helper.ts +17 -106
- package/src/urls/pattern-types.ts +36 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/discover-routers.ts +126 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +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 +44 -0
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +2 -0
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +126 -8
- 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-stub.ts +1 -21
- 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/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +39 -25
- package/src/vite/rango.ts +109 -118
- package/src/vite/router-discovery.ts +718 -119
- 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 +54 -39
- package/src/vite/utils/shared-utils.ts +90 -41
- 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,8 @@ function extractNamePrefixFromInclude(node) {
|
|
|
253
289
|
}
|
|
254
290
|
return null;
|
|
255
291
|
}
|
|
256
|
-
function extractIncludesWithDiagnostics(code) {
|
|
257
|
-
const sourceFile = ts3.createSourceFile(
|
|
292
|
+
function extractIncludesWithDiagnostics(code, sourceFileArg) {
|
|
293
|
+
const sourceFile = sourceFileArg ?? ts3.createSourceFile(
|
|
258
294
|
"input.tsx",
|
|
259
295
|
code,
|
|
260
296
|
ts3.ScriptTarget.Latest,
|
|
@@ -308,7 +344,7 @@ function extractIncludesWithDiagnostics(code) {
|
|
|
308
344
|
return { resolved, unresolvable };
|
|
309
345
|
}
|
|
310
346
|
function resolveImportedVariable(code, localName) {
|
|
311
|
-
const importRegex = /import\s
|
|
347
|
+
const importRegex = /import\s*(?:[\w$]+\s*,\s*)?\{([^}]+)\}\s*from\s*["']([^"']+)["']/g;
|
|
312
348
|
let match;
|
|
313
349
|
while ((match = importRegex.exec(code)) !== null) {
|
|
314
350
|
const imports = match[1];
|
|
@@ -345,8 +381,8 @@ function resolveImportPath(importSpec, fromFile) {
|
|
|
345
381
|
}
|
|
346
382
|
return null;
|
|
347
383
|
}
|
|
348
|
-
function extractUrlsBlockForVariable(code, varName) {
|
|
349
|
-
const sourceFile = ts3.createSourceFile(
|
|
384
|
+
function extractUrlsBlockForVariable(code, varName, sourceFileArg) {
|
|
385
|
+
const sourceFile = sourceFileArg ?? ts3.createSourceFile(
|
|
350
386
|
"input.tsx",
|
|
351
387
|
code,
|
|
352
388
|
ts3.ScriptTarget.Latest,
|
|
@@ -368,16 +404,20 @@ function extractUrlsBlockForVariable(code, varName) {
|
|
|
368
404
|
visit(sourceFile);
|
|
369
405
|
return result;
|
|
370
406
|
}
|
|
371
|
-
function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut) {
|
|
407
|
+
function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut, memo) {
|
|
372
408
|
const routeMap = {};
|
|
373
|
-
const
|
|
409
|
+
const blockSourceFile = parseBlock(memo, block);
|
|
410
|
+
const localRoutes = extractRoutesFromSource(block, blockSourceFile);
|
|
374
411
|
for (const { name, pattern, search } of localRoutes) {
|
|
375
412
|
routeMap[name] = pattern;
|
|
376
413
|
if (search && searchSchemasOut) {
|
|
377
414
|
searchSchemasOut[name] = search;
|
|
378
415
|
}
|
|
379
416
|
}
|
|
380
|
-
const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
|
|
417
|
+
const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
|
|
418
|
+
block,
|
|
419
|
+
blockSourceFile
|
|
420
|
+
);
|
|
381
421
|
if (diagnosticsOut) {
|
|
382
422
|
for (const entry of unresolvable) {
|
|
383
423
|
diagnosticsOut.push({ ...entry, sourceFile: filePath });
|
|
@@ -404,12 +444,15 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
404
444
|
targetFile,
|
|
405
445
|
imported.exportedName,
|
|
406
446
|
visited,
|
|
407
|
-
diagnosticsOut
|
|
447
|
+
diagnosticsOut,
|
|
448
|
+
void 0,
|
|
449
|
+
memo
|
|
408
450
|
);
|
|
409
451
|
} else {
|
|
410
452
|
const sameFileBlock = extractUrlsBlockForVariable(
|
|
411
453
|
fullSource,
|
|
412
|
-
variableName
|
|
454
|
+
variableName,
|
|
455
|
+
parseBlock(memo, fullSource)
|
|
413
456
|
);
|
|
414
457
|
if (!sameFileBlock) {
|
|
415
458
|
if (diagnosticsOut) {
|
|
@@ -427,7 +470,9 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
427
470
|
filePath,
|
|
428
471
|
variableName,
|
|
429
472
|
visited,
|
|
430
|
-
diagnosticsOut
|
|
473
|
+
diagnosticsOut,
|
|
474
|
+
void 0,
|
|
475
|
+
memo
|
|
431
476
|
);
|
|
432
477
|
}
|
|
433
478
|
if (namePrefix === null) {
|
|
@@ -451,18 +496,19 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
|
|
|
451
496
|
}
|
|
452
497
|
return routeMap;
|
|
453
498
|
}
|
|
454
|
-
function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock) {
|
|
499
|
+
function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock, memo) {
|
|
455
500
|
visited = visited ?? /* @__PURE__ */ new Set();
|
|
501
|
+
memo = memo ?? createScanMemo();
|
|
456
502
|
const realPath = resolve(filePath);
|
|
457
503
|
const key = variableName ? `${realPath}:${variableName}` : realPath;
|
|
458
504
|
if (visited.has(key)) {
|
|
459
|
-
console.warn(`[
|
|
505
|
+
console.warn(`[rango] Circular include detected, skipping: ${key}`);
|
|
460
506
|
return { routes: {}, searchSchemas: {} };
|
|
461
507
|
}
|
|
462
508
|
visited.add(key);
|
|
463
509
|
let source;
|
|
464
510
|
try {
|
|
465
|
-
source =
|
|
511
|
+
source = readSourceMemoized(memo, realPath);
|
|
466
512
|
} catch {
|
|
467
513
|
return { routes: {}, searchSchemas: {} };
|
|
468
514
|
}
|
|
@@ -470,7 +516,11 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
470
516
|
if (inlineBlock) {
|
|
471
517
|
block = inlineBlock;
|
|
472
518
|
} else if (variableName) {
|
|
473
|
-
const extracted = extractUrlsBlockForVariable(
|
|
519
|
+
const extracted = extractUrlsBlockForVariable(
|
|
520
|
+
source,
|
|
521
|
+
variableName,
|
|
522
|
+
parseBlock(memo, source)
|
|
523
|
+
);
|
|
474
524
|
if (!extracted) return { routes: {}, searchSchemas: {} };
|
|
475
525
|
block = extracted;
|
|
476
526
|
} else {
|
|
@@ -483,7 +533,8 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
483
533
|
realPath,
|
|
484
534
|
visited,
|
|
485
535
|
searchSchemas,
|
|
486
|
-
diagnosticsOut
|
|
536
|
+
diagnosticsOut,
|
|
537
|
+
memo
|
|
487
538
|
);
|
|
488
539
|
visited.delete(key);
|
|
489
540
|
return { routes, searchSchemas };
|
|
@@ -528,8 +579,16 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
528
579
|
let routes;
|
|
529
580
|
if (varNames.length > 0) {
|
|
530
581
|
routes = [];
|
|
582
|
+
const memo = createScanMemo();
|
|
531
583
|
for (const varName of varNames) {
|
|
532
|
-
const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
|
|
584
|
+
const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
|
|
585
|
+
filePath,
|
|
586
|
+
varName,
|
|
587
|
+
void 0,
|
|
588
|
+
void 0,
|
|
589
|
+
void 0,
|
|
590
|
+
memo
|
|
591
|
+
);
|
|
533
592
|
for (const [name, pattern] of Object.entries(routeMap)) {
|
|
534
593
|
const params = extractParamsFromPattern(pattern);
|
|
535
594
|
routes.push({
|
|
@@ -543,12 +602,12 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
543
602
|
} else {
|
|
544
603
|
routes = extractRoutesFromSource(source);
|
|
545
604
|
}
|
|
546
|
-
const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
|
|
605
|
+
const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
|
|
547
606
|
if (routes.length === 0) {
|
|
548
607
|
if (varNames.length > 0 && !existsSync2(genPath)) {
|
|
549
608
|
writeFileSync(genPath, generatePerModuleTypesSource([]));
|
|
550
609
|
console.log(
|
|
551
|
-
`[
|
|
610
|
+
`[rango] Generated route types (placeholder) -> ${genPath}`
|
|
552
611
|
);
|
|
553
612
|
}
|
|
554
613
|
return;
|
|
@@ -557,11 +616,11 @@ function writePerModuleRouteTypesForFile(filePath) {
|
|
|
557
616
|
const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
|
|
558
617
|
if (existing !== genSource) {
|
|
559
618
|
writeFileSync(genPath, genSource);
|
|
560
|
-
console.log(`[
|
|
619
|
+
console.log(`[rango] Generated route types -> ${genPath}`);
|
|
561
620
|
}
|
|
562
621
|
} catch (err) {
|
|
563
622
|
console.warn(
|
|
564
|
-
`[
|
|
623
|
+
`[rango] Failed to generate route types for ${filePath}: ${err.message}`
|
|
565
624
|
);
|
|
566
625
|
}
|
|
567
626
|
}
|
|
@@ -576,6 +635,131 @@ var init_per_module_writer = __esm({
|
|
|
576
635
|
}
|
|
577
636
|
});
|
|
578
637
|
|
|
638
|
+
// src/build/route-types/source-scan.ts
|
|
639
|
+
function isLineTerminator(ch) {
|
|
640
|
+
const c = ch.charCodeAt(0);
|
|
641
|
+
return c === 10 || c === 13 || c === 8232 || c === 8233;
|
|
642
|
+
}
|
|
643
|
+
function isRegexPositionAt(code, slashPos, prevChar) {
|
|
644
|
+
if (prevChar === void 0) return true;
|
|
645
|
+
if (prevChar === ")" || prevChar === "]" || prevChar === "}") return false;
|
|
646
|
+
if (!/[\w$]/.test(prevChar)) return true;
|
|
647
|
+
let k = slashPos - 1;
|
|
648
|
+
while (k >= 0 && /\s/.test(code[k])) k--;
|
|
649
|
+
const wordEnd = k + 1;
|
|
650
|
+
while (k >= 0 && /[\w$]/.test(code[k])) k--;
|
|
651
|
+
return REGEX_PRECEDING_KEYWORDS.has(code.slice(k + 1, wordEnd));
|
|
652
|
+
}
|
|
653
|
+
function makeCodeClassifier(code) {
|
|
654
|
+
const n = code.length;
|
|
655
|
+
let i = 0;
|
|
656
|
+
let skipStart = -1;
|
|
657
|
+
let skipEnd = -1;
|
|
658
|
+
let lastSig;
|
|
659
|
+
return (q) => {
|
|
660
|
+
if (q >= skipStart && q < skipEnd) return false;
|
|
661
|
+
while (i < n && i <= q) {
|
|
662
|
+
const c = code[i];
|
|
663
|
+
const d = i + 1 < n ? code[i + 1] : "";
|
|
664
|
+
let end = -1;
|
|
665
|
+
let transparent = false;
|
|
666
|
+
if (c === "/" && d === "/") {
|
|
667
|
+
let j = i + 2;
|
|
668
|
+
while (j < n && !isLineTerminator(code[j])) j++;
|
|
669
|
+
end = j;
|
|
670
|
+
transparent = true;
|
|
671
|
+
} else if (c === "/" && d === "*") {
|
|
672
|
+
let j = i + 2;
|
|
673
|
+
while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
|
|
674
|
+
end = Math.min(n, j + 2);
|
|
675
|
+
transparent = true;
|
|
676
|
+
} else if (c === '"' || c === "'" || c === "`") {
|
|
677
|
+
let j = i + 1;
|
|
678
|
+
while (j < n) {
|
|
679
|
+
if (code[j] === "\\") {
|
|
680
|
+
j += 2;
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
if (code[j] === c) {
|
|
684
|
+
j++;
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
j++;
|
|
688
|
+
}
|
|
689
|
+
end = j;
|
|
690
|
+
} else if (c === "/" && d !== "/" && d !== "*" && isRegexPositionAt(code, i, lastSig)) {
|
|
691
|
+
let j = i + 1;
|
|
692
|
+
let inClass = false;
|
|
693
|
+
let closed = false;
|
|
694
|
+
while (j < n && !isLineTerminator(code[j])) {
|
|
695
|
+
const r = code[j];
|
|
696
|
+
if (r === "\\") {
|
|
697
|
+
j += 2;
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
if (r === "[") inClass = true;
|
|
701
|
+
else if (r === "]") inClass = false;
|
|
702
|
+
else if (r === "/" && !inClass) {
|
|
703
|
+
j++;
|
|
704
|
+
closed = true;
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
j++;
|
|
708
|
+
}
|
|
709
|
+
if (closed) {
|
|
710
|
+
while (j < n && /[a-z]/.test(code[j])) j++;
|
|
711
|
+
end = j;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
if (end >= 0) {
|
|
715
|
+
if (q < end) {
|
|
716
|
+
skipStart = i;
|
|
717
|
+
skipEnd = end;
|
|
718
|
+
return false;
|
|
719
|
+
}
|
|
720
|
+
i = end;
|
|
721
|
+
if (!transparent) lastSig = "x";
|
|
722
|
+
} else {
|
|
723
|
+
if (!/\s/.test(c)) lastSig = c;
|
|
724
|
+
i++;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return true;
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
function firstCodeMatchIndex(code, pattern) {
|
|
731
|
+
const inCode = makeCodeClassifier(code);
|
|
732
|
+
pattern.lastIndex = 0;
|
|
733
|
+
let m;
|
|
734
|
+
while ((m = pattern.exec(code)) !== null) {
|
|
735
|
+
if (inCode(m.index)) return m.index;
|
|
736
|
+
if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
|
|
737
|
+
}
|
|
738
|
+
return -1;
|
|
739
|
+
}
|
|
740
|
+
var REGEX_PRECEDING_KEYWORDS;
|
|
741
|
+
var init_source_scan = __esm({
|
|
742
|
+
"src/build/route-types/source-scan.ts"() {
|
|
743
|
+
"use strict";
|
|
744
|
+
REGEX_PRECEDING_KEYWORDS = /* @__PURE__ */ new Set([
|
|
745
|
+
"return",
|
|
746
|
+
"typeof",
|
|
747
|
+
"instanceof",
|
|
748
|
+
"in",
|
|
749
|
+
"of",
|
|
750
|
+
"new",
|
|
751
|
+
"delete",
|
|
752
|
+
"void",
|
|
753
|
+
"do",
|
|
754
|
+
"else",
|
|
755
|
+
"yield",
|
|
756
|
+
"await",
|
|
757
|
+
"case",
|
|
758
|
+
"throw"
|
|
759
|
+
]);
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
|
|
579
763
|
// src/build/route-types/router-processing.ts
|
|
580
764
|
import {
|
|
581
765
|
readFileSync as readFileSync3,
|
|
@@ -612,7 +796,7 @@ function findRouterFilesRecursive(dir, filter, results) {
|
|
|
612
796
|
entries = readdirSync2(dir, { withFileTypes: true });
|
|
613
797
|
} catch (err) {
|
|
614
798
|
console.warn(
|
|
615
|
-
`[
|
|
799
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
616
800
|
);
|
|
617
801
|
return;
|
|
618
802
|
}
|
|
@@ -630,7 +814,7 @@ function findRouterFilesRecursive(dir, filter, results) {
|
|
|
630
814
|
if (filter && !filter(fullPath)) continue;
|
|
631
815
|
try {
|
|
632
816
|
const source = readFileSync3(fullPath, "utf-8");
|
|
633
|
-
if (ROUTER_CALL_PATTERN.test(source)) {
|
|
817
|
+
if (ROUTER_CALL_PATTERN.test(source) && firstCodeMatchIndex(source, ROUTER_CALL_PATTERN_G) >= 0) {
|
|
634
818
|
routerFilesInDir.push(fullPath);
|
|
635
819
|
}
|
|
636
820
|
} catch {
|
|
@@ -668,7 +852,7 @@ function findNestedRouterConflict(routerFiles) {
|
|
|
668
852
|
}
|
|
669
853
|
return null;
|
|
670
854
|
}
|
|
671
|
-
function formatNestedRouterConflictError(conflict, prefix = "[
|
|
855
|
+
function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
|
|
672
856
|
return `${prefix} Nested router roots are not supported.
|
|
673
857
|
Router root: ${conflict.ancestor}
|
|
674
858
|
Nested router: ${conflict.nested}
|
|
@@ -764,19 +948,38 @@ function extractBasenameFromRouter(code) {
|
|
|
764
948
|
visit(sourceFile);
|
|
765
949
|
return result;
|
|
766
950
|
}
|
|
767
|
-
function applyBasenameToRoutes(result,
|
|
951
|
+
function applyBasenameToRoutes(result, basename) {
|
|
768
952
|
const prefixed = {};
|
|
769
953
|
for (const [name, pattern] of Object.entries(result.routes)) {
|
|
770
954
|
if (pattern === "/") {
|
|
771
|
-
prefixed[name] =
|
|
772
|
-
} else if (
|
|
773
|
-
prefixed[name] =
|
|
955
|
+
prefixed[name] = basename;
|
|
956
|
+
} else if (basename.endsWith("/") && pattern.startsWith("/")) {
|
|
957
|
+
prefixed[name] = basename + pattern.slice(1);
|
|
774
958
|
} else {
|
|
775
|
-
prefixed[name] =
|
|
959
|
+
prefixed[name] = basename + pattern;
|
|
776
960
|
}
|
|
777
961
|
}
|
|
778
962
|
return { routes: prefixed, searchSchemas: result.searchSchemas };
|
|
779
963
|
}
|
|
964
|
+
function genFileTsPath(sourceFile) {
|
|
965
|
+
const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
966
|
+
return join2(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
|
|
967
|
+
}
|
|
968
|
+
function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
|
|
969
|
+
if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
|
|
970
|
+
return runtimeSchemas;
|
|
971
|
+
}
|
|
972
|
+
const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
|
|
973
|
+
if (Object.keys(staticParsed.searchSchemas).length === 0) {
|
|
974
|
+
return runtimeSchemas;
|
|
975
|
+
}
|
|
976
|
+
const filtered = {};
|
|
977
|
+
for (const name of publicRouteNames) {
|
|
978
|
+
const schema = staticParsed.searchSchemas[name];
|
|
979
|
+
if (schema) filtered[name] = schema;
|
|
980
|
+
}
|
|
981
|
+
return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
|
|
982
|
+
}
|
|
780
983
|
function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
781
984
|
let routerSource;
|
|
782
985
|
try {
|
|
@@ -789,7 +992,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
789
992
|
return { routes: {}, searchSchemas: {} };
|
|
790
993
|
}
|
|
791
994
|
const rawBasename = extractBasenameFromRouter(routerSource);
|
|
792
|
-
const
|
|
995
|
+
const basename = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
|
|
793
996
|
let result;
|
|
794
997
|
if (extraction.kind === "inline") {
|
|
795
998
|
result = buildCombinedRouteMapWithSearch(
|
|
@@ -814,8 +1017,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
814
1017
|
result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
|
|
815
1018
|
}
|
|
816
1019
|
}
|
|
817
|
-
if (
|
|
818
|
-
result = applyBasenameToRoutes(result,
|
|
1020
|
+
if (basename) {
|
|
1021
|
+
result = applyBasenameToRoutes(result, basename);
|
|
819
1022
|
}
|
|
820
1023
|
return result;
|
|
821
1024
|
}
|
|
@@ -897,7 +1100,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
897
1100
|
if (existsSync3(oldCombinedPath)) {
|
|
898
1101
|
unlinkSync(oldCombinedPath);
|
|
899
1102
|
console.log(
|
|
900
|
-
`[
|
|
1103
|
+
`[rango] Removed stale combined route types: ${oldCombinedPath}`
|
|
901
1104
|
);
|
|
902
1105
|
}
|
|
903
1106
|
} catch {
|
|
@@ -919,18 +1122,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
919
1122
|
}
|
|
920
1123
|
if (!extractUrlsFromRouter(routerSource)) continue;
|
|
921
1124
|
}
|
|
922
|
-
const
|
|
923
|
-
/\.(tsx?|jsx?)$/,
|
|
924
|
-
""
|
|
925
|
-
);
|
|
926
|
-
const outPath = join2(
|
|
927
|
-
dirname2(routerFilePath),
|
|
928
|
-
`${routerBasename}.named-routes.gen.ts`
|
|
929
|
-
);
|
|
1125
|
+
const outPath = genFileTsPath(routerFilePath);
|
|
930
1126
|
const existing = existsSync3(outPath) ? readFileSync3(outPath, "utf-8") : null;
|
|
931
1127
|
if (Object.keys(result.routes).length === 0) {
|
|
932
1128
|
if (!existing) {
|
|
933
1129
|
const emptySource = generateRouteTypesSource({});
|
|
1130
|
+
opts?.onWrite?.(outPath, emptySource);
|
|
934
1131
|
writeFileSync2(outPath, emptySource);
|
|
935
1132
|
}
|
|
936
1133
|
continue;
|
|
@@ -950,22 +1147,25 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
950
1147
|
continue;
|
|
951
1148
|
}
|
|
952
1149
|
}
|
|
1150
|
+
opts?.onWrite?.(outPath, source);
|
|
953
1151
|
writeFileSync2(outPath, source);
|
|
954
1152
|
console.log(
|
|
955
|
-
`[
|
|
1153
|
+
`[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
|
|
956
1154
|
);
|
|
957
1155
|
}
|
|
958
1156
|
}
|
|
959
1157
|
}
|
|
960
|
-
var ROUTER_CALL_PATTERN;
|
|
1158
|
+
var ROUTER_CALL_PATTERN, ROUTER_CALL_PATTERN_G;
|
|
961
1159
|
var init_router_processing = __esm({
|
|
962
1160
|
"src/build/route-types/router-processing.ts"() {
|
|
963
1161
|
"use strict";
|
|
964
1162
|
init_codegen();
|
|
1163
|
+
init_source_scan();
|
|
965
1164
|
init_include_resolution();
|
|
966
1165
|
init_per_module_writer();
|
|
967
1166
|
init_route_name();
|
|
968
1167
|
ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
|
|
1168
|
+
ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
|
|
969
1169
|
}
|
|
970
1170
|
});
|
|
971
1171
|
|
|
@@ -1003,7 +1203,7 @@ import {
|
|
|
1003
1203
|
import { createElement, StrictMode } from "react";
|
|
1004
1204
|
import { hydrateRoot } from "react-dom/client";
|
|
1005
1205
|
import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
|
|
1006
|
-
import { initBrowserApp,
|
|
1206
|
+
import { initBrowserApp, Rango } from "@rangojs/router/browser";
|
|
1007
1207
|
|
|
1008
1208
|
async function initializeApp() {
|
|
1009
1209
|
const deps = {
|
|
@@ -1014,11 +1214,16 @@ async function initializeApp() {
|
|
|
1014
1214
|
createTemporaryReferenceSet,
|
|
1015
1215
|
};
|
|
1016
1216
|
|
|
1017
|
-
|
|
1217
|
+
// initBrowserApp resolves the initial payload and returns the browser app
|
|
1218
|
+
// context, including strictMode (default true) from createRouter. StrictMode
|
|
1219
|
+
// is the default; createRouter({ strictMode: false }) ships the opt-out in the
|
|
1220
|
+
// payload metadata. StrictMode emits no DOM, so toggling never changes markup.
|
|
1221
|
+
const { strictMode } = await initBrowserApp({ rscStream, deps });
|
|
1018
1222
|
|
|
1223
|
+
const app = createElement(Rango);
|
|
1019
1224
|
hydrateRoot(
|
|
1020
1225
|
document,
|
|
1021
|
-
createElement(StrictMode, null,
|
|
1226
|
+
strictMode === false ? app : createElement(StrictMode, null, app)
|
|
1022
1227
|
);
|
|
1023
1228
|
}
|
|
1024
1229
|
|
|
@@ -1047,12 +1252,37 @@ export const renderHTML = createSSRHandler({
|
|
|
1047
1252
|
}
|
|
1048
1253
|
});
|
|
1049
1254
|
|
|
1255
|
+
// src/vite/utils/directive-prologue.ts
|
|
1256
|
+
import { parseAst } from "vite";
|
|
1257
|
+
function hasUseClientDirective(source) {
|
|
1258
|
+
let program;
|
|
1259
|
+
try {
|
|
1260
|
+
program = parseAst(source, { lang: "tsx" });
|
|
1261
|
+
} catch {
|
|
1262
|
+
return false;
|
|
1263
|
+
}
|
|
1264
|
+
for (const node of program.body ?? []) {
|
|
1265
|
+
if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
|
|
1266
|
+
if (node.expression.value === "use client") return true;
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
return false;
|
|
1272
|
+
}
|
|
1273
|
+
var init_directive_prologue = __esm({
|
|
1274
|
+
"src/vite/utils/directive-prologue.ts"() {
|
|
1275
|
+
"use strict";
|
|
1276
|
+
}
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1050
1279
|
// src/vite/plugins/version-plugin.ts
|
|
1051
1280
|
var version_plugin_exports = {};
|
|
1052
1281
|
__export(version_plugin_exports, {
|
|
1053
|
-
createVersionPlugin: () => createVersionPlugin
|
|
1282
|
+
createVersionPlugin: () => createVersionPlugin,
|
|
1283
|
+
isViteDepCachePath: () => isViteDepCachePath
|
|
1054
1284
|
});
|
|
1055
|
-
import { parseAst } from "vite";
|
|
1285
|
+
import { parseAst as parseAst2 } from "vite";
|
|
1056
1286
|
function isCodeModule(id) {
|
|
1057
1287
|
return /\.(tsx?|jsx?)($|\?)/.test(id);
|
|
1058
1288
|
}
|
|
@@ -1060,23 +1290,13 @@ function normalizeModuleId(id) {
|
|
|
1060
1290
|
return id.split("?", 1)[0];
|
|
1061
1291
|
}
|
|
1062
1292
|
function getClientModuleSignature(source) {
|
|
1293
|
+
if (!hasUseClientDirective(source)) return void 0;
|
|
1063
1294
|
let program;
|
|
1064
1295
|
try {
|
|
1065
|
-
program =
|
|
1296
|
+
program = parseAst2(source, { lang: "tsx" });
|
|
1066
1297
|
} catch {
|
|
1067
1298
|
return void 0;
|
|
1068
1299
|
}
|
|
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
1300
|
const exports = /* @__PURE__ */ new Set();
|
|
1081
1301
|
let hasDefault = false;
|
|
1082
1302
|
let hasExportAll = false;
|
|
@@ -1145,11 +1365,12 @@ function createVersionPlugin() {
|
|
|
1145
1365
|
let currentVersion = buildVersion;
|
|
1146
1366
|
let isDev = false;
|
|
1147
1367
|
let server = null;
|
|
1368
|
+
let resolvedCacheDir;
|
|
1148
1369
|
const clientModuleSignatures = /* @__PURE__ */ new Map();
|
|
1149
1370
|
let versionCounter = 0;
|
|
1150
1371
|
const bumpVersion = (reason) => {
|
|
1151
1372
|
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
1152
|
-
console.log(`[
|
|
1373
|
+
console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
|
|
1153
1374
|
const rscEnv = server?.environments?.rsc;
|
|
1154
1375
|
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
1155
1376
|
"\0" + VIRTUAL_IDS.version
|
|
@@ -1163,6 +1384,7 @@ function createVersionPlugin() {
|
|
|
1163
1384
|
enforce: "pre",
|
|
1164
1385
|
configResolved(config) {
|
|
1165
1386
|
isDev = config.command === "serve";
|
|
1387
|
+
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
1166
1388
|
},
|
|
1167
1389
|
configureServer(devServer) {
|
|
1168
1390
|
server = devServer;
|
|
@@ -1199,11 +1421,11 @@ function createVersionPlugin() {
|
|
|
1199
1421
|
}
|
|
1200
1422
|
return null;
|
|
1201
1423
|
},
|
|
1202
|
-
// Track RSC module changes and update version
|
|
1203
1424
|
async hotUpdate(ctx) {
|
|
1204
1425
|
if (!isDev) return;
|
|
1205
1426
|
const isRscModule = this.environment?.name === "rsc";
|
|
1206
1427
|
if (!isRscModule) return;
|
|
1428
|
+
if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
|
|
1207
1429
|
if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
|
|
1208
1430
|
return;
|
|
1209
1431
|
}
|
|
@@ -1233,10 +1455,22 @@ function createVersionPlugin() {
|
|
|
1233
1455
|
}
|
|
1234
1456
|
};
|
|
1235
1457
|
}
|
|
1458
|
+
function isViteDepCachePath(filePath, cacheDir) {
|
|
1459
|
+
if (!filePath) return false;
|
|
1460
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
1461
|
+
if (cacheDir) {
|
|
1462
|
+
const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1463
|
+
if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
|
|
1464
|
+
return true;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
|
|
1468
|
+
}
|
|
1236
1469
|
var init_version_plugin = __esm({
|
|
1237
1470
|
"src/vite/plugins/version-plugin.ts"() {
|
|
1238
1471
|
"use strict";
|
|
1239
1472
|
init_virtual_entries();
|
|
1473
|
+
init_directive_prologue();
|
|
1240
1474
|
}
|
|
1241
1475
|
});
|
|
1242
1476
|
|
|
@@ -1278,7 +1512,7 @@ var runtime_discovery_exports = {};
|
|
|
1278
1512
|
__export(runtime_discovery_exports, {
|
|
1279
1513
|
discoverAndWriteRouteTypes: () => discoverAndWriteRouteTypes
|
|
1280
1514
|
});
|
|
1281
|
-
import {
|
|
1515
|
+
import { resolve as resolve3 } from "node:path";
|
|
1282
1516
|
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
1283
1517
|
async function discoverAndWriteRouteTypes(opts) {
|
|
1284
1518
|
let createViteServer;
|
|
@@ -1388,22 +1622,12 @@ This means createRouter() stack trace parsing matched an internal frame.
|
|
|
1388
1622
|
Set an explicit \`id\` on createRouter() or check the call site.`
|
|
1389
1623
|
);
|
|
1390
1624
|
}
|
|
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`);
|
|
1625
|
+
routeSearchSchemas = resolveSearchSchemas(
|
|
1626
|
+
Object.keys(routeManifest),
|
|
1627
|
+
routeSearchSchemas,
|
|
1628
|
+
sourceFile
|
|
1629
|
+
);
|
|
1630
|
+
const outPath = genFileTsPath(sourceFile);
|
|
1407
1631
|
const source = generateRouteTypesSource(
|
|
1408
1632
|
routeManifest,
|
|
1409
1633
|
routeSearchSchemas && Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : void 0
|
|
@@ -1440,7 +1664,7 @@ var init_runtime_discovery = __esm({
|
|
|
1440
1664
|
|
|
1441
1665
|
// src/bin/rango.ts
|
|
1442
1666
|
init_generate_route_types();
|
|
1443
|
-
import { resolve as resolve4, dirname as
|
|
1667
|
+
import { resolve as resolve4, dirname as dirname3 } from "node:path";
|
|
1444
1668
|
import { readFileSync as readFileSync5, statSync, existsSync as existsSync5 } from "node:fs";
|
|
1445
1669
|
var [command, ...rawArgs] = process.argv.slice(2);
|
|
1446
1670
|
if (command === "generate") {
|
|
@@ -1511,12 +1735,12 @@ Examples:
|
|
|
1511
1735
|
);
|
|
1512
1736
|
}
|
|
1513
1737
|
function findProjectRoot(fromPath) {
|
|
1514
|
-
let dir =
|
|
1515
|
-
while (dir !==
|
|
1738
|
+
let dir = dirname3(resolve4(fromPath));
|
|
1739
|
+
while (dir !== dirname3(dir)) {
|
|
1516
1740
|
if (existsSync5(resolve4(dir, "package.json")) || existsSync5(resolve4(dir, "vite.config.ts")) || existsSync5(resolve4(dir, "vite.config.js"))) {
|
|
1517
1741
|
return dir;
|
|
1518
1742
|
}
|
|
1519
|
-
dir =
|
|
1743
|
+
dir = dirname3(dir);
|
|
1520
1744
|
}
|
|
1521
1745
|
return process.cwd();
|
|
1522
1746
|
}
|