@rozenite/network-activity-plugin 1.7.0 → 1.8.1

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +24 -0
  3. package/dist/devtools/App.html +2 -2
  4. package/dist/devtools/assets/{App-pokLiGYV.js → App-B3xlUjs6.js} +163 -115
  5. package/dist/devtools/assets/{App-BrSkOkws.css → App-m6xge0az.css} +13 -0
  6. package/dist/react-native/chunks/boot-recording.cjs +307 -28
  7. package/dist/react-native/chunks/boot-recording.js +310 -31
  8. package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +192 -141
  9. package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +193 -142
  10. package/dist/react-native/index.d.ts +24 -7
  11. package/dist/rozenite.json +1 -1
  12. package/dist/sdk/index.cjs +127 -0
  13. package/dist/sdk/index.d.ts +1243 -0
  14. package/dist/sdk/index.js +127 -0
  15. package/package.json +17 -6
  16. package/sdk.ts +59 -0
  17. package/src/react-native/__tests__/events-listener.test.ts +35 -0
  18. package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +21 -9
  19. package/src/react-native/agent/state.ts +13 -13
  20. package/src/react-native/agent/tools.ts +20 -146
  21. package/src/react-native/agent/use-network-activity-agent-tools.ts +73 -64
  22. package/src/react-native/events-listener.ts +12 -3
  23. package/src/react-native/http/http-inspector.ts +19 -5
  24. package/src/react-native/network-inspector.ts +46 -8
  25. package/src/react-native/nitro-fetch/__tests__/nitro-network-inspector.test.ts +198 -0
  26. package/src/react-native/nitro-fetch/nitro-network-inspector.ts +403 -0
  27. package/src/react-native/useHttpInspector.ts +9 -19
  28. package/src/react-native/useNetworkActivityDevTools.ts +13 -1
  29. package/src/react-native/websocket/__tests__/websocket-inspector.test.ts +69 -0
  30. package/src/react-native/websocket/websocket-inspector.ts +32 -17
  31. package/src/shared/agent-tools.ts +230 -0
  32. package/src/shared/client.ts +3 -0
  33. package/src/shared/http-events.ts +6 -0
  34. package/src/shared/websocket-events.ts +16 -7
  35. package/src/ui/components/RequestList.tsx +21 -0
  36. package/src/ui/components/SidePanel.tsx +12 -9
  37. package/src/ui/state/derived.ts +4 -0
  38. package/src/ui/state/model.ts +6 -1
  39. package/src/ui/state/store.ts +52 -36
  40. package/src/ui/tabs/HeadersTab.tsx +18 -4
  41. package/src/ui/tabs/ResponseTab.tsx +5 -3
  42. package/tsconfig.json +4 -1
  43. 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.websocket.on('websocket-connection-status-changed', (event) =>
86
- state.onWebSocketConnectionStatusChanged(event)
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) => state.onSSEMessage(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<PaginationInput>({
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<RequestIdInput>({
160
- pluginId,
183
+ useRozenitePluginAgentTool({
184
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
161
185
  tool: getRequestDetailsTool,
162
- handler: ({ requestId }: RequestIdInput) => state.getRequestDetails(requestId),
186
+ handler: ({ requestId }) => state.getRequestDetails(requestId),
163
187
  });
164
188
 
165
- useRozenitePluginAgentTool<RequestIdInput>({
166
- pluginId,
189
+ useRozenitePluginAgentTool({
190
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
167
191
  tool: getRequestBodyTool,
168
- handler: ({ requestId }: RequestIdInput) => state.getRequestBody(requestId),
192
+ handler: ({ requestId }) => state.getRequestBody(requestId),
169
193
  });
170
194
 
171
- useRozenitePluginAgentTool<
172
- RequestIdInput,
173
- Promise<NetworkActivityAgentBodyResult>
174
- >({
175
- pluginId,
195
+ useRozenitePluginAgentTool({
196
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
176
197
  tool: getResponseBodyTool,
177
- handler: async ({ requestId }: RequestIdInput) => {
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 request =
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<PaginationInput>({
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<RequestIdInput>({
239
- pluginId,
248
+ useRozenitePluginAgentTool({
249
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
240
250
  tool: getRealtimeConnectionDetailsTool,
241
- handler: ({ requestId }: RequestIdInput) =>
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 = <TEventMap extends Record<string, unknown>>(): EventsListener<TEventMap> => {
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 { getRequestBody, getResponseSize, getInitiatorFromStack, setupRequestOverride } from './http-utils';
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<typeof getNetworkRequestsRegistry>;
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 { getHTTPInspector, HTTPInspector, HTTP_EVENTS } from './http/http-inspector';
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 { getWebSocketInspector, WebSocketInspector, WEBSOCKET_EVENTS } from './websocket/websocket-inspector';
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(config: InspectorsConfig = { http: true, sse: true, websocket: true }) {
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
  })();