react-router 8.0.1 → 8.2.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/CHANGELOG.md +24 -0
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +1 -1
- package/dist/development/index-react-server.d.ts +35 -9
- package/dist/development/index-react-server.js +190 -157
- package/dist/development/index.d.ts +2 -2
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/components.js +1 -1
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.js +1 -1
- package/dist/development/lib/dom/lib.js +2 -2
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +1 -1
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/development/lib/dom/ssr/fallback.js +1 -1
- package/dist/development/lib/dom/ssr/fog-of-war.js +1 -1
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/development/lib/dom/ssr/routes.js +1 -1
- package/dist/development/lib/dom/ssr/server.js +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.js +1 -1
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +1 -1
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.d.ts +33 -6
- package/dist/development/lib/hooks.js +34 -7
- package/dist/development/lib/href.js +6 -3
- package/dist/development/lib/router/history.js +1 -1
- package/dist/development/lib/router/instrumentation.d.ts +33 -8
- package/dist/development/lib/router/instrumentation.js +176 -99
- package/dist/development/lib/router/router.js +20 -20
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.js +21 -4
- package/dist/development/lib/rsc/browser.js +1 -1
- package/dist/development/lib/rsc/errorBoundaries.js +1 -1
- package/dist/development/lib/rsc/html-stream/browser.js +1 -1
- package/dist/development/lib/rsc/html-stream/server.js +1 -1
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +3 -2
- package/dist/development/lib/rsc/server.ssr.js +1 -1
- package/dist/development/lib/server-runtime/cookies.js +1 -1
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +12 -5
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions.js +1 -1
- package/dist/development/lib/server-runtime/single-fetch.js +1 -1
- package/dist/development/lib/server-runtime/urls.js +1 -1
- package/dist/development/lib/server-runtime/warnings.js +1 -1
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
- package/dist/production/dom-export.js +1 -1
- package/dist/production/index-react-server-client.js +1 -1
- package/dist/production/index-react-server.d.ts +35 -9
- package/dist/production/index-react-server.js +190 -157
- package/dist/production/index.d.ts +2 -2
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/components.js +1 -1
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.js +1 -1
- package/dist/production/lib/dom/lib.js +2 -2
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +1 -1
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/production/lib/dom/ssr/fallback.js +1 -1
- package/dist/production/lib/dom/ssr/fog-of-war.js +1 -1
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.js +1 -1
- package/dist/production/lib/dom/ssr/routes.js +1 -1
- package/dist/production/lib/dom/ssr/server.js +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.js +1 -1
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +1 -1
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.d.ts +33 -6
- package/dist/production/lib/hooks.js +34 -7
- package/dist/production/lib/href.js +6 -3
- package/dist/production/lib/router/history.js +1 -1
- package/dist/production/lib/router/instrumentation.d.ts +33 -8
- package/dist/production/lib/router/instrumentation.js +176 -99
- package/dist/production/lib/router/router.js +20 -20
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.js +21 -4
- package/dist/production/lib/rsc/browser.js +1 -1
- package/dist/production/lib/rsc/errorBoundaries.js +1 -1
- package/dist/production/lib/rsc/html-stream/browser.js +1 -1
- package/dist/production/lib/rsc/html-stream/server.js +1 -1
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +3 -2
- package/dist/production/lib/rsc/server.ssr.js +1 -1
- package/dist/production/lib/server-runtime/cookies.js +1 -1
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +12 -5
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions.js +1 -1
- package/dist/production/lib/server-runtime/single-fetch.js +1 -1
- package/dist/production/lib/server-runtime/urls.js +1 -1
- package/dist/production/lib/server-runtime/warnings.js +1 -1
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/hot-module-replacement.md +1 -1
- package/docs/how-to/data-strategy.md +1 -1
- package/docs/how-to/instrumentation.md +131 -26
- package/docs/start/framework/deploying.md +4 -0
- package/docs/upgrading/component-routes.md +2 -2
- package/docs/upgrading/future.md +33 -0
- package/docs/upgrading/router-provider.md +6 -6
- package/docs/upgrading/v7.md +39 -22
- package/package.json +1 -1
|
@@ -143,12 +143,16 @@ interface NavigateFunction {
|
|
|
143
143
|
* All properties are optional.
|
|
144
144
|
*
|
|
145
145
|
* ```tsx
|
|
146
|
-
* navigate(
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
146
|
+
* navigate(
|
|
147
|
+
* {
|
|
148
|
+
* pathname: "/some/route",
|
|
149
|
+
* search: "?search=param",
|
|
150
|
+
* hash: "#hash",
|
|
151
|
+
* },
|
|
152
|
+
* {
|
|
153
|
+
* state: { some: "state" },
|
|
154
|
+
* },
|
|
155
|
+
* );
|
|
152
156
|
* ```
|
|
153
157
|
*
|
|
154
158
|
* If you use `state`, that will be available on the {@link Location} object on
|
|
@@ -576,6 +580,29 @@ declare function useRevalidator(): {
|
|
|
576
580
|
* parent/child routes or the route [`handle`](../../start/framework/route-module#handle)
|
|
577
581
|
* property
|
|
578
582
|
*
|
|
583
|
+
* Pairing the route `handle` with `useMatches` gets very powerful since you can put
|
|
584
|
+
* whatever you want on a route handle and have access to `useMatches` anywhere.
|
|
585
|
+
* Please see the [handle](../../how-to/using-handle) documentation for an example
|
|
586
|
+
* of breadcrumbs via `useMatches`/`handle`.
|
|
587
|
+
*
|
|
588
|
+
* ```tsx
|
|
589
|
+
* import { useMatches } from "react-router";
|
|
590
|
+
*
|
|
591
|
+
* function SomeComponent() {
|
|
592
|
+
* const matches = useMatches();
|
|
593
|
+
* // matches[i].id // route id
|
|
594
|
+
* // matches[i].pathname // the portion of the URL the route matched
|
|
595
|
+
* // matches[i].params // the parsed params from the URL
|
|
596
|
+
* // matches[i].loaderData // the data from the loader
|
|
597
|
+
* // matches[i].handle // the route handle with any app specific data
|
|
598
|
+
* }
|
|
599
|
+
* ```
|
|
600
|
+
*
|
|
601
|
+
* <docs-info>useMatches only works with a data router like `createBrowserRouter`,
|
|
602
|
+
* since they know the full route tree up front and can provide all of the current
|
|
603
|
+
* matches. Additionally, `useMatches` will not match down into any descendant route
|
|
604
|
+
* trees since the router isn't aware of the descendant routes.</docs-info>
|
|
605
|
+
*
|
|
579
606
|
* @public
|
|
580
607
|
* @category Hooks
|
|
581
608
|
* @mode framework
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.0
|
|
2
|
+
* react-router v8.2.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -162,12 +162,16 @@ const navigateEffectWarning = "You should call navigate() in a React.useEffect()
|
|
|
162
162
|
* All properties are optional.
|
|
163
163
|
*
|
|
164
164
|
* ```tsx
|
|
165
|
-
* navigate(
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
165
|
+
* navigate(
|
|
166
|
+
* {
|
|
167
|
+
* pathname: "/some/route",
|
|
168
|
+
* search: "?search=param",
|
|
169
|
+
* hash: "#hash",
|
|
170
|
+
* },
|
|
171
|
+
* {
|
|
172
|
+
* state: { some: "state" },
|
|
173
|
+
* },
|
|
174
|
+
* );
|
|
171
175
|
* ```
|
|
172
176
|
*
|
|
173
177
|
* If you use `state`, that will be available on the {@link Location} object on
|
|
@@ -904,6 +908,29 @@ function useRevalidator() {
|
|
|
904
908
|
* parent/child routes or the route [`handle`](../../start/framework/route-module#handle)
|
|
905
909
|
* property
|
|
906
910
|
*
|
|
911
|
+
* Pairing the route `handle` with `useMatches` gets very powerful since you can put
|
|
912
|
+
* whatever you want on a route handle and have access to `useMatches` anywhere.
|
|
913
|
+
* Please see the [handle](../../how-to/using-handle) documentation for an example
|
|
914
|
+
* of breadcrumbs via `useMatches`/`handle`.
|
|
915
|
+
*
|
|
916
|
+
* ```tsx
|
|
917
|
+
* import { useMatches } from "react-router";
|
|
918
|
+
*
|
|
919
|
+
* function SomeComponent() {
|
|
920
|
+
* const matches = useMatches();
|
|
921
|
+
* // matches[i].id // route id
|
|
922
|
+
* // matches[i].pathname // the portion of the URL the route matched
|
|
923
|
+
* // matches[i].params // the parsed params from the URL
|
|
924
|
+
* // matches[i].loaderData // the data from the loader
|
|
925
|
+
* // matches[i].handle // the route handle with any app specific data
|
|
926
|
+
* }
|
|
927
|
+
* ```
|
|
928
|
+
*
|
|
929
|
+
* <docs-info>useMatches only works with a data router like `createBrowserRouter`,
|
|
930
|
+
* since they know the full route tree up front and can provide all of the current
|
|
931
|
+
* matches. Additionally, `useMatches` will not match down into any descendant route
|
|
932
|
+
* trees since the router isn't aware of the descendant routes.</docs-info>
|
|
933
|
+
*
|
|
907
934
|
* @public
|
|
908
935
|
* @category Hooks
|
|
909
936
|
* @mode framework
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.0
|
|
2
|
+
* react-router v8.2.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
11
|
//#region lib/href.ts
|
|
12
|
+
function stringify(p) {
|
|
13
|
+
return p == null ? "" : typeof p === "string" ? p : String(p);
|
|
14
|
+
}
|
|
12
15
|
/**
|
|
13
16
|
Returns a resolved URL path for the specified route.
|
|
14
17
|
|
|
@@ -25,11 +28,11 @@ function href(path, ...args) {
|
|
|
25
28
|
const isRequired = questionMark === void 0;
|
|
26
29
|
const value = params?.[param];
|
|
27
30
|
if (isRequired && value === void 0) throw new Error(`Path '${path}' requires param '${param}' but it was not provided`);
|
|
28
|
-
return value
|
|
31
|
+
return value == null ? "" : "/" + encodeURIComponent(stringify(value));
|
|
29
32
|
});
|
|
30
33
|
if (path.endsWith("*")) {
|
|
31
34
|
const value = params?.["*"];
|
|
32
|
-
if (value !== void 0) result += "/" + value;
|
|
35
|
+
if (value !== void 0) result += "/" + stringify(value).split("/").map(encodeURIComponent).join("/");
|
|
33
36
|
}
|
|
34
37
|
return result || "/";
|
|
35
38
|
}
|
|
@@ -12,6 +12,19 @@ type ClientInstrumentation = {
|
|
|
12
12
|
type InstrumentRequestHandlerFunction = (handler: InstrumentableRequestHandler) => void;
|
|
13
13
|
type InstrumentRouterFunction = (router: InstrumentableRouter) => void;
|
|
14
14
|
type InstrumentRouteFunction = (route: InstrumentableRoute) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Route metadata available after React Router has matched an instrumented
|
|
17
|
+
* request, navigation, or fetcher call.
|
|
18
|
+
*/
|
|
19
|
+
type InstrumentationResultMeta = {
|
|
20
|
+
url: LoaderFunctionArgs["url"];
|
|
21
|
+
pattern: string;
|
|
22
|
+
params: LoaderFunctionArgs["params"];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Result returned by route-level instrumented handler calls, such as
|
|
26
|
+
* instrumented loaders, actions, middleware, and lazy route functions.
|
|
27
|
+
*/
|
|
15
28
|
type InstrumentationHandlerResult = {
|
|
16
29
|
status: "success";
|
|
17
30
|
error: undefined;
|
|
@@ -19,7 +32,21 @@ type InstrumentationHandlerResult = {
|
|
|
19
32
|
status: "error";
|
|
20
33
|
error: Error;
|
|
21
34
|
};
|
|
22
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Result returned by client-side router instrumented navigation and fetcher
|
|
37
|
+
* calls.
|
|
38
|
+
*/
|
|
39
|
+
type InstrumentationClientRouterResult = InstrumentationHandlerResult & {
|
|
40
|
+
meta: InstrumentationResultMeta | undefined;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Result returned by server request handler instrumentation.
|
|
44
|
+
*/
|
|
45
|
+
type InstrumentationServerHandlerResult = InstrumentationHandlerResult & {
|
|
46
|
+
statusCode: number;
|
|
47
|
+
meta: InstrumentationResultMeta | undefined;
|
|
48
|
+
};
|
|
49
|
+
type InstrumentFunction<T, TInnerResult = InstrumentationHandlerResult> = (handler: () => Promise<TInnerResult>, info: T) => Promise<void>;
|
|
23
50
|
type ReadonlyRequest = {
|
|
24
51
|
method: string;
|
|
25
52
|
url: string;
|
|
@@ -42,18 +69,16 @@ type RouteInstrumentations = {
|
|
|
42
69
|
action?: InstrumentFunction<RouteHandlerInstrumentationInfo>;
|
|
43
70
|
};
|
|
44
71
|
type RouteLazyInstrumentationInfo = undefined;
|
|
45
|
-
type RouteHandlerInstrumentationInfo = Readonly<{
|
|
72
|
+
type RouteHandlerInstrumentationInfo = Readonly<Omit<LoaderFunctionArgs, "request" | "context"> & {
|
|
46
73
|
request: ReadonlyRequest;
|
|
47
|
-
params: LoaderFunctionArgs["params"];
|
|
48
|
-
pattern: string;
|
|
49
74
|
context: ReadonlyContext;
|
|
50
75
|
}>;
|
|
51
76
|
type InstrumentableRouter = {
|
|
52
77
|
instrument(instrumentations: RouterInstrumentations): void;
|
|
53
78
|
};
|
|
54
79
|
type RouterInstrumentations = {
|
|
55
|
-
navigate?: InstrumentFunction<RouterNavigationInstrumentationInfo>;
|
|
56
|
-
fetch?: InstrumentFunction<RouterFetchInstrumentationInfo>;
|
|
80
|
+
navigate?: InstrumentFunction<RouterNavigationInstrumentationInfo, InstrumentationClientRouterResult>;
|
|
81
|
+
fetch?: InstrumentFunction<RouterFetchInstrumentationInfo, InstrumentationClientRouterResult>;
|
|
57
82
|
};
|
|
58
83
|
type RouterNavigationInstrumentationInfo = Readonly<{
|
|
59
84
|
to: string | number;
|
|
@@ -76,11 +101,11 @@ type InstrumentableRequestHandler = {
|
|
|
76
101
|
instrument(instrumentations: RequestHandlerInstrumentations): void;
|
|
77
102
|
};
|
|
78
103
|
type RequestHandlerInstrumentations = {
|
|
79
|
-
request?: InstrumentFunction<RequestHandlerInstrumentationInfo>;
|
|
104
|
+
request?: InstrumentFunction<RequestHandlerInstrumentationInfo, InstrumentationServerHandlerResult>;
|
|
80
105
|
};
|
|
81
106
|
type RequestHandlerInstrumentationInfo = Readonly<{
|
|
82
107
|
request: ReadonlyRequest;
|
|
83
108
|
context: ReadonlyContext | undefined;
|
|
84
109
|
}>;
|
|
85
110
|
//#endregion
|
|
86
|
-
export { ClientInstrumentation, InstrumentRequestHandlerFunction, InstrumentRouteFunction, InstrumentRouterFunction, InstrumentationHandlerResult, ServerInstrumentation };
|
|
111
|
+
export { ClientInstrumentation, InstrumentRequestHandlerFunction, InstrumentRouteFunction, InstrumentRouterFunction, InstrumentationClientRouterResult, InstrumentationHandlerResult, InstrumentationServerHandlerResult, ServerInstrumentation };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.0
|
|
2
|
+
* react-router v8.2.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
11
|
import { createPath, invariant } from "./history.js";
|
|
12
|
+
import { RouterContextProvider, createContext } from "./utils.js";
|
|
12
13
|
//#region lib/router/instrumentation.ts
|
|
13
14
|
const UninstrumentedSymbol = Symbol("Uninstrumented");
|
|
15
|
+
const instrumentationResultMetaContext = createContext();
|
|
16
|
+
let instrumentationClientResultMetaReceivers = /* @__PURE__ */ new WeakMap();
|
|
14
17
|
function getRouteInstrumentationUpdates(fns, route) {
|
|
15
18
|
let aggregated = {
|
|
16
19
|
lazy: [],
|
|
@@ -26,50 +29,67 @@ function getRouteInstrumentationUpdates(fns, route) {
|
|
|
26
29
|
index: route.index,
|
|
27
30
|
path: route.path,
|
|
28
31
|
instrument(i) {
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
if (i.lazy != null) aggregated.lazy.push(i.lazy);
|
|
33
|
+
if (i["lazy.loader"] != null) aggregated["lazy.loader"].push(i["lazy.loader"]);
|
|
34
|
+
if (i["lazy.action"] != null) aggregated["lazy.action"].push(i["lazy.action"]);
|
|
35
|
+
if (i["lazy.middleware"] != null) aggregated["lazy.middleware"].push(i["lazy.middleware"]);
|
|
36
|
+
if (i.middleware != null) aggregated.middleware.push(i.middleware);
|
|
37
|
+
if (i.loader != null) aggregated.loader.push(i.loader);
|
|
38
|
+
if (i.action != null) aggregated.action.push(i.action);
|
|
31
39
|
}
|
|
32
40
|
}));
|
|
33
41
|
let updates = {};
|
|
34
42
|
if (typeof route.lazy === "function" && aggregated.lazy.length > 0) {
|
|
35
|
-
let
|
|
36
|
-
|
|
43
|
+
let lazy = route.lazy;
|
|
44
|
+
updates.lazy = async (...args) => {
|
|
45
|
+
return throwOrReturnResult(await recurseRight(aggregated.lazy, void 0, () => lazy(...args), getInstrumentationInnerResult));
|
|
46
|
+
};
|
|
37
47
|
}
|
|
38
48
|
if (typeof route.lazy === "object") {
|
|
39
49
|
let lazyObject = route.lazy;
|
|
40
|
-
[
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
let lazyFn = lazyObject[key];
|
|
46
|
-
let instrumentations = aggregated[`lazy.${key}`];
|
|
47
|
-
if (typeof lazyFn === "function" && instrumentations.length > 0) {
|
|
48
|
-
let instrumented = wrapImpl(instrumentations, lazyFn, () => void 0);
|
|
49
|
-
if (instrumented) updates.lazy = Object.assign(updates.lazy || {}, { [key]: instrumented });
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
["loader", "action"].forEach((key) => {
|
|
54
|
-
let handler = route[key];
|
|
55
|
-
if (typeof handler === "function" && aggregated[key].length > 0) {
|
|
56
|
-
let original = handler[UninstrumentedSymbol] ?? handler;
|
|
57
|
-
let instrumented = wrapImpl(aggregated[key], original, (...args) => getHandlerInfo(args[0]));
|
|
58
|
-
if (instrumented) {
|
|
59
|
-
if (key === "loader" && original.hydrate === true) instrumented.hydrate = true;
|
|
60
|
-
instrumented[UninstrumentedSymbol] = original;
|
|
61
|
-
updates[key] = instrumented;
|
|
62
|
-
}
|
|
50
|
+
if (typeof lazyObject.middleware === "function" && aggregated["lazy.middleware"].length > 0) {
|
|
51
|
+
let middleware = lazyObject.middleware;
|
|
52
|
+
updates.lazy = Object.assign(updates.lazy || {}, { middleware: async (...args) => {
|
|
53
|
+
return throwOrReturnResult(await recurseRight(aggregated["lazy.middleware"], void 0, () => middleware(...args), getInstrumentationInnerResult));
|
|
54
|
+
} });
|
|
63
55
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
if (typeof lazyObject.loader === "function" && aggregated["lazy.loader"].length > 0) {
|
|
57
|
+
let loader = lazyObject.loader;
|
|
58
|
+
updates.lazy = Object.assign(updates.lazy || {}, { loader: async (...args) => {
|
|
59
|
+
return throwOrReturnResult(await recurseRight(aggregated["lazy.loader"], void 0, () => loader(...args), getInstrumentationInnerResult));
|
|
60
|
+
} });
|
|
61
|
+
}
|
|
62
|
+
if (typeof lazyObject.action === "function" && aggregated["lazy.action"].length > 0) {
|
|
63
|
+
let action = lazyObject.action;
|
|
64
|
+
updates.lazy = Object.assign(updates.lazy || {}, { action: async (...args) => {
|
|
65
|
+
return throwOrReturnResult(await recurseRight(aggregated["lazy.action"], void 0, () => action(...args), getInstrumentationInnerResult));
|
|
66
|
+
} });
|
|
71
67
|
}
|
|
72
|
-
|
|
68
|
+
}
|
|
69
|
+
if (typeof route.loader === "function" && aggregated.loader.length > 0) {
|
|
70
|
+
let original = getUninstrumentedHandler(route.loader);
|
|
71
|
+
let instrumented = async (...args) => {
|
|
72
|
+
return throwOrReturnResult(await recurseRight(aggregated.loader, getHandlerInfo(args[0]), () => original(...args), getInstrumentationInnerResult));
|
|
73
|
+
};
|
|
74
|
+
if (original.hydrate === true) instrumented.hydrate = true;
|
|
75
|
+
setUninstrumentedHandler(instrumented, original);
|
|
76
|
+
updates.loader = instrumented;
|
|
77
|
+
}
|
|
78
|
+
if (typeof route.action === "function" && aggregated.action.length > 0) {
|
|
79
|
+
let original = getUninstrumentedHandler(route.action);
|
|
80
|
+
let instrumented = async (...args) => {
|
|
81
|
+
return throwOrReturnResult(await recurseRight(aggregated.action, getHandlerInfo(args[0]), () => original(...args), getInstrumentationInnerResult));
|
|
82
|
+
};
|
|
83
|
+
setUninstrumentedHandler(instrumented, original);
|
|
84
|
+
updates.action = instrumented;
|
|
85
|
+
}
|
|
86
|
+
if (route.middleware && route.middleware.length > 0 && aggregated.middleware.length > 0) updates.middleware = route.middleware.map((middleware) => {
|
|
87
|
+
let original = getUninstrumentedHandler(middleware);
|
|
88
|
+
let instrumented = async (...args) => {
|
|
89
|
+
return throwOrReturnResult(await recurseRight(aggregated.middleware, getHandlerInfo(args[0]), () => original(...args), getInstrumentationInnerResult));
|
|
90
|
+
};
|
|
91
|
+
setUninstrumentedHandler(instrumented, original);
|
|
92
|
+
return instrumented;
|
|
73
93
|
});
|
|
74
94
|
return updates;
|
|
75
95
|
}
|
|
@@ -79,93 +99,138 @@ function instrumentClientSideRouter(router, fns) {
|
|
|
79
99
|
fetch: []
|
|
80
100
|
};
|
|
81
101
|
fns.forEach((fn) => fn({ instrument(i) {
|
|
82
|
-
|
|
83
|
-
|
|
102
|
+
if (i.navigate != null) aggregated.navigate.push(i.navigate);
|
|
103
|
+
if (i.fetch != null) aggregated.fetch.push(i.fetch);
|
|
84
104
|
} }));
|
|
85
105
|
if (aggregated.navigate.length > 0) {
|
|
86
|
-
let navigate = router.navigate
|
|
87
|
-
let instrumentedNavigate =
|
|
106
|
+
let navigate = getUninstrumentedHandler(router.navigate);
|
|
107
|
+
let instrumentedNavigate = async (...args) => {
|
|
88
108
|
let [to, opts] = args;
|
|
89
|
-
|
|
109
|
+
let meta;
|
|
110
|
+
let info = {
|
|
90
111
|
to: typeof to === "number" || typeof to === "string" ? to : to ? createPath(to) : ".",
|
|
91
112
|
...getRouterInfo(router, opts ?? {})
|
|
92
113
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
114
|
+
return throwOrReturnResult(await recurseRight(aggregated.navigate, info, async () => {
|
|
115
|
+
if (typeof to === "number") return await navigate(...args);
|
|
116
|
+
let cleanup = setInstrumentationClientResultMetaReceiver(router, (value) => {
|
|
117
|
+
meta = value;
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
return await navigate(...args);
|
|
121
|
+
} finally {
|
|
122
|
+
cleanup();
|
|
123
|
+
}
|
|
124
|
+
}, (result) => ({
|
|
125
|
+
...getInstrumentationInnerResult(result),
|
|
126
|
+
meta
|
|
127
|
+
})));
|
|
128
|
+
};
|
|
129
|
+
setUninstrumentedHandler(instrumentedNavigate, navigate);
|
|
130
|
+
router.navigate = instrumentedNavigate;
|
|
98
131
|
}
|
|
99
132
|
if (aggregated.fetch.length > 0) {
|
|
100
|
-
let fetch = router.fetch
|
|
101
|
-
let instrumentedFetch =
|
|
102
|
-
let [key, , href, opts] = args;
|
|
103
|
-
|
|
133
|
+
let fetch = getUninstrumentedHandler(router.fetch);
|
|
134
|
+
let instrumentedFetch = async (...args) => {
|
|
135
|
+
let [key, _, href, opts] = args;
|
|
136
|
+
let meta;
|
|
137
|
+
return throwOrReturnResult(await recurseRight(aggregated.fetch, {
|
|
104
138
|
href: href ?? ".",
|
|
105
139
|
fetcherKey: key,
|
|
106
140
|
...getRouterInfo(router, opts ?? {})
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
141
|
+
}, async () => {
|
|
142
|
+
let cleanup = setInstrumentationClientResultMetaReceiver(router, (value) => {
|
|
143
|
+
meta = value;
|
|
144
|
+
});
|
|
145
|
+
try {
|
|
146
|
+
return await fetch(...args);
|
|
147
|
+
} finally {
|
|
148
|
+
cleanup();
|
|
149
|
+
}
|
|
150
|
+
}, (result) => ({
|
|
151
|
+
...getInstrumentationInnerResult(result),
|
|
152
|
+
meta
|
|
153
|
+
})));
|
|
154
|
+
};
|
|
155
|
+
setUninstrumentedHandler(instrumentedFetch, fetch);
|
|
156
|
+
router.fetch = instrumentedFetch;
|
|
113
157
|
}
|
|
114
158
|
return router;
|
|
115
159
|
}
|
|
116
160
|
function instrumentHandler(handler, fns) {
|
|
117
161
|
let aggregated = { request: [] };
|
|
118
162
|
fns.forEach((fn) => fn({ instrument(i) {
|
|
119
|
-
|
|
120
|
-
for (let key of keys) if (i[key]) aggregated[key].push(i[key]);
|
|
163
|
+
if (i.request != null) aggregated.request.push(i.request);
|
|
121
164
|
} }));
|
|
122
165
|
let instrumentedHandler = handler;
|
|
123
|
-
if (aggregated.request.length > 0) instrumentedHandler =
|
|
166
|
+
if (aggregated.request.length > 0) instrumentedHandler = async (...args) => {
|
|
124
167
|
let [request, context] = args;
|
|
125
|
-
|
|
168
|
+
let instrumentationContext = context ?? new RouterContextProvider();
|
|
169
|
+
return throwOrReturnResult(await recurseRight(aggregated.request, {
|
|
126
170
|
request: getReadonlyRequest(request),
|
|
127
|
-
context:
|
|
128
|
-
}
|
|
129
|
-
|
|
171
|
+
context: getReadonlyContext(instrumentationContext)
|
|
172
|
+
}, () => handler(request, instrumentationContext), (result, info) => {
|
|
173
|
+
let meta;
|
|
174
|
+
try {
|
|
175
|
+
meta = info.context?.get(instrumentationResultMetaContext);
|
|
176
|
+
} catch {}
|
|
177
|
+
invariant(result.value instanceof Response, "Expected a Response from the request handler");
|
|
178
|
+
return {
|
|
179
|
+
...getInstrumentationInnerResult(result),
|
|
180
|
+
statusCode: result.value.status,
|
|
181
|
+
meta
|
|
182
|
+
};
|
|
183
|
+
}));
|
|
184
|
+
};
|
|
130
185
|
return instrumentedHandler;
|
|
131
186
|
}
|
|
132
|
-
function
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
187
|
+
function getUninstrumentedHandler(handler) {
|
|
188
|
+
return handler[UninstrumentedSymbol] ?? handler;
|
|
189
|
+
}
|
|
190
|
+
function setUninstrumentedHandler(handler, uninstrumentedHandler) {
|
|
191
|
+
handler[UninstrumentedSymbol] = uninstrumentedHandler;
|
|
192
|
+
}
|
|
193
|
+
function setInstrumentationClientResultMetaReceiver(router, receiver) {
|
|
194
|
+
instrumentationClientResultMetaReceivers.set(router, receiver);
|
|
195
|
+
return () => {
|
|
196
|
+
if (instrumentationClientResultMetaReceivers.get(router) === receiver) instrumentationClientResultMetaReceivers.delete(router);
|
|
138
197
|
};
|
|
139
198
|
}
|
|
140
|
-
|
|
199
|
+
function consumeInstrumentationClientResultMetaReceiver(router) {
|
|
200
|
+
let receiver = instrumentationClientResultMetaReceivers.get(router);
|
|
201
|
+
instrumentationClientResultMetaReceivers.delete(router);
|
|
202
|
+
return receiver;
|
|
203
|
+
}
|
|
204
|
+
function throwOrReturnResult(result) {
|
|
205
|
+
if (result.type === "error") throw result.value;
|
|
206
|
+
return result.value;
|
|
207
|
+
}
|
|
208
|
+
async function recurseRight(impls, info, handler, getInnerResult, state = {
|
|
209
|
+
result: null,
|
|
210
|
+
innerResult: null
|
|
211
|
+
}, index = impls.length - 1) {
|
|
141
212
|
let impl = impls[index];
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
213
|
+
if (!impl) {
|
|
214
|
+
try {
|
|
215
|
+
state.result = {
|
|
216
|
+
type: "success",
|
|
217
|
+
value: await handler()
|
|
218
|
+
};
|
|
219
|
+
} catch (e) {
|
|
220
|
+
state.result = {
|
|
221
|
+
type: "error",
|
|
222
|
+
value: e
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
state.innerResult = getInnerResult(state.result, info);
|
|
226
|
+
} else {
|
|
155
227
|
let handlerPromise = void 0;
|
|
156
228
|
let callHandler = async () => {
|
|
157
229
|
if (handlerPromise) console.error("You cannot call instrumented handlers more than once");
|
|
158
|
-
else handlerPromise = recurseRight(impls, info, handler, index - 1);
|
|
159
|
-
|
|
160
|
-
invariant(
|
|
161
|
-
|
|
162
|
-
status: "error",
|
|
163
|
-
error: result.value
|
|
164
|
-
};
|
|
165
|
-
return {
|
|
166
|
-
status: "success",
|
|
167
|
-
error: void 0
|
|
168
|
-
};
|
|
230
|
+
else handlerPromise = recurseRight(impls, info, handler, getInnerResult, state, index - 1);
|
|
231
|
+
await handlerPromise;
|
|
232
|
+
invariant(state.innerResult, "Expected an inner result");
|
|
233
|
+
return state.innerResult;
|
|
169
234
|
};
|
|
170
235
|
try {
|
|
171
236
|
await impl(callHandler, info);
|
|
@@ -175,18 +240,30 @@ async function recurseRight(impls, info, handler, index) {
|
|
|
175
240
|
if (!handlerPromise) await callHandler();
|
|
176
241
|
await handlerPromise;
|
|
177
242
|
}
|
|
178
|
-
if (result) return result;
|
|
179
|
-
|
|
243
|
+
if (state.result) return state.result;
|
|
244
|
+
state.result = {
|
|
180
245
|
type: "error",
|
|
181
246
|
value: /* @__PURE__ */ new Error("No result assigned in instrumentation chain.")
|
|
182
247
|
};
|
|
248
|
+
state.innerResult = getInnerResult(state.result, info);
|
|
249
|
+
return state.result;
|
|
250
|
+
}
|
|
251
|
+
function getInstrumentationInnerResult(result) {
|
|
252
|
+
if (result.type === "error" && result.value instanceof Error) return {
|
|
253
|
+
status: "error",
|
|
254
|
+
error: result.value
|
|
255
|
+
};
|
|
256
|
+
return {
|
|
257
|
+
status: "success",
|
|
258
|
+
error: void 0
|
|
259
|
+
};
|
|
183
260
|
}
|
|
184
261
|
function getHandlerInfo(args) {
|
|
185
|
-
let { request, context, params
|
|
262
|
+
let { request, context, params } = args;
|
|
186
263
|
return {
|
|
264
|
+
...args,
|
|
187
265
|
request: getReadonlyRequest(request),
|
|
188
266
|
params: { ...params },
|
|
189
|
-
pattern,
|
|
190
267
|
context: getReadonlyContext(context)
|
|
191
268
|
};
|
|
192
269
|
}
|
|
@@ -210,4 +287,4 @@ function getReadonlyContext(context) {
|
|
|
210
287
|
return { get: (ctx) => context.get(ctx) };
|
|
211
288
|
}
|
|
212
289
|
//#endregion
|
|
213
|
-
export { getRouteInstrumentationUpdates, instrumentClientSideRouter, instrumentHandler };
|
|
290
|
+
export { consumeInstrumentationClientResultMetaReceiver, getRouteInstrumentationUpdates, instrumentClientSideRouter, instrumentHandler, instrumentationResultMetaContext };
|