@rozenite/network-activity-plugin 1.7.0-rc.2 → 1.8.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 (43) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +24 -0
  3. package/dist/devtools/App.html +2 -2
  4. package/dist/devtools/assets/{App-pokLiGYV.js → App-B3xlUjs6.js} +163 -115
  5. package/dist/devtools/assets/{App-BrSkOkws.css → App-m6xge0az.css} +13 -0
  6. package/dist/react-native/chunks/boot-recording.cjs +307 -28
  7. package/dist/react-native/chunks/boot-recording.js +310 -31
  8. package/dist/react-native/chunks/useNetworkActivityDevTools.require.cjs +192 -141
  9. package/dist/react-native/chunks/useNetworkActivityDevTools.require.js +193 -142
  10. package/dist/react-native/index.d.ts +24 -7
  11. package/dist/rozenite.json +1 -1
  12. package/dist/sdk/index.cjs +127 -0
  13. package/dist/sdk/index.d.ts +1243 -0
  14. package/dist/sdk/index.js +127 -0
  15. package/package.json +17 -6
  16. package/sdk.ts +59 -0
  17. package/src/react-native/__tests__/events-listener.test.ts +35 -0
  18. package/src/react-native/agent/__tests__/network-activity-agent-state.test.ts +21 -9
  19. package/src/react-native/agent/state.ts +13 -13
  20. package/src/react-native/agent/tools.ts +20 -146
  21. package/src/react-native/agent/use-network-activity-agent-tools.ts +73 -64
  22. package/src/react-native/events-listener.ts +12 -3
  23. package/src/react-native/http/http-inspector.ts +19 -5
  24. package/src/react-native/network-inspector.ts +46 -8
  25. package/src/react-native/nitro-fetch/__tests__/nitro-network-inspector.test.ts +198 -0
  26. package/src/react-native/nitro-fetch/nitro-network-inspector.ts +403 -0
  27. package/src/react-native/useHttpInspector.ts +9 -19
  28. package/src/react-native/useNetworkActivityDevTools.ts +13 -1
  29. package/src/react-native/websocket/__tests__/websocket-inspector.test.ts +69 -0
  30. package/src/react-native/websocket/websocket-inspector.ts +32 -17
  31. package/src/shared/agent-tools.ts +230 -0
  32. package/src/shared/client.ts +3 -0
  33. package/src/shared/http-events.ts +6 -0
  34. package/src/shared/websocket-events.ts +16 -7
  35. package/src/ui/components/RequestList.tsx +21 -0
  36. package/src/ui/components/SidePanel.tsx +12 -9
  37. package/src/ui/state/derived.ts +4 -0
  38. package/src/ui/state/model.ts +6 -1
  39. package/src/ui/state/store.ts +52 -36
  40. package/src/ui/tabs/HeadersTab.tsx +18 -4
  41. package/src/ui/tabs/ResponseTab.tsx +5 -3
  42. package/tsconfig.json +4 -1
  43. package/vite.config.ts +7 -0
@@ -4,6 +4,7 @@ const react = require("react");
4
4
  const pluginBridge = require("@rozenite/plugin-bridge");
5
5
  const bootRecording = require("./boot-recording.cjs");
6
6
  const agentBridge = require("@rozenite/agent-bridge");
7
+ const agentShared = require("@rozenite/agent-shared");
7
8
  const DEFAULT_PAGE_LIMIT = 20;
8
9
  const MAX_PAGE_LIMIT = 100;
9
10
  const HTTP_BUFFER_CAPACITY = 500;
@@ -623,121 +624,132 @@ const getNetworkActivityAgentState = /* @__PURE__ */ (() => {
623
624
  return instance;
624
625
  };
625
626
  })();
