@rozenite/network-activity-plugin 1.0.0-alpha.8 → 1.0.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.
Files changed (160) hide show
  1. package/README.md +2 -0
  2. package/dist/App.html +2 -2
  3. package/dist/assets/{App-R2ZMH9wJ.css → App-BrSkOkws.css} +269 -2
  4. package/dist/assets/{App-lNMijPJ4.js → App-C6wCDVkW.js} +17485 -10814
  5. package/dist/event-source.cjs +22 -0
  6. package/dist/event-source.js +23 -0
  7. package/dist/react-native.cjs +4 -1
  8. package/dist/react-native.js +4 -1
  9. package/dist/rozenite.json +1 -1
  10. package/dist/src/react-native/config.d.ts +20 -0
  11. package/dist/src/react-native/{network-inspector.d.ts → http/network-inspector.d.ts} +1 -1
  12. package/dist/src/react-native/http/overrides-registry.d.ts +6 -0
  13. package/dist/src/react-native/{xhr-interceptor.d.ts → http/xhr-interceptor.d.ts} +7 -1
  14. package/dist/src/react-native/sse/event-source.d.ts +2 -0
  15. package/dist/src/react-native/sse/sse-inspector.d.ts +9 -0
  16. package/dist/src/react-native/sse/sse-interceptor.d.ts +36 -0
  17. package/dist/src/react-native/sse/types.d.ts +6 -0
  18. package/dist/src/react-native/useNetworkActivityDevTools.d.ts +2 -1
  19. package/dist/src/react-native/utils/getBlobName.d.ts +35 -0
  20. package/dist/src/react-native/utils/getFormDataEntries.d.ts +18 -0
  21. package/dist/src/react-native/utils.d.ts +6 -0
  22. package/dist/src/react-native/websocket/websocket-inspector.d.ts +9 -0
  23. package/dist/src/react-native/websocket/websocket-interceptor.d.ts +74 -0
  24. package/dist/src/shared/client.d.ts +53 -6
  25. package/dist/src/shared/sse-events.d.ts +38 -0
  26. package/dist/src/shared/websocket-events.d.ts +60 -0
  27. package/dist/src/ui/components/Badge.d.ts +1 -1
  28. package/dist/src/ui/components/Button.d.ts +2 -2
  29. package/dist/src/ui/components/CodeBlock.d.ts +3 -0
  30. package/dist/src/ui/components/CodeEditor.d.ts +5 -0
  31. package/dist/src/ui/components/CookieCard.d.ts +7 -0
  32. package/dist/src/ui/components/CopyRequestDropdown.d.ts +7 -0
  33. package/dist/src/ui/components/DropdownMenu.d.ts +27 -0
  34. package/dist/src/ui/components/FilterBar.d.ts +10 -0
  35. package/dist/src/ui/components/JsonTreeCopyableItem.d.ts +7 -0
  36. package/dist/src/ui/components/KeyValueGrid.d.ts +13 -0
  37. package/dist/src/ui/components/OverrideResponse.d.ts +8 -0
  38. package/dist/src/ui/components/RequestBody.d.ts +6 -0
  39. package/dist/src/ui/components/RequestList.d.ts +13 -28
  40. package/dist/src/ui/components/ScrollArea.d.ts +3 -2
  41. package/dist/src/ui/components/Section.d.ts +8 -0
  42. package/dist/src/ui/components/Separator.d.ts +2 -1
  43. package/dist/src/ui/components/SidePanel.d.ts +1 -0
  44. package/dist/src/ui/components/Tabs.d.ts +7 -0
  45. package/dist/src/ui/components/Toolbar.d.ts +1 -0
  46. package/dist/src/ui/hooks/useCopyToClipboard.d.ts +4 -0
  47. package/dist/src/ui/state/derived.d.ts +5 -0
  48. package/dist/src/ui/state/hooks.d.ts +21 -0
  49. package/dist/src/ui/state/model.d.ts +103 -0
  50. package/dist/src/ui/state/store.d.ts +48 -0
  51. package/dist/src/ui/tabs/CookiesTab.d.ts +3 -6
  52. package/dist/src/ui/tabs/HeadersTab.d.ts +3 -15
  53. package/dist/src/ui/tabs/MessagesTab.d.ts +5 -0
  54. package/dist/src/ui/tabs/RequestTab.d.ts +2 -7
  55. package/dist/src/ui/tabs/ResponseTab.d.ts +2 -8
  56. package/dist/src/ui/tabs/SSEMessagesTab.d.ts +5 -0
  57. package/dist/src/ui/tabs/TimingTab.d.ts +3 -5
  58. package/dist/src/ui/types.d.ts +4 -1
  59. package/dist/src/ui/utils/assert.d.ts +1 -0
  60. package/dist/src/ui/utils/checkRequestBodyBinary.d.ts +2 -0
  61. package/dist/src/ui/utils/copyToClipboard.d.ts +1 -0
  62. package/dist/src/ui/utils/escapeShellArg.d.ts +1 -0
  63. package/dist/src/ui/utils/generateCurlCommand.d.ts +2 -0
  64. package/dist/src/ui/utils/generateFetchCall.d.ts +2 -0
  65. package/dist/src/ui/utils/generateMultipartBody.d.ts +4 -0
  66. package/dist/src/ui/utils/getId.d.ts +1 -0
  67. package/dist/src/ui/utils/getStatusColor.d.ts +1 -0
  68. package/dist/src/utils/applyReactNativeRequestHeadersLogic.d.ts +7 -0
  69. package/dist/src/utils/applyReactNativeResponseHeadersLogic.d.ts +9 -0
  70. package/dist/src/utils/cookieParser.d.ts +6 -0
  71. package/dist/src/utils/getContentTypeMimeType.d.ts +2 -0
  72. package/dist/src/utils/getHttpHeader.d.ts +5 -0
  73. package/dist/src/utils/getHttpHeaderValueAsString.d.ts +11 -0
  74. package/dist/src/utils/getStringSizeInBytes.d.ts +1 -0
  75. package/dist/src/utils/inferContentTypeFromPostData.d.ts +2 -0
  76. package/dist/src/utils/safeStringify.d.ts +1 -0
  77. package/dist/src/utils/typeChecks.d.ts +9 -0
  78. package/dist/useNetworkActivityDevTools.cjs +724 -40
  79. package/dist/useNetworkActivityDevTools.js +723 -41
  80. package/package.json +22 -8
  81. package/react-native.ts +6 -1
  82. package/src/react-native/config.ts +43 -0
  83. package/src/react-native/http/network-inspector.ts +388 -0
  84. package/src/react-native/http/overrides-registry.ts +32 -0
  85. package/src/react-native/{xhr-interceptor.ts → http/xhr-interceptor.ts} +19 -2
  86. package/src/react-native/{xml-request.d.ts → http/xml-request.d.ts} +1 -0
  87. package/src/react-native/sse/event-source.ts +25 -0
  88. package/src/react-native/sse/sse-inspector.ts +139 -0
  89. package/src/react-native/sse/sse-interceptor.ts +180 -0
  90. package/src/react-native/sse/types.ts +9 -0
  91. package/src/react-native/useNetworkActivityDevTools.ts +156 -4
  92. package/src/react-native/utils/getBlobName.ts +45 -0
  93. package/src/react-native/utils/getFormDataEntries.ts +32 -0
  94. package/src/react-native/utils.ts +43 -0
  95. package/src/react-native/websocket/websocket-inspector.ts +180 -0
  96. package/src/react-native/websocket/websocket-interceptor.d.ts +4 -0
  97. package/src/react-native/websocket/websocket-interceptor.ts +166 -0
  98. package/src/shared/client.ts +79 -6
  99. package/src/shared/sse-events.ts +47 -0
  100. package/src/shared/websocket-events.ts +79 -0
  101. package/src/ui/components/Button.tsx +1 -0
  102. package/src/ui/components/CodeBlock.tsx +19 -0
  103. package/src/ui/components/CodeEditor.tsx +26 -0
  104. package/src/ui/components/CookieCard.tsx +64 -0
  105. package/src/ui/components/CopyRequestDropdown.tsx +95 -0
  106. package/src/ui/components/DropdownMenu.tsx +206 -0
  107. package/src/ui/components/FilterBar.tsx +117 -0
  108. package/src/ui/components/Input.tsx +1 -1
  109. package/src/ui/components/JsonTree.tsx +20 -0
  110. package/src/ui/components/JsonTreeCopyableItem.tsx +37 -0
  111. package/src/ui/components/KeyValueGrid.tsx +51 -0
  112. package/src/ui/components/OverrideResponse.tsx +132 -0
  113. package/src/ui/components/RequestBody.tsx +86 -0
  114. package/src/ui/components/RequestList.tsx +101 -131
  115. package/src/ui/components/ScrollArea.tsx +1 -0
  116. package/src/ui/components/Section.tsx +46 -0
  117. package/src/ui/components/SidePanel.tsx +333 -0
  118. package/src/ui/components/Tabs.tsx +1 -1
  119. package/src/ui/components/Toolbar.tsx +45 -0
  120. package/src/ui/globals.css +4 -0
  121. package/src/ui/hooks/useCopyToClipboard.ts +28 -0
  122. package/src/ui/state/derived.ts +112 -0
  123. package/src/ui/state/hooks.ts +52 -0
  124. package/src/ui/state/model.ts +140 -0
  125. package/src/ui/state/store.ts +669 -0
  126. package/src/ui/tabs/CookiesTab.tsx +61 -278
  127. package/src/ui/tabs/HeadersTab.tsx +85 -103
  128. package/src/ui/tabs/MessagesTab.tsx +276 -0
  129. package/src/ui/tabs/RequestTab.tsx +58 -51
  130. package/src/ui/tabs/ResponseTab.tsx +101 -74
  131. package/src/ui/tabs/SSEMessagesTab.tsx +224 -0
  132. package/src/ui/tabs/TimingTab.tsx +30 -43
  133. package/src/ui/types.ts +4 -1
  134. package/src/ui/utils/assert.ts +5 -0
  135. package/src/ui/utils/checkRequestBodyBinary.ts +7 -0
  136. package/src/ui/utils/copyToClipboard.ts +3 -0
  137. package/src/ui/utils/escapeShellArg.ts +12 -0
  138. package/src/ui/utils/generateCurlCommand.ts +83 -0
  139. package/src/ui/utils/generateFetchCall.ts +64 -0
  140. package/src/ui/utils/generateMultipartBody.ts +19 -0
  141. package/src/ui/utils/getId.ts +10 -0
  142. package/src/ui/utils/getStatusColor.ts +15 -0
  143. package/src/ui/views/InspectorView.tsx +35 -319
  144. package/src/utils/applyReactNativeRequestHeadersLogic.ts +30 -0
  145. package/src/utils/applyReactNativeResponseHeadersLogic.ts +28 -0
  146. package/src/utils/cookieParser.ts +126 -0
  147. package/src/utils/getContentTypeMimeType.ts +17 -0
  148. package/src/utils/getHttpHeader.ts +17 -0
  149. package/src/utils/getHttpHeaderValueAsString.ts +13 -0
  150. package/src/utils/getStringSizeInBytes.ts +3 -0
  151. package/src/utils/inferContentTypeFromPostData.ts +9 -0
  152. package/src/utils/safeStringify.ts +7 -0
  153. package/src/utils/typeChecks.ts +27 -0
  154. package/tailwind.config.ts +3 -0
  155. package/vite.config.ts +12 -0
  156. package/dist/src/ui/utils/getHttpHeaderValue.d.ts +0 -2
  157. package/src/react-native/network-inspector.ts +0 -247
  158. package/src/ui/utils/getHttpHeaderValue.ts +0 -14
  159. /package/dist/src/react-native/{network-requests-registry.d.ts → http/network-requests-registry.d.ts} +0 -0
  160. /package/src/react-native/{network-requests-registry.ts → http/network-requests-registry.ts} +0 -0
