@buoy-gg/network 7.0.41 → 7.0.43

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 (272) hide show
  1. package/README.md +11 -85
  2. package/lib/commonjs/index.js +1 -332
  3. package/lib/commonjs/index.web.js +1 -420
  4. package/lib/commonjs/network/components/DataViewer.web.js +1 -879
  5. package/lib/commonjs/network/components/NetworkCopyScreen.web.js +1 -48
  6. package/lib/commonjs/network/components/NetworkCopySettingsView.js +27 -755
  7. package/lib/commonjs/network/components/NetworkCopySettingsView.web.js +14 -1242
  8. package/lib/commonjs/network/components/NetworkDetailScreen.web.js +1 -101
  9. package/lib/commonjs/network/components/NetworkDetailStepper.js +1 -108
  10. package/lib/commonjs/network/components/NetworkDetailStepper.web.js +1 -298
  11. package/lib/commonjs/network/components/NetworkEventDetailView.js +15 -1130
  12. package/lib/commonjs/network/components/NetworkEventDetailView.web.js +15 -1484
  13. package/lib/commonjs/network/components/NetworkEventItemCompact.js +2 -401
  14. package/lib/commonjs/network/components/NetworkEventItemCompact.web.js +2 -820
  15. package/lib/commonjs/network/components/NetworkFilterScreen.web.js +1 -55
  16. package/lib/commonjs/network/components/NetworkFilterViewV3.js +1 -442
  17. package/lib/commonjs/network/components/NetworkFilterViewV3.web.js +1 -1310
  18. package/lib/commonjs/network/components/NetworkHeaderLive.js +1 -375
  19. package/lib/commonjs/network/components/NetworkHeaderLive.web.js +1 -623
  20. package/lib/commonjs/network/components/NetworkHeaderMenu.js +1 -190
  21. package/lib/commonjs/network/components/NetworkListScreen.js +1 -403
  22. package/lib/commonjs/network/components/NetworkListScreen.web.js +1 -624
  23. package/lib/commonjs/network/components/NetworkModal.js +1 -786
  24. package/lib/commonjs/network/components/NetworkNumberPrompt.js +1 -178
  25. package/lib/commonjs/network/components/NetworkNumberPrompt.web.js +1 -232
  26. package/lib/commonjs/network/components/NetworkOverrideEditor.js +1 -814
  27. package/lib/commonjs/network/components/NetworkOverrideEditor.web.js +1 -942
  28. package/lib/commonjs/network/components/NetworkOverrideHeaderButton.js +1 -107
  29. package/lib/commonjs/network/components/NetworkOverrideHeaderButton.web.js +1 -133
  30. package/lib/commonjs/network/components/NetworkOverridesButton.js +1 -90
  31. package/lib/commonjs/network/components/NetworkOverridesButton.web.js +1 -143
  32. package/lib/commonjs/network/components/NetworkOverridesScreen.js +1 -543
  33. package/lib/commonjs/network/components/NetworkOverridesScreen.web.js +1 -830
  34. package/lib/commonjs/network/components/NetworkSavedScreen.js +1 -226
  35. package/lib/commonjs/network/components/NetworkSavedScreen.web.js +1 -463
  36. package/lib/commonjs/network/components/NetworkUpgradeBanner.js +1 -76
  37. package/lib/commonjs/network/components/response-editor/Explorer.js +1 -973
  38. package/lib/commonjs/network/components/response-editor/Explorer.web.js +1 -1136
  39. package/lib/commonjs/network/components/response-editor/deleteNestedDataByPath.js +1 -56
  40. package/lib/commonjs/network/components/response-editor/editorContext.js +1 -33
  41. package/lib/commonjs/network/components/response-editor/updateNestedDataByPath.js +1 -61
  42. package/lib/commonjs/network/conditions/NetworkConditionsControl.js +1 -235
  43. package/lib/commonjs/network/conditions/NetworkConditionsControl.test.js +1 -136
  44. package/lib/commonjs/network/conditions/NetworkConditionsIcon.js +1 -33
  45. package/lib/commonjs/network/conditions/NetworkFloatingTool.js +1 -310
  46. package/lib/commonjs/network/conditions/NetworkFloatingTool.test.js +1 -219
  47. package/lib/commonjs/network/conditions/store.js +1 -75
  48. package/lib/commonjs/network/conditions/wait.js +1 -43
  49. package/lib/commonjs/network/conditions/xhr.js +1 -135
  50. package/lib/commonjs/network/hooks/useLiveNetworkEvent.js +1 -62
  51. package/lib/commonjs/network/hooks/useNetworkBadgeCounts.js +1 -83
  52. package/lib/commonjs/network/hooks/useNetworkEventList.js +1 -108
  53. package/lib/commonjs/network/hooks/useNetworkEvents.js +1 -318
  54. package/lib/commonjs/network/hooks/useNetworkHasMatches.js +1 -56
  55. package/lib/commonjs/network/hooks/useNetworkSaved.js +1 -38
  56. package/lib/commonjs/network/hooks/useNetworkSelection.js +1 -53
  57. package/lib/commonjs/network/hooks/useOverrideRules.js +1 -36
  58. package/lib/commonjs/network/hooks/useTickEveryMinute.js +1 -21
  59. package/lib/commonjs/network/overrides/applyToFetch.js +1 -80
  60. package/lib/commonjs/network/overrides/applyToXhr.js +2 -510
  61. package/lib/commonjs/network/overrides/engine.js +1 -93
  62. package/lib/commonjs/network/overrides/matchRule.js +1 -87
  63. package/lib/commonjs/network/overrides/overriddenRows.js +1 -37
  64. package/lib/commonjs/network/overrides/overrideRulesStore.js +1 -550
  65. package/lib/commonjs/network/overrides/presets.js +1 -70
  66. package/lib/commonjs/network/overrides/resolveOverride.js +1 -158
  67. package/lib/commonjs/network/overrides/types.js +1 -90
  68. package/lib/commonjs/network/sync/networkBodyResolver.js +1 -39
  69. package/lib/commonjs/network/sync/networkSyncAdapter.js +1 -882
  70. package/lib/commonjs/network/sync/overrideHonesty.release.test.js +1 -36
  71. package/lib/commonjs/network/types/index.js +1 -5
  72. package/lib/commonjs/network/utils/extractOperationName.js +1 -80
  73. package/lib/commonjs/network/utils/filterNetworkEvents.js +1 -96
  74. package/lib/commonjs/network/utils/formatGraphQLVariables.js +1 -219
  75. package/lib/commonjs/network/utils/formatting.js +1 -30
  76. package/lib/commonjs/network/utils/generateCurl.js +2 -71
  77. package/lib/commonjs/network/utils/generateNetworkCopyText.js +37 -166
  78. package/lib/commonjs/network/utils/httpCompletion.js +1 -37
  79. package/lib/commonjs/network/utils/networkEventStore.js +1 -411
  80. package/lib/commonjs/network/utils/networkListener.js +4 -1352
  81. package/lib/commonjs/network/utils/networkSavedStore.js +3 -577
  82. package/lib/commonjs/network/utils/networkSelectionStore.js +1 -193
  83. package/lib/commonjs/network/utils/realNow.js +1 -0
  84. package/lib/commonjs/network/utils/requestId.js +1 -16
  85. package/lib/commonjs/network/utils/resolveRequestUrl.js +1 -15
  86. package/lib/commonjs/network/utils/selectSavedEvents.js +1 -39
  87. package/lib/commonjs/network/utils/startNetworkCapture.js +1 -24
  88. package/lib/commonjs/network/utils/withPinnedFirst.js +1 -32
  89. package/lib/commonjs/preset.js +1 -93
  90. package/lib/module/index.js +1 -104
  91. package/lib/module/index.web.js +1 -82
  92. package/lib/module/network/components/DataViewer.web.js +1 -875
  93. package/lib/module/network/components/NetworkCopyScreen.web.js +1 -44
  94. package/lib/module/network/components/NetworkCopySettingsView.js +27 -750
  95. package/lib/module/network/components/NetworkCopySettingsView.web.js +14 -1237
  96. package/lib/module/network/components/NetworkDetailScreen.web.js +1 -97
  97. package/lib/module/network/components/NetworkDetailStepper.js +1 -104
  98. package/lib/module/network/components/NetworkDetailStepper.web.js +1 -296
  99. package/lib/module/network/components/NetworkEventDetailView.js +15 -1129
  100. package/lib/module/network/components/NetworkEventDetailView.web.js +15 -1482
  101. package/lib/module/network/components/NetworkEventItemCompact.js +2 -398
  102. package/lib/module/network/components/NetworkEventItemCompact.web.js +2 -818
  103. package/lib/module/network/components/NetworkFilterScreen.web.js +1 -51
  104. package/lib/module/network/components/NetworkFilterViewV3.js +1 -438
  105. package/lib/module/network/components/NetworkFilterViewV3.web.js +1 -1306
  106. package/lib/module/network/components/NetworkHeaderLive.js +1 -366
  107. package/lib/module/network/components/NetworkHeaderLive.web.js +1 -617
  108. package/lib/module/network/components/NetworkHeaderMenu.js +1 -184
  109. package/lib/module/network/components/NetworkListScreen.js +1 -399
  110. package/lib/module/network/components/NetworkListScreen.web.js +1 -622
  111. package/lib/module/network/components/NetworkModal.js +1 -781
  112. package/lib/module/network/components/NetworkNumberPrompt.js +1 -174
  113. package/lib/module/network/components/NetworkNumberPrompt.web.js +1 -230
  114. package/lib/module/network/components/NetworkOverrideEditor.js +1 -811
  115. package/lib/module/network/components/NetworkOverrideEditor.web.js +1 -939
  116. package/lib/module/network/components/NetworkOverrideHeaderButton.js +1 -104
  117. package/lib/module/network/components/NetworkOverrideHeaderButton.web.js +1 -131
  118. package/lib/module/network/components/NetworkOverridesButton.js +1 -87
  119. package/lib/module/network/components/NetworkOverridesButton.web.js +1 -141
  120. package/lib/module/network/components/NetworkOverridesScreen.js +1 -539
  121. package/lib/module/network/components/NetworkOverridesScreen.web.js +1 -826
  122. package/lib/module/network/components/NetworkSavedScreen.js +1 -222
  123. package/lib/module/network/components/NetworkSavedScreen.web.js +1 -461
  124. package/lib/module/network/components/NetworkUpgradeBanner.js +1 -72
  125. package/lib/module/network/components/response-editor/Explorer.js +1 -972
  126. package/lib/module/network/components/response-editor/Explorer.web.js +1 -1133
  127. package/lib/module/network/components/response-editor/deleteNestedDataByPath.js +1 -51
  128. package/lib/module/network/components/response-editor/editorContext.js +1 -29
  129. package/lib/module/network/components/response-editor/updateNestedDataByPath.js +1 -56
  130. package/lib/module/network/conditions/NetworkConditionsControl.js +1 -231
  131. package/lib/module/network/conditions/NetworkConditionsControl.test.js +1 -135
  132. package/lib/module/network/conditions/NetworkConditionsIcon.js +1 -29
  133. package/lib/module/network/conditions/NetworkFloatingTool.js +1 -304
  134. package/lib/module/network/conditions/NetworkFloatingTool.test.js +1 -218
  135. package/lib/module/network/conditions/store.js +1 -65
  136. package/lib/module/network/conditions/wait.js +1 -38
  137. package/lib/module/network/conditions/xhr.js +1 -131
  138. package/lib/module/network/hooks/useLiveNetworkEvent.js +1 -58
  139. package/lib/module/network/hooks/useNetworkBadgeCounts.js +1 -79
  140. package/lib/module/network/hooks/useNetworkEventList.js +1 -104
  141. package/lib/module/network/hooks/useNetworkEvents.js +1 -314
  142. package/lib/module/network/hooks/useNetworkHasMatches.js +1 -52
  143. package/lib/module/network/hooks/useNetworkSaved.js +1 -34
  144. package/lib/module/network/hooks/useNetworkSelection.js +1 -46
  145. package/lib/module/network/hooks/useOverrideRules.js +1 -32
  146. package/lib/module/network/hooks/useTickEveryMinute.js +1 -11
  147. package/lib/module/network/overrides/applyToFetch.js +1 -72
  148. package/lib/module/network/overrides/applyToXhr.js +2 -502
  149. package/lib/module/network/overrides/engine.js +1 -85
  150. package/lib/module/network/overrides/matchRule.js +1 -81
  151. package/lib/module/network/overrides/overriddenRows.js +1 -33
  152. package/lib/module/network/overrides/overrideRulesStore.js +1 -547
  153. package/lib/module/network/overrides/presets.js +1 -65
  154. package/lib/module/network/overrides/resolveOverride.js +1 -152
  155. package/lib/module/network/overrides/types.js +1 -86
  156. package/lib/module/network/sync/networkBodyResolver.js +1 -34
  157. package/lib/module/network/sync/networkSyncAdapter.js +1 -880
  158. package/lib/module/network/sync/overrideHonesty.release.test.js +1 -35
  159. package/lib/module/network/types/index.js +1 -3
  160. package/lib/module/network/utils/extractOperationName.js +1 -76
  161. package/lib/module/network/utils/filterNetworkEvents.js +1 -92
  162. package/lib/module/network/utils/formatGraphQLVariables.js +1 -213
  163. package/lib/module/network/utils/formatting.js +1 -9
  164. package/lib/module/network/utils/generateCurl.js +2 -67
  165. package/lib/module/network/utils/generateNetworkCopyText.js +37 -162
  166. package/lib/module/network/utils/httpCompletion.js +1 -32
  167. package/lib/module/network/utils/networkEventStore.js +1 -409
  168. package/lib/module/network/utils/networkListener.js +4 -1341
  169. package/lib/module/network/utils/networkSavedStore.js +3 -572
  170. package/lib/module/network/utils/networkSelectionStore.js +1 -188
  171. package/lib/module/network/utils/realNow.js +1 -0
  172. package/lib/module/network/utils/requestId.js +1 -12
  173. package/lib/module/network/utils/resolveRequestUrl.js +1 -11
  174. package/lib/module/network/utils/selectSavedEvents.js +1 -35
  175. package/lib/module/network/utils/startNetworkCapture.js +1 -21
  176. package/lib/module/network/utils/withPinnedFirst.js +1 -28
  177. package/lib/module/preset.js +1 -91
  178. package/lib/typescript/network/overrides/engine.d.ts +1 -1
  179. package/lib/typescript/network/overrides/matchRule.d.ts +1 -1
  180. package/lib/typescript/network/overrides/resolveOverride.d.ts +2 -2
  181. package/lib/typescript/network/overrides/types.d.ts +9 -0
  182. package/lib/typescript/network/utils/networkListener.d.ts +11 -0
  183. package/lib/typescript/network/utils/realNow.d.ts +18 -0
  184. package/lib/web/index.mjs +73 -74
  185. package/package.json +3 -6
  186. package/lib/typescript/index.d.ts.map +0 -1
  187. package/lib/typescript/index.web.d.ts.map +0 -1
  188. package/lib/typescript/network/components/DataViewer.web.d.ts.map +0 -1
  189. package/lib/typescript/network/components/NetworkCopyScreen.web.d.ts.map +0 -1
  190. package/lib/typescript/network/components/NetworkCopySettingsView.d.ts.map +0 -1
  191. package/lib/typescript/network/components/NetworkCopySettingsView.web.d.ts.map +0 -1
  192. package/lib/typescript/network/components/NetworkDetailScreen.web.d.ts.map +0 -1
  193. package/lib/typescript/network/components/NetworkDetailStepper.d.ts.map +0 -1
  194. package/lib/typescript/network/components/NetworkDetailStepper.web.d.ts.map +0 -1
  195. package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +0 -1
  196. package/lib/typescript/network/components/NetworkEventDetailView.web.d.ts.map +0 -1
  197. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +0 -1
  198. package/lib/typescript/network/components/NetworkEventItemCompact.web.d.ts.map +0 -1
  199. package/lib/typescript/network/components/NetworkFilterScreen.web.d.ts.map +0 -1
  200. package/lib/typescript/network/components/NetworkFilterViewV3.d.ts.map +0 -1
  201. package/lib/typescript/network/components/NetworkFilterViewV3.web.d.ts.map +0 -1
  202. package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +0 -1
  203. package/lib/typescript/network/components/NetworkHeaderLive.web.d.ts.map +0 -1
  204. package/lib/typescript/network/components/NetworkHeaderMenu.d.ts.map +0 -1
  205. package/lib/typescript/network/components/NetworkListScreen.d.ts.map +0 -1
  206. package/lib/typescript/network/components/NetworkListScreen.web.d.ts.map +0 -1
  207. package/lib/typescript/network/components/NetworkModal.d.ts.map +0 -1
  208. package/lib/typescript/network/components/NetworkNumberPrompt.d.ts.map +0 -1
  209. package/lib/typescript/network/components/NetworkNumberPrompt.web.d.ts.map +0 -1
  210. package/lib/typescript/network/components/NetworkOverrideEditor.d.ts.map +0 -1
  211. package/lib/typescript/network/components/NetworkOverrideEditor.web.d.ts.map +0 -1
  212. package/lib/typescript/network/components/NetworkOverrideHeaderButton.d.ts.map +0 -1
  213. package/lib/typescript/network/components/NetworkOverrideHeaderButton.web.d.ts.map +0 -1
  214. package/lib/typescript/network/components/NetworkOverridesButton.d.ts.map +0 -1
  215. package/lib/typescript/network/components/NetworkOverridesButton.web.d.ts.map +0 -1
  216. package/lib/typescript/network/components/NetworkOverridesScreen.d.ts.map +0 -1
  217. package/lib/typescript/network/components/NetworkOverridesScreen.web.d.ts.map +0 -1
  218. package/lib/typescript/network/components/NetworkSavedScreen.d.ts.map +0 -1
  219. package/lib/typescript/network/components/NetworkSavedScreen.web.d.ts.map +0 -1
  220. package/lib/typescript/network/components/NetworkUpgradeBanner.d.ts.map +0 -1
  221. package/lib/typescript/network/components/response-editor/Explorer.d.ts.map +0 -1
  222. package/lib/typescript/network/components/response-editor/Explorer.web.d.ts.map +0 -1
  223. package/lib/typescript/network/components/response-editor/deleteNestedDataByPath.d.ts.map +0 -1
  224. package/lib/typescript/network/components/response-editor/editorContext.d.ts.map +0 -1
  225. package/lib/typescript/network/components/response-editor/updateNestedDataByPath.d.ts.map +0 -1
  226. package/lib/typescript/network/conditions/NetworkConditionsControl.d.ts.map +0 -1
  227. package/lib/typescript/network/conditions/NetworkConditionsControl.test.d.ts.map +0 -1
  228. package/lib/typescript/network/conditions/NetworkConditionsIcon.d.ts.map +0 -1
  229. package/lib/typescript/network/conditions/NetworkFloatingTool.d.ts.map +0 -1
  230. package/lib/typescript/network/conditions/NetworkFloatingTool.test.d.ts.map +0 -1
  231. package/lib/typescript/network/conditions/store.d.ts.map +0 -1
  232. package/lib/typescript/network/conditions/wait.d.ts.map +0 -1
  233. package/lib/typescript/network/conditions/xhr.d.ts.map +0 -1
  234. package/lib/typescript/network/hooks/useLiveNetworkEvent.d.ts.map +0 -1
  235. package/lib/typescript/network/hooks/useNetworkBadgeCounts.d.ts.map +0 -1
  236. package/lib/typescript/network/hooks/useNetworkEventList.d.ts.map +0 -1
  237. package/lib/typescript/network/hooks/useNetworkEvents.d.ts.map +0 -1
  238. package/lib/typescript/network/hooks/useNetworkHasMatches.d.ts.map +0 -1
  239. package/lib/typescript/network/hooks/useNetworkSaved.d.ts.map +0 -1
  240. package/lib/typescript/network/hooks/useNetworkSelection.d.ts.map +0 -1
  241. package/lib/typescript/network/hooks/useOverrideRules.d.ts.map +0 -1
  242. package/lib/typescript/network/hooks/useTickEveryMinute.d.ts.map +0 -1
  243. package/lib/typescript/network/overrides/applyToFetch.d.ts.map +0 -1
  244. package/lib/typescript/network/overrides/applyToXhr.d.ts.map +0 -1
  245. package/lib/typescript/network/overrides/engine.d.ts.map +0 -1
  246. package/lib/typescript/network/overrides/matchRule.d.ts.map +0 -1
  247. package/lib/typescript/network/overrides/overriddenRows.d.ts.map +0 -1
  248. package/lib/typescript/network/overrides/overrideRulesStore.d.ts.map +0 -1
  249. package/lib/typescript/network/overrides/presets.d.ts.map +0 -1
  250. package/lib/typescript/network/overrides/resolveOverride.d.ts.map +0 -1
  251. package/lib/typescript/network/overrides/types.d.ts.map +0 -1
  252. package/lib/typescript/network/sync/networkBodyResolver.d.ts.map +0 -1
  253. package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +0 -1
  254. package/lib/typescript/network/sync/overrideHonesty.release.test.d.ts.map +0 -1
  255. package/lib/typescript/network/types/index.d.ts.map +0 -1
  256. package/lib/typescript/network/utils/extractOperationName.d.ts.map +0 -1
  257. package/lib/typescript/network/utils/filterNetworkEvents.d.ts.map +0 -1
  258. package/lib/typescript/network/utils/formatGraphQLVariables.d.ts.map +0 -1
  259. package/lib/typescript/network/utils/formatting.d.ts.map +0 -1
  260. package/lib/typescript/network/utils/generateCurl.d.ts.map +0 -1
  261. package/lib/typescript/network/utils/generateNetworkCopyText.d.ts.map +0 -1
  262. package/lib/typescript/network/utils/httpCompletion.d.ts.map +0 -1
  263. package/lib/typescript/network/utils/networkEventStore.d.ts.map +0 -1
  264. package/lib/typescript/network/utils/networkListener.d.ts.map +0 -1
  265. package/lib/typescript/network/utils/networkSavedStore.d.ts.map +0 -1
  266. package/lib/typescript/network/utils/networkSelectionStore.d.ts.map +0 -1
  267. package/lib/typescript/network/utils/requestId.d.ts.map +0 -1
  268. package/lib/typescript/network/utils/resolveRequestUrl.d.ts.map +0 -1
  269. package/lib/typescript/network/utils/selectSavedEvents.d.ts.map +0 -1
  270. package/lib/typescript/network/utils/startNetworkCapture.d.ts.map +0 -1
  271. package/lib/typescript/network/utils/withPinnedFirst.d.ts.map +0 -1
  272. package/lib/typescript/preset.d.ts.map +0 -1
