Skip to content

Commit 4627a60

Browse files
committed
add middleware logs and events
1 parent 615671c commit 4627a60

19 files changed

Lines changed: 1272 additions & 18 deletions

File tree

packages/react-router-devtools/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
"require": "./dist/client.css"
6060
}
6161
},
62-
"files": ["dist"],
62+
"files": [
63+
"dist"
64+
],
6365
"repository": {
6466
"type": "git",
6567
"url": "git+https://github.com/forge-42/react-router-devtools.git"
@@ -157,4 +159,4 @@
157159
"@rollup/rollup-darwin-arm64": "^4.32.1",
158160
"@rollup/rollup-linux-x64-gnu": "^4.32.1"
159161
}
160-
}
162+
}

packages/react-router-devtools/src/client.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@
22
export { EmbeddedDevTools } from "./client/embedded-dev-tools.js"
33
export { withViteDevTools } from "./client/init/root.js"
44
export { defineClientConfig } from "./client/init/root.js"
5-
export { withClientLoaderWrapper, withClientActionWrapper, withLinksWrapper } from "./client/hof.js"
5+
export {
6+
withClientLoaderWrapper,
7+
withClientActionWrapper,
8+
withLinksWrapper,
9+
withClientMiddlewareWrapper,
10+
withClientMiddlewareWrapperSingle,
11+
} from "./client/hof.js"

