@rozenite/network-activity-plugin 1.7.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +24 -0
- package/dist/devtools/App.html +2 -2
- package/dist/devtools/assets/{App-pokLiGYV.js → App-B3xlUjs6.js} +163 -115
- package/dist/devtools/assets/{App-BrSkOkws.css → App-m6xge0az.css} +13 -0
- package/dist/react-native/chunks/boot-recording.cjs +307 -28
- package/dist/react-native/chunks/boot-recording.js +310 -31
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +192 -141
- package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +193 -142
- package/dist/react-native/index.d.ts +24 -7
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.cjs +127 -0
- package/dist/sdk/index.d.ts +1243 -0
- package/dist/sdk/index.js +127 -0
- package/package.json +17 -6
- package/sdk.ts +59 -0
- package/src/react-native/__tests__/events-listener.test.ts +35 -0
- package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +21 -9
- package/src/react-native/agent/state.ts +13 -13
- package/src/react-native/agent/tools.ts +20 -146
- package/src/react-native/agent/use-network-activity-agent-tools.ts +73 -64
- package/src/react-native/events-listener.ts +12 -3
- package/src/react-native/http/http-inspector.ts +19 -5
- package/src/react-native/network-inspector.ts +46 -8
- package/src/react-native/nitro-fetch/__tests__/nitro-network-inspector.test.ts +198 -0
- package/src/react-native/nitro-fetch/nitro-network-inspector.ts +403 -0
- package/src/react-native/useHttpInspector.ts +9 -19
- package/src/react-native/useNetworkActivityDevTools.ts +13 -1
- package/src/react-native/websocket/__tests__/websocket-inspector.test.ts +69 -0
- package/src/react-native/websocket/websocket-inspector.ts +32 -17
- package/src/shared/agent-tools.ts +230 -0
- package/src/shared/client.ts +3 -0
- package/src/shared/http-events.ts +6 -0
- package/src/shared/websocket-events.ts +16 -7
- package/src/ui/components/RequestList.tsx +21 -0
- package/src/ui/components/SidePanel.tsx +12 -9
- package/src/ui/state/derived.ts +4 -0
- package/src/ui/state/model.ts +6 -1
- package/src/ui/state/store.ts +52 -36
- package/src/ui/tabs/HeadersTab.tsx +18 -4
- package/src/ui/tabs/ResponseTab.tsx +5 -3
- package/tsconfig.json +4 -1
- package/vite.config.ts +7 -0
|
@@ -1023,6 +1023,10 @@ video {
|
|
|
1023
1023
|
.p-\[1px\] {
|
|
1024
1024
|
padding: 1px;
|
|
1025
1025
|
}
|
|
1026
|
+
.px-1\.5 {
|
|
1027
|
+
padding-left: 0.375rem;
|
|
1028
|
+
padding-right: 0.375rem;
|
|
1029
|
+
}
|
|
1026
1030
|
.px-2 {
|
|
1027
1031
|
padding-left: 0.5rem;
|
|
1028
1032
|
padding-right: 0.5rem;
|
|
@@ -1077,6 +1081,9 @@ video {
|
|
|
1077
1081
|
.font-mono {
|
|
1078
1082
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
1079
1083
|
}
|
|
1084
|
+
.text-\[10px\] {
|
|
1085
|
+
font-size: 10px;
|
|
1086
|
+
}
|
|
1080
1087
|
.text-base {
|
|
1081
1088
|
font-size: 1rem;
|
|
1082
1089
|
line-height: 1.5rem;
|
|
@@ -1099,12 +1106,18 @@ video {
|
|
|
1099
1106
|
.font-semibold {
|
|
1100
1107
|
font-weight: 600;
|
|
1101
1108
|
}
|
|
1109
|
+
.uppercase {
|
|
1110
|
+
text-transform: uppercase;
|
|
1111
|
+
}
|
|
1102
1112
|
.capitalize {
|
|
1103
1113
|
text-transform: capitalize;
|
|
1104
1114
|
}
|
|
1105
1115
|
.italic {
|
|
1106
1116
|
font-style: italic;
|
|
1107
1117
|
}
|
|
1118
|
+
.tracking-wide {
|
|
1119
|
+
letter-spacing: 0.025em;
|
|
1120
|
+
}
|
|
1108
1121
|
.tracking-widest {
|
|
1109
1122
|
letter-spacing: 0.1em;
|
|
1110
1123
|
}
|
|
@@ -206,7 +206,7 @@ function getContentTypeMime(headers) {
|
|
|
206
206
|
const actualValue = Array.isArray(value) ? value[0] : value;
|
|
207
207
|
return actualValue.split(";")[0].trim();
|
|
208
208
|
}
|
|
209
|
-
const getContentType = (request) => {
|
|
209
|
+
const getContentType$1 = (request) => {
|
|
210
210
|
const responseHeaders = request.responseHeaders;
|
|
211
211
|
const responseType = request.responseType;
|
|
212
212
|
const contentType = getContentTypeMime(responseHeaders || {});
|
|
@@ -366,7 +366,7 @@ const setupRequestOverride = (overridesRegistry, request) => {
|
|
|
366
366
|
Object.defineProperty(request, "responseType", { writable: true });
|
|
367
367
|
Object.defineProperty(request, "response", { writable: true });
|
|
368
368
|
Object.defineProperty(request, "responseText", { writable: true });
|
|
369
|
-
const contentType = getContentType(request);
|
|
369
|
+
const contentType = getContentType$1(request);
|
|
370
370
|
if (contentType === "application/json") {
|
|
371
371
|
request.responseType = "json";
|
|
372
372
|
} else if (contentType === "text/plain") {
|
|
@@ -459,7 +459,8 @@ const getHTTPInspector = () => {
|
|
|
459
459
|
postData: getRequestBody(data)
|
|
460
460
|
},
|
|
461
461
|
type: "XHR",
|
|
462
|
-
initiator
|
|
462
|
+
initiator,
|
|
463
|
+
source: "builtin"
|
|
463
464
|
});
|
|
464
465
|
request.addEventListener("readystatechange", () => {
|
|
465
466
|
if (request.readyState === READY_STATE_HEADERS_RECEIVED) {
|
|
@@ -472,7 +473,8 @@ const getHTTPInspector = () => {
|
|
|
472
473
|
timestamp: Date.now(),
|
|
473
474
|
loaded: event.loaded,
|
|
474
475
|
total: event.total,
|
|
475
|
-
lengthComputable: event.lengthComputable
|
|
476
|
+
lengthComputable: event.lengthComputable,
|
|
477
|
+
source: "builtin"
|
|
476
478
|
});
|
|
477
479
|
});
|
|
478
480
|
request.addEventListener("load", () => {
|
|
@@ -487,10 +489,11 @@ const getHTTPInspector = () => {
|
|
|
487
489
|
headers: applyReactNativeResponseHeadersLogic(
|
|
488
490
|
request.responseHeaders || {}
|
|
489
491
|
),
|
|
490
|
-
contentType: getContentType(request),
|
|
492
|
+
contentType: getContentType$1(request),
|
|
491
493
|
size: getResponseSize(request),
|
|
492
494
|
responseTime: Date.now()
|
|
493
|
-
}
|
|
495
|
+
},
|
|
496
|
+
source: "builtin"
|
|
494
497
|
});
|
|
495
498
|
});
|
|
496
499
|
request.addEventListener("loadend", () => {
|
|
@@ -499,7 +502,8 @@ const getHTTPInspector = () => {
|
|
|
499
502
|
timestamp: Date.now(),
|
|
500
503
|
duration: Date.now() - sendTime,
|
|
501
504
|
size: getResponseSize(request),
|
|
502
|
-
ttfb
|
|
505
|
+
ttfb,
|
|
506
|
+
source: "builtin"
|
|
503
507
|
});
|
|
504
508
|
});
|
|
505
509
|
request.addEventListener("error", () => {
|
|
@@ -508,7 +512,8 @@ const getHTTPInspector = () => {
|
|
|
508
512
|
timestamp: Date.now(),
|
|
509
513
|
type: "XHR",
|
|
510
514
|
error: "Failed",
|
|
511
|
-
canceled: false
|
|
515
|
+
canceled: false,
|
|
516
|
+
source: "builtin"
|
|
512
517
|
});
|
|
513
518
|
});
|
|
514
519
|
request.addEventListener("abort", () => {
|
|
@@ -517,7 +522,8 @@ const getHTTPInspector = () => {
|
|
|
517
522
|
timestamp: Date.now(),
|
|
518
523
|
type: "XHR",
|
|
519
524
|
error: "Aborted",
|
|
520
|
-
canceled: true
|
|
525
|
+
canceled: true,
|
|
526
|
+
source: "builtin"
|
|
521
527
|
});
|
|
522
528
|
});
|
|
523
529
|
request.addEventListener("timeout", () => {
|
|
@@ -526,7 +532,8 @@ const getHTTPInspector = () => {
|
|
|
526
532
|
timestamp: Date.now(),
|
|
527
533
|
type: "XHR",
|
|
528
534
|
error: "Timeout",
|
|
529
|
-
canceled: false
|
|
535
|
+
canceled: false,
|
|
536
|
+
source: "builtin"
|
|
530
537
|
});
|
|
531
538
|
});
|
|
532
539
|
});
|
|
@@ -583,10 +590,10 @@ const WEBSOCKET_EVENTS = [
|
|
|
583
590
|
const isWebSocketEvent = (type) => {
|
|
584
591
|
return WEBSOCKET_EVENTS.includes(type);
|
|
585
592
|
};
|
|
586
|
-
const
|
|
593
|
+
const toSocketId = (socketId) => String(socketId);
|
|
594
|
+
const createWebSocketInspector = (webSocketInterceptor = getWebSocketInterceptor()) => {
|
|
587
595
|
const eventEmitter = nanoevents.createNanoEvents();
|
|
588
596
|
const socketUrlMap = /* @__PURE__ */ new Map();
|
|
589
|
-
const webSocketInterceptor = getWebSocketInterceptor();
|
|
590
597
|
return {
|
|
591
598
|
enable: () => {
|
|
592
599
|
webSocketInterceptor.setConnectCallback(
|
|
@@ -595,10 +602,11 @@ const getWebSocketInspector = () => {
|
|
|
595
602
|
const event = {
|
|
596
603
|
type: "websocket-connect",
|
|
597
604
|
url,
|
|
598
|
-
socketId,
|
|
605
|
+
socketId: toSocketId(socketId),
|
|
599
606
|
timestamp: Date.now(),
|
|
600
607
|
protocols,
|
|
601
|
-
options
|
|
608
|
+
options,
|
|
609
|
+
source: "builtin"
|
|
602
610
|
};
|
|
603
611
|
eventEmitter.emit("websocket-connect", event);
|
|
604
612
|
}
|
|
@@ -612,10 +620,11 @@ const getWebSocketInspector = () => {
|
|
|
612
620
|
const event = {
|
|
613
621
|
type: "websocket-close",
|
|
614
622
|
url,
|
|
615
|
-
socketId,
|
|
623
|
+
socketId: toSocketId(socketId),
|
|
616
624
|
timestamp: Date.now(),
|
|
617
625
|
code: code || 0,
|
|
618
|
-
reason: reason || void 0
|
|
626
|
+
reason: reason || void 0,
|
|
627
|
+
source: "builtin"
|
|
619
628
|
};
|
|
620
629
|
eventEmitter.emit("websocket-close", event);
|
|
621
630
|
socketUrlMap.delete(socketId);
|
|
@@ -630,10 +639,11 @@ const getWebSocketInspector = () => {
|
|
|
630
639
|
const event = {
|
|
631
640
|
type: "websocket-message-received",
|
|
632
641
|
url,
|
|
633
|
-
socketId,
|
|
642
|
+
socketId: toSocketId(socketId),
|
|
634
643
|
timestamp: Date.now(),
|
|
635
644
|
data,
|
|
636
|
-
messageType: typeof data === "string" ? "text" : "binary"
|
|
645
|
+
messageType: typeof data === "string" ? "text" : "binary",
|
|
646
|
+
source: "builtin"
|
|
637
647
|
};
|
|
638
648
|
eventEmitter.emit("websocket-message-received", event);
|
|
639
649
|
}
|
|
@@ -647,9 +657,10 @@ const getWebSocketInspector = () => {
|
|
|
647
657
|
const event = {
|
|
648
658
|
type: "websocket-error",
|
|
649
659
|
url,
|
|
650
|
-
socketId,
|
|
660
|
+
socketId: toSocketId(socketId),
|
|
651
661
|
timestamp: Date.now(),
|
|
652
|
-
error
|
|
662
|
+
error,
|
|
663
|
+
source: "builtin"
|
|
653
664
|
};
|
|
654
665
|
eventEmitter.emit("websocket-error", event);
|
|
655
666
|
}
|
|
@@ -662,10 +673,11 @@ const getWebSocketInspector = () => {
|
|
|
662
673
|
const event = {
|
|
663
674
|
type: "websocket-message-sent",
|
|
664
675
|
url,
|
|
665
|
-
socketId,
|
|
676
|
+
socketId: toSocketId(socketId),
|
|
666
677
|
timestamp: Date.now(),
|
|
667
678
|
data,
|
|
668
|
-
messageType: typeof data === "string" ? "text" : "binary"
|
|
679
|
+
messageType: typeof data === "string" ? "text" : "binary",
|
|
680
|
+
source: "builtin"
|
|
669
681
|
};
|
|
670
682
|
eventEmitter.emit("websocket-message-sent", event);
|
|
671
683
|
});
|
|
@@ -677,8 +689,9 @@ const getWebSocketInspector = () => {
|
|
|
677
689
|
const event = {
|
|
678
690
|
type: "websocket-open",
|
|
679
691
|
url,
|
|
680
|
-
socketId,
|
|
681
|
-
timestamp: Date.now()
|
|
692
|
+
socketId: toSocketId(socketId),
|
|
693
|
+
timestamp: Date.now(),
|
|
694
|
+
source: "builtin"
|
|
682
695
|
};
|
|
683
696
|
eventEmitter.emit("websocket-open", event);
|
|
684
697
|
});
|
|
@@ -691,10 +704,11 @@ const getWebSocketInspector = () => {
|
|
|
691
704
|
const event = {
|
|
692
705
|
type: "websocket-close",
|
|
693
706
|
url,
|
|
694
|
-
socketId,
|
|
707
|
+
socketId: toSocketId(socketId),
|
|
695
708
|
timestamp: Date.now(),
|
|
696
709
|
code: error.code,
|
|
697
|
-
reason: error.reason
|
|
710
|
+
reason: error.reason,
|
|
711
|
+
source: "builtin"
|
|
698
712
|
};
|
|
699
713
|
eventEmitter.emit("websocket-close", event);
|
|
700
714
|
socketUrlMap.delete(socketId);
|
|
@@ -713,6 +727,9 @@ const getWebSocketInspector = () => {
|
|
|
713
727
|
on: (event, callback) => eventEmitter.on(event, callback)
|
|
714
728
|
};
|
|
715
729
|
};
|
|
730
|
+
const getWebSocketInspector = () => {
|
|
731
|
+
return createWebSocketInspector();
|
|
732
|
+
};
|
|
716
733
|
let connectCallback;
|
|
717
734
|
let messageCallback;
|
|
718
735
|
let errorCallback;
|
|
@@ -846,7 +863,7 @@ const getSSEInspector = () => {
|
|
|
846
863
|
status: sseXhr.status,
|
|
847
864
|
statusText: sseXhr.statusText,
|
|
848
865
|
headers: sseXhr.responseHeaders || {},
|
|
849
|
-
contentType: getContentType(sseXhr),
|
|
866
|
+
contentType: getContentType$1(sseXhr),
|
|
850
867
|
size: 0,
|
|
851
868
|
responseTime: Date.now()
|
|
852
869
|
}
|
|
@@ -935,6 +952,7 @@ class EventsListener {
|
|
|
935
952
|
constructor() {
|
|
936
953
|
this.messageQueue = [];
|
|
937
954
|
this.sendFunction = null;
|
|
955
|
+
this.filterFunction = null;
|
|
938
956
|
this.maxQueueSize = 200;
|
|
939
957
|
this.isQueuing = false;
|
|
940
958
|
}
|
|
@@ -952,6 +970,7 @@ class EventsListener {
|
|
|
952
970
|
*/
|
|
953
971
|
connect(sendFn, filterFn) {
|
|
954
972
|
this.sendFunction = sendFn;
|
|
973
|
+
this.filterFunction = filterFn ?? null;
|
|
955
974
|
this.isQueuing = false;
|
|
956
975
|
this.flushQueue(filterFn);
|
|
957
976
|
}
|
|
@@ -965,6 +984,9 @@ class EventsListener {
|
|
|
965
984
|
if (this.isQueuing) {
|
|
966
985
|
this.enqueueMessage({ type, data });
|
|
967
986
|
} else if (this.sendFunction) {
|
|
987
|
+
if (this.filterFunction && !this.filterFunction({ type, data })) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
968
990
|
this.sendFunction(type, data);
|
|
969
991
|
}
|
|
970
992
|
}
|
|
@@ -992,14 +1014,257 @@ class EventsListener {
|
|
|
992
1014
|
const createEventsListener = () => {
|
|
993
1015
|
return new EventsListener();
|
|
994
1016
|
};
|
|
1017
|
+
const NITRO_NETWORK_EVENTS = [
|
|
1018
|
+
"request-sent",
|
|
1019
|
+
"response-received",
|
|
1020
|
+
"request-completed",
|
|
1021
|
+
"request-failed",
|
|
1022
|
+
"websocket-connect",
|
|
1023
|
+
"websocket-open",
|
|
1024
|
+
"websocket-close",
|
|
1025
|
+
"websocket-message-sent",
|
|
1026
|
+
"websocket-message-received",
|
|
1027
|
+
"websocket-error"
|
|
1028
|
+
];
|
|
1029
|
+
const loadNitroModule = () => {
|
|
1030
|
+
try {
|
|
1031
|
+
return require("react-native-nitro-fetch");
|
|
1032
|
+
} catch {
|
|
1033
|
+
return null;
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
const timestampOrigin = typeof performance !== "undefined" && typeof performance.timeOrigin === "number" ? performance.timeOrigin : Date.now() - performance.now();
|
|
1037
|
+
const toEpochTime = (timestamp) => Math.round(timestampOrigin + timestamp);
|
|
1038
|
+
const toHeaders = (headers) => {
|
|
1039
|
+
return headers.reduce((acc, { key, value }) => {
|
|
1040
|
+
const existing = acc[key];
|
|
1041
|
+
if (existing === void 0) {
|
|
1042
|
+
acc[key] = value;
|
|
1043
|
+
return acc;
|
|
1044
|
+
}
|
|
1045
|
+
acc[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
|
|
1046
|
+
return acc;
|
|
1047
|
+
}, {});
|
|
1048
|
+
};
|
|
1049
|
+
const toPostData = (body) => {
|
|
1050
|
+
if (body == null) {
|
|
1051
|
+
return void 0;
|
|
1052
|
+
}
|
|
1053
|
+
return {
|
|
1054
|
+
type: "text",
|
|
1055
|
+
value: body
|
|
1056
|
+
};
|
|
1057
|
+
};
|
|
1058
|
+
const cloneEntry = (entry) => {
|
|
1059
|
+
return JSON.parse(JSON.stringify(entry));
|
|
1060
|
+
};
|
|
1061
|
+
const getContentType = (headers) => {
|
|
1062
|
+
return headers.find((header) => header.key.toLowerCase() === "content-type")?.value ?? "text/plain";
|
|
1063
|
+
};
|
|
1064
|
+
const normalizeReadyState = (readyState) => readyState.toUpperCase();
|
|
1065
|
+
const createNitroNetworkInspector = (getNitroModule = loadNitroModule) => {
|
|
1066
|
+
const eventEmitter = nanoevents.createNanoEvents();
|
|
1067
|
+
const previousEntries = /* @__PURE__ */ new Map();
|
|
1068
|
+
const responseBodies = /* @__PURE__ */ new Map();
|
|
1069
|
+
let nitroModule = null;
|
|
1070
|
+
let unsubscribe = null;
|
|
1071
|
+
const emitHttpEvents = (entry, previous) => {
|
|
1072
|
+
if (!previous) {
|
|
1073
|
+
eventEmitter.emit("request-sent", {
|
|
1074
|
+
requestId: entry.id,
|
|
1075
|
+
timestamp: toEpochTime(entry.startTime),
|
|
1076
|
+
request: {
|
|
1077
|
+
url: entry.url,
|
|
1078
|
+
method: entry.method,
|
|
1079
|
+
headers: toHeaders(entry.requestHeaders),
|
|
1080
|
+
postData: toPostData(entry.requestBody)
|
|
1081
|
+
},
|
|
1082
|
+
initiator: { type: "other" },
|
|
1083
|
+
type: "Fetch",
|
|
1084
|
+
source: "nitro"
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
if (entry.error) {
|
|
1088
|
+
if (!previous || previous.error !== entry.error) {
|
|
1089
|
+
eventEmitter.emit("request-failed", {
|
|
1090
|
+
requestId: entry.id,
|
|
1091
|
+
timestamp: toEpochTime(entry.endTime || entry.startTime),
|
|
1092
|
+
type: "Fetch",
|
|
1093
|
+
error: entry.error,
|
|
1094
|
+
canceled: entry.error === "Request canceled",
|
|
1095
|
+
source: "nitro"
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
const didResponseChange = !previous || previous.status !== entry.status || previous.statusText !== entry.statusText || previous.responseBodySize !== entry.responseBodySize || previous.endTime !== entry.endTime;
|
|
1101
|
+
if (!didResponseChange) {
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
const responseTimestamp = toEpochTime(entry.endTime || entry.startTime);
|
|
1105
|
+
eventEmitter.emit("response-received", {
|
|
1106
|
+
requestId: entry.id,
|
|
1107
|
+
timestamp: responseTimestamp,
|
|
1108
|
+
type: "Fetch",
|
|
1109
|
+
response: {
|
|
1110
|
+
url: entry.url,
|
|
1111
|
+
status: entry.status,
|
|
1112
|
+
statusText: entry.statusText,
|
|
1113
|
+
headers: toHeaders(entry.responseHeaders),
|
|
1114
|
+
contentType: getContentType(entry.responseHeaders),
|
|
1115
|
+
size: entry.responseBodySize,
|
|
1116
|
+
responseTime: responseTimestamp
|
|
1117
|
+
},
|
|
1118
|
+
source: "nitro"
|
|
1119
|
+
});
|
|
1120
|
+
eventEmitter.emit("request-completed", {
|
|
1121
|
+
requestId: entry.id,
|
|
1122
|
+
timestamp: responseTimestamp,
|
|
1123
|
+
duration: entry.duration,
|
|
1124
|
+
size: entry.responseBodySize,
|
|
1125
|
+
ttfb: entry.duration,
|
|
1126
|
+
source: "nitro"
|
|
1127
|
+
});
|
|
1128
|
+
};
|
|
1129
|
+
const emitWebSocketEvents = (entry, previous) => {
|
|
1130
|
+
const socketId = entry.id;
|
|
1131
|
+
const readyState = normalizeReadyState(entry.readyState);
|
|
1132
|
+
const previousReadyState = previous ? normalizeReadyState(previous.readyState) : null;
|
|
1133
|
+
if (!previous) {
|
|
1134
|
+
eventEmitter.emit("websocket-connect", {
|
|
1135
|
+
type: "websocket-connect",
|
|
1136
|
+
url: entry.url,
|
|
1137
|
+
socketId,
|
|
1138
|
+
timestamp: toEpochTime(entry.startTime),
|
|
1139
|
+
protocols: entry.protocols,
|
|
1140
|
+
options: [],
|
|
1141
|
+
source: "nitro"
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
if (readyState === "OPEN" && previousReadyState !== "OPEN") {
|
|
1145
|
+
eventEmitter.emit("websocket-open", {
|
|
1146
|
+
type: "websocket-open",
|
|
1147
|
+
url: entry.url,
|
|
1148
|
+
socketId,
|
|
1149
|
+
timestamp: toEpochTime(entry.startTime),
|
|
1150
|
+
source: "nitro"
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
const previousMessageCount = previous?.messages.length ?? 0;
|
|
1154
|
+
for (const message of entry.messages.slice(previousMessageCount)) {
|
|
1155
|
+
const event = {
|
|
1156
|
+
url: entry.url,
|
|
1157
|
+
socketId,
|
|
1158
|
+
timestamp: toEpochTime(message.timestamp),
|
|
1159
|
+
data: message.data,
|
|
1160
|
+
messageType: message.isBinary ? "binary" : "text",
|
|
1161
|
+
source: "nitro"
|
|
1162
|
+
};
|
|
1163
|
+
if (message.direction === "sent") {
|
|
1164
|
+
eventEmitter.emit("websocket-message-sent", {
|
|
1165
|
+
type: "websocket-message-sent",
|
|
1166
|
+
...event
|
|
1167
|
+
});
|
|
1168
|
+
} else {
|
|
1169
|
+
eventEmitter.emit("websocket-message-received", {
|
|
1170
|
+
type: "websocket-message-received",
|
|
1171
|
+
...event
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
if (entry.error && (!previous || previous.error !== entry.error)) {
|
|
1176
|
+
eventEmitter.emit("websocket-error", {
|
|
1177
|
+
type: "websocket-error",
|
|
1178
|
+
url: entry.url,
|
|
1179
|
+
socketId,
|
|
1180
|
+
timestamp: toEpochTime(entry.endTime || entry.startTime),
|
|
1181
|
+
error: entry.error,
|
|
1182
|
+
source: "nitro"
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
if (readyState === "CLOSED" && previousReadyState !== "CLOSED") {
|
|
1186
|
+
eventEmitter.emit("websocket-close", {
|
|
1187
|
+
type: "websocket-close",
|
|
1188
|
+
url: entry.url,
|
|
1189
|
+
socketId,
|
|
1190
|
+
timestamp: toEpochTime(entry.endTime || entry.startTime),
|
|
1191
|
+
code: entry.closeCode ?? 0,
|
|
1192
|
+
reason: entry.closeReason,
|
|
1193
|
+
source: "nitro"
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
};
|
|
1197
|
+
const handleEntry = (entry) => {
|
|
1198
|
+
const previous = previousEntries.get(entry.id);
|
|
1199
|
+
if (entry.type === "http") {
|
|
1200
|
+
responseBodies.set(entry.id, entry.responseBody ?? null);
|
|
1201
|
+
emitHttpEvents(entry, previous);
|
|
1202
|
+
} else {
|
|
1203
|
+
emitWebSocketEvents(entry, previous);
|
|
1204
|
+
}
|
|
1205
|
+
previousEntries.set(entry.id, cloneEntry(entry));
|
|
1206
|
+
};
|
|
1207
|
+
return {
|
|
1208
|
+
enable() {
|
|
1209
|
+
if (unsubscribe) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
nitroModule = getNitroModule();
|
|
1213
|
+
if (!nitroModule) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
nitroModule.NetworkInspector.enable();
|
|
1217
|
+
for (const entry of nitroModule.NetworkInspector.getEntries()) {
|
|
1218
|
+
previousEntries.set(entry.id, cloneEntry(entry));
|
|
1219
|
+
if (entry.type === "http") {
|
|
1220
|
+
responseBodies.set(entry.id, entry.responseBody ?? null);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
unsubscribe = nitroModule.NetworkInspector.onEntry(handleEntry);
|
|
1224
|
+
},
|
|
1225
|
+
disable() {
|
|
1226
|
+
unsubscribe?.();
|
|
1227
|
+
unsubscribe = null;
|
|
1228
|
+
nitroModule?.NetworkInspector.disable();
|
|
1229
|
+
},
|
|
1230
|
+
isEnabled() {
|
|
1231
|
+
return nitroModule?.NetworkInspector.isEnabled() ?? false;
|
|
1232
|
+
},
|
|
1233
|
+
dispose() {
|
|
1234
|
+
unsubscribe?.();
|
|
1235
|
+
unsubscribe = null;
|
|
1236
|
+
previousEntries.clear();
|
|
1237
|
+
responseBodies.clear();
|
|
1238
|
+
nitroModule?.NetworkInspector.disable();
|
|
1239
|
+
nitroModule = null;
|
|
1240
|
+
},
|
|
1241
|
+
getResponseBody(requestId) {
|
|
1242
|
+
return responseBodies.get(requestId) ?? null;
|
|
1243
|
+
},
|
|
1244
|
+
on(event, callback) {
|
|
1245
|
+
return eventEmitter.on(event, callback);
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
};
|
|
1249
|
+
const getNitroNetworkInspector = /* @__PURE__ */ (() => {
|
|
1250
|
+
let instance = null;
|
|
1251
|
+
return () => {
|
|
1252
|
+
if (!instance) {
|
|
1253
|
+
instance = createNitroNetworkInspector();
|
|
1254
|
+
}
|
|
1255
|
+
return instance;
|
|
1256
|
+
};
|
|
1257
|
+
})();
|
|
995
1258
|
const createNetworkInspectorInstance = () => {
|
|
996
1259
|
const http = getHTTPInspector();
|
|
997
1260
|
const sse = getSSEInspector();
|
|
998
1261
|
const websocket = getWebSocketInspector();
|
|
1262
|
+
const nitro = getNitroNetworkInspector();
|
|
999
1263
|
return {
|
|
1000
1264
|
http,
|
|
1001
1265
|
sse,
|
|
1002
1266
|
websocket,
|
|
1267
|
+
nitro,
|
|
1003
1268
|
setup(eventsListener) {
|
|
1004
1269
|
HTTP_EVENTS.forEach((event) => {
|
|
1005
1270
|
http.on(event, (data) => {
|
|
@@ -1016,21 +1281,36 @@ const createNetworkInspectorInstance = () => {
|
|
|
1016
1281
|
eventsListener.send(data.type, data);
|
|
1017
1282
|
});
|
|
1018
1283
|
});
|
|
1284
|
+
NITRO_NETWORK_EVENTS.forEach((event) => {
|
|
1285
|
+
nitro.on(event, (data) => {
|
|
1286
|
+
eventsListener.send(event, data);
|
|
1287
|
+
});
|
|
1288
|
+
});
|
|
1019
1289
|
},
|
|
1020
1290
|
enable(config = { http: true, sse: true, websocket: true }) {
|
|
1021
1291
|
if (config.http) http.enable();
|
|
1022
1292
|
if (config.sse) sse.enable();
|
|
1023
1293
|
if (config.websocket) websocket.enable();
|
|
1294
|
+
if (config.http || config.websocket) nitro.enable();
|
|
1024
1295
|
},
|
|
1025
1296
|
disable() {
|
|
1026
1297
|
http.disable();
|
|
1027
1298
|
sse.disable();
|
|
1028
1299
|
websocket.disable();
|
|
1300
|
+
nitro.disable();
|
|
1029
1301
|
},
|
|
1030
1302
|
dispose() {
|
|
1031
1303
|
http.dispose();
|
|
1032
1304
|
sse.dispose();
|
|
1033
1305
|
websocket.dispose();
|
|
1306
|
+
nitro.dispose();
|
|
1307
|
+
},
|
|
1308
|
+
async getResponseBody(requestId) {
|
|
1309
|
+
const request = http.getNetworkRequestsRegistry().getEntry(requestId);
|
|
1310
|
+
if (request) {
|
|
1311
|
+
return getResponseBody(request);
|
|
1312
|
+
}
|
|
1313
|
+
return nitro.getResponseBody(requestId);
|
|
1034
1314
|
}
|
|
1035
1315
|
};
|
|
1036
1316
|
};
|
|
@@ -1078,7 +1358,6 @@ const withOnBootNetworkActivityRecording = (options) => {
|
|
|
1078
1358
|
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
1079
1359
|
exports.createNetworkInspectorsConfiguration = createNetworkInspectorsConfiguration;
|
|
1080
1360
|
exports.getOverridesRegistry = getOverridesRegistry;
|
|
1081
|
-
exports.getResponseBody = getResponseBody;
|
|
1082
1361
|
exports.isHttpEvent = isHttpEvent;
|
|
1083
1362
|
exports.isSSEEvent = isSSEEvent;
|
|
1084
1363
|
exports.isWebSocketEvent = isWebSocketEvent;
|