626
- const startRecordingTool = {
627
- name: "startRecording",
628
- description: "Start recording network activity in the fallback network activity plugin.",
629
- inputSchema: {
630
- type: "object",
631
- properties: {}
632
- }
633
- };
634
- const stopRecordingTool = {
635
- name: "stopRecording",
636
- description: "Stop recording network activity without clearing the captured plugin buffer.",
637
- inputSchema: {
638
- type: "object",
639
- properties: {}
640
- }
641
- };
642
- const getRecordingStatusTool = {
643
- name: "getRecordingStatus",
644
- description: "Return network activity plugin recording state and buffer metadata.",
645
- inputSchema: {
646
- type: "object",
647
- properties: {}
648
- }
649
- };
650
- const listRequestsTool = {
651
- name: "listRequests",
652
- description: "List captured HTTP request summaries with cursor pagination from the fallback plugin.",
653
- inputSchema: {
654
- type: "object",
655
- properties: {
656
- limit: {
657
- type: "number",
658
- description: "Maximum number of requests to return. Defaults to 20."
659
- },
660
- cursor: {
661
- type: "string",
662
- description: "Opaque pagination cursor from a previous listRequests call."
663
- }
627
+ const NETWORK_ACTIVITY_AGENT_PLUGIN_ID = "@rozenite/network-activity-plugin";
628
+ const networkActivityToolDefinitions = {
629
+ startRecording: agentShared.defineAgentToolContract({
630
+ name: "startRecording",
631
+ description: "Start recording network activity in the fallback network activity plugin.",
632
+ inputSchema: {
633
+ type: "object",
634
+ properties: {}
664
635
  }
665
- }
666
- };
667
- const getRequestDetailsTool = {
668
- name: "getRequestDetails",
669
- description: "Return detailed metadata for a captured HTTP request without fetching response body.",
670
- inputSchema: {
671
- type: "object",
672
- properties: {
673
- requestId: {
674
- type: "string",
675
- description: "Captured plugin request ID to inspect."
676
- }
677
- },
678
- required: ["requestId"]
679
- }
680
- };
681
- const getRequestBodyTool = {
682
- name: "getRequestBody",
683
- description: "Return the captured request body for a plugin-recorded HTTP request when available.",
684
- inputSchema: {
685
- type: "object",
686
- properties: {
687
- requestId: {
688
- type: "string",
689
- description: "Captured plugin request ID to inspect."
690
- }
691
- },
692
- required: ["requestId"]
693
- }
694
- };
695
- const getResponseBodyTool = {
696
- name: "getResponseBody",
697
- description: "Return the captured response body for a plugin-recorded HTTP request when available.",
698
- inputSchema: {
699
- type: "object",
700
- properties: {
701
- requestId: {
702
- type: "string",
703
- description: "Captured plugin request ID to inspect."
636
+ }),
637
+ stopRecording: agentShared.defineAgentToolContract({
638
+ name: "stopRecording",
639
+ description: "Stop recording network activity without clearing the captured plugin buffer.",
640
+ inputSchema: {
641
+ type: "object",
642
+ properties: {}
643
+ }
644
+ }),
645
+ getRecordingStatus: agentShared.defineAgentToolContract({
646
+ name: "getRecordingStatus",
647
+ description: "Return network activity plugin recording state and buffer metadata.",
648
+ inputSchema: {
649
+ type: "object",
650
+ properties: {}
651
+ }
652
+ }),
653
+ listRequests: agentShared.defineAgentToolContract({
654
+ name: "listRequests",
655
+ description: "List captured HTTP request summaries with cursor pagination from the fallback plugin.",
656
+ inputSchema: {
657
+ type: "object",
658
+ properties: {
659
+ limit: {
660
+ type: "number",
661
+ description: "Maximum number of requests to return. Defaults to 20."
662
+ },
663
+ cursor: {
664
+ type: "string",
665
+ description: "Opaque pagination cursor from a previous listRequests call."
666
+ }
704
667
  }
705
- },
706
- required: ["requestId"]
707
- }
708
- };
709
- const listRealtimeConnectionsTool = {
710
- name: "listRealtimeConnections",
711
- description: "List captured WebSocket and SSE connections with cursor pagination.",
712
- inputSchema: {
713
- type: "object",
714
- properties: {
715
- limit: {
716
- type: "number",
717
- description: "Maximum number of realtime connections to return. Defaults to 20."
668
+ }
669
+ }),
670
+ getRequestDetails: agentShared.defineAgentToolContract({
671
+ name: "getRequestDetails",
672
+ description: "Return detailed metadata for a captured HTTP request without fetching response body.",
673
+ inputSchema: {
674
+ type: "object",
675
+ properties: {
676
+ requestId: {
677
+ type: "string",
678
+ description: "Captured plugin request ID to inspect."
679
+ }
718
680
  },
719
- cursor: {
720
- type: "string",
721
- description: "Opaque pagination cursor from a previous listRealtimeConnections call."
722
- }
681
+ required: ["requestId"]
723
682
  }
724
- }
725
- };
726
- const getRealtimeConnectionDetailsTool = {
727
- name: "getRealtimeConnectionDetails",
728
- description: "Return details for a captured WebSocket or SSE connection, including recent messages.",
729
- inputSchema: {
730
- type: "object",
731
- properties: {
732
- requestId: {
733
- type: "string",
734
- description: "Captured realtime request ID to inspect."
683
+ }),
684
+ getRequestBody: agentShared.defineAgentToolContract({
685
+ name: "getRequestBody",
686
+ description: "Return the captured request body for a plugin-recorded HTTP request when available.",
687
+ inputSchema: {
688
+ type: "object",
689
+ properties: {
690
+ requestId: {
691
+ type: "string",
692
+ description: "Captured plugin request ID to inspect."
693
+ }
694
+ },
695
+ required: ["requestId"]
696
+ }
697
+ }),
698
+ getResponseBody: agentShared.defineAgentToolContract({
699
+ name: "getResponseBody",
700
+ description: "Return the captured response body for a plugin-recorded HTTP request when available.",
701
+ inputSchema: {
702
+ type: "object",
703
+ properties: {
704
+ requestId: {
705
+ type: "string",
706
+ description: "Captured plugin request ID to inspect."
707
+ }
708
+ },
709
+ required: ["requestId"]
710
+ }
711
+ }),
712
+ listRealtimeConnections: agentShared.defineAgentToolContract({
713
+ name: "listRealtimeConnections",
714
+ description: "List captured WebSocket and SSE connections with cursor pagination.",
715
+ inputSchema: {
716
+ type: "object",
717
+ properties: {
718
+ limit: {
719
+ type: "number",
720
+ description: "Maximum number of realtime connections to return. Defaults to 20."
721
+ },
722
+ cursor: {
723
+ type: "string",
724
+ description: "Opaque pagination cursor from a previous listRealtimeConnections call."
725
+ }
735
726
  }
736
- },
737
- required: ["requestId"]
738
- }
727
+ }
728
+ }),
729
+ getRealtimeConnectionDetails: agentShared.defineAgentToolContract({
730
+ name: "getRealtimeConnectionDetails",
731
+ description: "Return details for a captured WebSocket or SSE connection, including recent messages.",
732
+ inputSchema: {
733
+ type: "object",
734
+ properties: {
735
+ requestId: {
736
+ type: "string",
737
+ description: "Captured realtime request ID to inspect."
738
+ }
739
+ },
740
+ required: ["requestId"]
741
+ }
742
+ })
739
743
  };
740
- const pluginId = "@rozenite/network-activity-plugin";
744
+ const startRecordingTool = networkActivityToolDefinitions.startRecording;
745
+ const stopRecordingTool = networkActivityToolDefinitions.stopRecording;
746
+ const getRecordingStatusTool = networkActivityToolDefinitions.getRecordingStatus;
747
+ const listRequestsTool = networkActivityToolDefinitions.listRequests;
748
+ const getRequestDetailsTool = networkActivityToolDefinitions.getRequestDetails;
749
+ const getRequestBodyTool = networkActivityToolDefinitions.getRequestBody;
750
+ const getResponseBodyTool = networkActivityToolDefinitions.getResponseBody;
751
+ const listRealtimeConnectionsTool = networkActivityToolDefinitions.listRealtimeConnections;
752
+ const getRealtimeConnectionDetailsTool = networkActivityToolDefinitions.getRealtimeConnectionDetails;
741
753
  const useNetworkActivityAgentTools = ({
742
754
  client,
743
755
  networkInspector,
@@ -766,6 +778,22 @@ const useNetworkActivityAgentTools = ({
766
778
  "request-failed",
767
779
  (event) => state.onRequestFailed(event)
768
780
  ),
781
+ networkInspector.nitro.on(
782
+ "request-sent",
783
+ (event) => state.onRequestSent(event)
784
+ ),
785
+ networkInspector.nitro.on(
786
+ "response-received",
787
+ (event) => state.onResponseReceived(event)
788
+ ),
789
+ networkInspector.nitro.on(
790
+ "request-completed",
791
+ (event) => state.onRequestCompleted(event)
792
+ ),
793
+ networkInspector.nitro.on(
794
+ "request-failed",
795
+ (event) => state.onRequestFailed(event)
796
+ ),
769
797
  networkInspector.websocket.on(
770
798
  "websocket-connect",
771
799
  (event) => state.onWebSocketConnect(event)
@@ -794,8 +822,35 @@ const useNetworkActivityAgentTools = ({
794
822
  "websocket-connection-status-changed",
795
823
  (event) => state.onWebSocketConnectionStatusChanged(event)
796
824
  ),
825
+ networkInspector.nitro.on(
826
+ "websocket-connect",
827
+ (event) => state.onWebSocketConnect(event)
828
+ ),
829
+ networkInspector.nitro.on(
830
+ "websocket-open",
831
+ (event) => state.onWebSocketOpen(event)
832
+ ),
833
+ networkInspector.nitro.on(
834
+ "websocket-close",
835
+ (event) => state.onWebSocketClose(event)
836
+ ),
837
+ networkInspector.nitro.on(
838
+ "websocket-message-sent",
839
+ (event) => state.onWebSocketMessageSent(event)
840
+ ),
841
+ networkInspector.nitro.on(
842
+ "websocket-message-received",
843
+ (event) => state.onWebSocketMessageReceived(event)
844
+ ),
845
+ networkInspector.nitro.on(
846
+ "websocket-error",
847
+ (event) => state.onWebSocketError(event)
848
+ ),
797
849
  networkInspector.sse.on("sse-open", (event) => state.onSSEOpen(event)),
798
- networkInspector.sse.on("sse-message", (event) => state.onSSEMessage(event)),
850
+ networkInspector.sse.on(
851
+ "sse-message",
852
+ (event) => state.onSSEMessage(event)
853
+ ),
799
854
  networkInspector.sse.on("sse-error", (event) => state.onSSEError(event)),
800
855
  networkInspector.sse.on("sse-close", (event) => state.onSSEClose(event))
801
856
  ];
@@ -822,7 +877,7 @@ const useNetworkActivityAgentTools = ({
822
877
  };
823
878
  }, [client, enabledInspectors, state]);
824
879
  agentBridge.useRozenitePluginAgentTool({
825
- pluginId,
880
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
826
881
  tool: startRecordingTool,
827
882
  handler: () => {
828
883
  networkInspector.http.getNetworkRequestsRegistry().clear();
@@ -835,7 +890,7 @@ const useNetworkActivityAgentTools = ({
835
890
  }
836
891
  });
837
892
  agentBridge.useRozenitePluginAgentTool({
838
- pluginId,
893
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
839
894
  tool: stopRecordingTool,
840
895
  handler: () => {
841
896
  const result = state.stopRecording();
@@ -847,27 +902,27 @@ const useNetworkActivityAgentTools = ({
847
902
  }
848
903
  });
849
904
  agentBridge.useRozenitePluginAgentTool({
850
- pluginId,
905
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
851
906
  tool: getRecordingStatusTool,
852
907
  handler: () => state.getStatus()
853
908
  });
854
909
  agentBridge.useRozenitePluginAgentTool({
855
- pluginId,
910
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
856
911
  tool: listRequestsTool,
857
912
  handler: (input = {}) => state.listRequests(input)
858
913
  });
859
914
  agentBridge.useRozenitePluginAgentTool({
860
- pluginId,
915
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
861
916
  tool: getRequestDetailsTool,
862
917
  handler: ({ requestId }) => state.getRequestDetails(requestId)
863
918
  });
864
919
  agentBridge.useRozenitePluginAgentTool({
865
- pluginId,
920
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
866
921
  tool: getRequestBodyTool,
867
922
  handler: ({ requestId }) => state.getRequestBody(requestId)
868
923
  });
869
924
  agentBridge.useRozenitePluginAgentTool({
870
- pluginId,
925
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
871
926
  tool: getResponseBodyTool,
872
927
  handler: async ({ requestId }) => {
873
928
  const record = state.getHttpRecord(requestId);
@@ -888,15 +943,7 @@ const useNetworkActivityAgentTools = ({
888
943
  reason: "Response body is unavailable until the request finishes loading."
889
944
  };
890
945
  }
891
- const request = networkInspector.http.getNetworkRequestsRegistry().getEntry(requestId);
892
- if (!request) {
893
- return {
894
- requestId,
895
- available: false,
896
- reason: "Response body is unavailable because the request object is no longer in the plugin registry."
897
- };
898
- }
899
- const body = await bootRecording.getResponseBody(request);
946
+ const body = await networkInspector.getResponseBody(requestId);
900
947
  if (body === null) {
901
948
  return {
902
949
  requestId,
@@ -915,39 +962,34 @@ const useNetworkActivityAgentTools = ({
915
962
  }
916
963
  });
917
964
  agentBridge.useRozenitePluginAgentTool({
918
- pluginId,
965
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
919
966
  tool: listRealtimeConnectionsTool,
920
967
  handler: (input = {}) => state.listRealtimeConnections(input)
921
968
  });
922
969
  agentBridge.useRozenitePluginAgentTool({
923
- pluginId,
970
+ pluginId: NETWORK_ACTIVITY_AGENT_PLUGIN_ID,
924
971
  tool: getRealtimeConnectionDetailsTool,
925
972
  handler: ({ requestId }) => state.getRealtimeConnectionDetails(requestId)
926
973
  });
927
974
  };
928
975
  const overridesRegistry = bootRecording.getOverridesRegistry();
929
- const useHttpInspector = (client, httpInspector, isEnabled, isRecordingEnabled) => {
976
+ const useHttpInspector = (client, networkInspector, isEnabled, isRecordingEnabled) => {
930
977
  react.useEffect(() => {
931
978
  if (!client || !isEnabled) {
932
979
  return;
933
980
  }
934
- const networkRequestsRegistry = httpInspector.getNetworkRequestsRegistry();
935
981
  const subscriptions = [
936
982
  client.onMessage("network-enable", () => {
937
- httpInspector.enable();
983
+ networkInspector.http.enable();
938
984
  }),
939
985
  client.onMessage("network-disable", () => {
940
- httpInspector.disable();
986
+ networkInspector.http.disable();
941
987
  }),
942
988
  client.onMessage("set-overrides", (data) => {
943
989
  overridesRegistry.setOverrides(data.overrides);
944
990
  }),
945
991
  client.onMessage("get-response-body", async ({ requestId }) => {
946
- const request = networkRequestsRegistry.getEntry(requestId);
947
- if (!request) {
948
- return;
949
- }
950
- const body = await bootRecording.getResponseBody(request);
992
+ const body = await networkInspector.getResponseBody(requestId);
951
993
  client.send("response-body", {
952
994
  requestId,
953
995
  body
@@ -955,13 +997,13 @@ const useHttpInspector = (client, httpInspector, isEnabled, isRecordingEnabled)
955
997
  })
956
998
  ];
957
999
  if (isRecordingEnabled) {
958
- httpInspector.enable();
1000
+ networkInspector.http.enable();
959
1001
  }
960
1002
  return () => {
961
1003
  subscriptions.forEach((subscription) => subscription.remove());
962
- httpInspector.dispose();
1004
+ networkInspector.http.dispose();
963
1005
  };
964
- }, [client, httpInspector, isEnabled, isRecordingEnabled]);
1006
+ }, [client, networkInspector, isEnabled, isRecordingEnabled]);
965
1007
  };
966
1008
  const useWebSocketInspector = (client, websocketInspector, isEnabled, isRecordingEnabled) => {
967
1009
  react.useEffect(() => {
@@ -1047,6 +1089,11 @@ const useNetworkActivityDevTools = (config = bootRecording.DEFAULT_CONFIG) => {
1047
1089
  const subscriptions = [
1048
1090
  client.onMessage("network-enable", () => {
1049
1091
  isRecordingEnabledRef.current = true;
1092
+ networkInspector.enable({
1093
+ http: isHttpInspectorEnabled,
1094
+ websocket: isWebSocketInspectorEnabled,
1095
+ sse: isSSEInspectorEnabled
1096
+ });
1050
1097
  eventsListener.connect(client.send, (message) => {
1051
1098
  const type = message.type;
1052
1099
  if (bootRecording.isHttpEvent(type)) {
@@ -1063,11 +1110,15 @@ const useNetworkActivityDevTools = (config = bootRecording.DEFAULT_CONFIG) => {
1063
1110
  }),
1064
1111
  client.onMessage("network-disable", () => {
1065
1112
  isRecordingEnabledRef.current = false;
1113
+ networkInspector.disable();
1066
1114
  }),
1067
1115
  client.onMessage("get-client-ui-settings", () => {
1068
1116
  sendClientUISettings();
1069
1117
  })
1070
1118
  ];
1119
+ client.send("recording-state", {
1120
+ isRecording: isRecordingEnabledRef.current
1121
+ });
1071
1122
  sendClientUISettings();
1072
1123
  return () => {
1073
1124
  subscriptions.forEach((subscription) => subscription.remove());
@@ -1081,7 +1132,7 @@ const useNetworkActivityDevTools = (config = bootRecording.DEFAULT_CONFIG) => {
1081
1132
  ]);
1082
1133
  useHttpInspector(
1083
1134
  client,
1084
- networkInspector.http,
1135
+ networkInspector,
1085
1136
  isHttpInspectorEnabled,
1086
1137
  isRecordingEnabledRef.current
1087
1138
  );