@rangojs/router 0.5.2 → 0.6.0
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/dist/bin/rango.js +343 -125
- package/dist/types/browser/react/use-router.d.ts +10 -3
- package/dist/types/browser/react/use-search-params.d.ts +57 -10
- package/dist/types/browser/types.d.ts +22 -0
- package/dist/types/build/merge-full-manifests.d.ts +3 -0
- package/dist/types/build/route-trie.d.ts +4 -73
- package/dist/types/build/route-types/per-module-writer.d.ts +6 -4
- package/dist/types/build/route-types/router-processing.d.ts +2 -3
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/taint.d.ts +12 -6
- package/dist/types/client-urls/client-root.d.ts +38 -0
- package/dist/types/client-urls/client-urls.d.ts +5 -0
- package/dist/types/client-urls/navigation.d.ts +38 -0
- package/dist/types/client-urls/revalidation-protocol.d.ts +25 -0
- package/dist/types/client-urls/server-projection.d.ts +62 -0
- package/dist/types/client-urls/types.d.ts +144 -0
- package/dist/types/client.d.ts +12 -4
- package/dist/types/client.rsc.d.ts +4 -1
- package/dist/types/decode-loader-results.d.ts +37 -0
- package/dist/types/errors.d.ts +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/loader-redirect.d.ts +27 -0
- package/dist/types/outlet-context.d.ts +12 -0
- package/dist/types/outlet-provider.d.ts +3 -1
- package/dist/types/redirect-origin.d.ts +4 -0
- package/dist/types/route-content-wrapper.d.ts +42 -1
- package/dist/types/route-definition/helpers-types.d.ts +13 -2
- package/dist/types/router/error-handling.d.ts +35 -1
- package/dist/types/router/intercept-resolution.d.ts +12 -0
- package/dist/types/router/loader-resolution.d.ts +24 -2
- package/dist/types/router/revalidation.d.ts +7 -0
- package/dist/types/router/route-trie-builder.d.ts +77 -0
- package/dist/types/router/router-interfaces.d.ts +20 -0
- package/dist/types/router/segment-resolution/helpers.d.ts +1 -1
- package/dist/types/router/trie-matching.d.ts +1 -1
- package/dist/types/rsc/manifest-init.d.ts +5 -5
- package/dist/types/rsc/shell-capture.d.ts +9 -0
- package/dist/types/rsc/shell-serve.d.ts +11 -0
- package/dist/types/rsc/types.d.ts +30 -0
- package/dist/types/segment-system.d.ts +2 -0
- package/dist/types/server/context.d.ts +10 -0
- package/dist/types/server/handle-store.d.ts +34 -3
- package/dist/types/server/request-context.d.ts +11 -1
- package/dist/types/server.d.ts +1 -0
- package/dist/types/ssr/index.d.ts +22 -0
- package/dist/types/ssr/ssr-root.d.ts +10 -0
- package/dist/types/testing/dom.entry.d.ts +1 -1
- package/dist/types/testing/render-route.d.ts +16 -6
- package/dist/types/testing/run-loader.d.ts +9 -0
- package/dist/types/types/boundaries.d.ts +22 -0
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/loader-types.d.ts +57 -5
- package/dist/types/types/segments.d.ts +7 -0
- package/dist/types/urls/path-helper-types.d.ts +10 -4
- package/dist/types/vite/discovery/client-urls-projection.d.ts +53 -0
- package/dist/types/vite/discovery/discover-routers.d.ts +1 -1
- package/dist/types/vite/discovery/state.d.ts +8 -1
- package/dist/vite/index.js +5313 -2365
- package/package.json +1 -1
- package/skills/breadcrumbs/SKILL.md +39 -9
- package/skills/catalog.json +7 -1
- package/skills/client-urls/SKILL.md +338 -0
- package/skills/comparison/references/framework-comparison.md +23 -9
- package/skills/hooks/SKILL.md +2 -2
- package/skills/hooks/data.md +11 -2
- package/skills/hooks/handle-and-actions.md +7 -0
- package/skills/hooks/outlets.md +26 -5
- package/skills/hooks/urls.md +40 -3
- package/skills/loader/SKILL.md +132 -20
- package/skills/migrate-nextjs/SKILL.md +70 -10
- package/skills/migrate-react-router/SKILL.md +49 -13
- package/skills/migrate-react-router/component-migration.md +18 -13
- package/skills/migrate-react-router/data-and-actions.md +14 -3
- package/skills/migrate-react-router/route-mapping.md +15 -2
- package/skills/parallel/SKILL.md +32 -1
- package/skills/ppr/SKILL.md +16 -6
- package/skills/prerender/SKILL.md +8 -4
- package/skills/rango/SKILL.md +21 -17
- package/skills/react-compiler/SKILL.md +3 -3
- package/skills/route/SKILL.md +5 -2
- package/skills/router-setup/SKILL.md +16 -2
- package/skills/scripts/SKILL.md +16 -6
- package/skills/shell-manifest/SKILL.md +16 -7
- package/skills/testing/SKILL.md +2 -2
- package/skills/testing/client-components.md +6 -0
- package/skills/testing/handles.md +30 -8
- package/skills/testing/loader.md +51 -49
- package/skills/testing/middleware.md +1 -1
- package/skills/theme/SKILL.md +8 -5
- package/src/bin/rango.ts +7 -3
- package/src/browser/navigation-bridge.ts +6 -0
- package/src/browser/navigation-client.ts +5 -0
- package/src/browser/partial-update.ts +65 -13
- package/src/browser/react/use-router.ts +40 -11
- package/src/browser/react/use-search-params.ts +140 -17
- package/src/browser/rsc-router.tsx +59 -0
- package/src/browser/server-action-bridge.ts +26 -0
- package/src/browser/types.ts +22 -0
- package/src/build/merge-full-manifests.ts +161 -0
- package/src/build/route-trie.ts +9 -332
- package/src/build/route-types/include-resolution.ts +66 -11
- package/src/build/route-types/per-module-writer.ts +11 -6
- package/src/build/route-types/router-processing.ts +184 -153
- package/src/build/runtime-discovery.ts +23 -12
- package/src/cache/cache-exec-scope.ts +47 -0
- package/src/cache/cache-runtime.ts +24 -25
- package/src/cache/taint.ts +28 -9
- package/src/client-urls/client-root.tsx +168 -0
- package/src/client-urls/client-urls.ts +698 -0
- package/src/client-urls/navigation.ts +237 -0
- package/src/client-urls/revalidation-protocol.ts +56 -0
- package/src/client-urls/server-projection.ts +579 -0
- package/src/client-urls/types.ts +195 -0
- package/src/client.rsc.tsx +12 -0
- package/src/client.tsx +49 -6
- package/src/decode-loader-results.ts +113 -0
- package/src/errors.ts +14 -0
- package/src/handles/deferred-resolution.ts +14 -7
- package/src/index.ts +1 -0
- package/src/loader-redirect.tsx +64 -0
- package/src/outlet-context.ts +12 -0
- package/src/outlet-provider.tsx +15 -1
- package/src/redirect-origin.ts +29 -0
- package/src/route-content-wrapper.tsx +96 -3
- package/src/route-definition/dsl-helpers.ts +28 -3
- package/src/route-definition/helpers-types.ts +13 -0
- package/src/route-definition/redirect.ts +17 -18
- package/src/router/error-handling.ts +65 -11
- package/src/router/intercept-resolution.ts +29 -0
- package/src/router/loader-resolution.ts +261 -28
- package/src/router/match-result.ts +7 -0
- package/src/router/revalidation.ts +24 -11
- package/src/router/route-trie-builder.ts +334 -0
- package/src/router/router-interfaces.ts +38 -0
- package/src/router/segment-resolution/fresh.ts +47 -0
- package/src/router/segment-resolution/helpers.ts +9 -11
- package/src/router/segment-resolution/loader-cache.ts +14 -24
- package/src/router/segment-resolution/revalidation.ts +20 -1
- package/src/router/trie-matching.ts +3 -3
- package/src/router.ts +46 -1
- package/src/rsc/full-payload.ts +6 -0
- package/src/rsc/handler.ts +10 -7
- package/src/rsc/loader-fetch.ts +2 -2
- package/src/rsc/manifest-init.ts +28 -9
- package/src/rsc/rsc-rendering.ts +15 -1
- package/src/rsc/shell-capture.ts +12 -0
- package/src/rsc/shell-serve.ts +15 -2
- package/src/rsc/ssr-setup.ts +10 -1
- package/src/rsc/types.ts +31 -2
- package/src/segment-system.tsx +83 -26
- package/src/server/context.ts +10 -0
- package/src/server/cookie-store.ts +19 -19
- package/src/server/handle-store.ts +185 -48
- package/src/server/request-context.ts +30 -6
- package/src/server.ts +7 -0
- package/src/ssr/index.tsx +37 -2
- package/src/ssr/ssr-root.tsx +29 -2
- package/src/testing/dom.entry.ts +1 -1
- package/src/testing/render-route.tsx +22 -8
- package/src/testing/run-loader.ts +51 -13
- package/src/types/boundaries.ts +19 -0
- package/src/types/index.ts +1 -0
- package/src/types/loader-types.ts +60 -5
- package/src/types/segments.ts +7 -0
- package/src/urls/include-helper.ts +22 -4
- package/src/urls/path-helper-types.ts +14 -1
- package/src/use-loader.tsx +67 -6
- package/src/vite/discovery/client-urls-projection.ts +322 -0
- package/src/vite/discovery/discover-routers.ts +43 -17
- package/src/vite/discovery/state.ts +11 -1
- package/src/vite/discovery/virtual-module-codegen.ts +20 -0
- package/src/vite/plugins/virtual-entries.ts +12 -3
- package/src/vite/router-discovery.ts +163 -12
package/dist/types/client.d.ts
CHANGED
|
@@ -42,8 +42,9 @@ import { type ClientErrorBoundaryFallbackProps } from "./types";
|
|
|
42
42
|
* }
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
|
-
export declare function Outlet({ name }?: {
|
|
45
|
+
export declare function Outlet({ name, fallback, }?: {
|
|
46
46
|
name?: `@${string}`;
|
|
47
|
+
fallback?: ReactNode;
|
|
47
48
|
}): ReactNode;
|
|
48
49
|
/**
|
|
49
50
|
* ParallelOutlet component - renders content for a named parallel slot
|
|
@@ -74,7 +75,7 @@ export declare function ParallelOutlet({ name }: {
|
|
|
74
75
|
name: `@${string}`;
|
|
75
76
|
}): ReactNode;
|
|
76
77
|
/**
|
|
77
|
-
* Hook to access outlet content programmatically
|
|
78
|
+
* Hook to access outlet content and descendant pending state programmatically.
|
|
78
79
|
*
|
|
79
80
|
* Alternative to using <Outlet /> component. Useful when you need
|
|
80
81
|
* direct access to the outlet content in your logic.
|
|
@@ -83,12 +84,18 @@ export declare function ParallelOutlet({ name }: {
|
|
|
83
84
|
* ```tsx
|
|
84
85
|
* function BlogLayout() {
|
|
85
86
|
* const outlet = useOutlet();
|
|
86
|
-
* return <div><h1>Blog</h1>{outlet}</div>;
|
|
87
|
+
* return <div aria-busy={outlet.pending}><h1>Blog</h1>{outlet.content}</div>;
|
|
87
88
|
* }
|
|
88
89
|
* ```
|
|
89
90
|
*/
|
|
90
|
-
export
|
|
91
|
+
export interface OutletState {
|
|
92
|
+
readonly content: ReactNode;
|
|
93
|
+
readonly pending: boolean;
|
|
94
|
+
}
|
|
95
|
+
export declare function useOutlet(): OutletState;
|
|
91
96
|
export { useLoader, useFetchLoader, useRefreshLoaders, type LoadFunction, type UseLoaderResult, type UseFetchLoaderResult, type UseLoaderOptions, } from "./use-loader.js";
|
|
97
|
+
export { clientUrls } from "./client-urls/client-urls.js";
|
|
98
|
+
export type { ClientUrlPatterns, ClientUrlRouteRecord, } from "./client-urls/client-urls.js";
|
|
92
99
|
/**
|
|
93
100
|
* Props for the ErrorBoundary component
|
|
94
101
|
*/
|
|
@@ -156,6 +163,7 @@ export { useNavigation } from "./browser/react/use-navigation.js";
|
|
|
156
163
|
export { useRouter } from "./browser/react/use-router.js";
|
|
157
164
|
export { usePathname } from "./browser/react/use-pathname.js";
|
|
158
165
|
export { useSearchParams } from "./browser/react/use-search-params.js";
|
|
166
|
+
export type { SearchParamsInit, SetSearchParams, SetSearchParamsOptions, } from "./browser/react/use-search-params.js";
|
|
159
167
|
export { useParams } from "./browser/react/use-params.js";
|
|
160
168
|
export { useNonce } from "./browser/react/nonce-context.js";
|
|
161
169
|
export type { RouterInstance, RouterNavigateOptions, ReadonlyURLSearchParams, ActionState, ActionLifecycleState, } from "./browser/types.js";
|
|
@@ -8,12 +8,15 @@
|
|
|
8
8
|
* The bundler uses the "react-server" export condition to select this file
|
|
9
9
|
* in RSC context, while the regular client.tsx is used in client components.
|
|
10
10
|
*/
|
|
11
|
-
export { Outlet, ParallelOutlet, useOutlet, useLoader, ErrorBoundary, type ErrorBoundaryProps, } from "./client.js";
|
|
11
|
+
export { Outlet, ParallelOutlet, useOutlet, type OutletState, useLoader, ErrorBoundary, type ErrorBoundaryProps, } from "./client.js";
|
|
12
12
|
export { useFetchLoader, useRefreshLoaders, type LoadFunction, type UseLoaderResult, type UseFetchLoaderResult, type UseLoaderOptions, } from "./use-loader.js";
|
|
13
13
|
export { createLoader } from "./route-definition.js";
|
|
14
|
+
export { clientUrls } from "./client-urls/client-urls.js";
|
|
15
|
+
export type { ClientUrlPatterns, ClientUrlRouteRecord, } from "./client-urls/client-urls.js";
|
|
14
16
|
export { useRouter } from "./browser/react/use-router.js";
|
|
15
17
|
export { usePathname } from "./browser/react/use-pathname.js";
|
|
16
18
|
export { useSearchParams } from "./browser/react/use-search-params.js";
|
|
19
|
+
export type { SearchParamsInit, SetSearchParams, SetSearchParamsOptions, } from "./browser/react/use-search-params.js";
|
|
17
20
|
export { useParams } from "./browser/react/use-params.js";
|
|
18
21
|
export { useNonce } from "./browser/react/nonce-context.js";
|
|
19
22
|
export { useMount } from "./browser/react/use-mount.js";
|
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Markers for loader-thrown AUTHORITY SIGNALS (notFound()/redirect()) on the
|
|
4
|
+
* reconstructed read-site error. Siblings of LOADER_ERROR_FALLBACK, routed
|
|
5
|
+
* differently by StreamedLoaderErrorBoundary: NOT_FOUND renders the
|
|
6
|
+
* server-rendered not-found UI riding the envelope; REDIRECT triggers a
|
|
7
|
+
* client replace-navigation to the (server-resolved, same-origin-guarded)
|
|
8
|
+
* target. Signals are control flow, not failures — they take precedence over
|
|
9
|
+
* the plain error-fallback path.
|
|
10
|
+
*
|
|
11
|
+
* Only decodeLoaderEntry (the read-site path — client components, so the
|
|
12
|
+
* throw lands in the router-owned boundary; during document SSR, Fizz emits
|
|
13
|
+
* the Suspense fallback and replays the throw at hydration) throws these.
|
|
14
|
+
* decodeLoaderResults runs during the SERVER tree build on forceAwait/action
|
|
15
|
+
* lanes, where a throw would collapse the whole payload — it routes signals
|
|
16
|
+
* through the errorFallback slot instead (same visual: the slot replaces the
|
|
17
|
+
* children under OutletProvider).
|
|
18
|
+
*/
|
|
19
|
+
export declare const LOADER_NOT_FOUND_FALLBACK: unique symbol;
|
|
20
|
+
export declare const LOADER_REDIRECT: unique symbol;
|
|
2
21
|
export declare function decodeLoaderResults(resolvedData: any[], loaderIds: string[]): {
|
|
3
22
|
loaderData: Record<string, any>;
|
|
4
23
|
errorFallback: ReactNode;
|
|
5
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Marker property carrying the errorBoundary() fallback on a read-site loader
|
|
27
|
+
* error. decodeLoaderEntry attaches the pre-rendered boundary node (produced
|
|
28
|
+
* server-side by loader-resolution) to the thrown error; the router-owned
|
|
29
|
+
* StreamedLoaderErrorBoundary above the readers (segment-system wires it for
|
|
30
|
+
* every loader-bearing segment) catches by this marker and renders the
|
|
31
|
+
* fallback — restoring the build-time errorFallback-swap contract for
|
|
32
|
+
* streamed loaders. Errors without the marker rethrow to the app's boundaries.
|
|
33
|
+
*/
|
|
34
|
+
export declare const LOADER_ERROR_FALLBACK: unique symbol;
|
|
35
|
+
/**
|
|
36
|
+
* Streaming useLoader: single-entry decode for read-site resolution. Mirrors
|
|
37
|
+
* decodeLoaderResults for one result. An error entry throws the reconstructed
|
|
38
|
+
* error (name/stack/code/cause preserved); when the entry carries an
|
|
39
|
+
* errorBoundary() fallback, the node rides the throw via
|
|
40
|
+
* LOADER_ERROR_FALLBACK for the boundary above the readers to render.
|
|
41
|
+
*/
|
|
42
|
+
export declare function decodeLoaderEntry(result: any): any;
|
package/dist/types/errors.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare class DataNotFoundError extends Error {
|
|
|
38
38
|
cause?: unknown;
|
|
39
39
|
constructor(message?: string, options?: ErrorOptions);
|
|
40
40
|
}
|
|
41
|
+
export declare function isDataNotFoundError(error: unknown): error is DataNotFoundError;
|
|
41
42
|
/**
|
|
42
43
|
* Convenience function to throw a DataNotFoundError
|
|
43
44
|
* Shorter syntax for common not-found scenarios
|
package/dist/types/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export { RouteNotFoundError, DataNotFoundError, notFound, MiddlewareError, HandlerError, BuildError, DslContextError, InvalidHandlerError, RouterError, Skip, isSkip, } from "./errors.js";
|
|
13
13
|
export type { DocumentProps, DefaultEnv, RouteDefinition, RouteConfig, RouteDefinitionOptions, TrailingSlashMode, Handler, // Supports params object, path pattern, or route name
|
|
14
|
-
HandlerContext, ExtractParams, GenericParams, Middleware, RevalidateParams, Revalidate, ActionRef, RouteKeys, LoaderDefinition, LoaderFn, LoaderContext, FetchableLoaderOptions, LoadOptions, ErrorInfo, ErrorBoundaryFallbackProps, ErrorBoundaryHandler, ClientErrorBoundaryFallbackProps, NotFoundInfo, NotFoundBoundaryFallbackProps, NotFoundBoundaryHandler, ErrorPhase, OnErrorContext, OnErrorCallback, } from "./types.js";
|
|
14
|
+
HandlerContext, ExtractParams, GenericParams, Middleware, RevalidateParams, Revalidate, ActionRef, RouteKeys, LoaderDefinition, LoaderFn, LoaderContext, LoaderOptions, FetchableLoaderOptions, LoadOptions, ErrorInfo, ErrorBoundaryFallbackProps, ErrorBoundaryHandler, ClientErrorBoundaryFallbackProps, NotFoundInfo, NotFoundBoundaryFallbackProps, NotFoundBoundaryHandler, ErrorPhase, OnErrorContext, OnErrorCallback, } from "./types.js";
|
|
15
15
|
export type { SearchSchema, SearchSchemaValue, ResolveSearchSchema, RouteSearchParams, RouteParams, } from "./search-params.js";
|
|
16
16
|
export { TRACKING_SEARCH_PARAMS, type CacheSearchParams, } from "./cache/search-params-filter.js";
|
|
17
17
|
export { createLoader } from "./loader.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Executes a loader-thrown redirect() once mounted. The target was resolved
|
|
4
|
+
* through the soft-redirect same-origin rules server-side
|
|
5
|
+
* (wrapLoaderWithErrorHandling), so anything absolute AND cross-origin here is
|
|
6
|
+
* an explicit `{ external: true }` opt-in — those leave via location.replace
|
|
7
|
+
* (the SPA router cannot cross origins); everything else is a router
|
|
8
|
+
* replace-navigation. Renders nothing while the navigation commits.
|
|
9
|
+
*
|
|
10
|
+
* Own module (not route-content-wrapper.tsx) because BOTH consumers need it
|
|
11
|
+
* without a cycle: the StreamedLoaderErrorBoundary redirect branch (read-site
|
|
12
|
+
* throw path) and decodeLoaderResults (aggregate forceAwait/action path, which
|
|
13
|
+
* runs during the server tree build and cannot throw — it plants this element
|
|
14
|
+
* in the errorFallback slot instead).
|
|
15
|
+
*/
|
|
16
|
+
export declare function LoaderRedirect({ to, state, }: {
|
|
17
|
+
to: string;
|
|
18
|
+
/**
|
|
19
|
+
* Resolved `redirect(url, { state })` record off the loader-result marker.
|
|
20
|
+
* Delivered as the redirect navigation's state (same application path as
|
|
21
|
+
* the ServerRedirect lane in navigation-bridge.ts: buildHistoryState
|
|
22
|
+
* spreads the `__rsc_ls_*` keys into the target entry). `_skipCache`
|
|
23
|
+
* matches that lane — a cached segment commit must not skip the re-render
|
|
24
|
+
* that lets useLocationState read the fresh entry.
|
|
25
|
+
*/
|
|
26
|
+
state?: Record<string, unknown>;
|
|
27
|
+
}): ReactNode;
|
|
@@ -2,9 +2,21 @@ import { type Context, type ReactNode } from "react";
|
|
|
2
2
|
import type { ResolvedSegment } from "./types";
|
|
3
3
|
export interface OutletContextValue {
|
|
4
4
|
content: ReactNode;
|
|
5
|
+
/** Unresolved client-route work owned by descendants of this outlet. */
|
|
6
|
+
pending?: boolean;
|
|
5
7
|
parallel?: ResolvedSegment[];
|
|
6
8
|
segment?: ResolvedSegment;
|
|
7
9
|
loaderData?: Record<string, any>;
|
|
10
|
+
/**
|
|
11
|
+
* SPIKE (streaming useLoader): per-loader UNDECODED results keyed by loader
|
|
12
|
+
* $$id. A value may be a pending Promise (loader still streaming) or an
|
|
13
|
+
* already-settled result entry. useLoader `use()`es a pending value at the
|
|
14
|
+
* read site — implicit suspension to the nearest consumer Suspense boundary —
|
|
15
|
+
* and decodes via decodeLoaderEntry. Populated instead of `loaderData` on
|
|
16
|
+
* streaming lanes (plain navs, document SSR); forceAwait/action lanes keep
|
|
17
|
+
* the resolved `loaderData` record.
|
|
18
|
+
*/
|
|
19
|
+
loaderStreams?: Record<string, unknown>;
|
|
8
20
|
parent?: OutletContextValue | null;
|
|
9
21
|
/** Loading component for Suspense fallback (from segment's loading() definition) */
|
|
10
22
|
loading?: ReactNode;
|
|
@@ -3,10 +3,12 @@ import type { ResolvedSegment } from "./types.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Outlet content provider — stores parent context for useLoader chain walking.
|
|
5
5
|
*/
|
|
6
|
-
export declare function OutletProvider({ content, parallel, segment, loaderData, children, }: {
|
|
6
|
+
export declare function OutletProvider({ content, parallel, segment, loaderData, loaderStreams, pending, children, }: {
|
|
7
7
|
content: ReactNode;
|
|
8
8
|
parallel?: ResolvedSegment[];
|
|
9
9
|
segment?: ResolvedSegment;
|
|
10
10
|
loaderData?: Record<string, any>;
|
|
11
|
+
loaderStreams?: Record<string, unknown>;
|
|
12
|
+
pending?: boolean;
|
|
11
13
|
children: ReactNode;
|
|
12
14
|
}): ReactNode;
|
|
@@ -58,6 +58,10 @@ export declare function resolveSoftRedirectUrl(url: string, requestOrigin: strin
|
|
|
58
58
|
export declare function markExternalRedirect(response: Response): void;
|
|
59
59
|
/** Read the out-of-band `{ external: true }` brand off a Response. */
|
|
60
60
|
export declare function isExternalRedirect(response: Response): boolean;
|
|
61
|
+
/** Brand a redirect Response with its RESOLVED location-state record. */
|
|
62
|
+
export declare function attachRedirectState(response: Response, state: Record<string, unknown>): void;
|
|
63
|
+
/** Read the resolved location-state record off a redirect Response. */
|
|
64
|
+
export declare function getRedirectState(response: Response): Record<string, unknown> | undefined;
|
|
61
65
|
/**
|
|
62
66
|
* Reserved internal header name. No longer a trust signal -- the external
|
|
63
67
|
* opt-in is the out-of-band brand above. It is kept only so the redirect-rebuild
|
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
+
import { Component } from "react";
|
|
2
3
|
import type { ResolvedSegment } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Router-owned error boundary for read-site loader errors. segment-system
|
|
6
|
+
* wraps every loader-bearing segment's children in one (unconditionally —
|
|
7
|
+
* streams and forceAwait lanes alike, so the tree shape never differs between
|
|
8
|
+
* navigation lanes; see docs/tree-structure.md). A loader error thrown by a
|
|
9
|
+
* suspending read carries its errorBoundary() fallback via
|
|
10
|
+
* LOADER_ERROR_FALLBACK (decodeLoaderEntry); this boundary renders that node,
|
|
11
|
+
* restoring the pre-streaming errorFallback-swap contract.
|
|
12
|
+
*
|
|
13
|
+
* Loader-thrown AUTHORITY SIGNALS ride sibling markers:
|
|
14
|
+
* - LOADER_NOT_FOUND_FALLBACK (notFound()): renders the SERVER-RENDERED
|
|
15
|
+
* not-found UI carried on the marker — nearest notFoundBoundary → router
|
|
16
|
+
* notFound option — zero extra fetches. Document lane: Fizz emitted the
|
|
17
|
+
* Suspense fallback and replays the throw at hydration, so the swap happens
|
|
18
|
+
* client-side (the HTTP status was already set opportunistically by the
|
|
19
|
+
* producer when the rejection won the flush race).
|
|
20
|
+
* - LOADER_REDIRECT (redirect()): mounts LoaderRedirect, which navigates.
|
|
21
|
+
*
|
|
22
|
+
* Errors without any marker rethrow to the app's own boundaries.
|
|
23
|
+
*/
|
|
24
|
+
export declare class StreamedLoaderErrorBoundary extends Component<{
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}, {
|
|
27
|
+
error: unknown;
|
|
28
|
+
}> {
|
|
29
|
+
state: {
|
|
30
|
+
error: unknown;
|
|
31
|
+
};
|
|
32
|
+
static getDerivedStateFromError(error: unknown): {
|
|
33
|
+
error: unknown;
|
|
34
|
+
};
|
|
35
|
+
render(): ReactNode;
|
|
36
|
+
}
|
|
3
37
|
/**
|
|
4
38
|
* Stable async wrapper component for route content
|
|
5
39
|
* Using a module-level component ensures React sees the same component reference
|
|
@@ -30,6 +64,13 @@ export declare function RouteContentWrapper({ content, fallback, segmentId, }: {
|
|
|
30
64
|
export interface LoaderBoundaryProps {
|
|
31
65
|
loaderDataPromise: Promise<any[]> | any[];
|
|
32
66
|
loaderIds: string[];
|
|
67
|
+
/**
|
|
68
|
+
* SPIKE (streaming useLoader): per-loader UNDECODED results from the
|
|
69
|
+
* producer (values or individually-pending promises). When present, the
|
|
70
|
+
* resolver passes them through instead of resolving the aggregate above
|
|
71
|
+
* the children; useLoader suspends per loader at the read site.
|
|
72
|
+
*/
|
|
73
|
+
loaderStreams?: Record<string, unknown>;
|
|
33
74
|
fallback?: ReactNode;
|
|
34
75
|
outletKey: string;
|
|
35
76
|
outletContent: ReactNode;
|
|
@@ -37,4 +78,4 @@ export interface LoaderBoundaryProps {
|
|
|
37
78
|
parallel?: ResolvedSegment[];
|
|
38
79
|
children: ReactNode;
|
|
39
80
|
}
|
|
40
|
-
export declare function LoaderBoundary({ loaderDataPromise, loaderIds, fallback, outletKey, outletContent, segment, parallel, children, }: LoaderBoundaryProps): ReactNode;
|
|
81
|
+
export declare function LoaderBoundary({ loaderDataPromise, loaderIds, loaderStreams, fallback, outletKey, outletContent, segment, parallel, children, }: LoaderBoundaryProps): ReactNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import type { ExtractRouteParams, Handler, PartialCacheOptions, ErrorBoundaryHandler, LoaderDefinition, MiddlewareFn, NotFoundBoundaryHandler, ResolvedRouteMap, RouteDefinition, ShouldRevalidateFn, TransitionConfig } from "../types.js";
|
|
2
|
+
import type { ExtractRouteParams, Handler, PartialCacheOptions, ErrorBoundaryHandler, LoaderDefinition, LoaderOptions, MiddlewareFn, NotFoundBoundaryHandler, ResolvedRouteMap, RouteDefinition, ShouldRevalidateFn, TransitionConfig } from "../types.js";
|
|
3
3
|
import type { AllUseItems, LayoutItem, RouteItem, ParallelItem, InterceptItem, MiddlewareItem, RevalidateItem, LoaderItem, LoadingItem, ErrorBoundaryItem, NotFoundBoundaryItem, LayoutUseItem, RouteUseItem, ParallelUseItem, InterceptUseItem, LoaderUseItem, CacheItem, TransitionItem, UseItems } from "../route-types.js";
|
|
4
4
|
import type { StaticHandlerRef } from "../static-handler.js";
|
|
5
5
|
export type { AllUseItems, LayoutItem, RouteItem, ParallelItem, InterceptItem, MiddlewareItem, RevalidateItem, LoaderItem, ErrorBoundaryItem, NotFoundBoundaryItem, LayoutUseItem, RouteUseItem, ParallelUseItem, InterceptUseItem, CacheItem, } from "../route-types.js";
|
|
@@ -208,10 +208,21 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
208
208
|
* return <div>{data.name}</div>;
|
|
209
209
|
* }
|
|
210
210
|
* ```
|
|
211
|
+
* Pass `{ stream: "navigation" }` to await this loader before first flush on
|
|
212
|
+
* DOCUMENT requests (see {@link LoaderOptions}) — the opt-in for loaders whose
|
|
213
|
+
* data, handle pushes, or thrown notFound()/redirect() must be in the SSR'd
|
|
214
|
+
* HTML. Per-loader: a dynamic sibling in the same segment keeps streaming.
|
|
215
|
+
*
|
|
216
|
+
* ```typescript
|
|
217
|
+
* loader(ProductLoader, { stream: "navigation" }, () => [cache()]),
|
|
218
|
+
* loader(RecommendationsLoader), // still streams behind loading()
|
|
219
|
+
* ```
|
|
220
|
+
*
|
|
211
221
|
* @param loaderDef - Loader created with createLoader()
|
|
222
|
+
* @param optionsOrUse - Delivery options, or the use() callback when passing none
|
|
212
223
|
* @param use - Optional callback for loader-specific revalidation rules
|
|
213
224
|
*/
|
|
214
|
-
loader: <TData>(loaderDef: LoaderDefinition<TData>, use?: () => UseItems<LoaderUseItem>) => LoaderItem;
|
|
225
|
+
loader: <TData>(loaderDef: LoaderDefinition<TData>, optionsOrUse?: LoaderOptions | (() => UseItems<LoaderUseItem>), use?: () => UseItems<LoaderUseItem>) => LoaderItem;
|
|
215
226
|
/**
|
|
216
227
|
* Attach a loading component to the current route/layout
|
|
217
228
|
* ```typescript
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Error boundary and not-found boundary handling for Rango.
|
|
5
5
|
* Also includes the shared invokeOnError utility for error callback invocation.
|
|
6
6
|
*/
|
|
7
|
-
import type
|
|
7
|
+
import { type ReactNode } from "react";
|
|
8
8
|
import type { EntryData } from "../server/context";
|
|
9
9
|
import type { ResolvedSegment, ErrorInfo, ErrorBoundaryHandler, NotFoundInfo, NotFoundBoundaryHandler, ErrorPhase, OnErrorCallback } from "../types";
|
|
10
10
|
/**
|
|
@@ -69,6 +69,40 @@ export declare function createErrorSegment(errorInfo: ErrorInfo, fallback: React
|
|
|
69
69
|
export declare function createNotFoundInfo(error: {
|
|
70
70
|
message: string;
|
|
71
71
|
}, segmentId: string, segmentType: NotFoundInfo["segmentType"], pathname?: string): NotFoundInfo;
|
|
72
|
+
/** Router-level `createRouter({ notFound })` option shape. */
|
|
73
|
+
export type NotFoundComponentOption = ReactNode | ((props: {
|
|
74
|
+
pathname: string;
|
|
75
|
+
}) => ReactNode);
|
|
76
|
+
/**
|
|
77
|
+
* Pick the effective notFound fallback: nearest `notFoundBoundary`, else the
|
|
78
|
+
* router-level `notFound` option, else a plain default.
|
|
79
|
+
*
|
|
80
|
+
* The router option is resolved ONLY when no nearer boundary won — it may be a
|
|
81
|
+
* user render function doing arbitrary work, so computing it eagerly (as three
|
|
82
|
+
* earlier copies of this policy did) burned a full render on every 404 that a
|
|
83
|
+
* boundary was going to handle anyway.
|
|
84
|
+
*
|
|
85
|
+
* Every 404 origin routes through here — segment resolution
|
|
86
|
+
* (`segment-resolution/helpers.ts`), loader-thrown `notFound()`
|
|
87
|
+
* (`loader-resolution.ts`), and the unmatched-route path (`rsc/handler.ts`) —
|
|
88
|
+
* so the default text and the boundary-wins precedence cannot drift apart.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveNotFoundFallback(boundary: ReactNode | NotFoundBoundaryHandler | null | undefined, notFoundComponent: NotFoundComponentOption | undefined, pathname: string | undefined): ReactNode | NotFoundBoundaryHandler;
|
|
91
|
+
/**
|
|
92
|
+
* The router-level default alone: `createRouter({ notFound })` rendered, or the
|
|
93
|
+
* plain fallback node. Separate from {@link resolveNotFoundFallback} for the
|
|
94
|
+
* unmatched-route path, which has no entry chain and therefore no boundary to
|
|
95
|
+
* consult — it gets a `ReactNode` back rather than a possible handler.
|
|
96
|
+
*/
|
|
97
|
+
export declare function resolveDefaultNotFound(notFoundComponent: NotFoundComponentOption | undefined, pathname: string | undefined): ReactNode;
|
|
98
|
+
/**
|
|
99
|
+
* Invoke a notFound fallback that may be a boundary handler or a plain node.
|
|
100
|
+
*
|
|
101
|
+
* Callers that cannot propagate a throw (the loader envelope) wrap this in
|
|
102
|
+
* their own try/catch; it deliberately does not swallow, so a throwing boundary
|
|
103
|
+
* still surfaces where that is the correct behavior.
|
|
104
|
+
*/
|
|
105
|
+
export declare function renderNotFoundFallback(fallback: ReactNode | NotFoundBoundaryHandler, notFoundInfo: NotFoundInfo): ReactNode;
|
|
72
106
|
/**
|
|
73
107
|
* Create a notFound segment with the fallback component
|
|
74
108
|
* Renders the fallback with not found info
|
|
@@ -19,6 +19,18 @@ export declare function evaluateInterceptWhen(intercept: InterceptEntry, selecto
|
|
|
19
19
|
* Find an intercept for the target route by walking up the entry chain.
|
|
20
20
|
* Returns the first (innermost) matching intercept along with the entry that defines it.
|
|
21
21
|
*/
|
|
22
|
+
/**
|
|
23
|
+
* Collect every intercept TARGET route name reachable from an origin entry —
|
|
24
|
+
* the same chain walk findInterceptForRoute() performs when this location is
|
|
25
|
+
* the navigation origin. Shipped in payload metadata so the browser-local
|
|
26
|
+
* clientUrls matcher can DECLINE its optimistic presentation for targets an
|
|
27
|
+
* intercept would claim (the committed result keeps the origin page + modal,
|
|
28
|
+
* so destination loading would flash and revert). Deliberately includes
|
|
29
|
+
* `when`-conditional intercepts: selectors need the live navigation context,
|
|
30
|
+
* so the browser stays conservative — worst case a non-intercepted navigation
|
|
31
|
+
* loses its optimistic loading, never the reverse.
|
|
32
|
+
*/
|
|
33
|
+
export declare function collectInterceptTargetNames(fromEntry: EntryData | null): string[];
|
|
22
34
|
export declare function findInterceptForRoute(targetRouteKey: string, fromEntry: EntryData | null, selectorContext?: InterceptSelectorContext | null, isAction?: boolean): {
|
|
23
35
|
intercept: InterceptEntry;
|
|
24
36
|
entry: EntryData;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { ReactNode } from "react";
|
|
7
7
|
import type { EntryData } from "../server/context";
|
|
8
|
-
import type { HandlerContext, LoaderDataResult, ErrorBoundaryHandler, ErrorInfo } from "../types";
|
|
8
|
+
import type { HandlerContext, LoaderDataResult, ErrorBoundaryHandler, ErrorInfo, NotFoundBoundaryHandler } from "../types";
|
|
9
9
|
/**
|
|
10
10
|
* Internal callback signature for loader error notifications.
|
|
11
11
|
* This is a simplified callback for internal use in wrapLoaderWithErrorHandling.
|
|
@@ -21,12 +21,34 @@ export type LoaderErrorCallback = (error: unknown, context: {
|
|
|
21
21
|
* Catches errors and converts them to LoaderDataResult objects that include
|
|
22
22
|
* error info and pre-rendered fallback UI when an error boundary is available.
|
|
23
23
|
*
|
|
24
|
+
* Loader-thrown SIGNALS are routed before error handling — they are control
|
|
25
|
+
* flow, not failures (onError is not invoked for them):
|
|
26
|
+
* - notFound(): the not-found UI is resolved and rendered HERE, server-side
|
|
27
|
+
* (nearest notFoundBoundary → router notFound option → default), exactly
|
|
28
|
+
* like the consumption lane (segment-resolution/helpers.ts), and rides the
|
|
29
|
+
* envelope's `fallback` — the client swaps with zero extra fetches. The
|
|
30
|
+
* response status is opportunistically set to 404 via the request stub: if
|
|
31
|
+
* the rejection settles before the document Response is constructed the
|
|
32
|
+
* status is a real 404; after, the stub write is inert (streamed fix-up
|
|
33
|
+
* only). Nav-lane payloads are 200 either way — the client owns 404
|
|
34
|
+
* presentation there.
|
|
35
|
+
* - redirect() (thrown 3xx Response): the target is resolved through the
|
|
36
|
+
* soft-redirect same-origin rules NOW so unsafe targets never leave the
|
|
37
|
+
* server; the client navigates when the entry decodes. No document-lane
|
|
38
|
+
* 302 — pre-stream redirect authority belongs to middleware (doctrine);
|
|
39
|
+
* a loader redirect is always a client-side navigate.
|
|
40
|
+
*
|
|
24
41
|
* @param onError - Optional callback invoked when loader errors occur.
|
|
25
42
|
* This has a simplified signature for internal use - the caller (typically
|
|
26
43
|
* wrapLoaderPromise in router.ts) is responsible for bridging to the full
|
|
27
44
|
* OnErrorCallback with complete request context (request, url, env, etc.).
|
|
28
45
|
*/
|
|
29
|
-
export declare function wrapLoaderWithErrorHandling<T>(promise: Promise<T>, entry: EntryData, segmentId: string, pathname: string, findNearestErrorBoundary: (entry: EntryData | null) => ReactNode | ErrorBoundaryHandler | null, createErrorInfo: (error: unknown, segmentId: string, segmentType: ErrorInfo["segmentType"]) => ErrorInfo, onError?: LoaderErrorCallback
|
|
46
|
+
export declare function wrapLoaderWithErrorHandling<T>(promise: Promise<T>, entry: EntryData, segmentId: string, pathname: string, findNearestErrorBoundary: (entry: EntryData | null) => ReactNode | ErrorBoundaryHandler | null, createErrorInfo: (error: unknown, segmentId: string, segmentType: ErrorInfo["segmentType"]) => ErrorInfo, onError?: LoaderErrorCallback, notFoundDeps?: {
|
|
47
|
+
findNearestNotFoundBoundary: (entry: EntryData | null) => ReactNode | NotFoundBoundaryHandler | null;
|
|
48
|
+
notFoundComponent?: ReactNode | ((props: {
|
|
49
|
+
pathname: string;
|
|
50
|
+
}) => ReactNode);
|
|
51
|
+
}): Promise<LoaderDataResult<T>>;
|
|
30
52
|
/**
|
|
31
53
|
* Set up the use() method on handler context to access loaders and handles.
|
|
32
54
|
*
|
|
@@ -43,10 +43,17 @@ interface EvaluateRevalidationOptions<TEnv> {
|
|
|
43
43
|
* reason flows into the trace. Callers use this when client-knowledge
|
|
44
44
|
* (e.g. parallel slot not in clientSegmentIds) should dictate the seed
|
|
45
45
|
* instead of the params/method-based heuristic.
|
|
46
|
+
*
|
|
47
|
+
* `floor` makes a `true` seed a guarantee rather than a suggestion: user fns
|
|
48
|
+
* may raise the decision but never lower it. Set it when the segment has no
|
|
49
|
+
* client-side content to fall back on, so a `false` would render nothing
|
|
50
|
+
* instead of keeping a cached copy — see the parallel-slot call site in
|
|
51
|
+
* segment-resolution/revalidation.ts.
|
|
46
52
|
*/
|
|
47
53
|
defaultOverride?: {
|
|
48
54
|
value: boolean;
|
|
49
55
|
reason: string;
|
|
56
|
+
floor?: boolean;
|
|
50
57
|
};
|
|
51
58
|
}
|
|
52
59
|
/**
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Route Trie Construction
|
|
3
|
+
*
|
|
4
|
+
* Builds a serializable trie from route manifest data for O(path_length)
|
|
5
|
+
* route matching at runtime.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* A response-type variant folded into a primary leaf's negotiate list. `pa` is
|
|
9
|
+
* the variant's own positional param-name array, carried so the runtime can
|
|
10
|
+
* re-key the matched params under the variant's names when it wins negotiation
|
|
11
|
+
* (the trie match extracts params under the PRIMARY leaf's pa). Omitted when the
|
|
12
|
+
* variant has no params; absent/identical pa means no re-key is needed.
|
|
13
|
+
*/
|
|
14
|
+
export interface NegotiateVariant {
|
|
15
|
+
routeKey: string;
|
|
16
|
+
responseType: string;
|
|
17
|
+
pa?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface TrieLeaf {
|
|
20
|
+
/** Route name (e.g., "site.l1_500") */
|
|
21
|
+
n: string;
|
|
22
|
+
/** Static prefix of the entry (e.g., "/site") */
|
|
23
|
+
sp: string;
|
|
24
|
+
/** Constraint validation: paramName -> allowed values */
|
|
25
|
+
cv?: Record<string, string[]>;
|
|
26
|
+
/** Ordered param names for this route (positional) */
|
|
27
|
+
pa?: string[];
|
|
28
|
+
/** Trailing slash mode */
|
|
29
|
+
ts?: string;
|
|
30
|
+
/** Route has pre-rendered data available */
|
|
31
|
+
pr?: true;
|
|
32
|
+
/** Passthrough: handler kept in bundle for live fallback on unknown params */
|
|
33
|
+
pt?: true;
|
|
34
|
+
/** Response type for non-RSC routes (json, text, image, any) */
|
|
35
|
+
rt?: string;
|
|
36
|
+
/** Negotiate variants: response-type routes sharing this path */
|
|
37
|
+
nv?: NegotiateVariant[];
|
|
38
|
+
/** RSC-first: RSC route was defined before response-type variants */
|
|
39
|
+
rf?: true;
|
|
40
|
+
}
|
|
41
|
+
export interface TrieNode {
|
|
42
|
+
/** Route terminal at this node */
|
|
43
|
+
r?: TrieLeaf;
|
|
44
|
+
/** Static segment children */
|
|
45
|
+
s?: Record<string, TrieNode>;
|
|
46
|
+
/** Param child: { n: paramName, c: child node } */
|
|
47
|
+
p?: {
|
|
48
|
+
n: string;
|
|
49
|
+
c: TrieNode;
|
|
50
|
+
};
|
|
51
|
+
/** Suffix-param children keyed by suffix (e.g., ".html" -> { n: "productId", c: ... }) */
|
|
52
|
+
xp?: Record<string, {
|
|
53
|
+
n: string;
|
|
54
|
+
c: TrieNode;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Wildcard terminal: leaf + paramName (`pn`). `pn` is "*" for the bare `/*`
|
|
58
|
+
* form and the param name for a named catch-all (`:name+`/`:name*`). `w1`
|
|
59
|
+
* marks a one-or-more catch-all (`:name+`): the runtime walker then rejects
|
|
60
|
+
* the zero-segment/empty-remainder case. Absent `w1` is zero-or-more.
|
|
61
|
+
*/
|
|
62
|
+
w?: TrieLeaf & {
|
|
63
|
+
pn: string;
|
|
64
|
+
w1?: true;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build a route trie from route manifest data.
|
|
69
|
+
*
|
|
70
|
+
* @param routeManifest - Map of route name to full URL pattern
|
|
71
|
+
* @param routeToStaticPrefix - Map of route name to its entry's staticPrefix
|
|
72
|
+
* @param routeTrailingSlash - Optional map of route name to trailing slash mode
|
|
73
|
+
* @param prerenderRouteNames - Optional set of prerendered route names (sets leaf.pr)
|
|
74
|
+
* @param passthroughRouteNames - Optional set of passthrough route names (sets leaf.pt)
|
|
75
|
+
* @param responseTypeRoutes - Optional map of route name to response type (sets leaf.rt)
|
|
76
|
+
*/
|
|
77
|
+
export declare function buildRouteTrie(routeManifest: Record<string, string>, routeToStaticPrefix: Record<string, string>, routeTrailingSlash?: Record<string, string>, prerenderRouteNames?: Set<string>, passthroughRouteNames?: Set<string>, responseTypeRoutes?: Record<string, string>): TrieNode;
|
|
@@ -2,6 +2,7 @@ import type { ComponentType } from "react";
|
|
|
2
2
|
import type { SerializedManifest } from "../debug.js";
|
|
3
3
|
import type { ReverseFunction } from "../reverse.js";
|
|
4
4
|
import type { UrlPatterns } from "../urls.js";
|
|
5
|
+
import type { ClientUrlPatterns } from "../client-urls/types.js";
|
|
5
6
|
import type { UrlBuilder, EnvCompatible } from "../urls/pattern-types.js";
|
|
6
7
|
import type { EntryData } from "../server/context";
|
|
7
8
|
import type { ErrorInfo, MatchResult } from "../types";
|
|
@@ -27,6 +28,11 @@ export interface RouterRequestInput<TEnv, TVars = DefaultVars> {
|
|
|
27
28
|
vars?: Partial<TVars>;
|
|
28
29
|
ctx?: ExecutionContext;
|
|
29
30
|
}
|
|
31
|
+
/** One materialized UrlPatterns registration and its live router mount index. */
|
|
32
|
+
export interface UrlPatternMount<TEnv = any> {
|
|
33
|
+
readonly patterns: UrlPatterns<TEnv, any>;
|
|
34
|
+
readonly mountIndex: number;
|
|
35
|
+
}
|
|
30
36
|
/**
|
|
31
37
|
* Merge route patterns with response types into a single route map.
|
|
32
38
|
* Routes with response types get { path, response } objects; others stay as strings.
|
|
@@ -79,6 +85,12 @@ export interface Rango<TEnv = any, TRoutes extends Record<string, unknown> = Rec
|
|
|
79
85
|
* ```
|
|
80
86
|
*/
|
|
81
87
|
routes<T extends UrlPatterns<any, any, any>>(patterns: T & EnvCompatible<T, TEnv>): Rango<TEnv, TRoutes & (NonNullable<T["_routes"]> extends Record<string, unknown> ? MergeRoutesWithResponses<NonNullable<T["_routes"]>, T["_responses"]> : Record<string, string>)>;
|
|
88
|
+
/**
|
|
89
|
+
* Pure-client mounting shorthand: normalizes to a root include in the
|
|
90
|
+
* canonical urls() tree (`include("/", definition, { name: "" })`) — same
|
|
91
|
+
* lazy materialization as mounting through include() yourself.
|
|
92
|
+
*/
|
|
93
|
+
routes<T extends ClientUrlPatterns<any>>(patterns: T): Rango<TEnv, TRoutes & (NonNullable<T["_routes"]> extends Record<string, unknown> ? NonNullable<T["_routes"]> : Record<string, string>)>;
|
|
82
94
|
routes(builder: UrlBuilder<TEnv>): Rango<TEnv, TRoutes>;
|
|
83
95
|
/**
|
|
84
96
|
* Add global middleware that runs on all routes
|
|
@@ -184,7 +196,15 @@ export interface RangoInternal<TEnv = any, TRoutes extends Record<string, unknow
|
|
|
184
196
|
* `urls<{ DB }>()` cannot be mounted on a `createRouter<{}>()`.
|
|
185
197
|
*/
|
|
186
198
|
routes<T extends UrlPatterns<any, any, any>>(patterns: T & EnvCompatible<T, TEnv>): Rango<TEnv, TRoutes & (NonNullable<T["_routes"]> extends Record<string, unknown> ? MergeRoutesWithResponses<NonNullable<T["_routes"]>, T["_responses"]> : Record<string, string>)>;
|
|
199
|
+
/**
|
|
200
|
+
* Pure-client mounting shorthand: normalizes to a root include in the
|
|
201
|
+
* canonical urls() tree (`include("/", definition, { name: "" })`) — same
|
|
202
|
+
* lazy materialization as mounting through include() yourself.
|
|
203
|
+
*/
|
|
204
|
+
routes<T extends ClientUrlPatterns<any>>(patterns: T): Rango<TEnv, TRoutes & (NonNullable<T["_routes"]> extends Record<string, unknown> ? NonNullable<T["_routes"]> : Record<string, string>)>;
|
|
187
205
|
routes(builder: UrlBuilder<TEnv>): Rango<TEnv, TRoutes>;
|
|
206
|
+
/** Materialized UrlPatterns registrations in registration order. */
|
|
207
|
+
readonly __urlpatternMounts: readonly UrlPatternMount<TEnv>[];
|
|
188
208
|
/**
|
|
189
209
|
* Add global middleware that runs on all routes
|
|
190
210
|
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Layout handler resolution with static fallback
|
|
8
8
|
* - Error boundary segment creation
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import type { ReactNode } from "react";
|
|
11
11
|
import type { EntryData } from "../../server/context";
|
|
12
12
|
import type { ResolvedSegment, HandlerContext } from "../../types";
|
|
13
13
|
import type { SegmentResolutionDeps } from "../types.js";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Walks the pre-built trie by path segments in O(path_length) time.
|
|
5
5
|
* Falls back to null when no match is found (caller uses regex fallback).
|
|
6
6
|
*/
|
|
7
|
-
import type { TrieNode, NegotiateVariant } from "
|
|
7
|
+
import type { TrieNode, NegotiateVariant } from "./route-trie-builder.js";
|
|
8
8
|
export interface TrieMatchResult {
|
|
9
9
|
/** Route name */
|
|
10
10
|
routeKey: string;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Router Manifest Initialization
|
|
3
3
|
*
|
|
4
|
-
* Builds a fresh route trie from
|
|
5
|
-
* where the manifest exists but the trie needs rebuilding.
|
|
4
|
+
* Builds a fresh route trie from every registered URL-pattern mount for
|
|
5
|
+
* dev/HMR scenarios where the manifest exists but the trie needs rebuilding.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
-
* Build a fresh route trie from router
|
|
9
|
-
* per-router cache. Also sets the per-router manifest and merges into
|
|
10
|
-
*
|
|
8
|
+
* Build a fresh route trie from the router's URL-pattern mounts and store it in
|
|
9
|
+
* the per-router cache. Also sets the per-router manifest and merges into the
|
|
10
|
+
* global manifest for reverse()/href().
|
|
11
11
|
*
|
|
12
12
|
* Called when manifest data may exist but the per-router trie is missing,
|
|
13
13
|
* which happens in dev mode after HMR: the virtual module sets the manifest
|
|
@@ -273,6 +273,15 @@ export declare function gateFlightForCapture(source: ReadableStream<Uint8Array>,
|
|
|
273
273
|
*/
|
|
274
274
|
export interface ShellCaptureDescriptor {
|
|
275
275
|
key: string;
|
|
276
|
+
/**
|
|
277
|
+
* The key's search portion (shellSearchSeed: `?`-prefixed sorted search,
|
|
278
|
+
* cache.searchParams filter applied, or ""). Seeds the capture render's SSR
|
|
279
|
+
* store so static-part `useSearchParams` reads bake markup consistent with
|
|
280
|
+
* the shell's own key; the resume pass derives the identical string from
|
|
281
|
+
* the HIT request. Computed next to the key so the two cannot drift.
|
|
282
|
+
* Omitted (build-time bare-pathname captures) = search-less, same as "".
|
|
283
|
+
*/
|
|
284
|
+
searchSeed?: string;
|
|
276
285
|
/**
|
|
277
286
|
* The RSC handler's build version (HandlerContext.version), stamped into the
|
|
278
287
|
* stored entry as ShellCacheEntry.buildVersion — the serve-side
|
|
@@ -94,6 +94,17 @@ export declare function resolvePprConfig(entry: EntryData | undefined | null): R
|
|
|
94
94
|
* and lookup makes every shell request a permanent miss.
|
|
95
95
|
*/
|
|
96
96
|
export declare function buildShellKey(url: URL, filter?: SearchParamsFilter): string;
|
|
97
|
+
/**
|
|
98
|
+
* The shell key's search portion (`?`-prefixed sorted search with the
|
|
99
|
+
* cache.searchParams filter applied, or "") — ALSO the string the capture and
|
|
100
|
+
* resume SSR renders seed their store location with (SSRRenderOptions.search
|
|
101
|
+
* / ShellCaptureOptions.search / ShellResumeOptions.search). Search is part
|
|
102
|
+
* of shell identity, so static-part `useSearchParams` reads render exactly
|
|
103
|
+
* what the key names; deriving seed and key from this one helper is what
|
|
104
|
+
* keeps capture, resume, and lookup byte-agreed (drift = replay mismatch or
|
|
105
|
+
* permanent MISS).
|
|
106
|
+
*/
|
|
107
|
+
export declare function shellSearchSeed(url: URL, filter?: SearchParamsFilter): string;
|
|
97
108
|
/**
|
|
98
109
|
* Version gates for a stored shell: reactVersion AND buildVersion must both
|
|
99
110
|
* match the running server. The postponed blob encodes hole positions against
|