@@ -0,0 +1,180 @@
1
+ import { createNanoEvents } from 'nanoevents';
2
+ import { getWebSocketInterceptor } from './websocket-interceptor';
3
+ import {
4
+ WebSocketEvent,
5
+ WebSocketEventMap,
6
+ } from '../../shared/websocket-events';
7
+
8
+ type NanoEventsMap = {
9
+ [K in keyof WebSocketEventMap]: (data: WebSocketEventMap[K]) => void;
10
+ };
11
+
12
+ export type WebSocketInspector = {
13
+ enable: () => void;
14
+ disable: () => void;
15
+ isEnabled: () => boolean;
16
+ dispose: () => void;
17
+ on: <TEventType extends keyof WebSocketEventMap>(
18
+ event: TEventType,
19
+ callback: (data: WebSocketEventMap[TEventType]) => void
20
+ ) => () => void;
21
+ };
22
+
23
+ export const getWebSocketInspector = (): WebSocketInspector => {
24
+ const eventEmitter = createNanoEvents<NanoEventsMap>();
25
+ const socketUrlMap = new Map<number, string>();
26
+ const webSocketInterceptor = getWebSocketInterceptor();
27
+
28
+ return {
29
+ enable: () => {
30
+ webSocketInterceptor.setConnectCallback(
31
+ (
32
+ url: string,
33
+ protocols: string[] | null,
34
+ options: string[],
35
+ socketId: number
36
+ ) => {
37
+ socketUrlMap.set(socketId, url);
38
+ const event: WebSocketEvent = {
39
+ type: 'websocket-connect',
40
+ url,
41
+ socketId,
42
+ timestamp: Date.now(),
43
+ protocols,
44
+ options,
45
+ };
46
+ eventEmitter.emit('websocket-connect', event);
47
+ }
48
+ );
49
+
50
+ webSocketInterceptor.setCloseCallback(
51
+ (code: number | null, reason: string | null, socketId: number) => {
52
+ const url = socketUrlMap.get(socketId);
53
+
54
+ if (!url) {
55
+ return;
56
+ }
57
+
58
+ const event: WebSocketEvent = {
59
+ type: 'websocket-close',
60
+ url,
61
+ socketId,
62
+ timestamp: Date.now(),
63
+ code: code || 0,
64
+ reason: reason || undefined,
65
+ };
66
+ eventEmitter.emit('websocket-close', event);
67
+ socketUrlMap.delete(socketId);
68
+ }
69
+ );
70
+
71
+ webSocketInterceptor.setOnMessageCallback(
72
+ (data: string, socketId: number) => {
73
+ const url = socketUrlMap.get(socketId);
74
+
75
+ if (!url) {
76
+ return;
77
+ }
78
+
79
+ const event: WebSocketEvent = {
80
+ type: 'websocket-message-received',
81
+ url,
82
+ socketId,
83
+ timestamp: Date.now(),
84
+ data,
85
+ messageType: typeof data === 'string' ? 'text' : 'binary',
86
+ };
87
+ eventEmitter.emit('websocket-message-received', event);
88
+ }
89
+ );
90
+
91
+ webSocketInterceptor.setOnErrorCallback(
92
+ (error: string, socketId: number) => {
93
+ const url = socketUrlMap.get(socketId);
94
+
95
+ if (!url) {
96
+ return;
97
+ }
98
+
99
+ const event: WebSocketEvent = {
100
+ type: 'websocket-error',
101
+ url,
102
+ socketId,
103
+ timestamp: Date.now(),
104
+ error,
105
+ };
106
+ eventEmitter.emit('websocket-error', event);
107
+ }
108
+ );
109
+
110
+ webSocketInterceptor.setSendCallback((data: string, socketId: number) => {
111
+ const url = socketUrlMap.get(socketId);
112
+
113
+ if (!url) {
114
+ return;
115
+ }
116
+
117
+ const event: WebSocketEvent = {
118
+ type: 'websocket-message-sent',
119
+ url,
120
+ socketId,
121
+ timestamp: Date.now(),
122
+ data,
123
+ messageType: typeof data === 'string' ? 'text' : 'binary',
124
+ };
125
+ eventEmitter.emit('websocket-message-sent', event);
126
+ });
127
+
128
+ webSocketInterceptor.setOnOpenCallback((socketId: number) => {
129
+ const url = socketUrlMap.get(socketId);
130
+
131
+ if (!url) {
132
+ return;
133
+ }
134
+
135
+ const event: WebSocketEvent = {
136
+ type: 'websocket-open',
137
+ url,
138
+ socketId,
139
+ timestamp: Date.now(),
140
+ };
141
+ eventEmitter.emit('websocket-open', event);
142
+ });
143
+
144
+ webSocketInterceptor.setOnCloseCallback(
145
+ (error: { code: number; reason?: string }, socketId: number) => {
146
+ const url = socketUrlMap.get(socketId);
147
+
148
+ if (!url) {
149
+ return;
150
+ }
151
+
152
+ const event: WebSocketEvent = {
153
+ type: 'websocket-close',
154
+ url,
155
+ socketId,
156
+ timestamp: Date.now(),
157
+ code: error.code,
158
+ reason: error.reason,
159
+ };
160
+ eventEmitter.emit('websocket-close', event);
161
+ socketUrlMap.delete(socketId);
162
+ }
163
+ );
164
+
165
+ webSocketInterceptor.enableInterception();
166
+ },
167
+ disable: () => {
168
+ webSocketInterceptor.disableInterception();
169
+ },
170
+ isEnabled: () => webSocketInterceptor.isInterceptorEnabled(),
171
+ dispose: () => {
172
+ eventEmitter.events = {};
173
+ socketUrlMap.clear();
174
+ },
175
+ on: <TEventType extends keyof WebSocketEventMap>(
176
+ event: TEventType,
177
+ callback: (data: WebSocketEventMap[TEventType]) => void
178
+ ) => eventEmitter.on(event, callback as NanoEventsMap[TEventType]),
179
+ };
180
+ };
@@ -0,0 +1,4 @@
1
+ declare module 'react-native/Libraries/WebSocket/WebSocketInterceptor' {
2
+ const WebSocketInterceptor: unknown;
3
+ export default WebSocketInterceptor;
4
+ }
@@ -0,0 +1,166 @@
1
+ import { Platform } from 'react-native';
2
+ import WebSocketInterceptor from 'react-native/Libraries/WebSocket/WebSocketInterceptor';
3
+
4
+ export interface WebSocketInterceptor {
5
+ /**
6
+ * Invoked when RCTWebSocketModule.close(...) is called.
7
+ */
8
+ setCloseCallback(
9
+ callback: (
10
+ code: number | null,
11
+ reason: string | null,
12
+ socketId: number
13
+ ) => void
14
+ ): void;
15
+
16
+ /**
17
+ * Invoked when RCTWebSocketModule.send(...) or sendBinary(...) is called.
18
+ */
19
+ setSendCallback(callback: (data: string, socketId: number) => void): void;
20
+
21
+ /**
22
+ * Invoked when RCTWebSocketModule.connect(...) is called.
23
+ */
24
+ setConnectCallback(
25
+ callback: (
26
+ url: string,
27
+ protocols: string[] | null,
28
+ options: string[],
29
+ socketId: number
30
+ ) => void
31
+ ): void;
32
+
33
+ /**
34
+ * Invoked when event "websocketOpen" happens.
35
+ */
36
+ setOnOpenCallback(callback: (socketId: number) => void): void;
37
+
38
+ /**
39
+ * Invoked when event "websocketMessage" happens.
40
+ */
41
+ setOnMessageCallback(
42
+ callback: (data: string, socketId: number) => void
43
+ ): void;
44
+
45
+ /**
46
+ * Invoked when event "websocketFailed" happens.
47
+ */
48
+ setOnErrorCallback(callback: (error: string, socketId: number) => void): void;
49
+
50
+ /**
51
+ * Invoked when event "websocketClosed" happens.
52
+ */
53
+ setOnCloseCallback(
54
+ callback: (
55
+ error: { code: number; reason?: string },
56
+ socketId: number
57
+ ) => void
58
+ ): void;
59
+
60
+ isInterceptorEnabled(): boolean;
61
+ enableInterception(): void;
62
+ disableInterception(): void;
63
+ }
64
+
65
+ export interface WebSocketInterceptorPreRN079 {
66
+ /**
67
+ * Invoked when RCTWebSocketModule.close(...) is called.
68
+ */
69
+ setCloseCallback(
70
+ callback: (
71
+ code: number | null,
72
+ reason: string | null,
73
+ socketId: number
74
+ ) => void
75
+ ): void;
76
+
77
+ /**
78
+ * Invoked when RCTWebSocketModule.send(...) or sendBinary(...) is called.
79
+ */
80
+ setSendCallback(callback: (data: string, socketId: number) => void): void;
81
+
82
+ /**
83
+ * Invoked when RCTWebSocketModule.connect(...) is called.
84
+ */
85
+ setConnectCallback(
86
+ callback: (
87
+ url: string,
88
+ protocols: string[] | null,
89
+ options: string[],
90
+ socketId: number
91
+ ) => void
92
+ ): void;
93
+
94
+ /**
95
+ * Invoked when event "websocketOpen" happens.
96
+ */
97
+ setOnOpenCallback(callback: (socketId: number) => void): void;
98
+
99
+ /**
100
+ * Invoked when event "websocketMessage" happens.
101
+ */
102
+ setOnMessageCallback(
103
+ callback: (socketId: number, data: string) => void
104
+ ): void;
105
+
106
+ /**
107
+ * Invoked when event "websocketFailed" happens.
108
+ */
109
+ setOnErrorCallback(callback: (socketId: number, error: string) => void): void;
110
+
111
+ /**
112
+ * Invoked when event "websocketClosed" happens.
113
+ */
114
+ setOnCloseCallback(
115
+ callback: (
116
+ socketId: number,
117
+ error: { code: number; reason?: string }
118
+ ) => void
119
+ ): void;
120
+
121
+ isInterceptorEnabled(): boolean;
122
+ enableInterception(): void;
123
+ disableInterception(): void;
124
+ }
125
+
126
+ export const getWebSocketInterceptor = (): WebSocketInterceptor => {
127
+ /**
128
+ * Note: RN 0.79 changed the order of the arguments.
129
+ * @see https://github.com/facebook/react-native/commit/d2adb976abebcb0f38750903d98fbb5a3f50924b
130
+ */
131
+
132
+ if (Platform.constants.reactNativeVersion.minor >= 79) {
133
+ return WebSocketInterceptor as WebSocketInterceptor;
134
+ } else {
135
+ const WebSocketInterceptorPreRN079 =
136
+ WebSocketInterceptor as WebSocketInterceptorPreRN079;
137
+
138
+ return {
139
+ ...WebSocketInterceptorPreRN079,
140
+ setOnMessageCallback: (
141
+ callback: (data: string, socketId: number) => void
142
+ ) => {
143
+ WebSocketInterceptorPreRN079.setOnMessageCallback((socketId, data) => {
144
+ callback(data, socketId);
145
+ });
146
+ },
147
+ setOnCloseCallback: (
148
+ callback: (
149
+ error: { code: number; reason?: string },
150
+ socketId: number
151
+ ) => void
152
+ ) => {
153
+ WebSocketInterceptorPreRN079.setOnCloseCallback((error, socketId) => {
154
+ callback(socketId, error);
155
+ });
156
+ },
157
+ setOnErrorCallback: (
158
+ callback: (error: string, socketId: number) => void
159
+ ) => {
160
+ WebSocketInterceptorPreRN079.setOnErrorCallback((error, socketId) => {
161
+ callback(socketId, error);
162
+ });
163
+ },
164
+ } as WebSocketInterceptor;
165
+ }
166
+ };
@@ -1,15 +1,68 @@
1
1
  import { RozeniteDevToolsClient } from '@rozenite/plugin-bridge';