@@ -1,781 +1 @@
1
- "use strict";
2
-
3
- import { createRemoteConditionsSource, openNetworkFloatingTool } from "../conditions/NetworkFloatingTool";
4
- import { useState, useRef, useEffect, useCallback } from "react";
5
- import { View, StyleSheet, TouchableOpacity } from "react-native";
6
- import { Search, Wifi, Filter, Bookmark, JsModal, ModalHeader, devToolsStorageKeys, macOSColors, night, persistentStorage, NightSegmented, useFeatureGate, UpgradeModal, PowerToggleButton, useIgnoredPatterns, windowDragProps } from "@buoy-gg/shared-ui";
7
- import { NetworkFilterViewV3 } from "./NetworkFilterViewV3";
8
- import { TickProvider } from "../hooks/useTickEveryMinute";
9
- import { NetworkEventDetailView } from "./NetworkEventDetailView";
10
- import { NetworkCopySettingsView, DEFAULT_COPY_SETTINGS } from "./NetworkCopySettingsView";
11
- import { NetworkHeaderBadges, NetworkClearButton, NetworkDetailPinActions, NetworkHeaderCopyButton } from "./NetworkHeaderLive";
12
- import { NetworkListScreen } from "./NetworkListScreen";
13
- import { NetworkSavedScreen } from "./NetworkSavedScreen";
14
- import { NetworkOverridesScreen } from "./NetworkOverridesScreen";
15
- import { NetworkOverridesButton } from "./NetworkOverridesButton";
16
- import { NetworkOverrideHeaderButton } from "./NetworkOverrideHeaderButton";
17
- import { NetworkHeaderMenu, NetworkHeaderMenuButton, NetworkHeaderMenuItem } from "./NetworkHeaderMenu";
18
- import { NetworkDetailStepper } from "./NetworkDetailStepper";
19
- import { useNetworkEventList } from "../hooks/useNetworkEventList";
20
- import { useLiveNetworkEvent } from "../hooks/useLiveNetworkEvent";
21
- import { useHasNetworkSelection, useNetworkBodyEventId, useSelectedNetworkEventId } from "../hooks/useNetworkSelection";
22
- import { networkSelectionStore } from "../utils/networkSelectionStore";
23
- import { FREE_TIER_SAVED_LIMIT, MAX_SAVED } from "../utils/networkSavedStore";
24
- import { FREE_TIER_RULE_LIMIT as FREE_TIER_OVERRIDE_LIMIT, MAX_RULES as MAX_OVERRIDE_RULES } from "../overrides/types";
25
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
26
- // ============================================================================
27
- // Screens (rule4 stable router: each gates itself with `return null`; the
28
- // root renders all four as stable siblings instead of a nested ternary).
29
- // Subscribing screens run their hooks unconditionally and pass
30
- // `paused || !visible` so hidden screens don't subscribe.
31
- // ============================================================================
32
-
33
- function NetworkDetailScreen({
34
- visible,
35
- paused,
36
- ignoredPatternValues,
37
- onTogglePattern,
38
- isPro,
39
- filter,
40
- ignoredPatterns,
41
- fromSaved,
42
- savedSearch,
43
- applySafeAreaInset
44
- }) {
45
- /**
46
- * The detail renders at the IMMEDIATE selection — every step, no delay.
47
- * Measured, 100 steps at a 150ms tap interval over 64KB payloads:
48
- *
49
- * whole detail, bodies included ... 647ms/step
50
- * detail with no bodies at all .... 43ms/step (over the 150ms tap gap)
51
- *
52
- * So ~93% of a step is the request/response BODY trees, and everything else
53
- * — status, URL breakdown, timing, header counts — is affordable at any tap
54
- * rate. Deferring the whole detail (which is what this used to do) therefore
55
- * bought nothing a user could feel: it made the cheap 43ms wait alongside
56
- * the expensive 450ms instead of splitting them.
57
- *
58
- * So only the expensive part waits. `bodyId` trails `selectedId` by the
59
- * settle window, so `heavyReady` is false exactly while the cursor is still
60
- * moving — the JSON trees are skipped during a burst and mount once you land.
61
- */
62
- const eventId = useSelectedNetworkEventId();
63
- const settledId = useNetworkBodyEventId();
64
- const heavyReady = eventId != null && eventId === settledId;
65
- // Resolve the ID to the live event so a request opened while pending picks
66
- // up its response/error in place instead of freezing on the snapshot taken
67
- // when the row was tapped.
68
- const event = useLiveNetworkEvent(eventId, {
69
- paused: paused || !visible
70
- });
71
-
72
- // Instrumentation for the benchmark harness. Gated on `heavyReady` on
73
- // purpose: the cheap chrome now renders on every step, so reporting here
74
- // unconditionally would make `bodyMs` a duplicate of `cursorMs`. What the
75
- // harness needs to know is when the expensive TREES landed.
76
- useEffect(() => {
77
- if (visible && event && heavyReady) {
78
- networkSelectionStore.reportRendered(event.id);
79
- }
80
- }, [visible, event, heavyReady]);
81
- if (!visible) return null;
82
- // Column: the detail body scrolls, the stepper stays pinned under it. The
83
- // body owns its scroll here (see `bodyOwnsScroll`) — inside JsModal's
84
- // wrapper the footer would scroll away with the content. The spacer keeps
85
- // the footer at the bottom on the rare frame where the ID resolves to
86
- // nothing (cleared, aged out, and not saved).
87
- return /*#__PURE__*/_jsxs(View, {
88
- style: styles.detailRoot,
89
- children: [event ? /*#__PURE__*/_jsx(NetworkEventDetailView, {
90
- event: event,
91
- ignoredPatterns: ignoredPatternValues,
92
- onTogglePattern: onTogglePattern,
93
- showBodies: heavyReady
94
- }) : /*#__PURE__*/_jsx(View, {
95
- style: styles.detailBodyFallback
96
- }), /*#__PURE__*/_jsx(NetworkDetailStepper, {
97
- paused: paused,
98
- filter: filter,
99
- ignoredPatterns: ignoredPatterns,
100
- isPro: isPro,
101
- fromSaved: fromSaved,
102
- savedSearch: savedSearch,
103
- applySafeAreaInset: applySafeAreaInset
104
- })]
105
- });
106
- }
107
- function NetworkFilterScreen({
108
- visible,
109
- paused,
110
- isPro,
111
- filter,
112
- onFilterChange,
113
- ignoredPatterns,
114
- onRemovePattern,
115
- onAddPattern,
116
- onTogglePatternMode
117
- }) {
118
- // Facet counts read the same filtered list the user is looking at.
119
- const {
120
- events
121
- } = useNetworkEventList({
122
- filter,
123
- ignoredPatterns,
124
- paused,
125
- visible,
126
- isPro
127
- });
128
- if (!visible) return null;
129
- return /*#__PURE__*/_jsx(NetworkFilterViewV3, {
130
- events: events,
131
- filter: filter,
132
- onFilterChange: onFilterChange,
133
- ignoredPatterns: ignoredPatterns,
134
- onRemovePattern: onRemovePattern,
135
- onAddPattern: onAddPattern,
136
- onTogglePatternMode: onTogglePatternMode
137
- });
138
- }
139
- function NetworkCopyScreen({
140
- visible,
141
- paused,
142
- isPro,
143
- filter,
144
- ignoredPatterns,
145
- settings,
146
- onSettingsChange
147
- }) {
148
- const {
149
- events
150
- } = useNetworkEventList({
151
- filter,
152
- ignoredPatterns,
153
- paused,
154
- visible,
155
- isPro
156
- });
157
- if (!visible) return null;
158
- return /*#__PURE__*/_jsx(NetworkCopySettingsView, {
159
- settings: settings,
160
- onSettingsChange: onSettingsChange,
161
- events: events
162
- });
163
- }
164
-
165
- // ============================================================================
166
- // Root — UI-state orchestration ONLY (rule3). No event-store subscription
167
- // lives here: live data is consumed by the header leaves
168
- // (NetworkHeaderLive) and the screens, so network events never re-render
169
- // the modal shell/header. Profiling evidence: tool-bench 2026-07-06 —
170
- // with the subscription here, 15 events re-rendered JsModal + every
171
- // header button 15× and all visible rows 105×.
172
- // ============================================================================
173
-
174
- function NetworkModalInner({
175
- visible,
176
- onClose,
177
- onBack,
178
- onMinimize,
179
- enableSharedModalDimensions = false,
180
- inline = false,
181
- paused: pausedProp,
182
- onPausedChange,
183
- remoteConditions
184
- }) {
185
- const {
186
- isPro
187
- } = useFeatureGate();
188
-
189
- // Capture pause (the power toggle's freeze-stream semantic) — gates
190
- // every subscriber in this modal's tree via props. Controlled when the host
191
- // supplies both halves; otherwise this local state is the source of truth.
192
- const [pausedState, setPausedState] = useState(false);
193
- const controlledPause = pausedProp != null && onPausedChange != null;
194
- const paused = controlledPause ? pausedProp : pausedState;
195
- const setPaused = next => {
196
- const value = typeof next === "function" ? next(paused) : next;
197
- if (controlledPause) onPausedChange(value);else setPausedState(value);
198
- };
199
- const [filter, setFilter] = useState({});
200
- /**
201
- * The cursor lives in `networkSelectionStore`, and the root subscribes to
202
- * the BOOLEAN only. That is the whole point: this component re-renders
203
- * `JsModal` (which can never bail — its `header` prop is a fresh object
204
- * every render), the entire header, and all five screens. None of them care
205
- * WHICH request is selected, only THAT one is, and this flips twice a
206
- * session instead of once per tap.
207
- */
208
- const hasSelection = useHasNetworkSelection();
209
- const [showFilterView, setShowFilterView] = useState(false);
210
- const [showSavedView, setShowSavedView] = useState(false);
211
- const [showOverridesView, setShowOverridesView] = useState(false);
212
- const [showHeaderMenu, setShowHeaderMenu] = useState(false);
213
- const [minimizeRequest, setMinimizeRequest] = useState(0);
214
- const [remoteConditionsSource] = useState(createRemoteConditionsSource);
215
- useEffect(() => {
216
- remoteConditionsSource.update(remoteConditions);
217
- }, [remoteConditionsSource, remoteConditions]);
218
- useEffect(() => () => remoteConditionsSource.update(undefined), [remoteConditionsSource]);
219
- /**
220
- * Overrides are a DEVICE capability — a rule runs inside the app's own
221
- * `fetch`/`XMLHttpRequest`, which the dashboard doesn't have.
222
- *
223
- * That doesn't mean the dashboard can't AUTHOR them: in `inline` mode the
224
- * rule store runs as a mirror of the connected device (see
225
- * `overrideRulesStore.enableRemoteMode`), so the screens below are the same
226
- * ones the phone renders and every edit is forwarded. The one thing the
227
- * dashboard never does is apply a rule to its own traffic —
228
- * `disableEngine()` guarantees that.
229
- */
230
- const overridesAvailable = true;
231
- /**
232
- * A rule prefilled from a request the user was looking at, handed to the
233
- * Overrides screen when it mounts. Lives here rather than in that screen
234
- * because the request that seeds it is on a DIFFERENT screen — this is the
235
- * one place both are in scope.
236
- */
237
- const [pendingOverrideDraft, setPendingOverrideDraft] = useState(null);
238
- const [activeTab, setActiveTab] = useState("filters");
239
- const [searchText, setSearchText] = useState("");
240
- const [isSearchActive, setIsSearchActive] = useState(false);
241
- // True while the header's clear ✕ is being pressed. With a mouse, pressing
242
- // the ✕ blurs the input FIRST, and the blur handler below closes search —
243
- // which unmounts the ✕ before its own press can fire, so the query was
244
- // never cleared (desktop). Press-in lands before the blur, so the blur
245
- // handler can tell this dismissal apart from a click elsewhere.
246
- const clearPressRef = useRef(false);
247
- // The Saved screen's search box lives HERE, not in that screen, because the
248
- // detail footer steps through the same list the user was just looking at —
249
- // and the Saved screen is unmounted while a detail is open.
250
- const [savedSearch, setSavedSearch] = useState("");
251
- const searchInputRef = useRef(null);
252
- // Ignored domains/URL patterns live in a shared, persisted singleton store
253
- // (@buoy-gg/shared-ui) so the Network tool and the Events tool stay in sync.
254
- const {
255
- patterns: ignoredPatterns,
256
- values: ignoredPatternValues,
257
- add: addIgnoredPattern,
258
- remove: removeIgnoredPattern,
259
- toggle: toggleIgnoredPattern,
260
- toggleMode: toggleIgnoredPatternMode
261
- } = useIgnoredPatterns();
262
- const [copySettings, setCopySettings] = useState(DEFAULT_COPY_SETTINGS);
263
- const hasLoadedCopySettings = useRef(false);
264
- const [showUpgradeModal, setShowUpgradeModal] = useState(false);
265
- // Which ceiling the user hit — the upgrade sheet has to argue for the thing
266
- // they were actually trying to do, not for exporting.
267
- const [upgradeReason, setUpgradeReason] = useState("export");
268
- const showUpgrade = reason => {
269
- setUpgradeReason(reason);
270
- setShowUpgradeModal(true);
271
- };
272
-
273
- // Auto-close upgrade modal when user becomes Pro
274
- useEffect(() => {
275
- if (showUpgradeModal && isPro) {
276
- setShowUpgradeModal(false);
277
- }
278
- }, [showUpgradeModal, isPro]);
279
-
280
- // Load persisted copy settings on mount
281
- useEffect(() => {
282
- if (!visible || hasLoadedCopySettings.current) return;
283
- const loadCopySettings = async () => {
284
- try {
285
- const stored = await persistentStorage.getItem(devToolsStorageKeys.network.copyOptions());
286
- if (stored) {
287
- const settings = JSON.parse(stored);
288
- setCopySettings(settings);
289
- }
290
- } catch (_error) {
291
- // Silently fail - use defaults
292
- } finally {
293
- hasLoadedCopySettings.current = true;
294
- }
295
- };
296
- loadCopySettings();
297
- }, [visible]);
298
-
299
- // Save copy settings when they change
300
- useEffect(() => {
301
- if (!hasLoadedCopySettings.current) return; // Don't save on initial load
302
-
303
- const saveCopySettings = async () => {
304
- try {
305
- await persistentStorage.setItem(devToolsStorageKeys.network.copyOptions(), JSON.stringify(copySettings));
306
- } catch (_error) {
307
- // Silently fail - settings will remain in memory
308
- }
309
- };
310
- saveCopySettings();
311
- }, [copySettings]);
312
-
313
- // Simple handlers - no useCallback needed per rule2
314
- const handleBack = () => {
315
- networkSelectionStore.clear();
316
- };
317
-
318
- // Stable identity: this is passed down to the memoized list rows.
319
- const handleEventPress = useCallback(event => {
320
- networkSelectionStore.select(event.id);
321
- }, []);
322
-
323
- /**
324
- * "Custom…" in a request's Override section. Stable identity because the
325
- * detail view is memoized on its props and an unstable callback would defeat
326
- * the bail-out that keeps prev/next stepping cheap.
327
- */
328
- const handleOverridePress = useCallback((draft, ruleId) => {
329
- setPendingOverrideDraft(ruleId ? {
330
- ...draft,
331
- id: ruleId
332
- } : draft);
333
- setShowOverridesView(true);
334
- // Leave the detail view, or its header would sit on top of the editor.
335
- networkSelectionStore.clear();
336
- }, []);
337
-
338
- // Stable identity: the Overrides screen adopts the draft in an effect keyed
339
- // on both, so an unstable callback would re-run it every render.
340
- const handlePendingOverrideConsumed = useCallback(() => setPendingOverrideDraft(null), []);
341
-
342
- // Non-null while the Overrides screen has its rule editor open — the editor
343
- // is that screen's own state, so the header asks it first before popping the
344
- // whole screen. See the prop's comment on NetworkOverridesScreen.
345
- const overridesBackRef = useRef(null);
346
- const handleSearch = text => {
347
- setSearchText(text);
348
- setFilter(prev => ({
349
- ...prev,
350
- searchText: text
351
- }));
352
- };
353
- const toggleStatusFilter = status => {
354
- setFilter(prev => ({
355
- ...prev,
356
- status: prev.status === status ? undefined : status
357
- }));
358
- };
359
-
360
- // JsModal owns the mode; the only thing this modal needs it for is the
361
- // detail footer's bottom inset — a bottom sheet sits on the home indicator,
362
- // a floating window does not (same call StorageModalWithTabs makes).
363
- const [modalMode, setModalMode] = useState("bottomSheet");
364
- const handleModeChange = mode => {
365
- setModalMode(mode);
366
- };
367
- useEffect(() => {
368
- if (isSearchActive) {
369
- requestAnimationFrame(() => {
370
- searchInputRef.current?.focus();
371
- });
372
- }
373
- }, [isSearchActive]);
374
-
375
- // Compact header with actions (like Sentry/Storage modals)
376
- const renderHeaderContent = () => {
377
- // Filter view header with tabs — the night segmented control (the same
378
- // one the dial settings header uses).
379
- if (showFilterView) {
380
- return /*#__PURE__*/_jsxs(ModalHeader, {
381
- children: [/*#__PURE__*/_jsx(ModalHeader.Navigation, {
382
- onBack: () => setShowFilterView(false)
383
- }), /*#__PURE__*/_jsx(ModalHeader.Content, {
384
- title: "",
385
- noMargin: true,
386
- children: /*#__PURE__*/_jsx(NightSegmented, {
387
- size: "sm",
388
- tabs: [{
389
- key: "filters",
390
- label: "Filters"
391
- }, {
392
- key: "copy",
393
- label: "Copy"
394
- }],
395
- activeKey: activeTab,
396
- onChange: tab => setActiveTab(tab)
397
- })
398
- })]
399
- });
400
- }
401
-
402
- // Event detail view header
403
- if (hasSelection) {
404
- return /*#__PURE__*/_jsxs(ModalHeader, {
405
- children: [/*#__PURE__*/_jsx(ModalHeader.Navigation, {
406
- onBack: handleBack
407
- }), /*#__PURE__*/_jsx(ModalHeader.Content, {
408
- title: "Request Details",
409
- centered: true
410
- }), /*#__PURE__*/_jsxs(ModalHeader.Actions, {
411
- children: [overridesAvailable ? /*#__PURE__*/_jsx(NetworkOverrideHeaderButton, {
412
- onOpen: handleOverridePress
413
- }) : null, /*#__PURE__*/_jsx(NetworkDetailPinActions, {
414
- isPro: isPro,
415
- onUpgradePress: () => showUpgrade("saved")
416
- })]
417
- })]
418
- });
419
- }
420
-
421
- // Overrides manager header.
422
- if (showOverridesView && overridesAvailable) {
423
- return /*#__PURE__*/_jsxs(ModalHeader, {
424
- children: [/*#__PURE__*/_jsx(ModalHeader.Navigation, {
425
- onBack: () => {
426
- if (overridesBackRef.current?.()) return;
427
- setShowOverridesView(false);
428
- setPendingOverrideDraft(null);
429
- }
430
- }), /*#__PURE__*/_jsx(ModalHeader.Content, {
431
- title: "Response Overrides",
432
- centered: true
433
- })]
434
- });
435
- }
436
-
437
- // Saved (favorites) header. Checked AFTER the detail branch so opening a
438
- // saved request still gets the detail header — and its pin/save toggles.
439
- if (showSavedView) {
440
- return /*#__PURE__*/_jsxs(ModalHeader, {
441
- children: [/*#__PURE__*/_jsx(ModalHeader.Navigation, {
442
- onBack: () => setShowSavedView(false)
443
- }), /*#__PURE__*/_jsx(ModalHeader.Content, {
444
- title: "Saved Requests",
445
- centered: true
446
- })]
447
- });
448
- }
449
-
450
- // Main list view header with search and filters. The live pieces
451
- // (count chips, copy, trash) are self-subscribing leaves — this
452
- // header function itself only re-runs on user interaction.
453
- return /*#__PURE__*/_jsxs(ModalHeader, {
454
- children: [onBack && /*#__PURE__*/_jsx(ModalHeader.Navigation, {
455
- onBack: onBack
456
- }), /*#__PURE__*/_jsx(ModalHeader.Content, {
457
- title: "",
458
- children: isSearchActive ? /*#__PURE__*/_jsx(ModalHeader.Search, {
459
- value: searchText,
460
- onChangeText: handleSearch,
461
- onCancel: () => {
462
- handleSearch("");
463
- setIsSearchActive(false);
464
- },
465
- onDismiss: () => setIsSearchActive(false),
466
- dismissOnBlur: true,
467
- clearOnlyWhenText: true,
468
- placeholder: "Search URL, method, operation, error...",
469
- accessibilityLabel: "Search network requests",
470
- iconSize: 14,
471
- testID: "buoy-network-search-input",
472
- clearTestID: "buoy-network-search-clear",
473
- inputProps: {
474
- "sentry-label": "ignore network search header"
475
- }
476
- }) : /*#__PURE__*/_jsx(NetworkHeaderBadges, {
477
- activeStatus: filter.status,
478
- onToggleStatus: toggleStatusFilter,
479
- ignoredPatterns: ignoredPatterns,
480
- paused: paused
481
- })
482
- }), /*#__PURE__*/_jsxs(ModalHeader.Actions, {
483
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
484
- "sentry-label": "ignore open search",
485
- testID: "buoy-network-search-open",
486
- accessibilityLabel: "Open search",
487
- accessibilityRole: "button",
488
- onPress: () => setIsSearchActive(true),
489
- style: styles.headerActionButton,
490
- children: /*#__PURE__*/_jsx(Search, {
491
- size: 14,
492
- color: night.color.textSecondary
493
- })
494
- }), overridesAvailable ? /*#__PURE__*/_jsx(NetworkOverridesButton, {
495
- onPress: () => setShowOverridesView(true)
496
- }) : null, /*#__PURE__*/_jsx(PowerToggleButton, {
497
- isEnabled: !paused,
498
- onToggle: () => setPaused(prev => !prev),
499
- accessibilityLabel: paused ? "Resume network capture" : "Pause network capture",
500
- testID: "buoy-network-power"
501
- }), /*#__PURE__*/_jsx(NetworkClearButton, {
502
- paused: paused
503
- }), /*#__PURE__*/_jsx(NetworkHeaderMenuButton, {
504
- onPress: () => setShowHeaderMenu(prev => !prev),
505
- isOpen: showHeaderMenu,
506
- hasIndicator: hasActiveFilter
507
- })]
508
- })]
509
- });
510
- };
511
-
512
- // Surfaced on the ⋯ so moving Filters into the menu doesn't hide the one
513
- // thing that button was communicating.
514
- const hasActiveFilter = !!(filter.status || filter.method || filter.contentType);
515
- const persistenceKey = enableSharedModalDimensions ? devToolsStorageKeys.modal.root() : devToolsStorageKeys.network.modal();
516
- if (!visible) return null;
517
-
518
- // The LIST screen owns its scrolling (FlatList virtualization requires
519
- // it — inside JsModal's ScrollView wrapper every row mounts, which at
520
- // the 500-event cap measured 17 JS FPS / 133% CPU / 1.4GB; see
521
- // NetworkListScreen). The Saved screen is a FlatList too, so it takes the
522
- // same deal. The DETAIL screen owns it as well, so its prev/next footer
523
- // stays pinned instead of scrolling away with the body. Filter/copy still
524
- // use the wrapper.
525
- const bodyOwnsScroll = hasSelection || !showFilterView;
526
- const body = /*#__PURE__*/_jsxs(_Fragment, {
527
- children: [/*#__PURE__*/_jsxs(View, {
528
- style: styles.container,
529
- children: [/*#__PURE__*/_jsx(NetworkDetailScreen, {
530
- visible: hasSelection,
531
- paused: paused,
532
- ignoredPatternValues: ignoredPatternValues,
533
- onTogglePattern: toggleIgnoredPattern,
534
- isPro: isPro,
535
- filter: filter,
536
- ignoredPatterns: ignoredPatterns
537
- // `showSavedView` is what Back returns to, so it is also which list
538
- // the user came from — and therefore which one to step through.
539
- ,
540
- fromSaved: showSavedView,
541
- savedSearch: savedSearch
542
- // Inline (desktop panel) has no home indicator to clear.
543
- ,
544
- applySafeAreaInset: !inline && modalMode === "bottomSheet"
545
- }), /*#__PURE__*/_jsx(NetworkFilterScreen, {
546
- visible: showFilterView && activeTab === "filters" && !hasSelection,
547
- paused: paused,
548
- isPro: isPro,
549
- filter: filter,
550
- onFilterChange: setFilter,
551
- ignoredPatterns: ignoredPatterns,
552
- onRemovePattern: removeIgnoredPattern,
553
- onAddPattern: addIgnoredPattern,
554
- onTogglePatternMode: toggleIgnoredPatternMode
555
- }), /*#__PURE__*/_jsx(NetworkCopyScreen, {
556
- visible: showFilterView && activeTab === "copy" && !hasSelection,
557
- paused: paused,
558
- isPro: isPro,
559
- filter: filter,
560
- ignoredPatterns: ignoredPatterns,
561
- settings: copySettings,
562
- onSettingsChange: setCopySettings
563
- }), /*#__PURE__*/_jsx(NetworkOverridesScreen, {
564
- visible: overridesAvailable && showOverridesView && !hasSelection && !showFilterView,
565
- isPro: isPro,
566
- onUpgradePress: () => showUpgrade("overrides"),
567
- pendingDraft: pendingOverrideDraft,
568
- onPendingConsumed: handlePendingOverrideConsumed,
569
- backHandlerRef: overridesBackRef
570
- // Inline (desktop panel) has no home indicator to clear.
571
- ,
572
- applySafeAreaInset: !inline && modalMode === "bottomSheet"
573
- }), /*#__PURE__*/_jsx(NetworkSavedScreen, {
574
- visible: showSavedView && !hasSelection && !showFilterView &&
575
- // Overrides wins in the header branch too — the two must agree, or
576
- // one screen renders under the other's header.
577
- !(showOverridesView && overridesAvailable),
578
- isPro: isPro,
579
- copySettings: copySettings,
580
- search: savedSearch,
581
- onSearchChange: setSavedSearch,
582
- onEventPress: handleEventPress,
583
- onUpgradePress: () => showUpgrade("saved")
584
- }), /*#__PURE__*/_jsx(NetworkListScreen, {
585
- visible: !hasSelection && !showFilterView && !showSavedView && !(showOverridesView && overridesAvailable),
586
- paused: paused,
587
- filter: filter,
588
- ignoredPatterns: ignoredPatterns,
589
- isPro: isPro,
590
- searchText: searchText,
591
- onEventPress: handleEventPress,
592
- onUpgradePress: () => showUpgrade("export")
593
- })]
594
- }), showHeaderMenu ? /*#__PURE__*/_jsxs(NetworkHeaderMenu, {
595
- onClose: () => setShowHeaderMenu(false),
596
- children: [/*#__PURE__*/_jsx(NetworkHeaderMenuItem, {
597
- icon: /*#__PURE__*/_jsx(Wifi, {
598
- size: 14,
599
- color: night.color.textSecondary
600
- }),
601
- label: "Network throttling",
602
- testID: "buoy-network-menu-throttling",
603
- onPress: () => {
604
- setShowHeaderMenu(false);
605
- openNetworkFloatingTool(remoteConditions ? remoteConditionsSource : undefined);
606
- if (!inline) setMinimizeRequest(value => value + 1);
607
- }
608
- }), /*#__PURE__*/_jsx(NetworkHeaderMenuItem, {
609
- icon: /*#__PURE__*/_jsx(Filter, {
610
- size: 14,
611
- color: hasActiveFilter ? night.color.accent : night.color.textSecondary
612
- }),
613
- label: "Filters",
614
- detail: hasActiveFilter ? "Active" : undefined,
615
- onPress: () => {
616
- setShowHeaderMenu(false);
617
- setActiveTab("filters");
618
- setShowFilterView(true);
619
- }
620
- }), /*#__PURE__*/_jsx(NetworkHeaderMenuItem, {
621
- icon: /*#__PURE__*/_jsx(Bookmark, {
622
- size: 14,
623
- color: night.color.textSecondary
624
- }),
625
- label: "Saved requests",
626
- onPress: () => {
627
- setShowHeaderMenu(false);
628
- setShowSavedView(true);
629
- }
630
- }), /*#__PURE__*/_jsx(View, {
631
- style: styles.menuCopyRow,
632
- children: /*#__PURE__*/_jsx(NetworkHeaderCopyButton, {
633
- isPro: isPro,
634
- filter: filter,
635
- ignoredPatterns: ignoredPatterns,
636
- copySettings: copySettings,
637
- paused: paused,
638
- onUpgradePress: () => {
639
- setShowHeaderMenu(false);
640
- showUpgrade("export");
641
- },
642
- label: "Copy requests"
643
- })
644
- })]
645
- }) : null, /*#__PURE__*/_jsx(UpgradeModal, {
646
- visible: showUpgradeModal,
647
- onClose: () => setShowUpgradeModal(false),
648
- featureName: upgradeReason === "saved" ? "Saved Requests" : upgradeReason === "overrides" ? "Response Overrides" : "Network Export",
649
- description: upgradeReason === "saved" ? "Keep the requests that matter. Saved requests survive Clear, app restarts, and the 500-request history cap." : upgradeReason === "overrides" ? "Force any endpoint to fail, stall or return something else — no backend changes, no code changes. Free keeps one active rule." : "Export network requests to share with your team, debug APIs, or feed into AI tools.",
650
- benefits: upgradeReason === "overrides" ? [`Run ${MAX_OVERRIDE_RULES} rules at once (free keeps ${FREE_TIER_OVERRIDE_LIMIT})`, "Force a 500, a 401 or an empty list in one tap", "Simulate offline, timeouts and slow connections", "Rules survive an app reload, so you can test the boot path"] : upgradeReason === "saved" ? [`Save up to ${MAX_SAVED} requests (free keeps ${FREE_TIER_SAVED_LIMIT})`, "Failed requests stay put through a Clear", "Snapshots survive an app restart", "Export saved requests to teammates or AI assistants"] : ["Export to JSON, Markdown, or plain text", "Customizable copy presets (URLs only, LLM-ready, full data)", "Share request details with teammates", "Feed network data directly to AI assistants"]
651
- })]
652
- });
653
-
654
- // The ONLY thing that differs between the phone and the desktop dashboard is
655
- // which shell the header and body go in. Everything above this line is shared.
656
- if (inline) {
657
- return /*#__PURE__*/_jsxs(View, {
658
- style: styles.inlineRoot,
659
- children: [/*#__PURE__*/_jsx(View, {
660
- style: styles.inlineHeader,
661
- ...windowDragProps,
662
- children: renderHeaderContent()
663
- }), body]
664
- });
665
- }
666
- return /*#__PURE__*/_jsx(JsModal, {
667
- visible: visible,
668
- onClose: onClose,
669
- onMinimize: onMinimize,
670
- minimizeRequest: minimizeRequest,
671
- persistenceKey: persistenceKey,
672
- variant: "night",
673
- header: {
674
- showToggleButton: true,
675
- customContent: renderHeaderContent()
676
- },
677
- onModeChange: handleModeChange,
678
- enablePersistence: true,
679
- initialMode: "bottomSheet",
680
- enableGlitchEffects: true,
681
- disableScrollWrapper: bodyOwnsScroll
682
- // Night hoists the ToolBackground to the sheet root (field runs through
683
- // the header). The desktop INLINE panel never goes through JsModal — its
684
- // host (the workbench) hoists one shared field instead, so the body
685
- // mounts none of its own in either shell.
686
- ,
687
- styles: {},
688
- children: body
689
- });
690
- }
691
- const styles = StyleSheet.create({
692
- container: {
693
- flex: 1,
694
- // Transparent so the HOST's hoisted star field shows through — the night
695
- // JsModal's sheet-root field in the modal, the desktop workbench's shared
696
- // row field in the inline panel.
697
- backgroundColor: "transparent"
698
- },
699
- /** Detail = scrolling body + pinned stepper footer. `minHeight: 0` so the
700
- * body's ScrollView scrolls instead of stretching the column. */
701
- detailRoot: {
702
- flex: 1,
703
- minHeight: 0
704
- },
705
- /** Holds the footer down when the selected ID resolves to no event. */
706
- detailBodyFallback: {
707
- flex: 1
708
- },
709
- /** Inline shell — fills the host panel; `minHeight: 0` so the list's own
710
- * FlatList can scroll instead of stretching the column. Transparent so the
711
- * desktop workbench's hoisted sky (one field spanning sidebar + panel)
712
- * shows through — the shell paints its own base beneath that field. */
713
- inlineRoot: {
714
- flex: 1,
715
- minHeight: 0,
716
- backgroundColor: "transparent"
717
- },
718
- inlineHeader: {
719
- paddingHorizontal: 12,
720
- paddingVertical: 8,
721
- borderBottomWidth: 1,
722
- borderBottomColor: macOSColors.border.default,
723
- // Clear, like Bench — the host's hoisted sky shows through the header.
724
- backgroundColor: "transparent"
725
- },
726
- // Night chrome — the header is glass over the star field, so the search
727
- // field and action chips sit on the Everlights dark-glass fill.
728
- menuCopyRow: {
729
- paddingHorizontal: 6
730
- },
731
- headerActionButton: {
732
- width: 32,
733
- height: 32,
734
- borderRadius: 8,
735
- backgroundColor: night.color.buttonSurface,
736
- borderWidth: 1,
737
- borderColor: night.color.border,
738
- alignItems: "center",
739
- justifyContent: "center"
740
- },
741
- activeFilterButton: {
742
- backgroundColor: night.color.accentSoft,
743
- borderColor: night.color.accentBorderStrong
744
- }
745
- });
746
-
747
- /**
748
- * High-level modal surface that wraps the network monitoring experience with shared timing
749
- * context. Automatically injects the `TickProvider` so timestamps refresh while the modal is open.
750
- */
751
- export function NetworkModal(props) {
752
- return /*#__PURE__*/_jsx(TickProvider, {
753
- children: /*#__PURE__*/_jsx(NetworkModalInner, {
754
- ...props
755
- })
756
- });
757
- }
758
- /**
759
- * The same network tool as `NetworkModal`, rendered INLINE — header bar, then
760
- * body — for hosts that place tools in a panel rather than a modal. Buoy Desktop
761
- * is the only one today.
762
- *
763
- * This exists so there is exactly ONE network tool. The desktop dashboard used
764
- * to ship its own 1,258-line copy of the modal's internals, which is how the two
765
- * surfaces drifted apart in the first place; anything added here now shows up on
766
- * both without a second edit.
767
- */
768
- export function NetworkToolView(props = {}) {
769
- return /*#__PURE__*/_jsx(TickProvider, {
770
- children: /*#__PURE__*/_jsx(NetworkModalInner, {
771
- ...props,
772
- inline: true,
773
- visible: true
774
- // Inline has no chrome to drive: there is no close button, no minimize
775
- // and no outer back — the host panel owns all of that.
776
- ,
777
- onClose: noop
778
- })
779
- });
780
- }
781
- const noop = () => {};
1
+ "use strict";import{createRemoteConditionsSource as De,openNetworkFloatingTool as _e}from"../conditions/NetworkFloatingTool";import{useState as n,useRef as x,useEffect as k,useCallback as G}from"react";import{View as E,StyleSheet as Ve,TouchableOpacity as qe}from"react-native";import{Search as He,Wifi as Le,Filter as Ue,Bookmark as ze,JsModal as je,ModalHeader as o,devToolsStorageKeys as D,macOSColors as Ke,night as u,persistentStorage as de,NightSegmented as We,useFeatureGate as Je,UpgradeModal as $e,PowerToggleButton as Ge,useIgnoredPatterns as Xe,windowDragProps as Ye}from"@buoy-gg/shared-ui";import{NetworkFilterViewV3 as Qe}from"./NetworkFilterViewV3";import{TickProvider as ue}from"../hooks/useTickEveryMinute";import{NetworkEventDetailView as Ze}from"./NetworkEventDetailView";import{NetworkCopySettingsView as et,DEFAULT_COPY_SETTINGS as tt}from"./NetworkCopySettingsView";import{NetworkHeaderBadges as rt,NetworkClearButton as ot,NetworkDetailPinActions as nt,NetworkHeaderCopyButton as st}from"./NetworkHeaderLive";import{NetworkListScreen as at}from"./NetworkListScreen";import{NetworkSavedScreen as it}from"./NetworkSavedScreen";import{NetworkOverridesScreen as lt}from"./NetworkOverridesScreen";import{NetworkOverridesButton as ct}from"./NetworkOverridesButton";import{NetworkOverrideHeaderButton as dt}from"./NetworkOverrideHeaderButton";import{NetworkHeaderMenu as ut,NetworkHeaderMenuButton as pt,NetworkHeaderMenuItem as X}from"./NetworkHeaderMenu";import{NetworkDetailStepper as ft}from"./NetworkDetailStepper";import{useNetworkEventList as pe}from"../hooks/useNetworkEventList";import{useLiveNetworkEvent as ht}from"../hooks/useLiveNetworkEvent";import{useHasNetworkSelection as gt,useNetworkBodyEventId as mt,useSelectedNetworkEventId as St}from"../hooks/useNetworkSelection";import{networkSelectionStore as _}from"../utils/networkSelectionStore";import{FREE_TIER_SAVED_LIMIT as vt,MAX_SAVED as wt}from"../utils/networkSavedStore";import{FREE_TIER_RULE_LIMIT as yt,MAX_RULES as kt}from"../overrides/types";import{jsx as e,jsxs as l,Fragment as Pt}from"react/jsx-runtime";function bt({visible:r,paused:p,ignoredPatternValues:f,onTogglePattern:h,isPro:v,filter:c,ignoredPatterns:g,fromSaved:m,savedSearch:w,applySafeAreaInset:i}){const M=St();const V=mt();const b=M!=null&&M===V;const s=ht(M,{paused:p||!r});k(()=>{if(r&&s&&b){_.reportRendered(s.id)}},[r,s,b]);if(!r)return null;return l(E,{style:P.detailRoot,children:[s?e(Ze,{event:s,ignoredPatterns:f,onTogglePattern:h,showBodies:b}):e(E,{style:P.detailBodyFallback}),e(ft,{paused:p,filter:c,ignoredPatterns:g,isPro:v,fromSaved:m,savedSearch:w,applySafeAreaInset:i})]})}function Ct({visible:r,paused:p,isPro:f,filter:h,onFilterChange:v,ignoredPatterns:c,onRemovePattern:g,onAddPattern:m,onTogglePatternMode:w}){const{events:i}=pe({filter:h,ignoredPatterns:c,paused:p,visible:r,isPro:f});if(!r)return null;return e(Qe,{events:i,filter:h,onFilterChange:v,ignoredPatterns:c,onRemovePattern:g,onAddPattern:m,onTogglePatternMode:w})}function Rt({visible:r,paused:p,isPro:f,filter:h,ignoredPatterns:v,settings:c,onSettingsChange:g}){const{events:m}=pe({filter:h,ignoredPatterns:v,paused:p,visible:r,isPro:f});if(!r)return null;return e(et,{settings:c,onSettingsChange:g,events:m})}function fe({visible:r,onClose:p,onBack:f,onMinimize:h,enableSharedModalDimensions:v=false,inline:c=false,paused:g,onPausedChange:m,remoteConditions:w}){const{isPro:i}=Je();const[M,V]=n(false);const b=g!=null&&m!=null;const s=b?g:M;const he=t=>{const a=typeof t==="function"?t(s):t;if(b)m(a);else V(a)};const[d,q]=n({});const S=gt();const[y,Y]=n(false);const[O,Q]=n(false);const[B,H]=n(false);const[Z,C]=n(false);const[ge,me]=n(0);const[T]=n(De);k(()=>{T.update(w)},[T,w]);k(()=>()=>T.update(void 0),[T]);const R=true;const[Se,L]=n(null);const[U,ee]=n("filters");const[te,ve]=n("");const[z,j]=n(false);const It=x(false);const[re,we]=n("");const ye=x(null);const{patterns:N,values:ke,add:Pe,remove:be,toggle:Ce,toggleMode:Re}=Xe();const[F,oe]=n(tt);const K=x(false);const[W,J]=n(false);const[I,Ne]=n("export");const A=t=>{Ne(t);J(true)};k(()=>{if(W&&i){J(false)}},[W,i]);k(()=>{if(!r||K.current)return;const t=async()=>{try{const a=await de.getItem(D.network.copyOptions());if(a){const xe=JSON.parse(a);oe(xe)}}catch(a){}finally{K.current=true}};t()},[r]);k(()=>{if(!K.current)return;const t=async()=>{try{await de.setItem(D.network.copyOptions(),JSON.stringify(F))}catch(a){}};t()},[F]);const Ie=()=>{_.clear()};const ne=G(t=>{_.select(t.id)},[]);const Ee=G((t,a)=>{L(a?{...t,id:a}:t);H(true);_.clear()},[]);const Me=G(()=>L(null),[]);const se=x(null);const ae=t=>{ve(t);q(a=>({...a,searchText:t}))};const Te=t=>{q(a=>({...a,status:a.status===t?void 0:t}))};const[ie,Fe]=n("bottomSheet");const Ae=t=>{Fe(t)};k(()=>{if(z){requestAnimationFrame(()=>{ye.current?.focus()})}},[z]);const le=()=>{if(y){return l(o,{children:[e(o.Navigation,{onBack:()=>Y(false)}),e(o.Content,{title:"",noMargin:true,children:e(We,{size:"sm",tabs:[{key:"filters",label:"Filters"},{key:"copy",label:"Copy"}],activeKey:U,onChange:t=>ee(t)})})]})}if(S){return l(o,{children:[e(o.Navigation,{onBack:Ie}),e(o.Content,{title:"Request Details",centered:true}),l(o.Actions,{children:[R?e(dt,{onOpen:Ee}):null,e(nt,{isPro:i,onUpgradePress:()=>A("saved")})]})]})}if(B&&R){return l(o,{children:[e(o.Navigation,{onBack:()=>{if(se.current?.())return;H(false);L(null)}}),e(o.Content,{title:"Response Overrides",centered:true})]})}if(O){return l(o,{children:[e(o.Navigation,{onBack:()=>Q(false)}),e(o.Content,{title:"Saved Requests",centered:true})]})}return l(o,{children:[f&&e(o.Navigation,{onBack:f}),e(o.Content,{title:"",children:z?e(o.Search,{value:te,onChangeText:ae,onCancel:()=>{ae("");j(false)},onDismiss:()=>j(false),dismissOnBlur:true,clearOnlyWhenText:true,placeholder:"Search URL, method, operation, error...",accessibilityLabel:"Search network requests",iconSize:14,testID:"buoy-network-search-input",clearTestID:"buoy-network-search-clear",inputProps:{"sentry-label":"ignore network search header"}}):e(rt,{activeStatus:d.status,onToggleStatus:Te,ignoredPatterns:N,paused:s})}),l(o.Actions,{children:[e(qe,{"sentry-label":"ignore open search",testID:"buoy-network-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",onPress:()=>j(true),style:P.headerActionButton,children:e(He,{size:14,color:u.color.textSecondary})}),R?e(ct,{onPress:()=>H(true)}):null,e(Ge,{isEnabled:!s,onToggle:()=>he(t=>!t),accessibilityLabel:s?"Resume network capture":"Pause network capture",testID:"buoy-network-power"}),e(ot,{paused:s}),e(pt,{onPress:()=>C(t=>!t),isOpen:Z,hasIndicator:$})]})]})};const $=!!(d.status||d.method||d.contentType);const Oe=v?D.modal.root():D.network.modal();if(!r)return null;const Be=S||!y;const ce=l(Pt,{children:[l(E,{style:P.container,children:[e(bt,{visible:S,paused:s,ignoredPatternValues:ke,onTogglePattern:Ce,isPro:i,filter:d,ignoredPatterns:N,fromSaved:O,savedSearch:re,applySafeAreaInset:!c&&ie==="bottomSheet"}),e(Ct,{visible:y&&U==="filters"&&!S,paused:s,isPro:i,filter:d,onFilterChange:q,ignoredPatterns:N,onRemovePattern:be,onAddPattern:Pe,onTogglePatternMode:Re}),e(Rt,{visible:y&&U==="copy"&&!S,paused:s,isPro:i,filter:d,ignoredPatterns:N,settings:F,onSettingsChange:oe}),e(lt,{visible:R&&B&&!S&&!y,isPro:i,onUpgradePress:()=>A("overrides"),pendingDraft:Se,onPendingConsumed:Me,backHandlerRef:se,applySafeAreaInset:!c&&ie==="bottomSheet"}),e(it,{visible:O&&!S&&!y&&!(B&&R),isPro:i,copySettings:F,search:re,onSearchChange:we,onEventPress:ne,onUpgradePress:()=>A("saved")}),e(at,{visible:!S&&!y&&!O&&!(B&&R),paused:s,filter:d,ignoredPatterns:N,isPro:i,searchText:te,onEventPress:ne,onUpgradePress:()=>A("export")})]}),Z?l(ut,{onClose:()=>C(false),children:[e(X,{icon:e(Le,{size:14,color:u.color.textSecondary}),label:"Network throttling",testID:"buoy-network-menu-throttling",onPress:()=>{C(false);_e(w?T:void 0);if(!c)me(t=>t+1)}}),e(X,{icon:e(Ue,{size:14,color:$?u.color.accent:u.color.textSecondary}),label:"Filters",detail:$?"Active":void 0,onPress:()=>{C(false);ee("filters");Y(true)}}),e(X,{icon:e(ze,{size:14,color:u.color.textSecondary}),label:"Saved requests",onPress:()=>{C(false);Q(true)}}),e(E,{style:P.menuCopyRow,children:e(st,{isPro:i,filter:d,ignoredPatterns:N,copySettings:F,paused:s,onUpgradePress:()=>{C(false);A("export")},label:"Copy requests"})})]}):null,e($e,{visible:W,onClose:()=>J(false),featureName:I==="saved"?"Saved Requests":I==="overrides"?"Response Overrides":"Network Export",description:I==="saved"?"Keep the requests that matter. Saved requests survive Clear, app restarts, and the 500-request history cap.":I==="overrides"?"Force any endpoint to fail, stall or return something else \u2014 no backend changes, no code changes. Free keeps one active rule.":"Export network requests to share with your team, debug APIs, or feed into AI tools.",benefits:I==="overrides"?[`Run ${kt} rules at once (free keeps ${yt})`,"Force a 500, a 401 or an empty list in one tap","Simulate offline, timeouts and slow connections","Rules survive an app reload, so you can test the boot path"]:I==="saved"?[`Save up to ${wt} requests (free keeps ${vt})`,"Failed requests stay put through a Clear","Snapshots survive an app restart","Export saved requests to teammates or AI assistants"]:["Export to JSON, Markdown, or plain text","Customizable copy presets (URLs only, LLM-ready, full data)","Share request details with teammates","Feed network data directly to AI assistants"]})]});if(c){return l(E,{style:P.inlineRoot,children:[e(E,{style:P.inlineHeader,...Ye,children:le()}),ce]})}return e(je,{visible:r,onClose:p,onMinimize:h,minimizeRequest:ge,persistenceKey:Oe,variant:"night",header:{showToggleButton:true,customContent:le()},onModeChange:Ae,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:Be,styles:{},children:ce})}const P=Ve.create({container:{flex:1,backgroundColor:"transparent"},detailRoot:{flex:1,minHeight:0},detailBodyFallback:{flex:1},inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:Ke.border.default,backgroundColor:"transparent"},menuCopyRow:{paddingHorizontal:6},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:u.color.buttonSurface,borderWidth:1,borderColor:u.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:u.color.accentSoft,borderColor:u.color.accentBorderStrong}});export function NetworkModal(r){return e(ue,{children:e(fe,{...r})})}export function NetworkToolView(r={}){return e(ue,{children:e(fe,{...r,inline:true,visible:true,onClose:Nt})})}const Nt=()=>{};