@rozenite/network-activity-plugin 1.0.0-alpha.7 → 1.0.0-alpha.9

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 (96) hide show
  1. package/dist/App.html +2 -2
  2. package/dist/assets/{App-CIflVb88.js → App-CA1Fbh0I.js} +12009 -10809
  3. package/dist/assets/{App-Czu6Vt2P.css → App-DoHQsY5s.css} +43 -0
  4. package/dist/event-source.cjs +22 -0
  5. package/dist/event-source.js +23 -0
  6. package/dist/rozenite.json +1 -1
  7. package/dist/src/react-native/{network-inspector.d.ts → http/network-inspector.d.ts} +1 -1
  8. package/dist/src/react-native/sse/event-source.d.ts +2 -0
  9. package/dist/src/react-native/sse/sse-inspector.d.ts +9 -0
  10. package/dist/src/react-native/sse/sse-interceptor.d.ts +36 -0
  11. package/dist/src/react-native/sse/types.d.ts +6 -0
  12. package/dist/src/react-native/utils.d.ts +6 -0
  13. package/dist/src/react-native/websocket/websocket-inspector.d.ts +9 -0
  14. package/dist/src/react-native/websocket/websocket-interceptor.d.ts +74 -0
  15. package/dist/src/shared/client.d.ts +8 -4
  16. package/dist/src/shared/sse-events.d.ts +35 -0
  17. package/dist/src/shared/websocket-events.d.ts +60 -0
  18. package/dist/src/ui/components/Badge.d.ts +1 -1
  19. package/dist/src/ui/components/Button.d.ts +1 -1
  20. package/dist/src/ui/components/JsonTreeCopyableItem.d.ts +7 -0
  21. package/dist/src/ui/components/RequestList.d.ts +6 -26
  22. package/dist/src/ui/components/SidePanel.d.ts +1 -0
  23. package/dist/src/ui/components/Toolbar.d.ts +1 -0
  24. package/dist/src/ui/hooks/useCopyToClipboard.d.ts +4 -0
  25. package/dist/src/ui/state/derived.d.ts +5 -0
  26. package/dist/src/ui/state/hooks.d.ts +17 -0
  27. package/dist/src/ui/state/model.d.ts +98 -0
  28. package/dist/src/ui/state/store.d.ts +24 -0
  29. package/dist/src/ui/tabs/CookiesTab.d.ts +3 -6
  30. package/dist/src/ui/tabs/HeadersTab.d.ts +3 -15
  31. package/dist/src/ui/tabs/MessagesTab.d.ts +5 -0
  32. package/dist/src/ui/tabs/RequestTab.d.ts +2 -7
  33. package/dist/src/ui/tabs/ResponseTab.d.ts +2 -8
  34. package/dist/src/ui/tabs/SSEMessagesTab.d.ts +5 -0
  35. package/dist/src/ui/tabs/TimingTab.d.ts +3 -5
  36. package/dist/src/ui/types.d.ts +6 -3
  37. package/dist/src/ui/utils/assert.d.ts +1 -0
  38. package/dist/src/ui/utils/copyToClipboard.d.ts +1 -0
  39. package/dist/src/ui/utils/getHttpHeaderValue.d.ts +2 -0
  40. package/dist/src/ui/utils/getId.d.ts +1 -0
  41. package/dist/src/ui/utils/getStatusColor.d.ts +1 -0
  42. package/dist/useNetworkActivityDevTools.cjs +433 -34
  43. package/dist/useNetworkActivityDevTools.js +431 -34
  44. package/package.json +19 -8
  45. package/src/react-native/{network-inspector.ts → http/network-inspector.ts} +14 -32
  46. package/src/react-native/{xml-request.d.ts → http/xml-request.d.ts} +1 -0
  47. package/src/react-native/sse/event-source.ts +25 -0
  48. package/src/react-native/sse/sse-inspector.ts +117 -0
  49. package/src/react-native/sse/sse-interceptor.ts +162 -0
  50. package/src/react-native/sse/types.ts +9 -0
  51. package/src/react-native/useNetworkActivityDevTools.ts +75 -1
  52. package/src/react-native/utils.ts +43 -0
  53. package/src/react-native/websocket/websocket-inspector.ts +180 -0
  54. package/src/react-native/websocket/websocket-interceptor.d.ts +4 -0
  55. package/src/react-native/websocket/websocket-interceptor.ts +166 -0
  56. package/src/shared/client.ts +10 -4
  57. package/src/shared/sse-events.ts +44 -0
  58. package/src/shared/websocket-events.ts +79 -0
  59. package/src/ui/components/Badge.tsx +1 -1
  60. package/src/ui/components/Button.tsx +1 -1
  61. package/src/ui/components/Input.tsx +1 -1
  62. package/src/ui/components/JsonTree.tsx +13 -0
  63. package/src/ui/components/JsonTreeCopyableItem.tsx +33 -0
  64. package/src/ui/components/RequestList.tsx +42 -123
  65. package/src/ui/components/ScrollArea.tsx +1 -1
  66. package/src/ui/components/Separator.tsx +1 -1
  67. package/src/ui/components/SidePanel.tsx +323 -0
  68. package/src/ui/components/Tabs.tsx +2 -2
  69. package/src/ui/components/Toolbar.tsx +45 -0
  70. package/src/ui/hooks/useCopyToClipboard.ts +28 -0
  71. package/src/ui/state/derived.ts +112 -0
  72. package/src/ui/state/hooks.ts +44 -0
  73. package/src/ui/state/model.ts +129 -0
  74. package/src/ui/state/store.ts +559 -0
  75. package/src/ui/tabs/CookiesTab.tsx +168 -179
  76. package/src/ui/tabs/HeadersTab.tsx +24 -31
  77. package/src/ui/tabs/MessagesTab.tsx +276 -0
  78. package/src/ui/tabs/RequestTab.tsx +28 -31
  79. package/src/ui/tabs/ResponseTab.tsx +10 -12
  80. package/src/ui/tabs/SSEMessagesTab.tsx +213 -0
  81. package/src/ui/tabs/TimingTab.tsx +33 -44
  82. package/src/ui/types.ts +6 -2
  83. package/src/ui/utils/assert.ts +5 -0
  84. package/src/ui/utils/copyToClipboard.ts +3 -0
  85. package/src/ui/utils/getHttpHeaderValue.ts +14 -0
  86. package/src/ui/utils/getId.ts +10 -0
  87. package/src/ui/utils/getStatusColor.ts +15 -0
  88. package/src/ui/views/InspectorView.tsx +24 -320
  89. package/tailwind.config.ts +3 -0
  90. package/vite.config.ts +12 -0
  91. /package/dist/src/react-native/{network-requests-registry.d.ts → http/network-requests-registry.d.ts} +0 -0
  92. /package/dist/src/react-native/{xhr-interceptor.d.ts → http/xhr-interceptor.d.ts} +0 -0
  93. /package/dist/src/ui/{utils.d.ts → utils/cn.d.ts} +0 -0
  94. /package/src/react-native/{network-requests-registry.ts → http/network-requests-registry.ts} +0 -0
  95. /package/src/react-native/{xhr-interceptor.ts → http/xhr-interceptor.ts} +0 -0
  96. /package/src/ui/{utils.ts → utils/cn.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { ScrollArea } from '../components/ScrollArea';
2
2
  import { Badge } from '../components/Badge';
3
- import { NetworkEntry } from '../types';
3
+ import { HttpHeaders } from '../../shared/client';
4
+ import { HttpNetworkEntry, SSENetworkEntry } from '../state/model';
4
5
 
5
6
  type Cookie = {
6
7
  name: string;
@@ -15,10 +16,7 @@ type Cookie = {
15
16
  };
16
17
 
17
18
  export type CookiesTabProps = {
18
- selectedRequest: {
19
- id: string;
20
- };
21
- networkEntries: Map<string, NetworkEntry>;
19
+ selectedRequest: HttpNetworkEntry | SSENetworkEntry;
22
20
  };
23
21
 
24
22
  const parseCookieString = (cookieString: string): Cookie[] => {
@@ -71,7 +69,7 @@ const parseCookieString = (cookieString: string): Cookie[] => {
71
69
  };
72
70
 
73
71
  const extractCookiesFromHeaders = (
74
- headers: Record<string, string>
72
+ headers: HttpHeaders
75
73
  ): {
76
74
  requestCookies: Cookie[];
77
75
  responseCookies: Cookie[];
@@ -95,196 +93,187 @@ const extractCookiesFromHeaders = (
95
93
  return { requestCookies, responseCookies };
96
94
  };
97
95
 
98
- export const CookiesTab = ({
99
- selectedRequest,
100
- networkEntries,
101
- }: CookiesTabProps) => {
96
+ export const CookiesTab = ({ selectedRequest }: CookiesTabProps) => {
102
97
  return (
103
- <ScrollArea className="h-full min-h-0 p-4">
104
- {(() => {
105
- const entry = networkEntries.get(selectedRequest.id);
106
- if (!entry) {
107
- return (
108
- <div className="text-sm text-gray-400">
109
- No request data available
110
- </div>
111
- );
112
- }
98
+ <ScrollArea className="h-full w-full">
99
+ <div className="p-4">
100
+ {(() => {
101
+ // Extract cookies from request and response headers separately
102
+ const requestHeaders = selectedRequest.request?.headers || {};
103
+ const responseHeaders = selectedRequest.response?.headers || {};
113
104
 
114
- // Extract cookies from request and response headers separately
115
- const requestHeaders = entry.request?.headers || {};
116
- const responseHeaders = entry.response?.headers || {};
105
+ const { requestCookies } = extractCookiesFromHeaders(requestHeaders);
106
+ const { responseCookies } =
107
+ extractCookiesFromHeaders(responseHeaders);
117
108
 
118
- const { requestCookies } = extractCookiesFromHeaders(requestHeaders);
119
- const { responseCookies } = extractCookiesFromHeaders(responseHeaders);
109
+ const hasRequestCookies = requestCookies.length > 0;
110
+ const hasResponseCookies = responseCookies.length > 0;
120
111
 
121
- const hasRequestCookies = requestCookies.length > 0;
122
- const hasResponseCookies = responseCookies.length > 0;
112
+ if (!hasRequestCookies && !hasResponseCookies) {
113
+ return (
114
+ <div className="text-sm text-gray-400">
115
+ No cookies for this request
116
+ </div>
117
+ );
118
+ }
123
119
 
124
- if (!hasRequestCookies && !hasResponseCookies) {
125
120
  return (
126
- <div className="text-sm text-gray-400">
127
- No cookies for this request
128
- </div>
129
- );
130
- }
131
-
132
- return (
133
- <div className="space-y-6">
134
- {/* Request Cookies */}
135
- {hasRequestCookies && (
136
- <div>
137
- <h4 className="text-sm font-medium text-gray-300 mb-3">
138
- Request Cookies ({requestCookies.length})
139
- </h4>
140
- <div className="space-y-2">
141
- {requestCookies.map((cookie, index) => (
142
- <div
143
- key={`request-${index}`}
144
- className="bg-gray-800 border border-gray-700 rounded p-3"
145
- >
146
- <div className="flex items-center justify-between mb-2">
147
- <span className="text-sm font-medium text-blue-400">
148
- {cookie.name}
149
- </span>
150
- <div className="flex items-center gap-2">
151
- {cookie.secure && (
152
- <Badge
153
- variant="outline"
154
- className="text-xs text-yellow-400 border-yellow-400"
155
- >
156
- Secure
157
- </Badge>
121
+ <div className="space-y-6">
122
+ {/* Request Cookies */}
123
+ {hasRequestCookies && (
124
+ <div>
125
+ <h4 className="text-sm font-medium text-gray-300 mb-3">
126
+ Request Cookies ({requestCookies.length})
127
+ </h4>
128
+ <div className="space-y-2">
129
+ {requestCookies.map((cookie, index) => (
130
+ <div
131
+ key={`request-${index}`}
132
+ className="bg-gray-800 border border-gray-700 rounded p-3"
133
+ >
134
+ <div className="flex items-center justify-between mb-2">
135
+ <span className="text-sm font-medium text-blue-400">
136
+ {cookie.name}
137
+ </span>
138
+ <div className="flex items-center gap-2">
139
+ {cookie.secure && (
140
+ <Badge
141
+ variant="outline"
142
+ className="text-xs text-yellow-400 border-yellow-400"
143
+ >
144
+ Secure
145
+ </Badge>
146
+ )}
147
+ {cookie.httpOnly && (
148
+ <Badge
149
+ variant="outline"
150
+ className="text-xs text-purple-400 border-purple-400"
151
+ >
152
+ HttpOnly
153
+ </Badge>
154
+ )}
155
+ </div>
156
+ </div>
157
+ <div className="text-sm text-gray-300 mb-2">
158
+ {cookie.value}
159
+ </div>
160
+ <div className="grid grid-cols-2 gap-4 text-xs text-gray-400">
161
+ {cookie.domain && (
162
+ <div>
163
+ <span className="font-medium">Domain:</span>{' '}
164
+ {cookie.domain}
165
+ </div>
166
+ )}
167
+ {cookie.path && (
168
+ <div>
169
+ <span className="font-medium">Path:</span>{' '}
170
+ {cookie.path}
171
+ </div>
172
+ )}
173
+ {cookie.expires && (
174
+ <div>
175
+ <span className="font-medium">Expires:</span>{' '}
176
+ {cookie.expires}
177
+ </div>
178
+ )}
179
+ {cookie.maxAge && (
180
+ <div>
181
+ <span className="font-medium">Max-Age:</span>{' '}
182
+ {cookie.maxAge}
183
+ </div>
158
184
  )}
159
- {cookie.httpOnly && (
160
- <Badge
161
- variant="outline"
162
- className="text-xs text-purple-400 border-purple-400"
163
- >
164
- HttpOnly
165
- </Badge>
185
+ {cookie.sameSite && (
186
+ <div>
187
+ <span className="font-medium">SameSite:</span>{' '}
188
+ {cookie.sameSite}
189
+ </div>
166
190
  )}
167
191
  </div>
168
192
  </div>
169
- <div className="text-sm text-gray-300 mb-2">
170
- {cookie.value}
171
- </div>
172
- <div className="grid grid-cols-2 gap-4 text-xs text-gray-400">
173
- {cookie.domain && (
174
- <div>
175
- <span className="font-medium">Domain:</span>{' '}
176
- {cookie.domain}
177
- </div>
178
- )}
179
- {cookie.path && (
180
- <div>
181
- <span className="font-medium">Path:</span>{' '}
182
- {cookie.path}
183
- </div>
184
- )}
185
- {cookie.expires && (
186
- <div>
187
- <span className="font-medium">Expires:</span>{' '}
188
- {cookie.expires}
189
- </div>
190
- )}
191
- {cookie.maxAge && (
192
- <div>
193
- <span className="font-medium">Max-Age:</span>{' '}
194
- {cookie.maxAge}
195
- </div>
196
- )}
197
- {cookie.sameSite && (
198
- <div>
199
- <span className="font-medium">SameSite:</span>{' '}
200
- {cookie.sameSite}
201
- </div>
202
- )}
203
- </div>
204
- </div>
205
- ))}
193
+ ))}
194
+ </div>
206
195
  </div>
207
- </div>
208
- )}
196
+ )}
209
197
 
210
- {/* Response Cookies */}
211
- {hasResponseCookies && (
212
- <div>
213
- <h4 className="text-sm font-medium text-gray-300 mb-3">
214
- Response Cookies ({responseCookies.length})
215
- </h4>
216
- <div className="space-y-2">
217
- {responseCookies.map((cookie, index) => (
218
- <div
219
- key={`response-${index}`}
220
- className="bg-gray-800 border border-gray-700 rounded p-3"
221
- >
222
- <div className="flex items-center justify-between mb-2">
223
- <span className="text-sm font-medium text-green-400">
224
- {cookie.name}
225
- </span>
226
- <div className="flex items-center gap-2">
227
- {cookie.secure && (
228
- <Badge
229
- variant="outline"
230
- className="text-xs text-yellow-400 border-yellow-400"
231
- >
232
- Secure
233
- </Badge>
198
+ {/* Response Cookies */}
199
+ {hasResponseCookies && (
200
+ <div>
201
+ <h4 className="text-sm font-medium text-gray-300 mb-3">
202
+ Response Cookies ({responseCookies.length})
203
+ </h4>
204
+ <div className="space-y-2">
205
+ {responseCookies.map((cookie, index) => (
206
+ <div
207
+ key={`response-${index}`}
208
+ className="bg-gray-800 border border-gray-700 rounded p-3"
209
+ >
210
+ <div className="flex items-center justify-between mb-2">
211
+ <span className="text-sm font-medium text-green-400">
212
+ {cookie.name}
213
+ </span>
214
+ <div className="flex items-center gap-2">
215
+ {cookie.secure && (
216
+ <Badge
217
+ variant="outline"
218
+ className="text-xs text-yellow-400 border-yellow-400"
219
+ >
220
+ Secure
221
+ </Badge>
222
+ )}
223
+ {cookie.httpOnly && (
224
+ <Badge
225
+ variant="outline"
226
+ className="text-xs text-purple-400 border-purple-400"
227
+ >
228
+ HttpOnly
229
+ </Badge>
230
+ )}
231
+ </div>
232
+ </div>
233
+ <div className="text-sm text-gray-300 mb-2">
234
+ {cookie.value}
235
+ </div>
236
+ <div className="grid grid-cols-2 gap-4 text-xs text-gray-400">
237
+ {cookie.domain && (
238
+ <div>
239
+ <span className="font-medium">Domain:</span>{' '}
240
+ {cookie.domain}
241
+ </div>
242
+ )}
243
+ {cookie.path && (
244
+ <div>
245
+ <span className="font-medium">Path:</span>{' '}
246
+ {cookie.path}
247
+ </div>
248
+ )}
249
+ {cookie.expires && (
250
+ <div>
251
+ <span className="font-medium">Expires:</span>{' '}
252
+ {cookie.expires}
253
+ </div>
234
254
  )}
235
- {cookie.httpOnly && (
236
- <Badge
237
- variant="outline"
238
- className="text-xs text-purple-400 border-purple-400"
239
- >
240
- HttpOnly
241
- </Badge>
255
+ {cookie.maxAge && (
256
+ <div>
257
+ <span className="font-medium">Max-Age:</span>{' '}
258
+ {cookie.maxAge}
259
+ </div>
260
+ )}
261
+ {cookie.sameSite && (
262
+ <div>
263
+ <span className="font-medium">SameSite:</span>{' '}
264
+ {cookie.sameSite}
265
+ </div>
242
266
  )}
243
267
  </div>
244
268
  </div>
245
- <div className="text-sm text-gray-300 mb-2">
246
- {cookie.value}
247
- </div>
248
- <div className="grid grid-cols-2 gap-4 text-xs text-gray-400">
249
- {cookie.domain && (
250
- <div>
251
- <span className="font-medium">Domain:</span>{' '}
252
- {cookie.domain}
253
- </div>
254
- )}
255
- {cookie.path && (
256
- <div>
257
- <span className="font-medium">Path:</span>{' '}
258
- {cookie.path}
259
- </div>
260
- )}
261
- {cookie.expires && (
262
- <div>
263
- <span className="font-medium">Expires:</span>{' '}
264
- {cookie.expires}
265
- </div>
266
- )}
267
- {cookie.maxAge && (
268
- <div>
269
- <span className="font-medium">Max-Age:</span>{' '}
270
- {cookie.maxAge}
271
- </div>
272
- )}
273
- {cookie.sameSite && (
274
- <div>
275
- <span className="font-medium">SameSite:</span>{' '}
276
- {cookie.sameSite}
277
- </div>
278
- )}
279
- </div>
280
- </div>
281
- ))}
269
+ ))}
270
+ </div>
282
271
  </div>
283
- </div>
284
- )}
285
- </div>
286
- );
287
- })()}
272
+ )}
273
+ </div>
274
+ );
275
+ })()}
276
+ </div>
288
277
  </ScrollArea>
289
278
  );
290
279
  };
@@ -1,29 +1,21 @@
1
+ import { useMemo } from 'react';
1
2
  import { ScrollArea } from '../components/ScrollArea';
2
- import { NetworkEntry } from '../types';
3
+ import { HttpNetworkEntry, SSENetworkEntry } from '../state/model';
4
+ import { getStatusColor } from '../utils/getStatusColor';
3
5
 
4
6
  export type HeadersTabProps = {
5
- selectedRequest: {
6
- id: string;
7
- domain: string;
8
- path: string;
9
- method: string;
10
- status: number;
11
- requestBody?: {
12
- type: string;
13
- data: string;
14
- };
15
- };
16
- networkEntries: Map<string, NetworkEntry>;
17
- getStatusColor: (status: number) => string;
7
+ selectedRequest: HttpNetworkEntry | SSENetworkEntry;
18
8
  };
19
9
 
20
- export const HeadersTab = ({
21
- selectedRequest,
22
- networkEntries,
23
- getStatusColor,
24
- }: HeadersTabProps) => {
10
+ export const HeadersTab = ({ selectedRequest }: HeadersTabProps) => {
11
+ const url = useMemo(() => {
12
+ const { hostname, port, pathname } = new URL(selectedRequest.request.url);
13
+
14
+ return `${hostname}${port ? `:${port}` : ''}${pathname}`;
15
+ }, [selectedRequest.request.url]);
16
+
25
17
  return (
26
- <ScrollArea className="h-full min-h-0">
18
+ <ScrollArea className="h-full w-full">
27
19
  <div className="p-4 space-y-4">
28
20
  <div>
29
21
  <h4 className="text-sm font-medium text-gray-300 mb-2">General</h4>
@@ -31,25 +23,28 @@ export const HeadersTab = ({
31
23
  <div className="flex">
32
24
  <span className="w-32 text-gray-400">Request URL:</span>
33
25
  <span className="text-blue-400">
34
- {selectedRequest.domain}
35
- {selectedRequest.path}
26
+ {url}
36
27
  </span>
37
28
  </div>
38
29
  <div className="flex">
39
30
  <span className="w-32 text-gray-400">Request Method:</span>
40
- <span>{selectedRequest.method}</span>
31
+ <span>{selectedRequest.request.method}</span>
41
32
  </div>
42
33
  <div className="flex">
43
34
  <span className="w-32 text-gray-400">Status Code:</span>
44
- <span className={getStatusColor(selectedRequest.status)}>
45
- {selectedRequest.status}
35
+ <span
36
+ className={getStatusColor(
37
+ selectedRequest.response?.status ?? 0
38
+ )}
39
+ >
40
+ {selectedRequest.response?.status ?? 'Pending'}
46
41
  </span>
47
42
  </div>
48
- {selectedRequest.requestBody && (
43
+ {selectedRequest.request.body && (
49
44
  <div className="flex">
50
45
  <span className="w-32 text-gray-400">Content-Type:</span>
51
46
  <span className="text-blue-400">
52
- {selectedRequest.requestBody.type}
47
+ {selectedRequest.request.body.type}
53
48
  </span>
54
49
  </div>
55
50
  )}
@@ -62,8 +57,7 @@ export const HeadersTab = ({
62
57
  </h4>
63
58
  <div className="space-y-1 text-sm font-mono">
64
59
  {(() => {
65
- const entry = networkEntries.get(selectedRequest.id);
66
- const responseHeaders = entry?.response?.headers;
60
+ const responseHeaders = selectedRequest.response?.headers;
67
61
  if (responseHeaders && Object.keys(responseHeaders).length > 0) {
68
62
  return Object.entries(responseHeaders).map(([key, value]) => (
69
63
  <div key={key} className="flex">
@@ -90,8 +84,7 @@ export const HeadersTab = ({
90
84
  </h4>
91
85
  <div className="space-y-1 text-sm font-mono">
92
86
  {(() => {
93
- const entry = networkEntries.get(selectedRequest.id);
94
- const requestHeaders = entry?.request?.headers;
87
+ const requestHeaders = selectedRequest.request.headers;
95
88
  if (requestHeaders && Object.keys(requestHeaders).length > 0) {
96
89
  return Object.entries(requestHeaders).map(([key, value]) => (
97
90
  <div key={key} className="flex">