2
+ import { WebSocketEventMap } from './websocket-events';
3
+ import { SSEEventMap } from './sse-events';
2
4
 
3
- export type HttpHeaders = Record<string, string>;
5
+ export type HttpHeaders = Record<string, string | string[]>;
6
+ export type XHRHeaders = NonNullable<XMLHttpRequest['responseHeaders']>;
7
+
8
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD';
4
9
 
5
10
  export type RequestId = string;
6
11
  export type Timestamp = number;
7
12
 
13
+ export type XHRPostData =
14
+ | string
15
+ | Blob
16
+ | FormData
17
+ | ArrayBuffer
18
+ | ArrayBufferView
19
+ | unknown
20
+ | null
21
+ | undefined;
22
+
23
+ export type RequestTextPostData = {
24
+ type: 'text';
25
+ value: string;
26
+ };
27
+
28
+ export type RequestBinaryPostData = {
29
+ type: 'binary';
30
+ value: {
31
+ size: number;
32
+ type?: string;
33
+ name?: string;
34
+ };
35
+ };
36
+
37
+ export type RequestFormDataPostData = {
38
+ type: 'form-data';
39
+ value: Record<string, RequestTextPostData | RequestBinaryPostData>;
40
+ };
41
+
42
+ export type RequestPostData =
43
+ | RequestTextPostData
44
+ | RequestFormDataPostData
45
+ | RequestBinaryPostData
46
+ | null
47
+ | undefined;
48
+
49
+ export type Cookie = {
50
+ name: string;
51
+ value: string;
52
+ domain?: string;
53
+ path?: string;
54
+ expires?: string;
55
+ maxAge?: string;
56
+ secure?: boolean;
57
+ httpOnly?: boolean;
58
+ sameSite?: string;
59
+ };
60
+
8
61
  export type Request = {
9
62
  url: string;
10
- method: string;
63
+ method: HttpMethod;
11
64
  headers: HttpHeaders;
12
- postData?: string;
65
+ postData?: RequestPostData;
13
66
  };
