@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.
- package/dist/App.html +2 -2
- package/dist/assets/{App-CIflVb88.js → App-CA1Fbh0I.js} +12009 -10809
- package/dist/assets/{App-Czu6Vt2P.css → App-DoHQsY5s.css} +43 -0
- package/dist/event-source.cjs +22 -0
- package/dist/event-source.js +23 -0
- package/dist/rozenite.json +1 -1
- package/dist/src/react-native/{network-inspector.d.ts → http/network-inspector.d.ts} +1 -1
- package/dist/src/react-native/sse/event-source.d.ts +2 -0
- package/dist/src/react-native/sse/sse-inspector.d.ts +9 -0
- package/dist/src/react-native/sse/sse-interceptor.d.ts +36 -0
- package/dist/src/react-native/sse/types.d.ts +6 -0
- package/dist/src/react-native/utils.d.ts +6 -0
- package/dist/src/react-native/websocket/websocket-inspector.d.ts +9 -0
- package/dist/src/react-native/websocket/websocket-interceptor.d.ts +74 -0
- package/dist/src/shared/client.d.ts +8 -4
- package/dist/src/shared/sse-events.d.ts +35 -0
- package/dist/src/shared/websocket-events.d.ts +60 -0
- package/dist/src/ui/components/Badge.d.ts +1 -1
- package/dist/src/ui/components/Button.d.ts +1 -1
- package/dist/src/ui/components/JsonTreeCopyableItem.d.ts +7 -0
- package/dist/src/ui/components/RequestList.d.ts +6 -26
- package/dist/src/ui/components/SidePanel.d.ts +1 -0
- package/dist/src/ui/components/Toolbar.d.ts +1 -0
- package/dist/src/ui/hooks/useCopyToClipboard.d.ts +4 -0
- package/dist/src/ui/state/derived.d.ts +5 -0
- package/dist/src/ui/state/hooks.d.ts +17 -0
- package/dist/src/ui/state/model.d.ts +98 -0
- package/dist/src/ui/state/store.d.ts +24 -0
- package/dist/src/ui/tabs/CookiesTab.d.ts +3 -6
- package/dist/src/ui/tabs/HeadersTab.d.ts +3 -15
- package/dist/src/ui/tabs/MessagesTab.d.ts +5 -0
- package/dist/src/ui/tabs/RequestTab.d.ts +2 -7
- package/dist/src/ui/tabs/ResponseTab.d.ts +2 -8
- package/dist/src/ui/tabs/SSEMessagesTab.d.ts +5 -0
- package/dist/src/ui/tabs/TimingTab.d.ts +3 -5
- package/dist/src/ui/types.d.ts +6 -3
- package/dist/src/ui/utils/assert.d.ts +1 -0
- package/dist/src/ui/utils/copyToClipboard.d.ts +1 -0
- package/dist/src/ui/utils/getHttpHeaderValue.d.ts +2 -0
- package/dist/src/ui/utils/getId.d.ts +1 -0
- package/dist/src/ui/utils/getStatusColor.d.ts +1 -0
- package/dist/useNetworkActivityDevTools.cjs +433 -34
- package/dist/useNetworkActivityDevTools.js +431 -34
- package/package.json +19 -8
- package/src/react-native/{network-inspector.ts → http/network-inspector.ts} +14 -32
- package/src/react-native/{xml-request.d.ts → http/xml-request.d.ts} +1 -0
- package/src/react-native/sse/event-source.ts +25 -0
- package/src/react-native/sse/sse-inspector.ts +117 -0
- package/src/react-native/sse/sse-interceptor.ts +162 -0
- package/src/react-native/sse/types.ts +9 -0
- package/src/react-native/useNetworkActivityDevTools.ts +75 -1
- package/src/react-native/utils.ts +43 -0
- package/src/react-native/websocket/websocket-inspector.ts +180 -0
- package/src/react-native/websocket/websocket-interceptor.d.ts +4 -0
- package/src/react-native/websocket/websocket-interceptor.ts +166 -0
- package/src/shared/client.ts +10 -4
- package/src/shared/sse-events.ts +44 -0
- package/src/shared/websocket-events.ts +79 -0
- package/src/ui/components/Badge.tsx +1 -1
- package/src/ui/components/Button.tsx +1 -1
- package/src/ui/components/Input.tsx +1 -1
- package/src/ui/components/JsonTree.tsx +13 -0
- package/src/ui/components/JsonTreeCopyableItem.tsx +33 -0
- package/src/ui/components/RequestList.tsx +42 -123
- package/src/ui/components/ScrollArea.tsx +1 -1
- package/src/ui/components/Separator.tsx +1 -1
- package/src/ui/components/SidePanel.tsx +323 -0
- package/src/ui/components/Tabs.tsx +2 -2
- package/src/ui/components/Toolbar.tsx +45 -0
- package/src/ui/hooks/useCopyToClipboard.ts +28 -0
- package/src/ui/state/derived.ts +112 -0
- package/src/ui/state/hooks.ts +44 -0
- package/src/ui/state/model.ts +129 -0
- package/src/ui/state/store.ts +559 -0
- package/src/ui/tabs/CookiesTab.tsx +168 -179
- package/src/ui/tabs/HeadersTab.tsx +24 -31
- package/src/ui/tabs/MessagesTab.tsx +276 -0
- package/src/ui/tabs/RequestTab.tsx +28 -31
- package/src/ui/tabs/ResponseTab.tsx +10 -12
- package/src/ui/tabs/SSEMessagesTab.tsx +213 -0
- package/src/ui/tabs/TimingTab.tsx +33 -44
- package/src/ui/types.ts +6 -2
- package/src/ui/utils/assert.ts +5 -0
- package/src/ui/utils/copyToClipboard.ts +3 -0
- package/src/ui/utils/getHttpHeaderValue.ts +14 -0
- package/src/ui/utils/getId.ts +10 -0
- package/src/ui/utils/getStatusColor.ts +15 -0
- package/src/ui/views/InspectorView.tsx +24 -320
- package/tailwind.config.ts +3 -0
- package/vite.config.ts +12 -0
- /package/dist/src/react-native/{network-requests-registry.d.ts → http/network-requests-registry.d.ts} +0 -0
- /package/dist/src/react-native/{xhr-interceptor.d.ts → http/xhr-interceptor.d.ts} +0 -0
- /package/dist/src/ui/{utils.d.ts → utils/cn.d.ts} +0 -0
- /package/src/react-native/{network-requests-registry.ts → http/network-requests-registry.ts} +0 -0
- /package/src/react-native/{xhr-interceptor.ts → http/xhr-interceptor.ts} +0 -0
- /package/src/ui/{utils.ts → utils/cn.ts} +0 -0
|
@@ -2,6 +2,41 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const react = require("react");
|
|
4
4
|
const pluginBridge = require("@rozenite/plugin-bridge");
|
|
5
|
+
const nanoevents = require("nanoevents");
|
|
6
|
+
const reactNative = require("react-native");
|
|
7
|
+
const WebSocketInterceptor = require("react-native/Libraries/WebSocket/WebSocketInterceptor");
|
|
8
|
+
const eventSource = require("./event-source.cjs");
|
|
9
|
+
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
10
|
+
const WebSocketInterceptor__default = /* @__PURE__ */ _interopDefault(WebSocketInterceptor);
|
|
11
|
+
function getHttpHeaderValue(headers, name) {
|
|
12
|
+
const lowerName = name.toLowerCase();
|
|
13
|
+
for (const key in headers) {
|
|
14
|
+
if (key.toLowerCase() === lowerName) {
|
|
15
|
+
return headers[key];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
const getContentType = (request) => {
|
|
21
|
+
const responseHeaders = request.responseHeaders;
|
|
22
|
+
const responseType = request.responseType;
|
|
23
|
+
const contentType = getHttpHeaderValue(responseHeaders || {}, "content-type");
|
|
24
|
+
if (contentType) {
|
|
25
|
+
return contentType.split(";")[0].trim();
|
|
26
|
+
}
|
|
27
|
+
switch (responseType) {
|
|
28
|
+
case "arraybuffer":
|
|
29
|
+
case "blob":
|
|
30
|
+
return "application/octet-stream";
|
|
31
|
+
case "text":
|
|
32
|
+
case "":
|
|
33
|
+
return "text/plain";
|
|
34
|
+
case "json":
|
|
35
|
+
return "application/json";
|
|
36
|
+
case "document":
|
|
37
|
+
return "text/html";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
5
40
|
const REQUEST_TTL = 1e3 * 60 * 5;
|
|
6
41
|
const getNetworkRequestsRegistry = () => {
|
|
7
42
|
const registry = /* @__PURE__ */ new Map();
|
|
@@ -43,7 +78,7 @@ let sendCallback;
|
|
|
43
78
|
let requestHeaderCallback;
|
|
44
79
|
let headerReceivedCallback;
|
|
45
80
|
let responseCallback;
|
|
46
|
-
let isInterceptorEnabled = false;
|
|
81
|
+
let isInterceptorEnabled$1 = false;
|
|
47
82
|
const XHRInterceptor = {
|
|
48
83
|
/**
|
|
49
84
|
* Invoked before XMLHttpRequest.open(...) is called.
|
|
@@ -76,10 +111,10 @@ const XHRInterceptor = {
|
|
|
76
111
|
requestHeaderCallback = callback;
|
|
77
112
|
},
|
|
78
113
|
isInterceptorEnabled() {
|
|
79
|
-
return isInterceptorEnabled;
|
|
114
|
+
return isInterceptorEnabled$1;
|
|
80
115
|
},
|
|
81
116
|
enableInterception() {
|
|
82
|
-
if (isInterceptorEnabled) {
|
|
117
|
+
if (isInterceptorEnabled$1) {
|
|
83
118
|
return;
|
|
84
119
|
}
|
|
85
120
|
XMLHttpRequest.prototype.open = function(method, url) {
|
|
@@ -102,7 +137,7 @@ const XHRInterceptor = {
|
|
|
102
137
|
this.addEventListener(
|
|
103
138
|
"readystatechange",
|
|
104
139
|
() => {
|
|
105
|
-
if (!isInterceptorEnabled) {
|
|
140
|
+
if (!isInterceptorEnabled$1) {
|
|
106
141
|
return;
|
|
107
142
|
}
|
|
108
143
|
if (this.readyState === this.HEADERS_RECEIVED) {
|
|
@@ -142,14 +177,14 @@ const XHRInterceptor = {
|
|
|
142
177
|
}
|
|
143
178
|
originalXHRSend.apply(this, arguments);
|
|
144
179
|
};
|
|
145
|
-
isInterceptorEnabled = true;
|
|
180
|
+
isInterceptorEnabled$1 = true;
|
|
146
181
|
},
|
|
147
182
|
// Unpatch XMLHttpRequest methods and remove the callbacks.
|
|
148
183
|
disableInterception() {
|
|
149
|
-
if (!isInterceptorEnabled) {
|
|
184
|
+
if (!isInterceptorEnabled$1) {
|
|
150
185
|
return;
|
|
151
186
|
}
|
|
152
|
-
isInterceptorEnabled = false;
|
|
187
|
+
isInterceptorEnabled$1 = false;
|
|
153
188
|
XMLHttpRequest.prototype.send = originalXHRSend;
|
|
154
189
|
XMLHttpRequest.prototype.open = originalXHROpen;
|
|
155
190
|
XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader;
|
|
@@ -161,25 +196,6 @@ const XHRInterceptor = {
|
|
|
161
196
|
}
|
|
162
197
|
};
|
|
163
198
|
const networkRequestsRegistry = getNetworkRequestsRegistry();
|
|
164
|
-
const getContentType = (request) => {
|
|
165
|
-
const responseHeaders = request.responseHeaders;
|
|
166
|
-
const responseType = request.responseType;
|
|
167
|
-
if (responseHeaders == null ? void 0 : responseHeaders["content-type"]) {
|
|
168
|
-
return responseHeaders["content-type"].split(";")[0].trim();
|
|
169
|
-
}
|
|
170
|
-
switch (responseType) {
|
|
171
|
-
case "arraybuffer":
|
|
172
|
-
case "blob":
|
|
173
|
-
return "application/octet-stream";
|
|
174
|
-
case "text":
|
|
175
|
-
case "":
|
|
176
|
-
return "text/plain";
|
|
177
|
-
case "json":
|
|
178
|
-
return "application/json";
|
|
179
|
-
case "document":
|
|
180
|
-
return "text/html";
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
199
|
const getResponseSize = (request) => {
|
|
184
200
|
if (typeof request.response === "object") {
|
|
185
201
|
return request.response.size;
|
|
@@ -188,7 +204,7 @@ const getResponseSize = (request) => {
|
|
|
188
204
|
};
|
|
189
205
|
const getResponseBody = async (request) => {
|
|
190
206
|
const responseType = request.responseType;
|
|
191
|
-
if (responseType === "text") {
|
|
207
|
+
if (responseType === "" || responseType === "text") {
|
|
192
208
|
return request.responseText;
|
|
193
209
|
}
|
|
194
210
|
if (responseType === "blob") {
|
|
@@ -233,12 +249,13 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
233
249
|
const handleRequestSend = (data, request) => {
|
|
234
250
|
const sendTime = Date.now();
|
|
235
251
|
const requestId = generateRequestId();
|
|
252
|
+
request._rozeniteRequestId = requestId;
|
|
236
253
|
const initiator = getInitiatorFromStack();
|
|
237
254
|
networkRequestsRegistry.addEntry(requestId, request);
|
|
238
255
|
let ttfb = 0;
|
|
239
256
|
pluginClient.send("request-sent", {
|
|
240
257
|
requestId,
|
|
241
|
-
timestamp: sendTime
|
|
258
|
+
timestamp: sendTime,
|
|
242
259
|
request: {
|
|
243
260
|
url: request._url,
|
|
244
261
|
method: request._method,
|
|
@@ -256,23 +273,23 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
256
273
|
request.addEventListener("load", () => {
|
|
257
274
|
pluginClient.send("response-received", {
|
|
258
275
|
requestId,
|
|
259
|
-
timestamp: Date.now()
|
|
276
|
+
timestamp: Date.now(),
|
|
260
277
|
type: "XHR",
|
|
261
278
|
response: {
|
|
262
279
|
url: request._url,
|
|
263
280
|
status: request.status,
|
|
264
281
|
statusText: request.statusText,
|
|
265
|
-
headers: request.responseHeaders,
|
|
282
|
+
headers: request.responseHeaders || {},
|
|
266
283
|
contentType: getContentType(request),
|
|
267
284
|
size: getResponseSize(request),
|
|
268
|
-
responseTime: Date.now()
|
|
285
|
+
responseTime: Date.now()
|
|
269
286
|
}
|
|
270
287
|
});
|
|
271
288
|
});
|
|
272
289
|
request.addEventListener("loadend", () => {
|
|
273
290
|
pluginClient.send("request-completed", {
|
|
274
291
|
requestId,
|
|
275
|
-
timestamp: Date.now()
|
|
292
|
+
timestamp: Date.now(),
|
|
276
293
|
duration: Date.now() - sendTime,
|
|
277
294
|
size: getResponseSize(request),
|
|
278
295
|
ttfb
|
|
@@ -281,7 +298,7 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
281
298
|
request.addEventListener("error", () => {
|
|
282
299
|
pluginClient.send("request-failed", {
|
|
283
300
|
requestId,
|
|
284
|
-
timestamp: Date.now()
|
|
301
|
+
timestamp: Date.now(),
|
|
285
302
|
type: "XHR",
|
|
286
303
|
error: "Failed",
|
|
287
304
|
canceled: false
|
|
@@ -290,7 +307,7 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
290
307
|
request.addEventListener("abort", () => {
|
|
291
308
|
pluginClient.send("request-failed", {
|
|
292
309
|
requestId,
|
|
293
|
-
timestamp: Date.now()
|
|
310
|
+
timestamp: Date.now(),
|
|
294
311
|
type: "XHR",
|
|
295
312
|
error: "Aborted",
|
|
296
313
|
canceled: true
|
|
@@ -342,6 +359,333 @@ const getNetworkInspector = (pluginClient) => {
|
|
|
342
359
|
dispose
|
|
343
360
|
};
|
|
344
361
|
};
|
|
362
|
+
const getWebSocketInterceptor = () => {
|
|
363
|
+
if (reactNative.Platform.constants.reactNativeVersion.minor >= 79) {
|
|
364
|
+
return WebSocketInterceptor__default.default;
|
|
365
|
+
} else {
|
|
366
|
+
const WebSocketInterceptorPreRN079 = WebSocketInterceptor__default.default;
|
|
367
|
+
return {
|
|
368
|
+
...WebSocketInterceptorPreRN079,
|
|
369
|
+
setOnMessageCallback: (callback) => {
|
|
370
|
+
WebSocketInterceptorPreRN079.setOnMessageCallback((socketId, data) => {
|
|
371
|
+
callback(data, socketId);
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
setOnCloseCallback: (callback) => {
|
|
375
|
+
WebSocketInterceptorPreRN079.setOnCloseCallback((error, socketId) => {
|
|
376
|
+
callback(socketId, error);
|
|
377
|
+
});
|
|
378
|
+
},
|
|
379
|
+
setOnErrorCallback: (callback) => {
|
|
380
|
+
WebSocketInterceptorPreRN079.setOnErrorCallback((error, socketId) => {
|
|
381
|
+
callback(socketId, error);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
const getWebSocketInspector = () => {
|
|
388
|
+
const eventEmitter = nanoevents.createNanoEvents();
|
|
389
|
+
const socketUrlMap = /* @__PURE__ */ new Map();
|
|
390
|
+
const webSocketInterceptor = getWebSocketInterceptor();
|
|
391
|
+
return {
|
|
392
|
+
enable: () => {
|
|
393
|
+
webSocketInterceptor.setConnectCallback(
|
|
394
|
+
(url, protocols, options, socketId) => {
|
|
395
|
+
socketUrlMap.set(socketId, url);
|
|
396
|
+
const event = {
|
|
397
|
+
type: "websocket-connect",
|
|
398
|
+
url,
|
|
399
|
+
socketId,
|
|
400
|
+
timestamp: Date.now(),
|
|
401
|
+
protocols,
|
|
402
|
+
options
|
|
403
|
+
};
|
|
404
|
+
eventEmitter.emit("websocket-connect", event);
|
|
405
|
+
}
|
|
406
|
+
);
|
|
407
|
+
webSocketInterceptor.setCloseCallback(
|
|
408
|
+
(code, reason, socketId) => {
|
|
409
|
+
const url = socketUrlMap.get(socketId);
|
|
410
|
+
if (!url) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const event = {
|
|
414
|
+
type: "websocket-close",
|
|
415
|
+
url,
|
|
416
|
+
socketId,
|
|
417
|
+
timestamp: Date.now(),
|
|
418
|
+
code: code || 0,
|
|
419
|
+
reason: reason || void 0
|
|
420
|
+
};
|
|
421
|
+
eventEmitter.emit("websocket-close", event);
|
|
422
|
+
socketUrlMap.delete(socketId);
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
webSocketInterceptor.setOnMessageCallback(
|
|
426
|
+
(data, socketId) => {
|
|
427
|
+
const url = socketUrlMap.get(socketId);
|
|
428
|
+
if (!url) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
const event = {
|
|
432
|
+
type: "websocket-message-received",
|
|
433
|
+
url,
|
|
434
|
+
socketId,
|
|
435
|
+
timestamp: Date.now(),
|
|
436
|
+
data,
|
|
437
|
+
messageType: typeof data === "string" ? "text" : "binary"
|
|
438
|
+
};
|
|
439
|
+
eventEmitter.emit("websocket-message-received", event);
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
webSocketInterceptor.setOnErrorCallback(
|
|
443
|
+
(error, socketId) => {
|
|
444
|
+
const url = socketUrlMap.get(socketId);
|
|
445
|
+
if (!url) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const event = {
|
|
449
|
+
type: "websocket-error",
|
|
450
|
+
url,
|
|
451
|
+
socketId,
|
|
452
|
+
timestamp: Date.now(),
|
|
453
|
+
error
|
|
454
|
+
};
|
|
455
|
+
eventEmitter.emit("websocket-error", event);
|
|
456
|
+
}
|
|
457
|
+
);
|
|
458
|
+
webSocketInterceptor.setSendCallback((data, socketId) => {
|
|
459
|
+
const url = socketUrlMap.get(socketId);
|
|
460
|
+
if (!url) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
const event = {
|
|
464
|
+
type: "websocket-message-sent",
|
|
465
|
+
url,
|
|
466
|
+
socketId,
|
|
467
|
+
timestamp: Date.now(),
|
|
468
|
+
data,
|
|
469
|
+
messageType: typeof data === "string" ? "text" : "binary"
|
|
470
|
+
};
|
|
471
|
+
eventEmitter.emit("websocket-message-sent", event);
|
|
472
|
+
});
|
|
473
|
+
webSocketInterceptor.setOnOpenCallback((socketId) => {
|
|
474
|
+
const url = socketUrlMap.get(socketId);
|
|
475
|
+
if (!url) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const event = {
|
|
479
|
+
type: "websocket-open",
|
|
480
|
+
url,
|
|
481
|
+
socketId,
|
|
482
|
+
timestamp: Date.now()
|
|
483
|
+
};
|
|
484
|
+
eventEmitter.emit("websocket-open", event);
|
|
485
|
+
});
|
|
486
|
+
webSocketInterceptor.setOnCloseCallback(
|
|
487
|
+
(error, socketId) => {
|
|
488
|
+
const url = socketUrlMap.get(socketId);
|
|
489
|
+
if (!url) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const event = {
|
|
493
|
+
type: "websocket-close",
|
|
494
|
+
url,
|
|
495
|
+
socketId,
|
|
496
|
+
timestamp: Date.now(),
|
|
497
|
+
code: error.code,
|
|
498
|
+
reason: error.reason
|
|
499
|
+
};
|
|
500
|
+
eventEmitter.emit("websocket-close", event);
|
|
501
|
+
socketUrlMap.delete(socketId);
|
|
502
|
+
}
|
|
503
|
+
);
|
|
504
|
+
webSocketInterceptor.enableInterception();
|
|
505
|
+
},
|
|
506
|
+
disable: () => {
|
|
507
|
+
webSocketInterceptor.disableInterception();
|
|
508
|
+
},
|
|
509
|
+
isEnabled: () => webSocketInterceptor.isInterceptorEnabled(),
|
|
510
|
+
dispose: () => {
|
|
511
|
+
eventEmitter.events = {};
|
|
512
|
+
socketUrlMap.clear();
|
|
513
|
+
},
|
|
514
|
+
on: (event, callback) => eventEmitter.on(event, callback)
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
let connectCallback;
|
|
518
|
+
let messageCallback;
|
|
519
|
+
let errorCallback;
|
|
520
|
+
let openEventCallback;
|
|
521
|
+
let closeCallback;
|
|
522
|
+
let isInterceptorEnabled = false;
|
|
523
|
+
const eventSourceClass = eventSource.getEventSource();
|
|
524
|
+
const originalOpen = eventSourceClass.prototype.open;
|
|
525
|
+
const SSEInterceptor = {
|
|
526
|
+
/**
|
|
527
|
+
* Invoked when EventSource.open() is called (connection attempt starting).
|
|
528
|
+
*/
|
|
529
|
+
setConnectCallback(callback) {
|
|
530
|
+
connectCallback = callback;
|
|
531
|
+
},
|
|
532
|
+
/**
|
|
533
|
+
* Invoked when a message event is received.
|
|
534
|
+
*/
|
|
535
|
+
setMessageCallback(callback) {
|
|
536
|
+
messageCallback = callback;
|
|
537
|
+
},
|
|
538
|
+
/**
|
|
539
|
+
* Invoked when an error event occurs.
|
|
540
|
+
*/
|
|
541
|
+
setErrorCallback(callback) {
|
|
542
|
+
errorCallback = callback;
|
|
543
|
+
},
|
|
544
|
+
/**
|
|
545
|
+
* Invoked when the connection is successfully opened (open event fired).
|
|
546
|
+
*/
|
|
547
|
+
setOpenEventCallback(callback) {
|
|
548
|
+
openEventCallback = callback;
|
|
549
|
+
},
|
|
550
|
+
/**
|
|
551
|
+
* Invoked when the connection is closed.
|
|
552
|
+
*/
|
|
553
|
+
setCloseCallback(callback) {
|
|
554
|
+
closeCallback = callback;
|
|
555
|
+
},
|
|
556
|
+
isInterceptorEnabled() {
|
|
557
|
+
return isInterceptorEnabled;
|
|
558
|
+
},
|
|
559
|
+
enableInterception() {
|
|
560
|
+
if (isInterceptorEnabled) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
eventSourceClass.prototype.open = function() {
|
|
564
|
+
if (connectCallback) {
|
|
565
|
+
connectCallback(this.url, this);
|
|
566
|
+
}
|
|
567
|
+
this.addEventListener("open", (event) => {
|
|
568
|
+
if (openEventCallback) {
|
|
569
|
+
openEventCallback(event, this);
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
this.addEventListener("message", (event) => {
|
|
573
|
+
if (messageCallback) {
|
|
574
|
+
messageCallback(event, this);
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
this.addEventListener(
|
|
578
|
+
"error",
|
|
579
|
+
(event) => {
|
|
580
|
+
if (errorCallback) {
|
|
581
|
+
errorCallback(event, this);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
);
|
|
585
|
+
this.addEventListener("close", (event) => {
|
|
586
|
+
if (closeCallback) {
|
|
587
|
+
closeCallback(event, this);
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
return originalOpen.call(this);
|
|
591
|
+
};
|
|
592
|
+
isInterceptorEnabled = true;
|
|
593
|
+
},
|
|
594
|
+
// Unpatch EventSource open method and remove the callbacks.
|
|
595
|
+
disableInterception() {
|
|
596
|
+
if (!isInterceptorEnabled) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
isInterceptorEnabled = false;
|
|
600
|
+
eventSourceClass.prototype.open = originalOpen;
|
|
601
|
+
connectCallback = null;
|
|
602
|
+
messageCallback = null;
|
|
603
|
+
errorCallback = null;
|
|
604
|
+
openEventCallback = null;
|
|
605
|
+
closeCallback = null;
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
const getSSEInspector = () => {
|
|
609
|
+
const eventEmitter = nanoevents.createNanoEvents();
|
|
610
|
+
const getRequestId = (eventSource2) => {
|
|
611
|
+
var _a;
|
|
612
|
+
const requestId = (_a = eventSource2._xhr) == null ? void 0 : _a._rozeniteRequestId;
|
|
613
|
+
if (!requestId) {
|
|
614
|
+
throw new Error(
|
|
615
|
+
"No request ID found for EventSource. This should never happen!"
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
return requestId;
|
|
619
|
+
};
|
|
620
|
+
return {
|
|
621
|
+
enable: () => {
|
|
622
|
+
SSEInterceptor.setOpenEventCallback((_, eventSource2) => {
|
|
623
|
+
const sseEventSource = eventSource2;
|
|
624
|
+
const requestId = getRequestId(sseEventSource);
|
|
625
|
+
const sseXhr = sseEventSource._xhr;
|
|
626
|
+
const event = {
|
|
627
|
+
type: "sse-open",
|
|
628
|
+
requestId,
|
|
629
|
+
timestamp: Date.now(),
|
|
630
|
+
response: {
|
|
631
|
+
url: sseXhr._url,
|
|
632
|
+
status: sseXhr.status,
|
|
633
|
+
statusText: sseXhr.statusText,
|
|
634
|
+
headers: sseXhr.responseHeaders || {},
|
|
635
|
+
contentType: getContentType(sseXhr),
|
|
636
|
+
size: 0,
|
|
637
|
+
responseTime: Date.now()
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
eventEmitter.emit("sse-open", event);
|
|
641
|
+
});
|
|
642
|
+
SSEInterceptor.setMessageCallback((messageEvent, eventSource2) => {
|
|
643
|
+
const sseEventSource = eventSource2;
|
|
644
|
+
const requestId = getRequestId(sseEventSource);
|
|
645
|
+
const event = {
|
|
646
|
+
type: "sse-message",
|
|
647
|
+
requestId,
|
|
648
|
+
timestamp: Date.now(),
|
|
649
|
+
data: messageEvent.data || ""
|
|
650
|
+
};
|
|
651
|
+
eventEmitter.emit("sse-message", event);
|
|
652
|
+
});
|
|
653
|
+
SSEInterceptor.setErrorCallback((errorEvent, eventSource2) => {
|
|
654
|
+
const sseEventSource = eventSource2;
|
|
655
|
+
const requestId = getRequestId(sseEventSource);
|
|
656
|
+
const event = {
|
|
657
|
+
type: "sse-error",
|
|
658
|
+
requestId,
|
|
659
|
+
timestamp: Date.now(),
|
|
660
|
+
error: {
|
|
661
|
+
type: errorEvent.type,
|
|
662
|
+
message: errorEvent.type === "timeout" ? "Timeout" : errorEvent.message
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
eventEmitter.emit("sse-error", event);
|
|
666
|
+
});
|
|
667
|
+
SSEInterceptor.setCloseCallback((_, eventSource2) => {
|
|
668
|
+
const sseEventSource = eventSource2;
|
|
669
|
+
const requestId = getRequestId(sseEventSource);
|
|
670
|
+
const event = {
|
|
671
|
+
type: "sse-close",
|
|
672
|
+
requestId,
|
|
673
|
+
timestamp: Date.now()
|
|
674
|
+
};
|
|
675
|
+
eventEmitter.emit("sse-close", event);
|
|
676
|
+
});
|
|
677
|
+
SSEInterceptor.enableInterception();
|
|
678
|
+
},
|
|
679
|
+
disable: () => {
|
|
680
|
+
SSEInterceptor.disableInterception();
|
|
681
|
+
},
|
|
682
|
+
isEnabled: () => SSEInterceptor.isInterceptorEnabled(),
|
|
683
|
+
dispose: () => {
|
|
684
|
+
eventEmitter.events = {};
|
|
685
|
+
},
|
|
686
|
+
on: (event, callback) => eventEmitter.on(event, callback)
|
|
687
|
+
};
|
|
688
|
+
};
|
|
345
689
|
const useNetworkActivityDevTools = () => {
|
|
346
690
|
const client = pluginBridge.useRozeniteDevToolsClient({
|
|
347
691
|
pluginId: "@rozenite/network-activity-plugin"
|
|
@@ -355,6 +699,61 @@ const useNetworkActivityDevTools = () => {
|
|
|
355
699
|
networkInspector.dispose();
|
|
356
700
|
};
|
|
357
701
|
}, [client]);
|
|
702
|
+
react.useEffect(() => {
|
|
703
|
+
if (!client) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
const eventsToForward = [
|
|
707
|
+
"websocket-connect",
|
|
708
|
+
"websocket-open",
|
|
709
|
+
"websocket-close",
|
|
710
|
+
"websocket-message-sent",
|
|
711
|
+
"websocket-message-received",
|
|
712
|
+
"websocket-error",
|
|
713
|
+
"websocket-connection-status-changed"
|
|
714
|
+
];
|
|
715
|
+
const websocketInspector = getWebSocketInspector();
|
|
716
|
+
eventsToForward.forEach((event) => {
|
|
717
|
+
websocketInspector.on(event, (event2) => {
|
|
718
|
+
client.send(event2.type, event2);
|
|
719
|
+
});
|
|
720
|
+
});
|
|
721
|
+
client.onMessage("network-enable", () => {
|
|
722
|
+
websocketInspector.enable();
|
|
723
|
+
});
|
|
724
|
+
client.onMessage("network-disable", () => {
|
|
725
|
+
websocketInspector.disable();
|
|
726
|
+
});
|
|
727
|
+
return () => {
|
|
728
|
+
websocketInspector.dispose();
|
|
729
|
+
};
|
|
730
|
+
}, [client]);
|
|
731
|
+
react.useEffect(() => {
|
|
732
|
+
if (!client) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const eventsToForward = [
|
|
736
|
+
"sse-open",
|
|
737
|
+
"sse-message",
|
|
738
|
+
"sse-error",
|
|
739
|
+
"sse-close"
|
|
740
|
+
];
|
|
741
|
+
const sseInspector = getSSEInspector();
|
|
742
|
+
eventsToForward.forEach((event) => {
|
|
743
|
+
sseInspector.on(event, (event2) => {
|
|
744
|
+
client.send(event2.type, event2);
|
|
745
|
+
});
|
|
746
|
+
});
|
|
747
|
+
client.onMessage("network-enable", () => {
|
|
748
|
+
sseInspector.enable();
|
|
749
|
+
});
|
|
750
|
+
client.onMessage("network-disable", () => {
|
|
751
|
+
sseInspector.disable();
|
|
752
|
+
});
|
|
753
|
+
return () => {
|
|
754
|
+
sseInspector.dispose();
|
|
755
|
+
};
|
|
756
|
+
}, [client]);
|
|
358
757
|
return client;
|
|
359
758
|
};
|
|
360
759
|
exports.useNetworkActivityDevTools = useNetworkActivityDevTools;
|