@rozenite/network-activity-plugin 1.5.1 → 1.7.0-rc.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 +20 -0
- package/README.md +2 -0
- package/dist/{App.html → devtools/App.html} +2 -2
- package/dist/{boot-recording.cjs → react-native/chunks/boot-recording.cjs} +1 -1
- package/dist/{boot-recording.js → react-native/chunks/boot-recording.js} +3 -3
- package/dist/react-native/chunks/boot-recording.require.cjs +5 -0
- package/dist/react-native/chunks/boot-recording.require.js +5 -0
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +1102 -0
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +1102 -0
- package/dist/{react-native.cjs → react-native/index.cjs} +2 -2
- package/dist/react-native/index.d.ts +305 -0
- package/dist/{react-native.js → react-native/index.js} +2 -2
- package/dist/rozenite.json +1 -1
- package/package.json +27 -7
- package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +250 -0
- package/src/react-native/agent/state.ts +869 -0
- package/src/react-native/agent/tools.ts +146 -0
- package/src/react-native/agent/use-network-activity-agent-tools.ts +244 -0
- package/src/react-native/http/http-inspector.ts +0 -1
- package/src/react-native/useNetworkActivityDevTools.ts +11 -0
- package/tsconfig.json +3 -0
- package/dist/react-native.d.ts +0 -4
- package/dist/rozenite.config.d.ts +0 -7
- package/dist/src/react-native/boot-recording.d.ts +0 -41
- package/dist/src/react-native/config.d.ts +0 -23
- package/dist/src/react-native/events-listener.d.ts +0 -44
- package/dist/src/react-native/http/http-inspector.d.ts +0 -10
- package/dist/src/react-native/http/http-utils.d.ts +0 -15
- package/dist/src/react-native/http/network-requests-registry.d.ts +0 -6
- package/dist/src/react-native/http/overrides-registry.d.ts +0 -6
- package/dist/src/react-native/http/xhr-interceptor.d.ts +0 -44
- package/dist/src/react-native/inspector.d.ts +0 -7
- package/dist/src/react-native/network-inspector.d.ts +0 -16
- package/dist/src/react-native/sse/event-source.d.ts +0 -2
- package/dist/src/react-native/sse/sse-inspector.d.ts +0 -6
- package/dist/src/react-native/sse/sse-interceptor.d.ts +0 -36
- package/dist/src/react-native/sse/types.d.ts +0 -6
- package/dist/src/react-native/useHttpInspector.d.ts +0 -3
- package/dist/src/react-native/useNetworkActivityDevTools.d.ts +0 -3
- package/dist/src/react-native/useSSEInspector.d.ts +0 -3
- package/dist/src/react-native/useWebSocketInspector.d.ts +0 -3
- package/dist/src/react-native/utils/getBlobName.d.ts +0 -35
- package/dist/src/react-native/utils/getFormDataEntries.d.ts +0 -18
- package/dist/src/react-native/utils.d.ts +0 -6
- package/dist/src/react-native/websocket/websocket-inspector.d.ts +0 -6
- package/dist/src/react-native/websocket/websocket-interceptor.d.ts +0 -73
- package/dist/src/shared/client.d.ts +0 -17
- package/dist/src/shared/http-events.d.ts +0 -106
- package/dist/src/shared/sse-events.d.ts +0 -38
- package/dist/src/shared/websocket-events.d.ts +0 -60
- package/dist/src/ui/App.d.ts +0 -1
- package/dist/src/ui/components/Badge.d.ts +0 -9
- package/dist/src/ui/components/Button.d.ts +0 -11
- package/dist/src/ui/components/CodeBlock.d.ts +0 -3
- package/dist/src/ui/components/CodeEditor.d.ts +0 -5
- package/dist/src/ui/components/CookieCard.d.ts +0 -7
- package/dist/src/ui/components/CopyRequestDropdown.d.ts +0 -7
- package/dist/src/ui/components/DropdownMenu.d.ts +0 -27
- package/dist/src/ui/components/FilterBar.d.ts +0 -10
- package/dist/src/ui/components/Input.d.ts +0 -3
- package/dist/src/ui/components/JsonTree.d.ts +0 -5
- package/dist/src/ui/components/JsonTreeCopyableItem.d.ts +0 -7
- package/dist/src/ui/components/KeyValueGrid.d.ts +0 -13
- package/dist/src/ui/components/OverrideResponse.d.ts +0 -8
- package/dist/src/ui/components/RequestBody.d.ts +0 -6
- package/dist/src/ui/components/RequestList.d.ts +0 -30
- package/dist/src/ui/components/ScrollArea.d.ts +0 -5
- package/dist/src/ui/components/Section.d.ts +0 -8
- package/dist/src/ui/components/Separator.d.ts +0 -4
- package/dist/src/ui/components/SidePanel.d.ts +0 -1
- package/dist/src/ui/components/Tabs.d.ts +0 -7
- package/dist/src/ui/components/Toolbar.d.ts +0 -1
- package/dist/src/ui/hooks/useCopyToClipboard.d.ts +0 -4
- package/dist/src/ui/state/derived.d.ts +0 -5
- package/dist/src/ui/state/hooks.d.ts +0 -21
- package/dist/src/ui/state/model.d.ts +0 -113
- package/dist/src/ui/state/store.d.ts +0 -48
- package/dist/src/ui/tabs/CookiesTab.d.ts +0 -5
- package/dist/src/ui/tabs/HeadersTab.d.ts +0 -5
- package/dist/src/ui/tabs/MessagesTab.d.ts +0 -5
- package/dist/src/ui/tabs/RequestTab.d.ts +0 -5
- package/dist/src/ui/tabs/ResponseTab.d.ts +0 -6
- package/dist/src/ui/tabs/SSEMessagesTab.d.ts +0 -5
- package/dist/src/ui/tabs/TimingTab.d.ts +0 -5
- package/dist/src/ui/types.d.ts +0 -26
- package/dist/src/ui/utils/assert.d.ts +0 -1
- package/dist/src/ui/utils/checkRequestBodyBinary.d.ts +0 -2
- package/dist/src/ui/utils/cn.d.ts +0 -2
- package/dist/src/ui/utils/copyToClipboard.d.ts +0 -1
- package/dist/src/ui/utils/escapeShellArg.d.ts +0 -1
- package/dist/src/ui/utils/generateCurlCommand.d.ts +0 -2
- package/dist/src/ui/utils/generateFetchCall.d.ts +0 -2
- package/dist/src/ui/utils/generateMultipartBody.d.ts +0 -4
- package/dist/src/ui/utils/getId.d.ts +0 -1
- package/dist/src/ui/utils/getStatusColor.d.ts +0 -1
- package/dist/src/ui/views/InspectorView.d.ts +0 -5
- package/dist/src/ui/views/LoadingView.d.ts +0 -1
- package/dist/src/utils/applyReactNativeRequestHeadersLogic.d.ts +0 -7
- package/dist/src/utils/applyReactNativeResponseHeadersLogic.d.ts +0 -9
- package/dist/src/utils/cookieParser.d.ts +0 -6
- package/dist/src/utils/getContentTypeMimeType.d.ts +0 -2
- package/dist/src/utils/getHttpHeader.d.ts +0 -5
- package/dist/src/utils/getHttpHeaderValueAsString.d.ts +0 -11
- package/dist/src/utils/getStringSizeInBytes.d.ts +0 -1
- package/dist/src/utils/inferContentTypeFromPostData.d.ts +0 -2
- package/dist/src/utils/safeStringify.d.ts +0 -1
- package/dist/src/utils/typeChecks.d.ts +0 -9
- package/dist/useNetworkActivityDevTools.cjs +0 -171
- package/dist/useNetworkActivityDevTools.js +0 -171
- /package/dist/{assets → devtools/assets}/App-BrSkOkws.css +0 -0
- /package/dist/{assets/App-CGt4qucR.js → devtools/assets/App-pokLiGYV.js} +0 -0
- /package/dist/{event-source.cjs → react-native/chunks/event-source.cjs} +0 -0
- /package/dist/{event-source.js → react-native/chunks/event-source.js} +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { AgentTool } from '@rozenite/agent-bridge';
|
|
2
|
+
|
|
3
|
+
export const startRecordingTool: AgentTool = {
|
|
4
|
+
name: 'startRecording',
|
|
5
|
+
description:
|
|
6
|
+
'Start recording network activity in the fallback network activity plugin.',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const stopRecordingTool: AgentTool = {
|
|
14
|
+
name: 'stopRecording',
|
|
15
|
+
description:
|
|
16
|
+
'Stop recording network activity without clearing the captured plugin buffer.',
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const getRecordingStatusTool: AgentTool = {
|
|
24
|
+
name: 'getRecordingStatus',
|
|
25
|
+
description:
|
|
26
|
+
'Return network activity plugin recording state and buffer metadata.',
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const listRequestsTool: AgentTool = {
|
|
34
|
+
name: 'listRequests',
|
|
35
|
+
description:
|
|
36
|
+
'List captured HTTP request summaries with cursor pagination from the fallback plugin.',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {
|
|
40
|
+
limit: {
|
|
41
|
+
type: 'number',
|
|
42
|
+
description: 'Maximum number of requests to return. Defaults to 20.',
|
|
43
|
+
},
|
|
44
|
+
cursor: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
description: 'Opaque pagination cursor from a previous listRequests call.',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const getRequestDetailsTool: AgentTool = {
|
|
53
|
+
name: 'getRequestDetails',
|
|
54
|
+
description:
|
|
55
|
+
'Return detailed metadata for a captured HTTP request without fetching response body.',
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
requestId: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
description: 'Captured plugin request ID to inspect.',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
required: ['requestId'],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const getRequestBodyTool: AgentTool = {
|
|
69
|
+
name: 'getRequestBody',
|
|
70
|
+
description:
|
|
71
|
+
'Return the captured request body for a plugin-recorded HTTP request when available.',
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
requestId: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Captured plugin request ID to inspect.',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
required: ['requestId'],
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const getResponseBodyTool: AgentTool = {
|
|
85
|
+
name: 'getResponseBody',
|
|
86
|
+
description:
|
|
87
|
+
'Return the captured response body for a plugin-recorded HTTP request when available.',
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
requestId: {
|
|
92
|
+
type: 'string',
|
|
93
|
+
description: 'Captured plugin request ID to inspect.',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
required: ['requestId'],
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const listRealtimeConnectionsTool: AgentTool = {
|
|
101
|
+
name: 'listRealtimeConnections',
|
|
102
|
+
description:
|
|
103
|
+
'List captured WebSocket and SSE connections with cursor pagination.',
|
|
104
|
+
inputSchema: {
|
|
105
|
+
type: 'object',
|
|
106
|
+
properties: {
|
|
107
|
+
limit: {
|
|
108
|
+
type: 'number',
|
|
109
|
+
description: 'Maximum number of realtime connections to return. Defaults to 20.',
|
|
110
|
+
},
|
|
111
|
+
cursor: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
description:
|
|
114
|
+
'Opaque pagination cursor from a previous listRealtimeConnections call.',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const getRealtimeConnectionDetailsTool: AgentTool = {
|
|
121
|
+
name: 'getRealtimeConnectionDetails',
|
|
122
|
+
description:
|
|
123
|
+
'Return details for a captured WebSocket or SSE connection, including recent messages.',
|
|
124
|
+
inputSchema: {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
requestId: {
|
|
128
|
+
type: 'string',
|
|
129
|
+
description: 'Captured realtime request ID to inspect.',
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
required: ['requestId'],
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const NETWORK_ACTIVITY_AGENT_TOOLS: AgentTool[] = [
|
|
137
|
+
startRecordingTool,
|
|
138
|
+
stopRecordingTool,
|
|
139
|
+
getRecordingStatusTool,
|
|
140
|
+
listRequestsTool,
|
|
141
|
+
getRequestDetailsTool,
|
|
142
|
+
getRequestBodyTool,
|
|
143
|
+
getResponseBodyTool,
|
|
144
|
+
listRealtimeConnectionsTool,
|
|
145
|
+
getRealtimeConnectionDetailsTool,
|
|
146
|
+
];
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useRozenitePluginAgentTool } from '@rozenite/agent-bridge';
|
|
3
|
+
import type { NetworkActivityDevToolsClient } from '../../shared/client';
|
|
4
|
+
import type { NetworkInspector } from '../network-inspector';
|
|
5
|
+
import { getResponseBody } from '../http/http-utils';
|
|
6
|
+
import {
|
|
7
|
+
getNetworkActivityAgentState,
|
|
8
|
+
type NetworkActivityAgentBodyResult,
|
|
9
|
+
} from './state';
|
|
10
|
+
import {
|
|
11
|
+
getRecordingStatusTool,
|
|
12
|
+
getRealtimeConnectionDetailsTool,
|
|
13
|
+
getRequestBodyTool,
|
|
14
|
+
getRequestDetailsTool,
|
|
15
|
+
getResponseBodyTool,
|
|
16
|
+
listRealtimeConnectionsTool,
|
|
17
|
+
listRequestsTool,
|
|
18
|
+
startRecordingTool,
|
|
19
|
+
stopRecordingTool,
|
|
20
|
+
} from './tools';
|
|
21
|
+
|
|
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
|
+
type AgentToolsConfig = {
|
|
34
|
+
client: NetworkActivityDevToolsClient | null;
|
|
35
|
+
networkInspector: NetworkInspector;
|
|
36
|
+
enabledInspectors: {
|
|
37
|
+
http: boolean;
|
|
38
|
+
websocket: boolean;
|
|
39
|
+
sse: boolean;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const useNetworkActivityAgentTools = ({
|
|
44
|
+
client,
|
|
45
|
+
networkInspector,
|
|
46
|
+
enabledInspectors,
|
|
47
|
+
}: AgentToolsConfig) => {
|
|
48
|
+
const state = getNetworkActivityAgentState();
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const unsubscribe = [
|
|
52
|
+
networkInspector.http.on('request-sent', (event) =>
|
|
53
|
+
state.onRequestSent(event)
|
|
54
|
+
),
|
|
55
|
+
networkInspector.http.on('request-progress', (event) =>
|
|
56
|
+
state.onRequestProgress(event)
|
|
57
|
+
),
|
|
58
|
+
networkInspector.http.on('response-received', (event) =>
|
|
59
|
+
state.onResponseReceived(event)
|
|
60
|
+
),
|
|
61
|
+
networkInspector.http.on('request-completed', (event) =>
|
|
62
|
+
state.onRequestCompleted(event)
|
|
63
|
+
),
|
|
64
|
+
networkInspector.http.on('request-failed', (event) =>
|
|
65
|
+
state.onRequestFailed(event)
|
|
66
|
+
),
|
|
67
|
+
networkInspector.websocket.on('websocket-connect', (event) =>
|
|
68
|
+
state.onWebSocketConnect(event)
|
|
69
|
+
),
|
|
70
|
+
networkInspector.websocket.on('websocket-open', (event) =>
|
|
71
|
+
state.onWebSocketOpen(event)
|
|
72
|
+
),
|
|
73
|
+
networkInspector.websocket.on('websocket-close', (event) =>
|
|
74
|
+
state.onWebSocketClose(event)
|
|
75
|
+
),
|
|
76
|
+
networkInspector.websocket.on('websocket-message-sent', (event) =>
|
|
77
|
+
state.onWebSocketMessageSent(event)
|
|
78
|
+
),
|
|
79
|
+
networkInspector.websocket.on('websocket-message-received', (event) =>
|
|
80
|
+
state.onWebSocketMessageReceived(event)
|
|
81
|
+
),
|
|
82
|
+
networkInspector.websocket.on('websocket-error', (event) =>
|
|
83
|
+
state.onWebSocketError(event)
|
|
84
|
+
),
|
|
85
|
+
networkInspector.websocket.on('websocket-connection-status-changed', (event) =>
|
|
86
|
+
state.onWebSocketConnectionStatusChanged(event)
|
|
87
|
+
),
|
|
88
|
+
networkInspector.sse.on('sse-open', (event) => state.onSSEOpen(event)),
|
|
89
|
+
networkInspector.sse.on('sse-message', (event) => state.onSSEMessage(event)),
|
|
90
|
+
networkInspector.sse.on('sse-error', (event) => state.onSSEError(event)),
|
|
91
|
+
networkInspector.sse.on('sse-close', (event) => state.onSSEClose(event)),
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
return () => {
|
|
95
|
+
unsubscribe.forEach((remove) => remove());
|
|
96
|
+
};
|
|
97
|
+
}, [networkInspector, state]);
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!client) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const subscriptions = [
|
|
105
|
+
client.onMessage('network-enable', () => {
|
|
106
|
+
state.startRecording({ enabledInspectors });
|
|
107
|
+
}),
|
|
108
|
+
client.onMessage('network-disable', () => {
|
|
109
|
+
if (state.getStatus().recording.isRecording) {
|
|
110
|
+
state.stopRecording();
|
|
111
|
+
}
|
|
112
|
+
}),
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
subscriptions.forEach((subscription) => subscription.remove());
|
|
117
|
+
};
|
|
118
|
+
}, [client, enabledInspectors, state]);
|
|
119
|
+
|
|
120
|
+
useRozenitePluginAgentTool({
|
|
121
|
+
pluginId,
|
|
122
|
+
tool: startRecordingTool,
|
|
123
|
+
handler: () => {
|
|
124
|
+
networkInspector.http.getNetworkRequestsRegistry().clear();
|
|
125
|
+
const result = state.startRecording({ enabledInspectors });
|
|
126
|
+
networkInspector.enable(enabledInspectors);
|
|
127
|
+
return {
|
|
128
|
+
started: true,
|
|
129
|
+
...result,
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
useRozenitePluginAgentTool({
|
|
135
|
+
pluginId,
|
|
136
|
+
tool: stopRecordingTool,
|
|
137
|
+
handler: () => {
|
|
138
|
+
const result = state.stopRecording();
|
|
139
|
+
networkInspector.disable();
|
|
140
|
+
return {
|
|
141
|
+
stopped: true,
|
|
142
|
+
...result,
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
useRozenitePluginAgentTool({
|
|
148
|
+
pluginId,
|
|
149
|
+
tool: getRecordingStatusTool,
|
|
150
|
+
handler: () => state.getStatus(),
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
useRozenitePluginAgentTool<PaginationInput>({
|
|
154
|
+
pluginId,
|
|
155
|
+
tool: listRequestsTool,
|
|
156
|
+
handler: (input = {}) => state.listRequests(input),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
useRozenitePluginAgentTool<RequestIdInput>({
|
|
160
|
+
pluginId,
|
|
161
|
+
tool: getRequestDetailsTool,
|
|
162
|
+
handler: ({ requestId }: RequestIdInput) => state.getRequestDetails(requestId),
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
useRozenitePluginAgentTool<RequestIdInput>({
|
|
166
|
+
pluginId,
|
|
167
|
+
tool: getRequestBodyTool,
|
|
168
|
+
handler: ({ requestId }: RequestIdInput) => state.getRequestBody(requestId),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
useRozenitePluginAgentTool<
|
|
172
|
+
RequestIdInput,
|
|
173
|
+
Promise<NetworkActivityAgentBodyResult>
|
|
174
|
+
>({
|
|
175
|
+
pluginId,
|
|
176
|
+
tool: getResponseBodyTool,
|
|
177
|
+
handler: async ({ requestId }: RequestIdInput) => {
|
|
178
|
+
const record = state.getHttpRecord(requestId);
|
|
179
|
+
if (!record) {
|
|
180
|
+
throw new Error(`Unknown request "${requestId}"`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (record.status === 'failed') {
|
|
184
|
+
return {
|
|
185
|
+
requestId,
|
|
186
|
+
available: false,
|
|
187
|
+
reason: 'Response body is unavailable because the request failed.',
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (record.status !== 'finished') {
|
|
192
|
+
return {
|
|
193
|
+
requestId,
|
|
194
|
+
available: false,
|
|
195
|
+
reason:
|
|
196
|
+
'Response body is unavailable until the request finishes loading.',
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
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);
|
|
212
|
+
if (body === null) {
|
|
213
|
+
return {
|
|
214
|
+
requestId,
|
|
215
|
+
available: false,
|
|
216
|
+
reason:
|
|
217
|
+
'The plugin could not extract a text response body for this request.',
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
requestId,
|
|
223
|
+
available: true,
|
|
224
|
+
body,
|
|
225
|
+
base64Encoded: false,
|
|
226
|
+
decoded: false,
|
|
227
|
+
mimeType: record.response?.contentType,
|
|
228
|
+
};
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
useRozenitePluginAgentTool<PaginationInput>({
|
|
233
|
+
pluginId,
|
|
234
|
+
tool: listRealtimeConnectionsTool,
|
|
235
|
+
handler: (input = {}) => state.listRealtimeConnections(input),
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
useRozenitePluginAgentTool<RequestIdInput>({
|
|
239
|
+
pluginId,
|
|
240
|
+
tool: getRealtimeConnectionDetailsTool,
|
|
241
|
+
handler: ({ requestId }: RequestIdInput) =>
|
|
242
|
+
state.getRealtimeConnectionDetails(requestId),
|
|
243
|
+
});
|
|
244
|
+
};
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
validateConfig,
|
|
11
11
|
} from './config';
|
|
12
12
|
import { createNetworkInspectorsConfiguration } from './boot-recording';
|
|
13
|
+
import { useNetworkActivityAgentTools } from './agent/use-network-activity-agent-tools';
|
|
13
14
|
import { useHttpInspector } from './useHttpInspector';
|
|
14
15
|
import { useWebSocketInspector } from './useWebSocketInspector';
|
|
15
16
|
import { useSSEInspector } from './useSSEInspector';
|
|
@@ -31,6 +32,16 @@ export const useNetworkActivityDevTools = (
|
|
|
31
32
|
|
|
32
33
|
const { eventsListener, networkInspector } = inspectorsConfig;
|
|
33
34
|
|
|
35
|
+
useNetworkActivityAgentTools({
|
|
36
|
+
client,
|
|
37
|
+
networkInspector,
|
|
38
|
+
enabledInspectors: {
|
|
39
|
+
http: isHttpInspectorEnabled,
|
|
40
|
+
websocket: isWebSocketInspectorEnabled,
|
|
41
|
+
sse: isSSEInspectorEnabled,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
34
45
|
useEffect(() => {
|
|
35
46
|
if (!client) {
|
|
36
47
|
return;
|
package/tsconfig.json
CHANGED
package/dist/react-native.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare let useNetworkActivityDevTools: typeof import('./src/react-native/useNetworkActivityDevTools').useNetworkActivityDevTools;
|
|
2
|
-
export declare let withOnBootNetworkActivityRecording: typeof import('./src/react-native/boot-recording').withOnBootNetworkActivityRecording;
|
|
3
|
-
export type { NetworkActivityDevToolsConfig } from './src/react-native/config';
|
|
4
|
-
export type { BootRecordingOptions } from './src/react-native/boot-recording';
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { NetworkActivityEventMap } from '../shared/client';
|
|
2
|
-
import { createEventsListener, EventsListenerOptions } from './events-listener';
|
|
3
|
-
import { NetworkInspector } from './network-inspector';
|
|
4
|
-
import { NetworkInspectorConfig } from './config';
|
|
5
|
-
type InspectorsConfiguration = {
|
|
6
|
-
eventsListener: ReturnType<typeof createEventsListener<NetworkActivityEventMap>>;
|
|
7
|
-
networkInspector: NetworkInspector;
|
|
8
|
-
};
|
|
9
|
-
export type BootRecordingOptions = NetworkInspectorConfig & EventsListenerOptions & {
|
|
10
|
-
/**
|
|
11
|
-
* Enable queuing of events during boot before DevTools connects.
|
|
12
|
-
* When true, network activity is captured and queued until DevTools is ready.
|
|
13
|
-
* When false, nothing is queued and inspectors are not even set up.
|
|
14
|
-
* @default true
|
|
15
|
-
*/
|
|
16
|
-
enableBootRecording?: boolean;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @internal
|
|
21
|
-
*/
|
|
22
|
-
export declare const createNetworkInspectorsConfiguration: (options?: BootRecordingOptions) => InspectorsConfiguration;
|
|
23
|
-
/**
|
|
24
|
-
* Enable network activity recording during app boot, before DevTools connects.
|
|
25
|
-
* Call this at the root of your app to capture early network requests.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```tsx
|
|
29
|
-
* import { withOnBootNetworkActivityRecording } from '@rozenite/network-activity-plugin';
|
|
30
|
-
*
|
|
31
|
-
* // At app entry point, before any network requests
|
|
32
|
-
* withOnBootNetworkActivityRecording();
|
|
33
|
-
*
|
|
34
|
-
* function App() {
|
|
35
|
-
* useNetworkActivityDevTools();
|
|
36
|
-
* // ...
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export declare const withOnBootNetworkActivityRecording: (options?: BootRecordingOptions) => void;
|
|
41
|
-
export {};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export type InspectorType = 'http' | 'websocket' | 'sse';
|
|
2
|
-
export type InspectorsConfig = {
|
|
3
|
-
[key in InspectorType]?: boolean;
|
|
4
|
-
};
|
|
5
|
-
export type NetworkInspectorConfig = {
|
|
6
|
-
/**
|
|
7
|
-
* Specifies which network inspectors are enabled.
|
|
8
|
-
* Set to `false` to disable monitoring for a specific type of network traffic.
|
|
9
|
-
* @default { http: true, websocket: true, sse: true }
|
|
10
|
-
*/
|
|
11
|
-
inspectors?: InspectorsConfig;
|
|
12
|
-
};
|
|
13
|
-
export type NetworkActivityDevToolsConfig = NetworkInspectorConfig & {
|
|
14
|
-
clientUISettings?: {
|
|
15
|
-
/**
|
|
16
|
-
* If true, display the entire relative URL as the request name in the UI instead of only the last path segment.
|
|
17
|
-
* @default false
|
|
18
|
-
*/
|
|
19
|
-
showUrlAsName?: boolean;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
export declare const DEFAULT_CONFIG: NetworkActivityDevToolsConfig;
|
|
23
|
-
export declare const validateConfig: (config: NetworkActivityDevToolsConfig) => void;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
type QueuedMessage<TEventMap extends Record<string, unknown>> = {
|
|
2
|
-
type: keyof TEventMap;
|
|
3
|
-
data: TEventMap[keyof TEventMap];
|
|
4
|
-
};
|
|
5
|
-
type SendFunction<TEventMap extends Record<string, unknown>> = <K extends keyof TEventMap>(type: K, data: TEventMap[K]) => void;
|
|
6
|
-
/**
|
|
7
|
-
* Generic events listener that queues messages until a send function is registered.
|
|
8
|
-
* This allows capturing events before the DevTools client connects and so be boot compliant.
|
|
9
|
-
*/
|
|
10
|
-
export declare class EventsListener<TEventMap extends Record<string, unknown>> {
|
|
11
|
-
private messageQueue;
|
|
12
|
-
private sendFunction;
|
|
13
|
-
private maxQueueSize;
|
|
14
|
-
private isQueuing;
|
|
15
|
-
setMaxQueueSize(size: number): void;
|
|
16
|
-
/**
|
|
17
|
-
* Enable queuing mode to capture events before client is connected
|
|
18
|
-
*/
|
|
19
|
-
enableQueuing(): void;
|
|
20
|
-
/**
|
|
21
|
-
* Connect the actual send function and automatically flush queued messages
|
|
22
|
-
*/
|
|
23
|
-
connect(sendFn: SendFunction<TEventMap>, filterFn?: (message: QueuedMessage<TEventMap>) => boolean): void;
|
|
24
|
-
isInQueueMode(): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Send a message (queued if not connected, sent directly if connected)
|
|
27
|
-
*/
|
|
28
|
-
send<K extends keyof TEventMap>(type: K, data: TEventMap[K]): void;
|
|
29
|
-
private enqueueMessage;
|
|
30
|
-
private flushQueue;
|
|
31
|
-
}
|
|
32
|
-
export type EventsListenerOptions = {
|
|
33
|
-
/**
|
|
34
|
-
* Maximum number of messages to queue before DevTools connects.
|
|
35
|
-
* @default 200
|
|
36
|
-
*/
|
|
37
|
-
maxQueueSize?: number;
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Create a new events listener instance for a specific event map.
|
|
41
|
-
* This factory can be used to create listeners for different protocols or plugins.
|
|
42
|
-
*/
|
|
43
|
-
export declare const createEventsListener: <TEventMap extends Record<string, unknown>>() => EventsListener<TEventMap>;
|
|
44
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { getNetworkRequestsRegistry } from './network-requests-registry';
|
|
2
|
-
import { HttpEventMap } from '../../shared/http-events';
|
|
3
|
-
import { Inspector } from '../inspector';
|
|
4
|
-
export type { HttpEventMap };
|
|
5
|
-
export declare const HTTP_EVENTS: (keyof HttpEventMap)[];
|
|
6
|
-
export declare const isHttpEvent: (type: string) => type is keyof HttpEventMap;
|
|
7
|
-
export type HTTPInspector = Inspector<HttpEventMap> & {
|
|
8
|
-
getNetworkRequestsRegistry: () => ReturnType<typeof getNetworkRequestsRegistry>;
|
|
9
|
-
};
|
|
10
|
-
export declare const getHTTPInspector: () => HTTPInspector;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { XHRPostData, RequestPostData } from '../../shared/client';
|
|
2
|
-
import { OverridesRegistry } from './overrides-registry';
|
|
3
|
-
export declare const getRequestBody: (body: XHRPostData) => RequestPostData;
|
|
4
|
-
export declare const getResponseSize: (request: XMLHttpRequest) => number | null;
|
|
5
|
-
export declare const getResponseBody: (request: XMLHttpRequest) => Promise<string | null>;
|
|
6
|
-
export declare const getInitiatorFromStack: () => {
|
|
7
|
-
type: string;
|
|
8
|
-
url?: string;
|
|
9
|
-
lineNumber?: number;
|
|
10
|
-
columnNumber?: number;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Applies override body and status to XMLHttpRequest objects.
|
|
14
|
-
*/
|
|
15
|
-
export declare const setupRequestOverride: (overridesRegistry: OverridesRegistry, request: XMLHttpRequest) => void;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { RequestOverride } from '../../shared/client';
|
|
2
|
-
export type OverridesRegistry = {
|
|
3
|
-
setOverrides: (newOverrides: [string, RequestOverride][]) => void;
|
|
4
|
-
getOverrideForUrl: (url: string) => RequestOverride | undefined;
|
|
5
|
-
};
|
|
6
|
-
export declare const getOverridesRegistry: () => OverridesRegistry;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { XHRPostData } from '../../shared/client';
|
|
2
|
-
type XHRInterceptorOpenCallback = (method: string, url: string, request: XMLHttpRequest) => void;
|
|
3
|
-
type XHRInterceptorSendCallback = (data: XHRPostData, request: XMLHttpRequest) => void;
|
|
4
|
-
type XHRInterceptorRequestHeaderCallback = (header: string, value: string, request: XMLHttpRequest) => void;
|
|
5
|
-
type XHRInterceptorHeaderReceivedCallback = (responseContentType: string | undefined, responseSize: number | undefined, allHeaders: string, request: XMLHttpRequest) => void;
|
|
6
|
-
type XHRInterceptorResponseCallback = (status: number, timeout: number, response: string, responseURL: string, responseType: string, request: XMLHttpRequest) => void;
|
|
7
|
-
type XHRInterceptorOverrideCallback = (request: XMLHttpRequest) => void;
|
|
8
|
-
/**
|
|
9
|
-
* A network interceptor which monkey-patches XMLHttpRequest methods
|
|
10
|
-
* to gather all network requests/responses, in order to show their
|
|
11
|
-
* information in the React Native inspector development tool.
|
|
12
|
-
* This supports interception with XMLHttpRequest API, including Fetch API
|
|
13
|
-
* and any other third party libraries that depend on XMLHttpRequest.
|
|
14
|
-
*/
|
|
15
|
-
export declare const XHRInterceptor: {
|
|
16
|
-
/**
|
|
17
|
-
* Invoked before XMLHttpRequest.open(...) is called.
|
|
18
|
-
*/
|
|
19
|
-
setOpenCallback(callback: XHRInterceptorOpenCallback): void;
|
|
20
|
-
/**
|
|
21
|
-
* Invoked before XMLHttpRequest.send(...) is called.
|
|
22
|
-
*/
|
|
23
|
-
setSendCallback(callback: XHRInterceptorSendCallback): void;
|
|
24
|
-
/**
|
|
25
|
-
* Invoked after xhr's readyState becomes xhr.HEADERS_RECEIVED.
|
|
26
|
-
*/
|
|
27
|
-
setHeaderReceivedCallback(callback: XHRInterceptorHeaderReceivedCallback): void;
|
|
28
|
-
/**
|
|
29
|
-
* Invoked after xhr's readyState becomes xhr.DONE.
|
|
30
|
-
*/
|
|
31
|
-
setResponseCallback(callback: XHRInterceptorResponseCallback): void;
|
|
32
|
-
/**
|
|
33
|
-
* Invoked before XMLHttpRequest.setRequestHeader(...) is called.
|
|
34
|
-
*/
|
|
35
|
-
setRequestHeaderCallback(callback: XHRInterceptorRequestHeaderCallback): void;
|
|
36
|
-
/**
|
|
37
|
-
* Invoked before XMLHttpRequest.send(...) is called.
|
|
38
|
-
*/
|
|
39
|
-
setOverrideCallback(callback: XHRInterceptorOverrideCallback): void;
|
|
40
|
-
isInterceptorEnabled(): boolean;
|
|
41
|
-
enableInterception(): void;
|
|
42
|
-
disableInterception(): void;
|
|
43
|
-
};
|
|
44
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { HTTPInspector } from './http/http-inspector';
|
|
2
|
-
import { SSEInspector } from './sse/sse-inspector';
|
|
3
|
-
import { WebSocketInspector } from './websocket/websocket-inspector';
|
|
4
|
-
import { EventsListener } from './events-listener';
|
|
5
|
-
import { NetworkActivityEventMap } from '../shared/client';
|
|
6
|
-
import { InspectorsConfig } from './config';
|
|
7
|
-
export type NetworkInspector = {
|
|
8
|
-
readonly http: HTTPInspector;
|
|
9
|
-
readonly sse: SSEInspector;
|
|
10
|
-
readonly websocket: WebSocketInspector;
|
|
11
|
-
setup: (eventsListener: EventsListener<NetworkActivityEventMap>) => void;
|
|
12
|
-
enable: (config?: InspectorsConfig) => void;
|
|
13
|
-
disable: () => void;
|
|
14
|
-
dispose: () => void;
|
|
15
|
-
};
|
|
16
|
-
export declare const getNetworkInspector: () => NetworkInspector;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { SSEEventMap } from '../../shared/sse-events';
|
|
2
|
-
import { Inspector } from '../inspector';
|
|
3
|
-
export type SSEInspector = Inspector<SSEEventMap>;
|
|
4
|
-
export declare const SSE_EVENTS: (keyof SSEEventMap)[];
|
|
5
|
-
export declare const isSSEEvent: (type: string) => type is keyof SSEEventMap;
|
|
6
|
-
export declare const getSSEInspector: () => SSEInspector;
|