14
67
 
15
68
  export type Response = {
@@ -18,7 +71,7 @@ export type Response = {
18
71
  statusText: string;
19
72
  headers: HttpHeaders;
20
73
  contentType: string;
21
- size: number;
74
+ size: number | null;
22
75
  responseTime: Timestamp;
23
76
  };
24
77
 
@@ -31,11 +84,26 @@ export type Initiator = {
31
84
 
32
85
  export type ResourceType = 'XHR' | 'Fetch' | 'Other';
33
86
 
87
+ export type RequestOverride = {
88
+ status?: number;
89
+ body?: string;
90
+ };
91
+
92
+ export type NetworkActivityClientUISettings = {
93
+ showUrlAsName?: boolean;
94
+ };
95
+
34
96
  export type NetworkActivityEventMap = {
35
97
  // Control events
36
98
  'network-enable': unknown;
37
99
  'network-disable': unknown;
38
100
 
101
+ // Client UI settings events
102
+ 'get-client-ui-settings': unknown;
103
+ 'client-ui-settings': {
104
+ settings?: NetworkActivityClientUISettings;
105
+ };
106
+
39
107
  // Network request events
40
108
  'request-sent': {
41
109
  requestId: RequestId;
@@ -56,7 +124,7 @@ export type NetworkActivityEventMap = {
56
124
  requestId: RequestId;
57
125
  timestamp: Timestamp;
58
126
  duration: number;
59
- size: number;
127
+ size: number | null;
60
128
  ttfb: number;
61
129
  };
62
130
 
@@ -76,7 +144,12 @@ export type NetworkActivityEventMap = {
76
144
  requestId: RequestId;
77
145
  body: string | null;
78
146
  };
79
- };
147
+
148
+ 'set-overrides': {
149
+ overrides: [string, RequestOverride][];
150
+ };
151
+ } & WebSocketEventMap &
152
+ SSEEventMap;
80
153
 
81
154
  export type NetworkActivityDevToolsClient =
82
155
  RozeniteDevToolsClient<NetworkActivityEventMap>;
@@ -0,0 +1,47 @@
1
+ import type { Response } from './client';
2
+
3
+ export type SSEConnectionStatus = 'connecting' | 'open' | 'closed';
4
+ export type SSERequestId = string;
5
+
6
+ export type SSEOpenEvent = {
7
+ type: 'sse-open';
8
+ requestId: SSERequestId;
9
+ timestamp: number;
10
+ response: Response;
11
+ };
12
+
13
+ export type SSEMessageEvent = {
14
+ type: 'sse-message';
15
+ requestId: SSERequestId;
16
+ timestamp: number;
17
+ payload: {
18
+ type: string;
19
+ data: string;
20
+ };
21
+ };
22
+
23
+ export type SSEErrorEvent = {
24
+ type: 'sse-error';
25
+ requestId: SSERequestId;
26
+ timestamp: number;
27
+ error: {
28
+ type: 'error' | 'timeout' | 'exception';
29
+ message: string;
30
+ };
31
+ };
32
+
33
+ export type SSECloseEvent = {
34
+ type: 'sse-close';
35
+ requestId: SSERequestId;
36
+ timestamp: number;
37
+ };
38
+
39
+ export type SSEEvent =
40
+ | SSEOpenEvent
41
+ | SSEMessageEvent
42
+ | SSEErrorEvent
43
+ | SSECloseEvent;
44
+
45
+ export type SSEEventMap = {
46
+ [K in SSEEvent['type']]: Extract<SSEEvent, { type: K }>;
47
+ };
@@ -0,0 +1,79 @@
1
+ export type WebSocketMessageType = 'text' | 'binary';
2
+
3
+ export type WebSocketConnectionStatus =
4
+ | 'connecting'
5
+ | 'open'
6
+ | 'closing'
7
+ | 'closed';
8
+
9
+ export type WebSocketConnectEvent = {
10
+ type: 'websocket-connect';
11
+ url: string;
12
+ socketId: number;
13
+ timestamp: number;
14
+ protocols: string[] | null;
15
+ options: string[];
16
+ };
17
+
18
+ export type WebSocketOpenEvent = {
19
+ type: 'websocket-open';
20
+ url: string;
21
+ socketId: number;
22
+ timestamp: number;
23
+ };
24
+
25
+ export type WebSocketCloseEvent = {
26
+ type: 'websocket-close';
27
+ url: string;
28
+ socketId: number;
29
+ timestamp: number;
30
+ code: number;
31
+ reason?: string;
32
+ };
33
+
34
+ export type WebSocketMessageSentEvent = {
35
+ type: 'websocket-message-sent';
36
+ url: string;
37
+ socketId: number;
38
+ timestamp: number;
39
+ data: string;
40
+ messageType: WebSocketMessageType;
41
+ };
42
+
43
+ export type WebSocketMessageReceivedEvent = {
44
+ type: 'websocket-message-received';
45
+ url: string;
46
+ socketId: number;
47
+ timestamp: number;
48
+ data: string;
49
+ messageType: WebSocketMessageType;
50
+ };
51
+
52
+ export type WebSocketErrorEvent = {
53
+ type: 'websocket-error';
54
+ url: string;
55
+ socketId: number;
56
+ timestamp: number;
57
+ error: string;
58
+ };
59
+
60
+ export type WebSocketConnectionStatusChangedEvent = {
61
+ type: 'websocket-connection-status-changed';
62
+ url: string;
63
+ socketId: number;
64
+ timestamp: number;
65
+ status: WebSocketConnectionStatus;
66
+ };
67
+
68
+ export type WebSocketEvent =
69
+ | WebSocketConnectEvent
70
+ | WebSocketOpenEvent
71
+ | WebSocketCloseEvent
72
+ | WebSocketMessageSentEvent
73
+ | WebSocketMessageReceivedEvent
74
+ | WebSocketErrorEvent
75
+ | WebSocketConnectionStatusChangedEvent;
76
+
77
+ export type WebSocketEventMap = {
78
+ [K in WebSocketEvent['type']]: Extract<WebSocketEvent, { type: K }>;
79
+ };
@@ -21,6 +21,7 @@ const buttonVariants = cva(
21
21
  },
22
22
  size: {
23
23
  default: 'h-10 px-4 py-2',
24
+ xs: 'h-7 rounded-md px-2 text-xs',
24
25
  sm: 'h-9 rounded-md px-3',
25
26
  lg: 'h-11 rounded-md px-8',
26
27
  icon: 'h-10 w-10',
@@ -0,0 +1,19 @@
1
+ import { HTMLProps } from 'react';
2
+ import { cn } from '../utils/cn';
3
+
4
+ export type CodeBlockProps = HTMLProps<HTMLPreElement>;
5
+
6
+ const codeBlockClassNames =
7
+ 'text-sm font-mono text-gray-300 whitespace-pre-wrap bg-gray-800 p-3 rounded-md border border-gray-700 overflow-x-auto wrap-anywhere';
8
+
9
+ export const CodeBlock = ({
10
+ children,
11
+ className,
12
+ ...props
13
+ }: CodeBlockProps) => {
14
+ return (
15
+ <pre className={cn(codeBlockClassNames, className)} {...props}>
16
+ {children}
17
+ </pre>
18
+ );
19
+ };
@@ -0,0 +1,26 @@
1
+ import { forwardRef } from 'react';
2
+
3
+ export type CodeEditorProps = {
4
+ data: string | undefined;
5
+ onInput?: (event: React.FormEvent<HTMLPreElement>) => void;
6
+ };
7
+
8
+ export const CodeEditor = forwardRef<HTMLPreElement, CodeEditorProps>(
9
+ ({ data, onInput }, ref) => {
10
+ return (
11
+ <pre
12
+ ref={ref}
13
+ contentEditable
14
+ suppressContentEditableWarning
15
+ className={
16
+ 'w-full text-sm font-mono text-gray-300 whitespace-pre-wrap bg-gray-800 p-3 rounded-md border border-gray-700 overflow-x-auto wrap-anywhere ring-offset-blue-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2'
17
+ }
18
+ onInput={onInput}
19
+ >
20
+ {data}
21
+ </pre>
22
+ );
23
+ }
24
+ );
25
+
26
+ CodeEditor.displayName = 'CodeEditor';