@rozenite/network-activity-plugin 1.7.0 → 1.8.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 +23 -0
- package/README.md +24 -0
- package/dist/devtools/App.html +2 -2
- package/dist/devtools/assets/{App-pokLiGYV.js → App-B3xlUjs6.js} +163 -115
- package/dist/devtools/assets/{App-BrSkOkws.css → App-m6xge0az.css} +13 -0
- package/dist/react-native/chunks/boot-recording.cjs +307 -28
- package/dist/react-native/chunks/boot-recording.js +310 -31
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +192 -141
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +193 -142
- package/dist/react-native/index.d.ts +24 -7
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.cjs +127 -0
- package/dist/sdk/index.d.ts +1243 -0
- package/dist/sdk/index.js +127 -0
- package/package.json +17 -6
- package/sdk.ts +59 -0
- package/src/react-native/__tests__/events-listener.test.ts +35 -0
- package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +21 -9
- package/src/react-native/agent/state.ts +13 -13
- package/src/react-native/agent/tools.ts +20 -146
- package/src/react-native/agent/use-network-activity-agent-tools.ts +73 -64
- package/src/react-native/events-listener.ts +12 -3
- package/src/react-native/http/http-inspector.ts +19 -5
- package/src/react-native/network-inspector.ts +46 -8
- package/src/react-native/nitro-fetch/__tests__/nitro-network-inspector.test.ts +198 -0
- package/src/react-native/nitro-fetch/nitro-network-inspector.ts +403 -0
- package/src/react-native/useHttpInspector.ts +9 -19
- package/src/react-native/useNetworkActivityDevTools.ts +13 -1
- package/src/react-native/websocket/__tests__/websocket-inspector.test.ts +69 -0
- package/src/react-native/websocket/websocket-inspector.ts +32 -17
- package/src/shared/agent-tools.ts +230 -0
- package/src/shared/client.ts +3 -0
- package/src/shared/http-events.ts +6 -0
- package/src/shared/websocket-events.ts +16 -7
- package/src/ui/components/RequestList.tsx +21 -0
- package/src/ui/components/SidePanel.tsx +12 -9
- package/src/ui/state/derived.ts +4 -0
- package/src/ui/state/model.ts +6 -1
- package/src/ui/state/store.ts +52 -36
- package/src/ui/tabs/HeadersTab.tsx +18 -4
- package/src/ui/tabs/ResponseTab.tsx +5 -3
- package/tsconfig.json +4 -1
- package/vite.config.ts +7 -0
|
@@ -2,11 +2,13 @@ import { useEffect } from 'react';
|
|
|
2
2
|
import { useRozenitePluginAgentTool } from '@rozenite/agent-bridge';
|
|
3
3
|
import type { NetworkActivityDevToolsClient } from '../../shared/client';
|
|
4
4
|
import type { NetworkInspector } from '../network-inspector';
|
|
5
|
-
import { getResponseBody } from '../http/http-utils';
|
|
6
5
|
import {
|
|
7
6
|
getNetworkActivityAgentState,
|
|
8
|
-
type NetworkActivityAgentBodyResult,
|
|
9
7
|
} from './state';
|
|
8
|
+
import {
|
|
9
|
+
NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
10
|
+
type NetworkActivityGetResponseBodyResult,
|
|
11
|
+
} from '../../shared/agent-tools';
|
|
10
12
|
import {
|
|
11
13
|
getRecordingStatusTool,
|
|
12
14
|
getRealtimeConnectionDetailsTool,
|
|
@@ -19,17 +21,6 @@ import {
|
|
|
19
21
|
stopRecordingTool,
|
|
20
22
|
} from './tools';
|
|
21
23
|
|
|
22
|
-
const pluginId = '@rozenite/network-activity-plugin';
|
|
23
|
-
|
|
24
|
-
type PaginationInput = {
|
|
25
|
-
limit?: number;
|
|
26
|
-
cursor?: string;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
type RequestIdInput = {
|
|
30
|
-
requestId: string;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
24
|
type AgentToolsConfig = {
|
|
34
25
|
client: NetworkActivityDevToolsClient | null;
|
|
35
26
|
networkInspector: NetworkInspector;
|
|
@@ -50,43 +41,76 @@ export const useNetworkActivityAgentTools = ({
|
|
|
50
41
|
useEffect(() => {
|
|
51
42
|
const unsubscribe = [
|
|
52
43
|
networkInspector.http.on('request-sent', (event) =>
|
|
53
|
-
state.onRequestSent(event)
|
|
44
|
+
state.onRequestSent(event),
|
|
54
45
|
),
|
|
55
46
|
networkInspector.http.on('request-progress', (event) =>
|
|
56
|
-
state.onRequestProgress(event)
|
|
47
|
+
state.onRequestProgress(event),
|
|
57
48
|
),
|
|
58
49
|
networkInspector.http.on('response-received', (event) =>
|
|
59
|
-
state.onResponseReceived(event)
|
|
50
|
+
state.onResponseReceived(event),
|
|
60
51
|
),
|
|
61
52
|
networkInspector.http.on('request-completed', (event) =>
|
|
62
|
-
state.onRequestCompleted(event)
|
|
53
|
+
state.onRequestCompleted(event),
|
|
63
54
|
),
|
|
64
55
|
networkInspector.http.on('request-failed', (event) =>
|
|
65
|
-
state.onRequestFailed(event)
|
|
56
|
+
state.onRequestFailed(event),
|
|
57
|
+
),
|
|
58
|
+
networkInspector.nitro.on('request-sent', (event) =>
|
|
59
|
+
state.onRequestSent(event),
|
|
60
|
+
),
|
|
61
|
+
networkInspector.nitro.on('response-received', (event) =>
|
|
62
|
+
state.onResponseReceived(event),
|
|
63
|
+
),
|
|
64
|
+
networkInspector.nitro.on('request-completed', (event) =>
|
|
65
|
+
state.onRequestCompleted(event),
|
|
66
|
+
),
|
|
67
|
+
networkInspector.nitro.on('request-failed', (event) =>
|
|
68
|
+
state.onRequestFailed(event),
|
|
66
69
|
),
|
|
67
70
|
networkInspector.websocket.on('websocket-connect', (event) =>
|
|
68
|
-
state.onWebSocketConnect(event)
|
|
71
|
+
state.onWebSocketConnect(event),
|
|
69
72
|
),
|
|
70
73
|
networkInspector.websocket.on('websocket-open', (event) =>
|
|
71
|
-
state.onWebSocketOpen(event)
|
|
74
|
+
state.onWebSocketOpen(event),
|
|
72
75
|
),
|
|
73
76
|
networkInspector.websocket.on('websocket-close', (event) =>
|
|
74
|
-
state.onWebSocketClose(event)
|
|
77
|
+
state.onWebSocketClose(event),
|
|
75
78
|
),
|
|
76
79
|
networkInspector.websocket.on('websocket-message-sent', (event) =>
|
|
77
|
-
state.onWebSocketMessageSent(event)
|
|
80
|
+
state.onWebSocketMessageSent(event),
|
|
78
81
|
),
|
|
79
82
|
networkInspector.websocket.on('websocket-message-received', (event) =>
|
|
80
|
-
state.onWebSocketMessageReceived(event)
|
|
83
|
+
state.onWebSocketMessageReceived(event),
|
|
81
84
|
),
|
|
82
85
|
networkInspector.websocket.on('websocket-error', (event) =>
|
|
83
|
-
state.onWebSocketError(event)
|
|
86
|
+
state.onWebSocketError(event),
|
|
87
|
+
),
|
|
88
|
+
networkInspector.websocket.on(
|
|
89
|
+
'websocket-connection-status-changed',
|
|
90
|
+
(event) => state.onWebSocketConnectionStatusChanged(event),
|
|
91
|
+
),
|
|
92
|
+
networkInspector.nitro.on('websocket-connect', (event) =>
|
|
93
|
+
state.onWebSocketConnect(event),
|
|
94
|
+
),
|
|
95
|
+
networkInspector.nitro.on('websocket-open', (event) =>
|
|
96
|
+
state.onWebSocketOpen(event),
|
|
97
|
+
),
|
|
98
|
+
networkInspector.nitro.on('websocket-close', (event) =>
|
|
99
|
+
state.onWebSocketClose(event),
|
|
100
|
+
),
|
|
101
|
+
networkInspector.nitro.on('websocket-message-sent', (event) =>
|
|
102
|
+
state.onWebSocketMessageSent(event),
|
|
84
103
|
),
|
|
85
|
-
networkInspector.
|
|
86
|
-
state.
|
|
104
|
+
networkInspector.nitro.on('websocket-message-received', (event) =>
|
|
105
|
+
state.onWebSocketMessageReceived(event),
|
|
106
|
+
),
|
|
107
|
+
networkInspector.nitro.on('websocket-error', (event) =>
|
|
108
|
+
state.onWebSocketError(event),
|
|
87
109
|
),
|
|
88
110
|
networkInspector.sse.on('sse-open', (event) => state.onSSEOpen(event)),
|
|
89
|
-
networkInspector.sse.on('sse-message', (event) =>
|
|
111
|
+
networkInspector.sse.on('sse-message', (event) =>
|
|
112
|
+
state.onSSEMessage(event),
|
|
113
|
+
),
|
|
90
114
|
networkInspector.sse.on('sse-error', (event) => state.onSSEError(event)),
|
|
91
115
|
networkInspector.sse.on('sse-close', (event) => state.onSSEClose(event)),
|
|
92
116
|
];
|
|
@@ -118,63 +142,60 @@ export const useNetworkActivityAgentTools = ({
|
|
|
118
142
|
}, [client, enabledInspectors, state]);
|
|
119
143
|
|
|
120
144
|
useRozenitePluginAgentTool({
|
|
121
|
-
pluginId,
|
|
145
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
122
146
|
tool: startRecordingTool,
|
|
123
147
|
handler: () => {
|
|
124
148
|
networkInspector.http.getNetworkRequestsRegistry().clear();
|
|
125
149
|
const result = state.startRecording({ enabledInspectors });
|
|
126
150
|
networkInspector.enable(enabledInspectors);
|
|
127
151
|
return {
|
|
128
|
-
started: true,
|
|
152
|
+
started: true as const,
|
|
129
153
|
...result,
|
|
130
154
|
};
|
|
131
155
|
},
|
|
132
156
|
});
|
|
133
157
|
|
|
134
158
|
useRozenitePluginAgentTool({
|
|
135
|
-
pluginId,
|
|
159
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
136
160
|
tool: stopRecordingTool,
|
|
137
161
|
handler: () => {
|
|
138
162
|
const result = state.stopRecording();
|
|
139
163
|
networkInspector.disable();
|
|
140
164
|
return {
|
|
141
|
-
stopped: true,
|
|
165
|
+
stopped: true as const,
|
|
142
166
|
...result,
|
|
143
167
|
};
|
|
144
168
|
},
|
|
145
169
|
});
|
|
146
170
|
|
|
147
171
|
useRozenitePluginAgentTool({
|
|
148
|
-
pluginId,
|
|
172
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
149
173
|
tool: getRecordingStatusTool,
|
|
150
174
|
handler: () => state.getStatus(),
|
|
151
175
|
});
|
|
152
176
|
|
|
153
|
-
useRozenitePluginAgentTool
|
|
154
|
-
pluginId,
|
|
177
|
+
useRozenitePluginAgentTool({
|
|
178
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
155
179
|
tool: listRequestsTool,
|
|
156
180
|
handler: (input = {}) => state.listRequests(input),
|
|
157
181
|
});
|
|
158
182
|
|
|
159
|
-
useRozenitePluginAgentTool
|
|
160
|
-
pluginId,
|
|
183
|
+
useRozenitePluginAgentTool({
|
|
184
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
161
185
|
tool: getRequestDetailsTool,
|
|
162
|
-
handler: ({ requestId }
|
|
186
|
+
handler: ({ requestId }) => state.getRequestDetails(requestId),
|
|
163
187
|
});
|
|
164
188
|
|
|
165
|
-
useRozenitePluginAgentTool
|
|
166
|
-
pluginId,
|
|
189
|
+
useRozenitePluginAgentTool({
|
|
190
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
167
191
|
tool: getRequestBodyTool,
|
|
168
|
-
handler: ({ requestId }
|
|
192
|
+
handler: ({ requestId }) => state.getRequestBody(requestId),
|
|
169
193
|
});
|
|
170
194
|
|
|
171
|
-
useRozenitePluginAgentTool
|
|
172
|
-
|
|
173
|
-
Promise<NetworkActivityAgentBodyResult>
|
|
174
|
-
>({
|
|
175
|
-
pluginId,
|
|
195
|
+
useRozenitePluginAgentTool({
|
|
196
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
176
197
|
tool: getResponseBodyTool,
|
|
177
|
-
handler: async ({ requestId }:
|
|
198
|
+
handler: async ({ requestId }): Promise<NetworkActivityGetResponseBodyResult> => {
|
|
178
199
|
const record = state.getHttpRecord(requestId);
|
|
179
200
|
if (!record) {
|
|
180
201
|
throw new Error(`Unknown request "${requestId}"`);
|
|
@@ -197,18 +218,7 @@ export const useNetworkActivityAgentTools = ({
|
|
|
197
218
|
};
|
|
198
219
|
}
|
|
199
220
|
|
|
200
|
-
const
|
|
201
|
-
networkInspector.http.getNetworkRequestsRegistry().getEntry(requestId);
|
|
202
|
-
if (!request) {
|
|
203
|
-
return {
|
|
204
|
-
requestId,
|
|
205
|
-
available: false,
|
|
206
|
-
reason:
|
|
207
|
-
'Response body is unavailable because the request object is no longer in the plugin registry.',
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const body = await getResponseBody(request);
|
|
221
|
+
const body = await networkInspector.getResponseBody(requestId);
|
|
212
222
|
if (body === null) {
|
|
213
223
|
return {
|
|
214
224
|
requestId,
|
|
@@ -229,16 +239,15 @@ export const useNetworkActivityAgentTools = ({
|
|
|
229
239
|
},
|
|
230
240
|
});
|
|
231
241
|
|
|
232
|
-
useRozenitePluginAgentTool
|
|
233
|
-
pluginId,
|
|
242
|
+
useRozenitePluginAgentTool({
|
|
243
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
234
244
|
tool: listRealtimeConnectionsTool,
|
|
235
245
|
handler: (input = {}) => state.listRealtimeConnections(input),
|
|
236
246
|
});
|
|
237
247
|
|
|
238
|
-
useRozenitePluginAgentTool
|
|
239
|
-
pluginId,
|
|
248
|
+
useRozenitePluginAgentTool({
|
|
249
|
+
pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
|
|
240
250
|
tool: getRealtimeConnectionDetailsTool,
|
|
241
|
-
handler: ({ requestId }
|
|
242
|
-
state.getRealtimeConnectionDetails(requestId),
|
|
251
|
+
handler: ({ requestId }) => state.getRealtimeConnectionDetails(requestId),
|
|
243
252
|
});
|
|
244
253
|
};
|
|
@@ -17,6 +17,9 @@ type SendFunction<TEventMap extends Record<string, unknown>> = <
|
|
|
17
17
|
export class EventsListener<TEventMap extends Record<string, unknown>> {
|
|
18
18
|
private messageQueue: QueuedMessage<TEventMap>[] = [];
|
|
19
19
|
private sendFunction: SendFunction<TEventMap> | null = null;
|
|
20
|
+
private filterFunction:
|
|
21
|
+
| ((message: QueuedMessage<TEventMap>) => boolean)
|
|
22
|
+
| null = null;
|
|
20
23
|
private maxQueueSize = 200;
|
|
21
24
|
private isQueuing = false;
|
|
22
25
|
|
|
@@ -36,9 +39,10 @@ export class EventsListener<TEventMap extends Record<string, unknown>> {
|
|
|
36
39
|
*/
|
|
37
40
|
public connect(
|
|
38
41
|
sendFn: SendFunction<TEventMap>,
|
|
39
|
-
filterFn?: (message: QueuedMessage<TEventMap>) => boolean
|
|
42
|
+
filterFn?: (message: QueuedMessage<TEventMap>) => boolean,
|
|
40
43
|
): void {
|
|
41
44
|
this.sendFunction = sendFn;
|
|
45
|
+
this.filterFunction = filterFn ?? null;
|
|
42
46
|
this.isQueuing = false;
|
|
43
47
|
this.flushQueue(filterFn);
|
|
44
48
|
}
|
|
@@ -54,6 +58,9 @@ export class EventsListener<TEventMap extends Record<string, unknown>> {
|
|
|
54
58
|
if (this.isQueuing) {
|
|
55
59
|
this.enqueueMessage({ type, data });
|
|
56
60
|
} else if (this.sendFunction) {
|
|
61
|
+
if (this.filterFunction && !this.filterFunction({ type, data })) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
57
64
|
this.sendFunction(type, data);
|
|
58
65
|
}
|
|
59
66
|
}
|
|
@@ -67,7 +74,7 @@ export class EventsListener<TEventMap extends Record<string, unknown>> {
|
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
private flushQueue(
|
|
70
|
-
filterFn?: (message: QueuedMessage<TEventMap>) => boolean
|
|
77
|
+
filterFn?: (message: QueuedMessage<TEventMap>) => boolean,
|
|
71
78
|
): void {
|
|
72
79
|
if (!this.sendFunction) {
|
|
73
80
|
return;
|
|
@@ -97,6 +104,8 @@ export type EventsListenerOptions = {
|
|
|
97
104
|
* Create a new events listener instance for a specific event map.
|
|
98
105
|
* This factory can be used to create listeners for different protocols or plugins.
|
|
99
106
|
*/
|
|
100
|
-
export const createEventsListener = <
|
|
107
|
+
export const createEventsListener = <
|
|
108
|
+
TEventMap extends Record<string, unknown>,
|
|
109
|
+
>(): EventsListener<TEventMap> => {
|
|
101
110
|
return new EventsListener<TEventMap>();
|
|
102
111
|
};
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { createNanoEvents } from 'nanoevents';
|
|
2
2
|
import { getNetworkRequestsRegistry } from './network-requests-registry';
|
|
3
3
|
import { XHRInterceptor } from './xhr-interceptor';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getRequestBody,
|
|
6
|
+
getResponseSize,
|
|
7
|
+
getInitiatorFromStack,
|
|
8
|
+
setupRequestOverride,
|
|
9
|
+
} from './http-utils';
|
|
5
10
|
import { applyReactNativeResponseHeadersLogic } from '../../utils/applyReactNativeResponseHeadersLogic';
|
|
6
11
|
import { getContentType } from '../utils';
|
|
7
12
|
import { getOverridesRegistry } from './overrides-registry';
|
|
@@ -28,7 +33,9 @@ type NanoEventsMap = {
|
|
|
28
33
|
};
|
|
29
34
|
|
|
30
35
|
export type HTTPInspector = Inspector<HttpEventMap> & {
|
|
31
|
-
getNetworkRequestsRegistry: () => ReturnType<
|
|
36
|
+
getNetworkRequestsRegistry: () => ReturnType<
|
|
37
|
+
typeof getNetworkRequestsRegistry
|
|
38
|
+
>;
|
|
32
39
|
};
|
|
33
40
|
|
|
34
41
|
const READY_STATE_HEADERS_RECEIVED = 2;
|
|
@@ -39,9 +46,9 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
39
46
|
|
|
40
47
|
const overridesRegistry = getOverridesRegistry();
|
|
41
48
|
XHRInterceptor.setOverrideCallback((request) =>
|
|
42
|
-
setupRequestOverride(overridesRegistry, request)
|
|
49
|
+
setupRequestOverride(overridesRegistry, request),
|
|
43
50
|
);
|
|
44
|
-
|
|
51
|
+
|
|
45
52
|
return {
|
|
46
53
|
enable: () => {
|
|
47
54
|
if (XHRInterceptor.isInterceptorEnabled()) return;
|
|
@@ -69,6 +76,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
69
76
|
},
|
|
70
77
|
type: 'XHR',
|
|
71
78
|
initiator,
|
|
79
|
+
source: 'builtin',
|
|
72
80
|
});
|
|
73
81
|
|
|
74
82
|
request.addEventListener('readystatechange', () => {
|
|
@@ -84,6 +92,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
84
92
|
loaded: event.loaded,
|
|
85
93
|
total: event.total,
|
|
86
94
|
lengthComputable: event.lengthComputable,
|
|
95
|
+
source: 'builtin',
|
|
87
96
|
});
|
|
88
97
|
});
|
|
89
98
|
|
|
@@ -103,6 +112,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
103
112
|
size: getResponseSize(request),
|
|
104
113
|
responseTime: Date.now(),
|
|
105
114
|
},
|
|
115
|
+
source: 'builtin',
|
|
106
116
|
});
|
|
107
117
|
});
|
|
108
118
|
|
|
@@ -113,6 +123,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
113
123
|
duration: Date.now() - sendTime,
|
|
114
124
|
size: getResponseSize(request),
|
|
115
125
|
ttfb,
|
|
126
|
+
source: 'builtin',
|
|
116
127
|
});
|
|
117
128
|
});
|
|
118
129
|
|
|
@@ -123,6 +134,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
123
134
|
type: 'XHR',
|
|
124
135
|
error: 'Failed',
|
|
125
136
|
canceled: false,
|
|
137
|
+
source: 'builtin',
|
|
126
138
|
});
|
|
127
139
|
});
|
|
128
140
|
|
|
@@ -133,6 +145,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
133
145
|
type: 'XHR',
|
|
134
146
|
error: 'Aborted',
|
|
135
147
|
canceled: true,
|
|
148
|
+
source: 'builtin',
|
|
136
149
|
});
|
|
137
150
|
});
|
|
138
151
|
|
|
@@ -143,6 +156,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
143
156
|
type: 'XHR',
|
|
144
157
|
error: 'Timeout',
|
|
145
158
|
canceled: false,
|
|
159
|
+
source: 'builtin',
|
|
146
160
|
});
|
|
147
161
|
});
|
|
148
162
|
});
|
|
@@ -167,7 +181,7 @@ export const getHTTPInspector = (): HTTPInspector => {
|
|
|
167
181
|
|
|
168
182
|
on: <TEventType extends keyof HttpEventMap>(
|
|
169
183
|
event: TEventType,
|
|
170
|
-
callback: (data: HttpEventMap[TEventType]) => void
|
|
184
|
+
callback: (data: HttpEventMap[TEventType]) => void,
|
|
171
185
|
) => eventEmitter.on(event, callback as NanoEventsMap[TEventType]),
|
|
172
186
|
};
|
|
173
187
|
};
|
|
@@ -1,78 +1,116 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getHTTPInspector,
|
|
3
|
+
HTTPInspector,
|
|
4
|
+
HTTP_EVENTS,
|
|
5
|
+
} from './http/http-inspector';
|
|
2
6
|
import { getSSEInspector, SSEInspector, SSE_EVENTS } from './sse/sse-inspector';
|
|
3
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
getWebSocketInspector,
|
|
9
|
+
WebSocketInspector,
|
|
10
|
+
WEBSOCKET_EVENTS,
|
|
11
|
+
} from './websocket/websocket-inspector';
|
|
12
|
+
import {
|
|
13
|
+
getNitroNetworkInspector,
|
|
14
|
+
NitroNetworkInspector,
|
|
15
|
+
NITRO_NETWORK_EVENTS,
|
|
16
|
+
} from './nitro-fetch/nitro-network-inspector';
|
|
4
17
|
import { EventsListener } from './events-listener';
|
|
5
18
|
import { NetworkActivityEventMap } from '../shared/client';
|
|
6
19
|
import type { InspectorsConfig } from './config';
|
|
20
|
+
import { getResponseBody as getHTTPResponseBody } from './http/http-utils';
|
|
7
21
|
|
|
8
22
|
export type NetworkInspector = {
|
|
9
23
|
readonly http: HTTPInspector;
|
|
10
24
|
readonly sse: SSEInspector;
|
|
11
25
|
readonly websocket: WebSocketInspector;
|
|
26
|
+
readonly nitro: NitroNetworkInspector;
|
|
12
27
|
setup: (eventsListener: EventsListener<NetworkActivityEventMap>) => void;
|
|
13
28
|
enable: (config?: InspectorsConfig) => void;
|
|
14
29
|
disable: () => void;
|
|
15
30
|
dispose: () => void;
|
|
31
|
+
getResponseBody: (requestId: string) => Promise<string | null>;
|
|
16
32
|
};
|
|
17
33
|
|
|
18
34
|
const createNetworkInspectorInstance = (): NetworkInspector => {
|
|
19
35
|
const http = getHTTPInspector();
|
|
20
36
|
const sse = getSSEInspector();
|
|
21
37
|
const websocket = getWebSocketInspector();
|
|
38
|
+
const nitro = getNitroNetworkInspector();
|
|
22
39
|
|
|
23
40
|
return {
|
|
24
41
|
http,
|
|
25
42
|
sse,
|
|
26
43
|
websocket,
|
|
44
|
+
nitro,
|
|
27
45
|
|
|
28
46
|
setup(eventsListener: EventsListener<NetworkActivityEventMap>) {
|
|
29
|
-
HTTP_EVENTS.forEach(event => {
|
|
47
|
+
HTTP_EVENTS.forEach((event) => {
|
|
30
48
|
http.on(event, (data) => {
|
|
31
49
|
eventsListener.send(event, data);
|
|
32
50
|
});
|
|
33
51
|
});
|
|
34
52
|
|
|
35
|
-
SSE_EVENTS.forEach(event => {
|
|
53
|
+
SSE_EVENTS.forEach((event) => {
|
|
36
54
|
sse.on(event, (data) => {
|
|
37
55
|
eventsListener.send(data.type, data);
|
|
38
56
|
});
|
|
39
57
|
});
|
|
40
58
|
|
|
41
|
-
WEBSOCKET_EVENTS.forEach(event => {
|
|
59
|
+
WEBSOCKET_EVENTS.forEach((event) => {
|
|
42
60
|
websocket.on(event, (data) => {
|
|
43
61
|
eventsListener.send(data.type, data);
|
|
44
62
|
});
|
|
45
63
|
});
|
|
64
|
+
|
|
65
|
+
NITRO_NETWORK_EVENTS.forEach((event) => {
|
|
66
|
+
nitro.on(event, (data) => {
|
|
67
|
+
eventsListener.send(event, data);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
46
70
|
},
|
|
47
71
|
|
|
48
|
-
enable(
|
|
72
|
+
enable(
|
|
73
|
+
config: InspectorsConfig = { http: true, sse: true, websocket: true },
|
|
74
|
+
) {
|
|
49
75
|
if (config.http) http.enable();
|
|
50
76
|
if (config.sse) sse.enable();
|
|
51
77
|
if (config.websocket) websocket.enable();
|
|
78
|
+
if (config.http || config.websocket) nitro.enable();
|
|
52
79
|
},
|
|
53
80
|
|
|
54
81
|
disable() {
|
|
55
82
|
http.disable();
|
|
56
83
|
sse.disable();
|
|
57
84
|
websocket.disable();
|
|
85
|
+
nitro.disable();
|
|
58
86
|
},
|
|
59
87
|
|
|
60
88
|
dispose() {
|
|
61
89
|
http.dispose();
|
|
62
90
|
sse.dispose();
|
|
63
91
|
websocket.dispose();
|
|
92
|
+
nitro.dispose();
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
async getResponseBody(requestId: string) {
|
|
96
|
+
const request = http.getNetworkRequestsRegistry().getEntry(requestId);
|
|
97
|
+
if (request) {
|
|
98
|
+
return getHTTPResponseBody(request);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return nitro.getResponseBody(requestId);
|
|
64
102
|
},
|
|
65
103
|
};
|
|
66
104
|
};
|
|
67
105
|
|
|
68
106
|
export const getNetworkInspector = (() => {
|
|
69
107
|
let instance: NetworkInspector | null = null;
|
|
70
|
-
|
|
108
|
+
|
|
71
109
|
return (): NetworkInspector => {
|
|
72
110
|
if (!instance) {
|
|
73
111
|
instance = createNetworkInspectorInstance();
|
|
74
112
|
}
|
|
75
|
-
|
|
113
|
+
|
|
76
114
|
return instance;
|
|
77
115
|
};
|
|
78
116
|
})();
|