Skip to content

Commit 2e989ef

Browse files
committed
feat: experimental support for some hooks and undici package
1 parent ff8f264 commit 2e989ef

File tree

14 files changed

+228
-22
lines changed

14 files changed

+228
-22
lines changed

apps/koa/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"test": "echo \"Error: no test specified\" && exit 1",
88
"watch": "nodemon --exec NODE_OPTIONS=--inspect-brk NODE_ENV=development ts-node --files ./src/index.ts",
99
"dev": "cross-env NETWORK_DEBUG_MODE=true node --inspect --watch ./src/index.js",
10-
"start": "cross-env NODE_ENV=production node --inspect --watch ./src/index.js",
10+
"start": "cross-env NODE_ENV=production node --inspect ./src/index.js",
1111
"build": "vite build"
1212
},
1313
"keywords": [],
@@ -35,6 +35,7 @@
3535
"ofetch": "^1.4.1",
3636
"ts-node": "^10.9.2",
3737
"typescript": "^5.4.5",
38+
"undici": "^6.20.1",
3839
"ws": "^8.17.0"
3940
}
4041
}

apps/koa/src/index.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,16 @@ const run = () => {
1313
const Koa = require('koa')
1414
const Router = require('koa-router')
1515
const { createFetch } = require('ofetch')
16+
const undici = require('undici')
1617

1718
const unregister = register()
18-
register()
19+
register({
20+
intercept: {
21+
undici: {
22+
fetch: true
23+
}
24+
}
25+
})
1926

2027
const app = new Koa()
2128
const router = new Router()
@@ -30,6 +37,13 @@ const run = () => {
3037
ctx.body = res
3138
})
3239

40+
router.get('/undici', async (ctx) => {
41+
await undici.fetch('https://jsonplaceholder.typicode.com/posts', {
42+
headers: { h: 1 }
43+
})
44+
ctx.body = 'right'
45+
})
46+
3347
router.get('/unregister', async (ctx) => {
3448
unregister()
3549
ctx.body = 'Unregistered'

packages/network-debugger/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-network-devtools",
3-
"version": "1.0.20",
3+
"version": "1.0.21",
44
"description": "Inspecting Node.js's Network with Chrome DevTools",
55
"homepage": "https://grinzero.github.io/node-network-devtools/",
66
"main": "./dist/index.js",
@@ -60,5 +60,8 @@
6060
"iconv-lite": "^0.6.3",
6161
"open": "^8.4.2",
6262
"ws": "^8.17.0"
63+
},
64+
"peerDependencies": {
65+
"undici": "^6"
6366
}
6467
}

packages/network-debugger/src/common.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,28 @@ export interface RegisterOptions {
9292
* @default true
9393
*/
9494
autoOpenDevtool?: boolean
95+
96+
/**
97+
* @description The option to intercept a certain packet.
98+
* If set false, the packet will not be intercepted.
99+
*/
100+
intercept?: {
101+
/**
102+
* @default true
103+
*/
104+
fetch?: boolean
105+
/**
106+
* @default true
107+
*/
108+
normal?: boolean
109+
/**
110+
* @default false
111+
*/
112+
undici?:
113+
| false
114+
| {
115+
fetch?: false | {}
116+
normal?: false | {}
117+
}
118+
}
95119
}

packages/network-debugger/src/core/fetch.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { RequestDetail } from '../common'
22
import { headersToObject } from '../utils/map'
33
import { MainProcess } from './fork'
4+
import { setCurrentCell } from './hooks/cell'
45

