@buoy-gg/network 5.0.0 → 6.0.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.
Files changed (41) hide show
  1. package/README.md +29 -353
  2. package/lib/commonjs/index.js +14 -0
  3. package/lib/commonjs/network/components/NetworkEventItemCompact.js +32 -18
  4. package/lib/commonjs/network/components/NetworkHeaderLive.js +199 -0
  5. package/lib/commonjs/network/components/NetworkListScreen.js +203 -0
  6. package/lib/commonjs/network/components/NetworkModal.js +153 -630
  7. package/lib/commonjs/network/hooks/useNetworkBadgeCounts.js +83 -0
  8. package/lib/commonjs/network/hooks/useNetworkEventList.js +93 -0
  9. package/lib/commonjs/network/hooks/useNetworkHasMatches.js +56 -0
  10. package/lib/commonjs/network/utils/filterNetworkEvents.js +96 -0
  11. package/lib/commonjs/network/utils/generateNetworkCopyText.js +139 -0
  12. package/lib/module/index.js +5 -0
  13. package/lib/module/network/components/NetworkEventItemCompact.js +32 -18
  14. package/lib/module/network/components/NetworkHeaderLive.js +193 -0
  15. package/lib/module/network/components/NetworkListScreen.js +199 -0
  16. package/lib/module/network/components/NetworkModal.js +157 -634
  17. package/lib/module/network/hooks/useNetworkBadgeCounts.js +79 -0
  18. package/lib/module/network/hooks/useNetworkEventList.js +89 -0
  19. package/lib/module/network/hooks/useNetworkHasMatches.js +52 -0
  20. package/lib/module/network/utils/filterNetworkEvents.js +92 -0
  21. package/lib/module/network/utils/generateNetworkCopyText.js +135 -0
  22. package/lib/typescript/index.d.ts +2 -0
  23. package/lib/typescript/index.d.ts.map +1 -1
  24. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts +0 -4
  25. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +1 -1
  26. package/lib/typescript/network/components/NetworkHeaderLive.d.ts +52 -0
  27. package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +1 -0
  28. package/lib/typescript/network/components/NetworkListScreen.d.ts +27 -0
  29. package/lib/typescript/network/components/NetworkListScreen.d.ts.map +1 -0
  30. package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -1
  31. package/lib/typescript/network/hooks/useNetworkBadgeCounts.d.ts +24 -0
  32. package/lib/typescript/network/hooks/useNetworkBadgeCounts.d.ts.map +1 -0
  33. package/lib/typescript/network/hooks/useNetworkEventList.d.ts +34 -0
  34. package/lib/typescript/network/hooks/useNetworkEventList.d.ts.map +1 -0
  35. package/lib/typescript/network/hooks/useNetworkHasMatches.d.ts +23 -0
  36. package/lib/typescript/network/hooks/useNetworkHasMatches.d.ts.map +1 -0
  37. package/lib/typescript/network/utils/filterNetworkEvents.d.ts +13 -0
  38. package/lib/typescript/network/utils/filterNetworkEvents.d.ts.map +1 -0
  39. package/lib/typescript/network/utils/generateNetworkCopyText.d.ts +11 -0
  40. package/lib/typescript/network/utils/generateNetworkCopyText.d.ts.map +1 -0
  41. package/package.json +3 -3
