@rangojs/router 0.0.0-experimental.a769fbe7 → 0.0.0-experimental.ac99d918
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/README.md +211 -43
- package/dist/bin/rango.js +279 -102
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3313 -1160
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +62 -11
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +63 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +222 -30
- package/skills/caching/SKILL.md +263 -8
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +250 -30
- package/skills/host-router/SKILL.md +124 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +223 -9
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +77 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +66 -5
- package/skills/router-setup/SKILL.md +38 -3
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -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 +121 -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 +120 -0
- package/skills/typesafety/SKILL.md +319 -27
- package/skills/use-cache/SKILL.md +36 -5
- package/skills/vercel/SKILL.md +107 -0
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +1 -66
- 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/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +81 -147
- 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 +66 -14
- package/src/browser/navigation-client.ts +172 -109
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/partial-update.ts +79 -93
- package/src/browser/prefetch/cache.ts +180 -62
- package/src/browser/prefetch/fetch.ts +252 -39
- package/src/browser/prefetch/queue.ts +42 -8
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +72 -10
- package/src/browser/react/NavigationProvider.tsx +83 -31
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -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 +23 -69
- package/src/browser/react/use-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- 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 +46 -11
- 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 +52 -1
- package/src/browser/rsc-router.tsx +111 -24
- package/src/browser/scroll-restoration.ts +29 -19
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -62
- package/src/browser/types.ts +60 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +6 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +333 -94
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +134 -32
- package/src/cache/cache-scope.ts +100 -74
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2256 -241
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +61 -20
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +22 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +17 -5
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/browser.ts +0 -1
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- 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 +69 -10
- package/src/index.ts +112 -14
- package/src/internal-debug.ts +2 -4
- 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/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +413 -275
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +107 -32
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +50 -8
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +0 -16
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +44 -23
- package/src/router/handler-context.ts +46 -30
- package/src/router/intercept-resolution.ts +23 -23
- package/src/router/lazy-includes.ts +15 -52
- package/src/router/loader-resolution.ts +207 -30
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +40 -42
- package/src/router/match-api.ts +120 -204
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +0 -7
- package/src/router/match-middleware/cache-lookup.ts +161 -262
- package/src/router/match-middleware/cache-store.ts +3 -33
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +45 -14
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +87 -39
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -140
- package/src/router/middleware.ts +169 -140
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +190 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +0 -27
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +119 -65
- package/src/router/segment-resolution/helpers.ts +34 -0
- package/src/router/segment-resolution/loader-cache.ts +40 -37
- package/src/router/segment-resolution/revalidation.ts +329 -305
- 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 +36 -0
- package/src/router/segment-resolution.ts +4 -1
- package/src/router/segment-wrappers.ts +0 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +128 -42
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -409
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +18 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +28 -4
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +53 -56
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -69
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +22 -9
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +208 -201
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +211 -52
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +289 -124
- package/src/ssr/index.tsx +22 -15
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -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 +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -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 +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -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 +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +124 -70
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +40 -11
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +12 -7
- package/src/types/segments.ts +36 -15
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -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 +192 -99
- 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 +51 -4
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +236 -6
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- 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 +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -317
- package/src/vite/plugins/performance-tracks.ts +65 -207
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +32 -23
- package/src/vite/plugins/virtual-entries.ts +46 -17
- package/src/vite/rango.ts +207 -125
- package/src/vite/router-discovery.ts +931 -133
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- 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/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 +27 -29
- package/src/vite/utils/shared-utils.ts +97 -44
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/debug-channel.ts +0 -93
- 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/router/middleware-cookies.ts +0 -55
|
@@ -7,47 +7,24 @@ export type DocumentProps = {
|
|
|
7
7
|
children: ReactNode;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
* Parse constraint values into a union type
|
|
12
|
-
* "a|b|c" -> "a" | "b" | "c"
|
|
13
|
-
*/
|
|
14
10
|
type ParseConstraint<T extends string> =
|
|
15
11
|
T extends `${infer First}|${infer Rest}` ? First | ParseConstraint<Rest> : T;
|
|
16
12
|
|
|
17
|
-
/**
|
|
18
|
-
* Extract param info from a param segment
|
|
19
|
-
*
|
|
20
|
-
* Handles:
|
|
21
|
-
* - :param -> { name: "param", optional: false, type: string }
|
|
22
|
-
* - :param? -> { name: "param", optional: true, type: string }
|
|
23
|
-
* - :param(a|b) -> { name: "param", optional: false, type: "a" | "b" }
|
|
24
|
-
* - :param(a|b)? -> { name: "param", optional: true, type: "a" | "b" }
|
|
25
|
-
*/
|
|
26
13
|
type ExtractParamInfo<T extends string> =
|
|
27
|
-
// Optional + constrained (with optional suffix): :param(a|b)?suffix
|
|
28
14
|
T extends `${infer Name}(${infer Constraint})?${string}`
|
|
29
15
|
? { name: Name; optional: true; type: ParseConstraint<Constraint> }
|
|
30
|
-
:
|
|
31
|
-
T extends `${infer Name}(${infer Constraint})${string}`
|
|
16
|
+
: T extends `${infer Name}(${infer Constraint})${string}`
|
|
32
17
|
? { name: Name; optional: false; type: ParseConstraint<Constraint> }
|
|
33
|
-
:
|
|
34
|
-
T extends `${infer Name}?${string}`
|
|
18
|
+
: T extends `${infer Name}?${string}`
|
|
35
19
|
? { name: Name; optional: true; type: string }
|
|
36
|
-
:
|
|
37
|
-
T extends `${infer Name}.${string}`
|
|
20
|
+
: T extends `${infer Name}.${string}`
|
|
38
21
|
? { name: Name; optional: false; type: string }
|
|
39
|
-
:
|
|
40
|
-
T extends `${infer Name}-${string}`
|
|
22
|
+
: T extends `${infer Name}-${string}`
|
|
41
23
|
? { name: Name; optional: false; type: string }
|
|
42
|
-
:
|
|
43
|
-
T extends `${infer Name}~${string}`
|
|
24
|
+
: T extends `${infer Name}~${string}`
|
|
44
25
|
? { name: Name; optional: false; type: string }
|
|
45
|
-
:
|
|
46
|
-
{ name: T; optional: false; type: string };
|
|
26
|
+
: { name: T; optional: false; type: string };
|
|
47
27
|
|
|
48
|
-
/**
|
|
49
|
-
* Build param object from info
|
|
50
|
-
*/
|
|
51
28
|
type ParamFromInfo<Info> = Info extends {
|
|
52
29
|
name: infer N extends string;
|
|
53
30
|
optional: true;
|
|
@@ -62,10 +39,6 @@ type ParamFromInfo<Info> = Info extends {
|
|
|
62
39
|
? { [K in N]: V }
|
|
63
40
|
: never;
|
|
64
41
|
|
|
65
|
-
/**
|
|
66
|
-
* Merge two param objects preserving optionality
|
|
67
|
-
* Uses Pick to preserve the modifiers from source types
|
|
68
|
-
*/
|
|
69
42
|
type MergeParams<A, B> = Pick<A, keyof A> & Pick<B, keyof B> extends infer O
|
|
70
43
|
? { [K in keyof O]: O[K] }
|
|
71
44
|
: never;
|
|
@@ -109,17 +82,11 @@ export type ExtractParams<
|
|
|
109
82
|
*/
|
|
110
83
|
export type TrailingSlashMode = "never" | "always" | "ignore";
|
|
111
84
|
|
|
112
|
-
/**
|
|
113
|
-
* Route configuration object (alternative to string path)
|
|
114
|
-
*/
|
|
115
85
|
export type RouteConfig = {
|
|
116
86
|
path: string;
|
|
117
87
|
trailingSlash?: TrailingSlashMode;
|
|
118
88
|
};
|
|
119
89
|
|
|
120
|
-
/**
|
|
121
|
-
* Route definition options (global defaults)
|
|
122
|
-
*/
|
|
123
90
|
export type RouteDefinitionOptions = {
|
|
124
91
|
trailingSlash?: TrailingSlashMode;
|
|
125
92
|
};
|
|
@@ -128,11 +95,6 @@ export type RouteDefinition = {
|
|
|
128
95
|
[key: string]: string | RouteConfig | RouteDefinition;
|
|
129
96
|
};
|
|
130
97
|
|
|
131
|
-
/**
|
|
132
|
-
* Recursively flatten nested routes with depth limit to prevent infinite recursion
|
|
133
|
-
* Transforms: { products: { detail: "/product/:slug" } } => { "products.detail": "/product/:slug" }
|
|
134
|
-
* Also handles RouteConfig objects: { api: { path: "/api" } } => { "api": "/api" }
|
|
135
|
-
*/
|
|
136
98
|
type FlattenRoutes<
|
|
137
99
|
T extends RouteDefinition,
|
|
138
100
|
Prefix extends string = "",
|
|
@@ -153,18 +115,12 @@ type FlattenRoutes<
|
|
|
153
115
|
: never;
|
|
154
116
|
}[keyof T];
|
|
155
117
|
|
|
156
|
-
/**
|
|
157
|
-
* Union to intersection helper
|
|
158
|
-
*/
|
|
159
118
|
type UnionToIntersection<U> = (
|
|
160
119
|
U extends unknown ? (k: U) => void : never
|
|
161
120
|
) extends (k: infer I) => void
|
|
162
121
|
? I
|
|
163
122
|
: never;
|
|
164
123
|
|
|
165
|
-
/**
|
|
166
|
-
* Resolved route map - flattened route definitions with full paths
|
|
167
|
-
*/
|
|
168
124
|
export type ResolvedRouteMap<T extends RouteDefinition> = UnionToIntersection<
|
|
169
125
|
FlattenRoutes<T>
|
|
170
126
|
>;
|
package/src/types/route-entry.ts
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
import type { AllUseItems } from "../route-types.js";
|
|
2
2
|
import type { TrailingSlashMode, ResolvedRouteMap } from "./route-config.js";
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Context captured for lazy include evaluation
|
|
6
|
-
*/
|
|
7
4
|
export interface LazyIncludeContext {
|
|
8
5
|
urlPrefix: string;
|
|
9
6
|
namePrefix: string | undefined;
|
|
10
7
|
parent: unknown; // EntryData - avoid circular import
|
|
8
|
+
/** Counter snapshot from pattern extraction for consistent shortCode indices */
|
|
9
|
+
counters?: Record<string, number>;
|
|
11
10
|
cacheProfiles?: Record<
|
|
12
11
|
string,
|
|
13
12
|
import("../cache/profile-registry.js").CacheProfile
|
|
14
13
|
>;
|
|
14
|
+
/** Root scope flag for dot-local reverse resolution */
|
|
15
|
+
rootScoped?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Positional include scope token composed from the parent scope plus this
|
|
18
|
+
* include's sibling index (`${parentScope}I${idx}`). Applied to direct-
|
|
19
|
+
* descendant shortCodes during lazy evaluation so routes inside the
|
|
20
|
+
* include cannot collide with siblings declared outside it.
|
|
21
|
+
*/
|
|
22
|
+
includeScope?: string;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
|
-
/**
|
|
18
|
-
* Internal route entry stored in router
|
|
19
|
-
*/
|
|
20
25
|
export interface RouteEntry<TEnv = any> {
|
|
21
26
|
prefix: string;
|
|
22
27
|
/**
|
|
@@ -69,7 +74,7 @@ export interface RouteEntry<TEnv = any> {
|
|
|
69
74
|
prerenderRouteKeys?: Set<string>;
|
|
70
75
|
|
|
71
76
|
/**
|
|
72
|
-
* Route keys in this entry that
|
|
77
|
+
* Route keys in this entry that are wrapped with `Passthrough()`.
|
|
73
78
|
* Used by the non-trie match path to set the `pt` flag.
|
|
74
79
|
*/
|
|
75
80
|
passthroughRouteKeys?: Set<string>;
|
package/src/types/segments.ts
CHANGED
|
@@ -10,7 +10,10 @@ export type ViewTransitionClass = Record<string, string> | string;
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Configuration for React's <ViewTransition> component.
|
|
13
|
-
*
|
|
13
|
+
*
|
|
14
|
+
* The phase fields (enter/exit/update/share/default/name) map directly to
|
|
15
|
+
* ViewTransitionProps (minus children/ref/callbacks). The `viewTransition`
|
|
16
|
+
* field is router-specific and is stripped before the config reaches React.
|
|
14
17
|
*/
|
|
15
18
|
export interface TransitionConfig {
|
|
16
19
|
enter?: ViewTransitionClass;
|
|
@@ -19,19 +22,25 @@ export interface TransitionConfig {
|
|
|
19
22
|
share?: ViewTransitionClass;
|
|
20
23
|
default?: ViewTransitionClass;
|
|
21
24
|
name?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the router wraps this segment's content in its own
|
|
27
|
+
* <ViewTransition> boundary.
|
|
28
|
+
*
|
|
29
|
+
* - "auto" (default): the router places the boundary, producing the
|
|
30
|
+
* router-owned cross-fade described by the phase fields above.
|
|
31
|
+
* - false: the router places no boundary. The navigation commit is still
|
|
32
|
+
* driven through startTransition (so loaders hold instead of flashing a
|
|
33
|
+
* skeleton, and consumer-placed <ViewTransition> elements still animate),
|
|
34
|
+
* but the router contributes no cross-fade of its own.
|
|
35
|
+
*
|
|
36
|
+
* When unset, inherits the createRouter({ viewTransition }) default.
|
|
37
|
+
*/
|
|
38
|
+
viewTransition?: "auto" | false;
|
|
22
39
|
}
|
|
23
40
|
|
|
24
41
|
/**
|
|
25
42
|
* Resolved segment with component
|
|
26
43
|
*
|
|
27
|
-
* Segment types:
|
|
28
|
-
* - layout: Wraps child content via <Outlet />
|
|
29
|
-
* - route: The leaf content for a URL
|
|
30
|
-
* - parallel: Named slots rendered via <ParallelOutlet name="@slot" />
|
|
31
|
-
* - loader: Data segment (no visual rendering, carries loaderData)
|
|
32
|
-
* - error: Error fallback segment (replaces failed segment with error UI)
|
|
33
|
-
* - notFound: Not found fallback segment (replaces segment when data not found)
|
|
34
|
-
*
|
|
35
44
|
* @internal This type is an implementation detail and may change without notice.
|
|
36
45
|
*/
|
|
37
46
|
export interface ResolvedSegment {
|
|
@@ -50,25 +59,28 @@ export interface ResolvedSegment {
|
|
|
50
59
|
parallelName?: string; // For parallels: the parallel group name (used to match with revalidations)
|
|
51
60
|
// Loader-specific fields
|
|
52
61
|
loaderId?: string; // For loaders: the loader $$id identifier
|
|
62
|
+
_inherited?: boolean; // For inherited loaders: dedup marker for buildMatchResult
|
|
53
63
|
loaderData?: any; // For loaders: the resolved data from loader execution
|
|
54
64
|
parallelLoading?: ReactNode; // For parallel-owned loaders: the parallel's loading fallback
|
|
55
65
|
// Intercept loader fields (for streaming loader data in parallel segments)
|
|
56
66
|
loaderDataPromise?: Promise<any[]> | any[]; // Loader data promise or resolved array
|
|
57
67
|
loaderIds?: string[]; // IDs ($$id) of loaders for this segment
|
|
58
|
-
parallelLoaderSources?: any[]; // Internal: preserves stable aggregate promise across renders
|
|
59
68
|
// Error-specific fields
|
|
60
69
|
error?: ErrorInfo; // For error segments: the error information
|
|
61
70
|
// NotFound-specific fields
|
|
62
71
|
notFoundInfo?: NotFoundInfo; // For notFound segments: the not found information
|
|
63
72
|
// Mount path from include() scope, used for MountContext.Provider wrapping
|
|
64
73
|
mountPath?: string;
|
|
74
|
+
/**
|
|
75
|
+
* @internal Server-side marker: true when the segment's handler actually ran
|
|
76
|
+
* this request (not skipped via the revalidate cache path). Used by
|
|
77
|
+
* match-result.ts to populate `MatchResult.resolvedIds` for client-side
|
|
78
|
+
* handle-bucket cleanup. Stripped from the wire payload before serialization
|
|
79
|
+
* — never reaches the client.
|
|
80
|
+
*/
|
|
81
|
+
_handlerRan?: boolean;
|
|
65
82
|
}
|
|
66
83
|
|
|
67
|
-
/**
|
|
68
|
-
* Segment metadata (without component)
|
|
69
|
-
*
|
|
70
|
-
* @internal This type is an implementation detail and may change without notice.
|
|
71
|
-
*/
|
|
72
84
|
export interface SegmentMetadata {
|
|
73
85
|
id: string;
|
|
74
86
|
type: "layout" | "route" | "parallel" | "loader" | "error" | "notFound";
|
|
@@ -116,6 +128,15 @@ export interface MatchResult {
|
|
|
116
128
|
segments: ResolvedSegment[];
|
|
117
129
|
matched: string[];
|
|
118
130
|
diff: string[];
|
|
131
|
+
/**
|
|
132
|
+
* Every segment id whose handler actually ran on the server this request,
|
|
133
|
+
* including ones with `component === null` that get filtered out of
|
|
134
|
+
* `segments`/`diff` to avoid wasted bytes. Drives the client's handle-
|
|
135
|
+
* cleanup pass — a slot that re-resolves and pushes nothing must clear
|
|
136
|
+
* its previous handle bucket, but `diff` doesn't carry it because the
|
|
137
|
+
* segment payload doesn't either. A superset of `diff`.
|
|
138
|
+
*/
|
|
139
|
+
resolvedIds: string[];
|
|
119
140
|
/**
|
|
120
141
|
* Merged route params from all matched segments
|
|
121
142
|
* Available for use by the handler after route matching
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { AllUseItems, IncludeItem } from "../route-types.js";
|
|
2
2
|
import {
|
|
3
|
-
getContext,
|
|
4
|
-
runWithPrefixes,
|
|
5
3
|
getUrlPrefix,
|
|
6
4
|
getNamePrefix,
|
|
7
|
-
|
|
5
|
+
requireDslContext,
|
|
8
6
|
} from "../server/context";
|
|
9
7
|
import {
|
|
10
8
|
INTERNAL_INCLUDE_SCOPE_PREFIX,
|
|
@@ -27,28 +25,10 @@ function allocateInternalIncludeScopeId(
|
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
/**
|
|
30
|
-
*
|
|
31
|
-
* This expands the include into actual route registrations
|
|
32
|
-
*/
|
|
33
|
-
function processIncludeItem(item: IncludeItem): AllUseItems[] {
|
|
34
|
-
const { prefix, patterns } = item;
|
|
35
|
-
const namePrefix =
|
|
36
|
-
(item as IncludeItem & { _lazyContext?: { namePrefix?: string } })
|
|
37
|
-
._lazyContext?.namePrefix ?? item.options?.name;
|
|
38
|
-
|
|
39
|
-
// Execute the nested patterns' handler with URL and name prefixes
|
|
40
|
-
// The urlPrefix being set tells nested urls() to skip RootLayout wrapping
|
|
41
|
-
return runWithPrefixes(prefix, namePrefix, () => {
|
|
42
|
-
// Call the nested patterns' handler - this registers routes with prefixed patterns/names
|
|
43
|
-
return (patterns as UrlPatterns).handler();
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Recursively process items, expanding any IncludeItems
|
|
49
|
-
* Returns items with IncludeItems expanded into actual route items
|
|
28
|
+
* Recursively walk items, recursing into layout children.
|
|
50
29
|
*
|
|
51
|
-
*
|
|
30
|
+
* All includes are lazy and kept as-is; the router expands them on the first
|
|
31
|
+
* matching request.
|
|
52
32
|
*/
|
|
53
33
|
export function processItems(items: readonly AllUseItems[]): AllUseItems[] {
|
|
54
34
|
const result: AllUseItems[] = [];
|
|
@@ -57,28 +37,8 @@ export function processItems(items: readonly AllUseItems[]): AllUseItems[] {
|
|
|
57
37
|
if (!item) continue;
|
|
58
38
|
|
|
59
39
|
if (item.type === "include") {
|
|
60
|
-
|
|
61
|
-
_expanded?: AllUseItems[];
|
|
62
|
-
lazy?: boolean;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// Lazy includes are NOT expanded here - kept for router to handle
|
|
66
|
-
if (includeItem.lazy) {
|
|
67
|
-
result.push(item);
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Eager includes are already expanded during include() call
|
|
72
|
-
if (includeItem._expanded) {
|
|
73
|
-
// Items were expanded immediately - just process them recursively
|
|
74
|
-
result.push(...processItems(includeItem._expanded));
|
|
75
|
-
} else {
|
|
76
|
-
// Fallback for legacy include items without _expanded
|
|
77
|
-
const expanded = processIncludeItem(item as IncludeItem);
|
|
78
|
-
result.push(...processItems(expanded));
|
|
79
|
-
}
|
|
40
|
+
result.push(item);
|
|
80
41
|
} else if (item.type === "layout" && (item as any).uses) {
|
|
81
|
-
// Process nested items in layout
|
|
82
42
|
const layoutItem = item as any;
|
|
83
43
|
layoutItem.uses = processItems(layoutItem.uses);
|
|
84
44
|
result.push(layoutItem);
|
|
@@ -93,13 +53,9 @@ export function processItems(items: readonly AllUseItems[]): AllUseItems[] {
|
|
|
93
53
|
/**
|
|
94
54
|
* Create include() helper for composing URL patterns
|
|
95
55
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* With `lazy: true`, patterns are NOT expanded at definition time. Instead,
|
|
101
|
-
* they're evaluated on first request that matches the prefix. This improves
|
|
102
|
-
* cold start time for apps with many routes.
|
|
56
|
+
* All includes are lazy: the nested patterns are NOT expanded at definition
|
|
57
|
+
* time. Instead they are evaluated on the first request that matches the
|
|
58
|
+
* prefix, which improves cold start time for apps with many routes.
|
|
103
59
|
*/
|
|
104
60
|
export function createIncludeHelper<TEnv>(): IncludeFn<TEnv> {
|
|
105
61
|
return (
|
|
@@ -107,9 +63,7 @@ export function createIncludeHelper<TEnv>(): IncludeFn<TEnv> {
|
|
|
107
63
|
patterns: UrlPatterns<TEnv>,
|
|
108
64
|
options?: IncludeOptions,
|
|
109
65
|
): IncludeItem => {
|
|
110
|
-
const
|
|
111
|
-
const ctx = store.getStore();
|
|
112
|
-
if (!ctx) throw new Error("include() must be called inside urls()");
|
|
66
|
+
const { ctx } = requireDslContext("include() must be called inside urls()");
|
|
113
67
|
|
|
114
68
|
const explicitName = options?.name;
|
|
115
69
|
const hasExplicitName = hasExplicitNameOption(options);
|
|
@@ -149,22 +103,32 @@ export function createIncludeHelper<TEnv>(): IncludeFn<TEnv> {
|
|
|
149
103
|
});
|
|
150
104
|
}
|
|
151
105
|
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
// and
|
|
161
|
-
|
|
106
|
+
// Allocate an include-scope token for this include() call. The token is
|
|
107
|
+
// appended to the parent's shortCode prefix whenever the include's
|
|
108
|
+
// direct-descendant shortCodes are generated (see getShortCode in
|
|
109
|
+
// context.ts), partitioning the parent's counter namespace so routes
|
|
110
|
+
// inside an include cannot collide with siblings declared outside it.
|
|
111
|
+
//
|
|
112
|
+
// Scopes compose: a nested include inside an outer include with scope
|
|
113
|
+
// "I0" allocates against the `${parent.shortCode}I0_include` counter
|
|
114
|
+
// and produces scope "I0I0", "I0I1", etc.
|
|
115
|
+
const parentScope = ctx.includeScope ?? "";
|
|
116
|
+
let includeScope = parentScope;
|
|
162
117
|
if (capturedParent?.shortCode) {
|
|
163
|
-
const
|
|
164
|
-
ctx.counters[
|
|
165
|
-
ctx.counters[
|
|
118
|
+
const includeCounterKey = `${capturedParent.shortCode}${parentScope}_include`;
|
|
119
|
+
ctx.counters[includeCounterKey] ??= 0;
|
|
120
|
+
const includeIdx = ctx.counters[includeCounterKey];
|
|
121
|
+
ctx.counters[includeCounterKey] = includeIdx + 1;
|
|
122
|
+
includeScope = `${parentScope}I${includeIdx}`;
|
|
166
123
|
}
|
|
167
124
|
|
|
125
|
+
// Snapshot parent's counters AFTER allocating the include scope so lazy
|
|
126
|
+
// manifest generation starts with the same counter state this include
|
|
127
|
+
// observed — its descendants still get fresh per-scope counters because
|
|
128
|
+
// they key off `${parent.shortCode}${includeScope}_*` (not shared with
|
|
129
|
+
// siblings outside the include).
|
|
130
|
+
const capturedCounters = { ...ctx.counters };
|
|
131
|
+
|
|
168
132
|
// Compute rootScoped at capture time, mirroring the logic in runWithPrefixes.
|
|
169
133
|
// This ensures lazy evaluation restores the correct scope state.
|
|
170
134
|
const parentRootScoped = ctx.rootScoped;
|
|
@@ -175,8 +139,6 @@ export function createIncludeHelper<TEnv>(): IncludeFn<TEnv> {
|
|
|
175
139
|
? (parentRootScoped ?? false)
|
|
176
140
|
: parentRootScoped;
|
|
177
141
|
|
|
178
|
-
// All includes are lazy - patterns are evaluated on first matching request
|
|
179
|
-
// This improves cold start time significantly for large route sets
|
|
180
142
|
return {
|
|
181
143
|
type: "include",
|
|
182
144
|
name,
|
|
@@ -191,6 +153,7 @@ export function createIncludeHelper<TEnv>(): IncludeFn<TEnv> {
|
|
|
191
153
|
counters: capturedCounters,
|
|
192
154
|
cacheProfiles: ctx.cacheProfiles,
|
|
193
155
|
rootScoped: capturedRootScoped,
|
|
156
|
+
includeScope,
|
|
194
157
|
},
|
|
195
158
|
} as IncludeItem;
|
|
196
159
|
};
|
package/src/urls/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// Response types and symbols
|
|
2
1
|
export {
|
|
3
2
|
RESPONSE_TYPE,
|
|
4
3
|
type ResponseHandler,
|
|
@@ -8,28 +7,21 @@ export {
|
|
|
8
7
|
type ResponseHandlerContext,
|
|
9
8
|
} from "./response-types.js";
|
|
10
9
|
|
|
11
|
-
// Pattern types
|
|
12
10
|
export type {
|
|
13
11
|
UnnamedRoute,
|
|
14
12
|
LocalOnlyInclude,
|
|
15
13
|
PathOptions,
|
|
16
|
-
PathDefinition,
|
|
17
14
|
UrlPatterns,
|
|
18
15
|
IncludeOptions,
|
|
19
16
|
} from "./pattern-types.js";
|
|
20
17
|
|
|
21
|
-
// Type extraction utilities
|
|
22
18
|
export type {
|
|
23
19
|
ExtractRoutes,
|
|
24
20
|
ExtractResponses,
|
|
25
|
-
|
|
26
|
-
ExtractPathParams,
|
|
27
|
-
ResponseError,
|
|
28
|
-
ResponseEnvelope,
|
|
21
|
+
ProblemDetails,
|
|
29
22
|
RouteResponse,
|
|
30
23
|
} from "./type-extraction.js";
|
|
31
24
|
|
|
32
|
-
// Path helper types
|
|
33
25
|
export type {
|
|
34
26
|
PathFn,
|
|
35
27
|
ResponsePathFn,
|
|
@@ -39,10 +31,8 @@ export type {
|
|
|
39
31
|
PathHelpers,
|
|
40
32
|
} from "./path-helper-types.js";
|
|
41
33
|
|
|
42
|
-
// Main entry point
|
|
43
34
|
export { urls } from "./urls-function.js";
|
|
44
35
|
|
|
45
|
-
// Re-exports from route-types
|
|
46
36
|
export type {
|
|
47
37
|
AllUseItems,
|
|
48
38
|
IncludeItem,
|
|
@@ -37,7 +37,10 @@ import type {
|
|
|
37
37
|
UseItems,
|
|
38
38
|
} from "../route-types.js";
|
|
39
39
|
import type { SearchSchema } from "../search-params.js";
|
|
40
|
-
import type {
|
|
40
|
+
import type {
|
|
41
|
+
PrerenderHandlerDefinition,
|
|
42
|
+
PassthroughHandlerDefinition,
|
|
43
|
+
} from "../prerender.js";
|
|
41
44
|
import type { StaticHandlerDefinition } from "../static-handler.js";
|
|
42
45
|
import type { InterceptWhenFn } from "../server/context";
|
|
43
46
|
import type {
|
|
@@ -70,6 +73,7 @@ export type PathFn<TEnv> = <
|
|
|
70
73
|
ctx: HandlerContext<TParams, TEnv, TSearch>,
|
|
71
74
|
) => ReactNode | Promise<ReactNode> | Response | Promise<Response>)
|
|
72
75
|
| PrerenderHandlerDefinition<TParams>
|
|
76
|
+
| PassthroughHandlerDefinition<TParams, TEnv>
|
|
73
77
|
| StaticHandlerDefinition<TParams>,
|
|
74
78
|
optionsOrUse?: PathOptions<TName, TSearch> | (() => UseItems<RouteUseItem>),
|
|
75
79
|
use?: () => UseItems<RouteUseItem>,
|
|
@@ -110,6 +114,12 @@ export type ResponsePathFn<TEnv> = <
|
|
|
110
114
|
* Path function for JSON response routes (path.json()).
|
|
111
115
|
* Handler can return plain JSON-serializable values or Response.
|
|
112
116
|
* TData is inferred from the handler's return type (excluding Response/Promise wrappers).
|
|
117
|
+
*
|
|
118
|
+
* Note: a nested Promise in the return (a forgotten await) is caught at runtime
|
|
119
|
+
* by response-route-handler.ts (it throws instead of silently emitting `{}`). A
|
|
120
|
+
* compile-time JsonValue constraint was evaluated and rejected — it breaks
|
|
121
|
+
* interface-typed returns (interfaces lack the index signature JsonValue
|
|
122
|
+
* requires) and preserves literal types in the inferred response shape.
|
|
113
123
|
*/
|
|
114
124
|
export type JsonResponsePathFn<TEnv> = <
|
|
115
125
|
const TPattern extends string,
|
|
@@ -229,12 +239,27 @@ export type PathHelpers<TEnv> = {
|
|
|
229
239
|
include: IncludeFn<TEnv>;
|
|
230
240
|
|
|
231
241
|
/**
|
|
232
|
-
* Define parallel routes that render simultaneously in named slots
|
|
242
|
+
* Define parallel routes that render simultaneously in named slots.
|
|
243
|
+
*
|
|
244
|
+
* A slot value can be a Handler / ReactNode / StaticHandlerDefinition
|
|
245
|
+
* (legacy form, broadcast use applies to every slot) or a slot descriptor
|
|
246
|
+
* `{ handler, use? }` whose `use` is scoped to that slot only. Per-slot
|
|
247
|
+
* merge order is `handler.use` → shared `use` → slot-local `use`, with
|
|
248
|
+
* narrowest scope winning for last-write-wins items like `loading()`.
|
|
233
249
|
*/
|
|
234
250
|
parallel: <
|
|
235
251
|
TSlots extends Record<
|
|
236
252
|
`@${string}`,
|
|
237
|
-
Handler<any, any, TEnv>
|
|
253
|
+
| Handler<any, any, TEnv>
|
|
254
|
+
| ReactNode
|
|
255
|
+
| StaticHandlerDefinition
|
|
256
|
+
| {
|
|
257
|
+
handler:
|
|
258
|
+
| Handler<any, any, TEnv>
|
|
259
|
+
| ReactNode
|
|
260
|
+
| StaticHandlerDefinition;
|
|
261
|
+
use?: () => ParallelUseItem[];
|
|
262
|
+
}
|
|
238
263
|
>,
|
|
239
264
|
>(
|
|
240
265
|
slots: TSlots,
|
|
@@ -245,7 +270,7 @@ export type PathHelpers<TEnv> = {
|
|
|
245
270
|
* Define an intercepting route for soft navigation
|
|
246
271
|
* Note: routeName must match a named path() in this urlpatterns
|
|
247
272
|
*/
|
|
248
|
-
intercept: keyof
|
|
273
|
+
intercept: keyof Rango.GeneratedRouteMap extends never
|
|
249
274
|
? (
|
|
250
275
|
slotName: `@${string}`,
|
|
251
276
|
routeName: string,
|
|
@@ -254,15 +279,26 @@ export type PathHelpers<TEnv> = {
|
|
|
254
279
|
) => InterceptItem
|
|
255
280
|
: (
|
|
256
281
|
slotName: `@${string}`,
|
|
257
|
-
routeName: (keyof
|
|
282
|
+
routeName: (keyof Rango.GeneratedRouteMap & string) | `.${string}`,
|
|
258
283
|
handler: ReactNode | Handler<any, any, TEnv>,
|
|
259
284
|
use?: () => InterceptUseItem[],
|
|
260
285
|
) => InterceptItem;
|
|
261
286
|
|
|
262
287
|
/**
|
|
263
|
-
* Attach middleware to the current route/layout
|
|
288
|
+
* Attach middleware to the current route/layout, or wrap child segments
|
|
264
289
|
*/
|
|
265
|
-
middleware:
|
|
290
|
+
middleware: {
|
|
291
|
+
(fn: MiddlewareFn<TEnv>): MiddlewareItem;
|
|
292
|
+
(
|
|
293
|
+
fn: MiddlewareFn<TEnv>,
|
|
294
|
+
children: () => UseItems<LayoutUseItem>,
|
|
295
|
+
): MiddlewareItem;
|
|
296
|
+
(fns: MiddlewareFn<TEnv>[]): MiddlewareItem;
|
|
297
|
+
(
|
|
298
|
+
fns: MiddlewareFn<TEnv>[],
|
|
299
|
+
children: () => UseItems<LayoutUseItem>,
|
|
300
|
+
): MiddlewareItem;
|
|
301
|
+
};
|
|
266
302
|
|
|
267
303
|
/**
|
|
268
304
|
* Control when a segment should revalidate during navigation
|
|
@@ -280,7 +316,10 @@ export type PathHelpers<TEnv> = {
|
|
|
280
316
|
/**
|
|
281
317
|
* Attach a loading component to the current route/layout
|
|
282
318
|
*/
|
|
283
|
-
loading: (
|
|
319
|
+
loading: (
|
|
320
|
+
component: ReactNode | (() => ReactNode),
|
|
321
|
+
options?: { ssr?: boolean },
|
|
322
|
+
) => LoadingItem;
|
|
284
323
|
|
|
285
324
|
/**
|
|
286
325
|
* Attach an error boundary to catch errors in this segment
|
|
@@ -309,15 +348,23 @@ export type PathHelpers<TEnv> = {
|
|
|
309
348
|
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
310
349
|
children: () => TChildren,
|
|
311
350
|
): TypedCacheItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
312
|
-
(options: PartialCacheOptions | false): TypedCacheItem<{}, {}>;
|
|
351
|
+
(options: PartialCacheOptions<TEnv> | false): TypedCacheItem<{}, {}>;
|
|
313
352
|
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
314
|
-
options: PartialCacheOptions | false,
|
|
353
|
+
options: PartialCacheOptions<TEnv> | false,
|
|
315
354
|
use: () => TChildren,
|
|
316
355
|
): TypedCacheItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
317
356
|
};
|
|
318
357
|
|
|
319
358
|
/**
|
|
320
|
-
*
|
|
359
|
+
* Opt a route (or group of routes) into transition-driven navigation.
|
|
360
|
+
*
|
|
361
|
+
* Two independent layers: (1) startTransition, on all React versions, holds
|
|
362
|
+
* the previous content across a same-route nav (no skeleton flash) and is the
|
|
363
|
+
* precondition for any view transition; (2) on experimental React, an
|
|
364
|
+
* additional `<ViewTransition>` boundary cross-fades/morphs the swap. Pass
|
|
365
|
+
* `{ viewTransition: false }` to keep #1 without the router boundary. A view
|
|
366
|
+
* transition cannot fire without a startTransition. See
|
|
367
|
+
* skills/view-transitions for the startTransition x ViewTransition matrix.
|
|
321
368
|
*/
|
|
322
369
|
transition: {
|
|
323
370
|
(): TransitionItem;
|