56
export function proxyFetch(mainProcess: MainProcess) {
67
if (!globalThis.fetch) {
@@ -15,10 +16,11 @@ export function proxyFetch(mainProcess: MainProcess) {
1516
}
1617
}
1718

18-
function fetchProxyFactory(fetchFn: typeof fetch, mainProcess: MainProcess) {
19+
export function fetchProxyFactory(fetchFn: typeof fetch, mainProcess: MainProcess) {
1920
return function (request: string | URL | Request, options?: RequestInit) {
2021
const requestDetail = new RequestDetail()
21-
requestDetail.requestStartTime = new Date().getTime()
22+
requestDetail.requestStartTime = Date.now()
23+
setCurrentCell({ request: requestDetail, pipes: [], isAborted: false })
2224

2325
if (typeof request === 'string') {
2426
requestDetail.url = request
@@ -37,10 +39,15 @@ function fetchProxyFactory(fetchFn: typeof fetch, mainProcess: MainProcess) {
3739
}
3840
requestDetail.requestData = options?.body
3941

40-
mainProcess.registerRequest(requestDetail)
41-
return fetchFn(request as string | Request, options)
42+
const result = fetchFn(request as string | Request, options)
4243
.then(fetchResponseHandlerFactory(requestDetail, mainProcess))
4344
.catch(fetchErrorHandlerFactory(requestDetail, mainProcess))
45+
.finally(() => {
46+
setCurrentCell(null)
47+
})
48+
49+
mainProcess.registerRequest(requestDetail)
50+
return result
4451
}
4552
}
4653

packages/network-debugger/src/core/fork.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import fs from 'fs'
99
import { sleep, checkMainProcessAlive } from '../utils/process'
1010
import { unlinkSafe } from '../utils/file'
1111
import { warn } from '../utils'
12+
import { getCurrentCell } from './hooks/cell'
1213

1314
class ExpectError extends Error {
1415
constructor(message: string) {
@@ -28,7 +29,7 @@ export class MainProcess {
2829
if (fs.existsSync(lockFilePath)) {
2930
// 读取 lock 文件中的进程号
3031
const pid = fs.readFileSync(lockFilePath, 'utf-8')
31-
await sleep(800)
32+
await sleep(1)
3233

3334
// 检测该进程是否存活且 port 是否被占用
3435
const isProcessAlice = await checkMainProcessAlive(pid, props.port!)
@@ -97,6 +98,10 @@ export class MainProcess {
9798
}
9899

99100
public async send(data: any) {
101+
const currentCell = getCurrentCell()
102+
if (currentCell?.isAborted) {
103+
return
104+
}
100105
const ws = await this.ws.catch((err) => {
101106
if (err instanceof ExpectError) {
102107
return null
@@ -108,9 +113,20 @@ export class MainProcess {
108113
}
109114

110115
public registerRequest(request: RequestDetail) {
116+
const currentCell = getCurrentCell()
117+
let req = request
118+
if (currentCell) {
119+
currentCell.request = req
120+
const pipes = currentCell.pipes.filter((p) => p.type === 'regsiter').map((p) => p.pipe)
121+
pipes.forEach((pipe) => {
122+
req = pipe(req)
123+
})
124+
currentCell.request = req
125+
}
126+
111127
this.send({
112128
type: 'registerRequest',
113-
data: request
129+
data: req
114130
})
115131
}
116132

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { type RequestDetail } from '../../common'
2+
3+
export interface Pipe<T = RequestDetail> {
4+
(req: T): T
5+
}
6+
7+
export interface Cell {
8+
request: RequestDetail
9+
pipes: Array<{
10+
pipe: Pipe<RequestDetail>
11+
type: 'regsiter'
12+
}>
13+
/**
14+
* @default false
15+
*/
16+
isAborted: boolean
17+
}
18+
19+
let currentCell: Cell | null = null
20+
21+
export function getCurrentCell() {
22+
return currentCell
23+
}
24+
25+
export function setCurrentCell(cell: Cell | null) {
26+
currentCell = cell
27+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './useRegisterRequest'
2+
export * from './useAbortRequest'
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { getCurrentCell } from './cell'
2+
3+
export const useAbortRequest = () => {
4+
const cell = getCurrentCell()
5+
6+
if (!cell) {
7+
throw new Error('useRegisterRequest must be used in request handler')
8+
}
9+
10+
cell.isAborted = true
11+
12+
return
13+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { RequestDetail } from '../../common'
2+
import { getCurrentCell } from './cell'
3+
4+
export interface RegisterRequestHook {
5+
(pipe: (req: RequestDetail) => RequestDetail): void
6+
}
7+
8+
export const useRegisterRequest: RegisterRequestHook = (pipe) => {
9+
const cell = getCurrentCell()
10+
11+
if (!cell) {
12+
throw new Error('useRegisterRequest must be used in request handler')
13+
}
14+
15+
cell.pipes.push({
16+
pipe,
17+
type: 'regsiter'
18+
})
19+
20+
return
21+
}

0 commit comments

Comments
 (0)