packages/react-router-devtools/src/client/components/network-tracer/NetworkBar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ interface NetworkBarProps {
2020
const COLORS = {
2121
loader: "#4ade80",
2222
"client-loader": "#60a5fa",
23-
action: "#f59e0b",
23+
action: "#FFD700",
2424
"client-action": "#ef4444",
25+
middleware: "#FFA500",
26+
"client-middleware": "#FF69B4",
2527
"custom-event": "#ffffff",
2628
pending: "#94a3b8",
2729
error: "#dc2626",

packages/react-router-devtools/src/client/components/network-tracer/NetworkWaterfall.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,28 @@ const TYPE_TEXT_COLORS = {
2929
"client-loader": "text-blue-500",
3030
action: "text-yellow-500",
3131
"client-action": "text-purple-500",
32+
middleware: "text-orange-500",
33+
"client-middleware": "text-pink-400",
3234
"custom-event": "text-white",
3335
}
3436

35-
type EventType = "loader" | "client-loader" | "action" | "client-action" | "custom-event"
37+
type EventType =
38+
| "loader"
39+
| "client-loader"
40+
| "action"
41+
| "client-action"
42+
| "middleware"
43+
| "client-middleware"
44+
| "custom-event"
3645

3746
const EVENT_TYPE_FILTERS: { value: EventType | "all"; label: string; color: string }[] = [
3847
{ value: "all", label: "All Events", color: "#ffffff" },
3948
{ value: "loader", label: "Loader", color: "#4ade80" },
4049
{ value: "client-loader", label: "Client Loader", color: "#60a5fa" },
41-
{ value: "action", label: "Action", color: "#f59e0b" },
50+
{ value: "action", label: "Action", color: "#FFD700" },
4251
{ value: "client-action", label: "Client Action", color: "#ef4444" },
52+
{ value: "middleware", label: "Middleware", color: "#FFA500" },
53+
{ value: "client-middleware", label: "Client Middleware", color: "#FF69B4" },
4354
{ value: "custom-event", label: "Custom Event", color: "#ffffff" },
4455
]
4556

@@ -201,6 +212,7 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
201212
}}
202213
onClick={() => setActiveTypeFilter(filter.value)}
203214
>
215+
<span className={styles.network.waterfall.filterColorCircle} style={{ backgroundColor: filter.color }} />
204216
{filter.label}
205217
{filter.value !== "all" && (
206218
<span className={styles.network.waterfall.filterCount}>
@@ -292,7 +304,11 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
292304
? styles.network.waterfall.requestButtonYellow
293305
: request.type === "client-action"
294306
? styles.network.waterfall.requestButtonPurple
295-
: styles.network.waterfall.requestButtonWhite
307+
: request.type === "middleware"
308+
? styles.network.waterfall.requestButtonOrange
309+
: request.type === "client-middleware"
310+
? styles.network.waterfall.requestButtonPinkLight
311+
: styles.network.waterfall.requestButtonWhite
296312

297313
const indicatorColorClass =
298314
request.type === "loader"
@@ -303,7 +319,11 @@ const NetworkWaterfall: React.FC<Props> = ({ requests, width }) => {
303319
? styles.network.waterfall.requestIndicatorYellow
304320
: request.type === "client-action"
305321
? styles.network.waterfall.requestIndicatorPurple
306-
: styles.network.waterfall.requestIndicatorWhite
322+
: request.type === "middleware"
323+
? styles.network.waterfall.requestIndicatorOrange
324+
: request.type === "client-middleware"
325+
? styles.network.waterfall.requestIndicatorPinkLight
326+
: styles.network.waterfall.requestIndicatorWhite
307327

308328
return (
309329
<div

packages/react-router-devtools/src/client/components/network-tracer/RequestDetails.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ export const RequestDetails: React.FC<RequestDetailsProps> = ({ request, onClose
3131
? styles.network.details.typeBadgeYellow
3232
: request.type === "client-action"
3333
? styles.network.details.typeBadgePurple
34-
: styles.network.details.typeBadgeWhite
34+
: request.type === "middleware"
35+
? styles.network.details.typeBadgeOrange
36+
: request.type === "client-middleware"
37+
? styles.network.details.typeBadgePinkLight
38+
: styles.network.details.typeBadgeWhite
3539

3640
const duration = request.endTime ? request.endTime - request.startTime : 0
3741

packages/react-router-devtools/src/client/hof.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,57 @@ export const withLinksWrapper = (links: LinksFunction, rdtStylesheet: string): L
7676
export const withClientActionWrapper = (clientAction: (args: ClientActionFunctionArgs) => any, routeId: string) => {
7777
return analyzeClientLoaderOrAction(clientAction, routeId, "client-action")
7878
}
79+
80+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
81+
const analyzeClientMiddleware = (middleware: any, routeId: string, index: number, middlewareName?: string) => {
82+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
83+
return async (args: any, next: any) => {
84+
const startTime = Date.now()
85+
const name = middlewareName || middleware.name || `Anonymous ${index}`
86+
87+
sendEventToDevServer({
88+
type: "client-middleware",
89+
url: args.request.url,
90+
headers: Object.fromEntries(args.request.headers.entries()),
91+
startTime,
92+
id: routeId,
93+
routeId: routeId,
94+
method: args.request.method,
95+
middlewareName: name,
96+
middlewareIndex: index,
97+
})
98+
99+
const result = await middleware(args, next)
100+
101+
sendEventToDevServer({
102+
type: "client-middleware",
103+
url: args.request.url,
104+
headers: Object.fromEntries(args.request.headers.entries()),
105+
startTime,
106+
endTime: Date.now(),
107+
id: routeId,
108+
routeId: routeId,
109+
method: args.request.method,
110+
middlewareName: name,
111+
middlewareIndex: index,
112+
})
113+
114+
return result
115+
}
116+
}
117+
118+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
119+
export const withClientMiddlewareWrapper = (middlewares: any[], routeId: string) => {
120+
return middlewares.map((middleware, index) => analyzeClientMiddleware(middleware, routeId, index))
121+
}
122+
123+
// Single middleware wrapper for use by AST transformation
124+
export const withClientMiddlewareWrapperSingle = (
125+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
126+
middleware: any,
127+
routeId: string,
128+
index: number,
129+
middlewareName: string
130+
) => {
131+
return analyzeClientMiddleware(middleware, routeId, index, middlewareName)
132+
}

packages/react-router-devtools/src/client/styles/use-styles.ts

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,12 @@ const stylesFactory = (theme: "light" | "dark") => {
15571557
font-weight: 700;
15581558
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
15591559
`,
1560+
filterColorCircle: css`
1561+
width: 0.5rem;
1562+
height: 0.5rem;
1563+
border-radius: 50%;
1564+
flex-shrink: 0;
1565+
`,
15601566
filterCount: css`
15611567
font-size: 0.6875rem;
15621568
opacity: 0.65;
@@ -1648,11 +1654,20 @@ const stylesFactory = (theme: "light" | "dark") => {
16481654
border-color: #3b82f6;
16491655
`,
16501656
requestButtonYellow: css`
1651-
border-color: #eab308;
1657+
border-color: #FFD700;
16521658
`,
16531659
requestButtonPurple: css`
16541660
border-color: #a855f7;
16551661
`,
1662+
requestButtonOrange: css`
1663+
border-color: #FFA500;
1664+
`,
1665+
requestButtonPink: css`
1666+
border-color: #FF1493;
1667+
`,
1668+
requestButtonPinkLight: css`
1669+
border-color: #FF69B4;
1670+
`,
16561671
requestButtonWhite: css`
16571672
border-color: #ffffff;
16581673
`,
@@ -1669,11 +1684,20 @@ const stylesFactory = (theme: "light" | "dark") => {
16691684
background-color: #3b82f6;
16701685
`,
16711686
requestIndicatorYellow: css`
1672-
background-color: #eab308;
1687+
background-color: #FFD700;
16731688
`,
16741689
requestIndicatorPurple: css`
16751690
background-color: #a855f7;
16761691
`,
1692+
requestIndicatorOrange: css`
1693+
background-color: #FFA500;
1694+
`,
1695+
requestIndicatorPink: css`
1696+
background-color: #FF1493;
1697+
`,
1698+
requestIndicatorPinkLight: css`
1699+
background-color: #FF69B4;
1700+
`,
16771701
requestIndicatorWhite: css`
16781702
background-color: #ffffff;
16791703
`,
@@ -1871,15 +1895,30 @@ const stylesFactory = (theme: "light" | "dark") => {
18711895
background-color: rgba(59, 130, 246, 0.15);
18721896
`,
18731897
typeBadgeYellow: css`
1874-
border-color: #eab308;
1875-
color: #eab308;
1876-
background-color: rgba(234, 179, 8, 0.15);
1898+
border-color: #FFD700;
1899+
color: #FFD700;
1900+
background-color: rgba(255, 215, 0, 0.15);
18771901
`,
18781902
typeBadgePurple: css`
18791903
border-color: #a855f7;
18801904
color: #a855f7;
18811905
background-color: rgba(168, 85, 247, 0.15);
18821906
`,
1907+
typeBadgeOrange: css`
1908+
border-color: #FFA500;
1909+
color: #FFA500;
1910+
background-color: rgba(255, 165, 0, 0.15);
1911+
`,
1912+
typeBadgePink: css`
1913+
border-color: #FF1493;
1914+
color: #FF1493;
1915+
background-color: rgba(255, 20, 147, 0.15);
1916+
`,
1917+
typeBadgePinkLight: css`
1918+
border-color: #FF69B4;
1919+
color: #FF69B4;
1920+
background-color: rgba(255, 105, 180, 0.15);
1921+
`,
18831922
typeBadgeWhite: css`
18841923
border-color: #ffffff;
18851924
color: #ffffff;
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
export { defineServerConfig } from "./server/config.js"
2-
export { withLoaderWrapper, withActionWrapper } from "./server/hof.js"
2+
export {
3+
withLoaderWrapper,
4+
withActionWrapper,
5+
withMiddlewareWrapper,
6+
withMiddlewareWrapperSingle,
7+
} from "./server/hof.js"

packages/react-router-devtools/src/server/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ export interface DevToolsServerConfig {
4848
* @default true
4949
*/
5050
serverTimings?: boolean
51+
/**
52+
* Whether to log middleware calls in the console
53+
* @default true
54+
*/
55+
middleware?: boolean
5156
}
5257
}
5358
declare global {

packages/react-router-devtools/src/server/hof.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router"
2-
import { analyzeLoaderOrAction } from "./utils"
2+
import { analyzeLoaderOrAction, analyzeMiddleware } from "./utils"
33

44
// biome-ignore lint/suspicious/noExplicitAny: can be any type
55
export const withLoaderWrapper = (loader: (args: LoaderFunctionArgs) => Promise<any>, id: string) => {
@@ -10,3 +10,20 @@ export const withLoaderWrapper = (loader: (args: LoaderFunctionArgs) => Promise<
1010
export const withActionWrapper = (action: (args: ActionFunctionArgs) => Promise<any>, id: string) => {
1111
return analyzeLoaderOrAction(id, "action", action)
1212
}
13+
14+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
15+
export const withMiddlewareWrapper = (middlewares: any[], routeId: string): any => {
16+
return middlewares.map((middleware, index) => analyzeMiddleware(middleware, routeId, index))
17+
}
18+
19+
// Single middleware wrapper for use by AST transformation
20+
export const withMiddlewareWrapperSingle = (
21+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
22+
middleware: any,
23+
routeId: string,
24+
index: number,
25+
middlewareName: string
26+
// biome-ignore lint/suspicious/noExplicitAny: we don't care about the type
27+
): any => {
28+
return analyzeMiddleware(middleware, routeId, index, middlewareName)
29+
}

0 commit comments

Comments
 (0)