package/README.md CHANGED
@@ -1,381 +1,57 @@
1
- # @buoy/network
1
+ # @buoy-gg/network
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@buoy%2Fnetwork)](https://www.npmjs.com/package/@buoy/network)
3
+ [![npm version](https://img.shields.io/npm/v/@buoy-gg/network?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/network) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/network?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/network)
4
4
 
5
- Network request monitoring and inspection tool for React Native development.
5
+ **See every HTTP request your React Native app makes — URL, headers, payloads, timing, and errors — live on the device, no Flipper or proxy required.**
6
6
 
7
- ## Features
7
+ Part of [Buoy](https://github.com/Buoy-gg/buoy) — devtools that live inside your React Native app. Install it and it auto-appears in the floating menu from [`@buoy-gg/core`](https://www.npmjs.com/package/@buoy-gg/core).
8
8
 
9
- - **Live Network Monitoring**: Track all fetch and XMLHttpRequest calls in real-time
10
- - **Request/Response Inspection**: View detailed information about headers, payloads, and responses
11
- - **Filtering**: Filter requests by status code, HTTP method, or URL pattern
12
- - **Timing Information**: See request duration and timing details
13
- - **Search**: Search through captured network events
14
- - **Pause/Resume**: Control when to capture network events
15
- - **Clear History**: Clear captured events when needed
16
- - **Beautiful UI**: Modern, game-themed interface matching other React Buoy tools
9
+ ![Network Monitor demo](https://github.com/user-attachments/assets/473ddf83-03cd-4bd1-8dc3-0f66eda9fa8a)
17
10
 
18
- ## Installation
19
-
20
- This package is part of the React Buoy monorepo and is automatically available to other packages and the example app.
21
-
22
- For external projects:
11
+ ## Install
23
12
 
24
13
  ```bash
25
- npm install @buoy/network
26
- # or
27
- pnpm add @buoy/network
28
- # or
29
- yarn add @buoy/network
30
- ```
31
-
32
- ## Quick Start
33
-
34
- ### Simplest Setup - Just 1 Line!
35
-
36
- **Import the preset and add it to your tools array. Done!**
37
-
38
- ```typescript
39
- import { networkToolPreset } from '@buoy/network';
40
- import { FloatingDevTools } from '@buoy/core';
41
-
42
- const installedApps = [
43
- networkToolPreset, // That's it! One line.
44
- // ...your other tools
45
- ];
46
-
47
- function App() {
48
- return (
49
- <FloatingDevTools
50
- apps={installedApps}
51
- environment="local"
52
- userRole="admin"
53
- />
54
- );
55
- }
56
- ```
57
-
58
- **Done!** The preset automatically:
59
- - ✅ Monitors all network requests
60
- - ✅ Intercepts fetch and XMLHttpRequest
61
- - ✅ Provides filtering and search
62
- - ✅ No configuration required
63
-
64
- ### Custom Configuration
65
-
66
- If you want to customize the appearance or behavior:
67
-
68
- ```typescript
69
- import { createNetworkTool } from '@buoy/network';
70
-
71
- const myNetworkTool = createNetworkTool({
72
- name: "REQUESTS",
73
- colorPreset: "purple",
74
- enableSharedModalDimensions: true,
75
- });
76
-
77
- const installedApps = [
78
- myNetworkTool,
79
- // ...other tools
80
- ];
14
+ npm install @buoy-gg/core @buoy-gg/network
81
15
  ```
82
16
 
83
- ### Alternative: Manual Setup
84
-
85
- If you're not using FloatingDevTools or want more control:
17
+ ## Quick start
86
18
 
87
- ```typescript
88
- import { NetworkModal } from '@buoy/network';
19
+ Fully automatic. Render the floating menu once — the Network Monitor is auto-discovered as soon as this package is installed:
89
20
 
90
- function App() {
91
- const [showNetwork, setShowNetwork] = useState(false);
21
+ ```tsx
22
+ import { FloatingDevTools } from "@buoy-gg/core";
92
23
 
24
+ export default function App() {
93
25
  return (
94
26
  <>
95
- <Button onPress={() => setShowNetwork(true)}>
96
- Open Network Monitor
97
- </Button>
98
-
99
- <NetworkModal
100
- visible={showNetwork}
101
- onClose={() => setShowNetwork(false)}
102
- />
27
+ {/* your app */}
28
+ <FloatingDevTools />
103
29
  </>
104
30
  );
105
31
  }
106
32
  ```
107
33
 
108
- ## API Reference
109
-
110
- ### Presets
111
-
112
- #### `networkToolPreset`
113
-
114
- Pre-configured network monitoring tool ready to use with FloatingDevTools.
115
-
116
- **Example:**
117
- ```typescript
118
- import { networkToolPreset } from '@buoy/network';
119
-
120
- const installedApps = [networkToolPreset];
121
- ```
122
-
123
- #### `createNetworkTool(options?)`
124
-
125
- Create a custom network monitoring tool configuration.
126
-
127
- **Options:**
128
- ```typescript
129
- {
130
- /** Tool name (default: "NET") */
131
- name?: string;
132
- /** Tool description */
133
- description?: string;
134
- /** Icon color preset (default: "cyan") */
135
- colorPreset?: "orange" | "cyan" | "purple" | "pink" | "yellow" | "green";
136
- /** Custom tool ID (default: "network") */
137
- id?: string;
138
- /** Enable shared modal dimensions */
139
- enableSharedModalDimensions?: boolean;
140
- }
141
- ```
142
-
143
- **Example:**
144
- ```typescript
145
- import { createNetworkTool } from '@buoy/network';
146
-
147
- const myNetworkTool = createNetworkTool({
148
- name: "API CALLS",
149
- colorPreset: "green",
150
- enableSharedModalDimensions: true,
151
- });
152
- ```
153
-
154
- ### Components
155
-
156
- #### `NetworkModal`
157
-
158
- Main modal component for monitoring network requests.
159
-
160
- **Props:**
161
- ```typescript
162
- interface NetworkModalProps {
163
- /** Whether the modal is visible */
164
- visible: boolean;
165
- /** Callback when modal is closed */
166
- onClose: () => void;
167
- /** Optional back button handler */
168
- onBack?: () => void;
169
- /** Whether to use shared modal dimensions */
170
- enableSharedModalDimensions?: boolean;
171
- }
172
- ```
173
-
174
- **Example:**
175
- ```typescript
176
- <NetworkModal
177
- visible={isVisible}
178
- onClose={handleClose}
179
- enableSharedModalDimensions={true}
180
- />
181
- ```
34
+ Want a different label or color? Build the tool with `createNetworkTool({ name, colorPreset })` and pass it via `apps={[...]}`.
182
35
 
183
- ### Hooks
36
+ ## What you get
184
37
 
185
- #### `useNetworkEvents()`
38
+ - **Every request, zero config** — intercepts `fetch` and `XMLHttpRequest`, so fetch, axios, GraphQL clients, and gRPC-web all show up automatically.
39
+ - **GraphQL gets special treatment** — operation names are extracted from queries, mutations, and subscriptions and shown with variables in arrow notation: `GetUser › 123`. No more guessing which `/graphql` request is which.
40
+ - **Full request detail** — request/response headers, payloads, HTTP status, and duration for every call, with status-colored rows.
41
+ - **Filter and search** — narrow by status code, HTTP method, or URL pattern; search captured events; pause/resume capture; clear history.
42
+ - **Ignore the noise** — a shared ignored-domains/URL filter (`useIgnoredPatterns`) hides endpoints you never want to see, shared with the Events tool.
43
+ - **Hooks for custom UIs** — `useNetworkEvents`, `useNetworkEventList`, and `useNetworkBadgeCounts` expose the capture stream with narrow per-consumer subscriptions.
186
44
 
187
- Access the list of captured network events and control functions.
188
-
189
- **Returns:**
190
- ```typescript
191
- {
192
- /** Array of captured network events */
193
- events: NetworkEvent[];
194
- /** Whether interception is enabled */
195
- isEnabled: boolean;
196
- /** Enable network interception */
197
- enable: () => void;
198
- /** Disable network interception */
199
- disable: () => void;
200
- /** Clear all captured events */
201
- clear: () => void;
202
- }
203
- ```
204
-
205
- **Example:**
206
- ```typescript
207
- import { useNetworkEvents } from '@buoy/network';
208
-
209
- function MyComponent() {
210
- const { events, isEnabled, enable, disable, clear } = useNetworkEvents();
211
-
212
- return (
213
- <View>
214
- <Text>Captured {events.length} requests</Text>
215
- <Button onPress={isEnabled ? disable : enable}>
216
- {isEnabled ? 'Pause' : 'Resume'}
217
- </Button>
218
- <Button onPress={clear}>Clear</Button>
219
- </View>
220
- );
221
- }
222
- ```
223
-
224
- ### Types
225
-
226
- #### `NetworkEvent`
227
-
228
- ```typescript
229
- interface NetworkEvent {
230
- /** Unique event ID */
231
- id: string;
232
- /** Request URL */
233
- url: string;
234
- /** HTTP method */
235
- method: string;
236
- /** HTTP status code */
237
- status?: number;
238
- /** Request headers */
239
- requestHeaders?: Record<string, string>;
240
- /** Response headers */
241
- responseHeaders?: Record<string, string>;
242
- /** Request body */
243
- requestBody?: any;
244
- /** Response body */
245
- responseBody?: any;
246
- /** Request start timestamp */
247
- startTime: number;
248
- /** Request end timestamp */
249
- endTime?: number;
250
- /** Request duration in ms */
251
- duration?: number;
252
- /** Error message if request failed */
253
- error?: string;
254
- }
255
- ```
256
-
257
- ## Use Cases
258
-
259
- ### API Debugging
260
-
261
- Monitor all API calls to your backend:
262
-
263
- ```typescript
264
- import { networkToolPreset } from '@buoy/network';
265
-
266
- // Add to your dev tools
267
- const installedApps = [networkToolPreset];
268
-
269
- // Now you can:
270
- // - See all API requests in real-time
271
- // - Inspect request/response payloads
272
- // - Check response times
273
- // - Debug failed requests
274
- ```
275
-
276
- ### Performance Monitoring
277
-
278
- Track slow network requests:
279
-
280
- ```typescript
281
- import { useNetworkEvents } from '@buoy/network';
282
-
283
- function PerformanceMonitor() {
284
- const { events } = useNetworkEvents();
285
-
286
- const slowRequests = events.filter(e => e.duration && e.duration > 1000);
287
-
288
- return (
289
- <View>
290
- <Text>Slow Requests: {slowRequests.length}</Text>
291
- {slowRequests.map(req => (
292
- <Text key={req.id}>
293
- {req.url} took {req.duration}ms
294
- </Text>
295
- ))}
296
- </View>
297
- );
298
- }
299
- ```
300
-
301
- ### Request Filtering
302
-
303
- Filter requests by specific criteria:
304
-
305
- ```typescript
306
- // In the Network Modal UI:
307
- // - Filter by status code (200, 404, 500, etc.)
308
- // - Filter by HTTP method (GET, POST, PUT, DELETE)
309
- // - Search by URL pattern
310
- // - Filter by success/error state
311
- ```
312
-
313
- ## Features in Detail
314
-
315
- ### Network Interception
316
-
317
- The package automatically intercepts:
318
- - `fetch()` calls
319
- - `XMLHttpRequest` calls
320
- - All HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
321
-
322
- ### Request Details
323
-
324
- For each request, you can view:
325
- - Full URL and query parameters
326
- - HTTP method and status code
327
- - Request and response headers
328
- - Request and response bodies
329
- - Timing information (duration, timestamps)
330
- - Error details if the request failed
331
-
332
- ### Filtering & Search
333
-
334
- - **By Status**: Filter by HTTP status codes
335
- - **By Method**: Filter by HTTP method
336
- - **By URL**: Search through request URLs
337
- - **By State**: Filter successful, pending, or failed requests
338
-
339
- ### Performance Tracking
340
-
341
- - View request duration
342
- - Identify slow requests
343
- - Monitor request timing
344
- - Track request count
345
-
346
- ## Dependencies
347
-
348
- - `@buoy/shared-ui` - Common UI components and utilities
349
- - React and React Native (peer dependencies)
350
-
351
- ## Development
352
-
353
- ### Building
354
-
355
- ```bash
356
- pnpm build
357
- ```
358
-
359
- ### Type Checking
360
-
361
- ```bash
362
- pnpm typecheck
363
- ```
364
-
365
- ### Clean Build
366
-
367
- ```bash
368
- pnpm clean
369
- ```
45
+ ## Desktop & AI
370
46
 
371
- ## License
47
+ The same live session streams to [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) (free, macOS/Windows/Linux) and to Claude Code or Cursor via the [Buoy MCP server](https://buoy.gg/buoy/latest/docs/mcp).
372
48
 
373
- MIT
49
+ ## Free vs Pro
374
50
 
375
- ## Contributing
51
+ Every tool is free. [Pro](https://buoy.gg/pricing) unlocks production builds, the MCP server, and unlimited capture. Every weekend, Pro features unlock free for everyone.
376
52
 
377
- See the main repository [CONTRIBUTING.md](../../CONTRIBUTING.md) for contribution guidelines.
53
+ ---
378
54
 
379
- ## Support
55
+ 📚 [Full docs](https://buoy.gg/buoy/latest/docs/tools/network) · [All Buoy tools](https://github.com/Buoy-gg/buoy)
380
56
 
381
- For issues and feature requests, please visit the [GitHub repository](https://github.com/LovesWorking/react-native-buoy/issues).
57
+ Proprietary software. © Buoy LLC. [Terms](https://buoy.gg/terms)
@@ -117,6 +117,18 @@ Object.defineProperty(exports, "useIgnoredPatterns", {
117
117
  return _sharedUi.useIgnoredPatterns;
118
118
  }
119
119
  });
120
+ Object.defineProperty(exports, "useNetworkBadgeCounts", {
121
+ enumerable: true,
122
+ get: function () {
123
+ return _useNetworkBadgeCounts.useNetworkBadgeCounts;
124
+ }
125
+ });
126
+ Object.defineProperty(exports, "useNetworkEventList", {
127
+ enumerable: true,
128
+ get: function () {
129
+ return _useNetworkEventList.useNetworkEventList;
130
+ }
131
+ });
120
132
  Object.defineProperty(exports, "useNetworkEvents", {
121
133
  enumerable: true,
122
134
  get: function () {
@@ -134,6 +146,8 @@ var _NetworkModal = require("./network/components/NetworkModal");
134
146
  var _NetworkEventDetailView = require("./network/components/NetworkEventDetailView");
135
147
  var _NetworkEventItemCompact = require("./network/components/NetworkEventItemCompact");
136
148
  var _useNetworkEvents = require("./network/hooks/useNetworkEvents");
149
+ var _useNetworkEventList = require("./network/hooks/useNetworkEventList");
150
+ var _useNetworkBadgeCounts = require("./network/hooks/useNetworkBadgeCounts");
137
151
  var _useTickEveryMinute = require("./network/hooks/useTickEveryMinute");
138
152
  var _formatting = require("./network/utils/formatting");
139
153
  var _sharedUi = require("@buoy-gg/shared-ui");
@@ -112,11 +112,33 @@ function SizeIndicators({
112
112
  * Compact list-row representation of a network event. Optimized for large lists with memoization
113
113
  * and periodic refresh via `useTickEveryMinute` to keep relative timestamps accurate.
114
114
  */
115
- const NetworkEventItemCompact = exports.NetworkEventItemCompact = /*#__PURE__*/(0, _react.memo)(({
115
+ /**
116
+ * Sole tick-context consumer in the row (rule2: composition over memo) —
117
+ * the periodic relative-timestamp tick re-renders ONLY this Text, not the
118
+ * whole card. Profiling (tool-bench 2026-07-06): the tick accounted for
119
+ * ~30 of 65 row renders (plus their SVG-icon churn) in a 12s recording.
120
+ */
121
+ function BottomRightTime({
122
+ timestamp,
123
+ duration
124
+ }) {
125
+ const tick = (0, _useTickEveryMinute.useTickEveryMinute)();
126
+ const relativeTime = (0, _sharedUi.formatRelativeTime)(timestamp, tick);
127
+ return duration ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
128
+ style: styles.bottomRightText,
129
+ children: [(0, _formatting.formatDuration)(duration), " ", relativeTime]
130
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
131
+ style: styles.bottomRightText,
132
+ children: relativeTime
133
+ });
134
+ }
135
+ const NetworkEventItemCompact = exports.NetworkEventItemCompact = /*#__PURE__*/(0, _react.memo)(
136
+ // Named function (not an arrow) so render-capture reports attribute row
137
+ // renders to this component instead of a compiled anonymous name.
138
+ function NetworkEventItemCompact({
116
139
  event,
117
140
  onPress
118
- }) => {
119
- const tick = (0, _useTickEveryMinute.useTickEveryMinute)();
141
+ }) {
120
142
  const statusColor = getStatusColor(event.status, event.error);
121
143
  const isPending = !event.status && !event.error;
122
144
  const contentType = getContentTypeBadge(event.responseHeaders);
@@ -138,15 +160,6 @@ const NetworkEventItemCompact = exports.NetworkEventItemCompact = /*#__PURE__*/(
138
160
  // For non-GraphQL requests with operation names (e.g., gRPC)
139
161
  displayUrl = `${displayUrl}\n(${event.operationName})`;
140
162
  }
141
-
142
- // Format time with both absolute and relative
143
- const timeString = new Date(event.timestamp).toLocaleTimeString("en-US", {
144
- hour: "numeric",
145
- minute: "2-digit",
146
- second: "2-digit",
147
- hour12: true
148
- });
149
- const relativeTime = (0, _sharedUi.formatRelativeTime)(event.timestamp, tick);
150
163
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.DevToolsCard, {
151
164
  onPress: () => onPress(event),
152
165
  style: styles.cardWrapper,
@@ -197,16 +210,17 @@ const NetworkEventItemCompact = exports.NetworkEventItemCompact = /*#__PURE__*/(
197
210
  })]
198
211
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
199
212
  style: styles.bottomRightContainer,
200
- children: event.duration ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
201
- style: styles.bottomRightText,
202
- children: [(0, _formatting.formatDuration)(event.duration), " ", relativeTime]
203
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
204
- style: styles.bottomRightText,
205
- children: relativeTime
213
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(BottomRightTime, {
214
+ timestamp: event.timestamp,
215
+ duration: event.duration
206
216
  })
207
217
  })]
208
218
  });
209
219
  });
220
+
221
+ // Without this, render-capture reports attribute row renders to the
222
+ // anonymous memo wrapper ("Memo"/"_c4") instead of the row.
223
+ NetworkEventItemCompact.displayName = "NetworkEventItemCompact";
210
224
  const styles = _reactNative.StyleSheet.create({
211
225
  cardWrapper: {
212
226
  marginHorizontal: 8