@buoy-gg/network 2.1.2 → 2.1.4-beta.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.
@@ -2,12 +2,13 @@
2
2
 
3
3
  /**
4
4
  * Hook for accessing network events and controls
5
- * Uses Reactotron-style listener pattern
5
+ *
6
+ * Uses self-managing Subscribable pattern - the network listener automatically
7
+ * starts when this hook mounts and stops when all subscribers unmount.
6
8
  */
7
9
 
8
- import { useState, useEffect, useCallback, useMemo } from "react";
10
+ import { useState, useEffect, useCallback, useMemo, useRef } from "react";
9
11
  import { networkEventStore } from "../utils/networkEventStore";
10
- import { networkListener, startNetworkListener, stopNetworkListener, addNetworkListener } from "../utils/networkListener";
11
12
  import { searchGraphQLVariables } from "../utils/formatGraphQLVariables";
12
13
 
13
14
  /** Free tier limit for network requests */
@@ -15,13 +16,15 @@ export const FREE_TIER_REQUEST_LIMIT = 25;
15
16
 
16
17
  /**
17
18
  * Custom hook for accessing network events and controls
18
- *
19
+ *
19
20
  * This hook provides a complete interface for network monitoring, including
20
- * event filtering, statistics calculation, and interception control. It uses
21
- * the Reactotron-style listener pattern for network event handling.
22
- *
21
+ * event filtering, statistics calculation, and interception control.
22
+ *
23
+ * The network listener automatically starts when this hook mounts and stops
24
+ * when all components using it unmount (Subscribable pattern from TanStack Query).
25
+ *
23
26
  * @returns Object containing filtered events, statistics, controls, and utilities
24
- *
27
+ *
25
28
  * @example
26
29
  * ```typescript
27
30
  * function NetworkMonitor() {
@@ -31,22 +34,19 @@ export const FREE_TIER_REQUEST_LIMIT = 25;
31
34
  * filter,
32
35
  * setFilter,
33
36
  * clearEvents,
34
- * toggleInterception,
35
- * isEnabled
37
+ * isCapturing
36
38
  * } = useNetworkEvents();
37
- *
39
+ *
38
40
  * return (
39
41
  * <div>
40
42
  * <p>Total requests: {stats.totalRequests}</p>
41
43
  * <p>Success rate: {stats.successfulRequests}/{stats.totalRequests}</p>
42
- * <button onClick={toggleInterception}>
43
- * {isEnabled ? 'Stop' : 'Start'} Monitoring
44
- * </button>
44
+ * <p>Capturing: {isCapturing ? 'Yes' : 'No'}</p>
45
45
  * </div>
46
46
  * );
47
47
  * }
48
48
  * ```
49
- *
49
+ *
50
50
  * @performance Uses memoization for expensive filtering and statistics calculations
51
51
  * @performance Optimizes string operations and array processing for large datasets
52
52
  * @performance Includes Set-based lookups for O(1) filter matching
@@ -59,54 +59,39 @@ export function useNetworkEvents(options = {}) {
59
59
  } = options;
60
60
  const [events, setEvents] = useState([]);
61
61
  const [filter, setFilter] = useState({});
62
- const [isEnabled, setIsEnabled] = useState(false);
62
+ const [isCapturing, setIsCapturing] = useState(true);
63
+ const unsubscribeRef = useRef(null);
63
64
 
64
- // Subscribe to event store changes
65
+ // Subscribe/unsubscribe to event store based on isCapturing state.
66
+ // Each subscriber is independent — pausing this hook's subscription
67
+ // does not affect other subscribers (e.g. the events tool).
65
68
  useEffect(() => {
66
- // Subscribe to store changes
67
- const unsubscribeStore = networkEventStore.subscribe(setEvents);
68
-
69
- // Add listener to network events
70
- const unsubscribeListener = addNetworkListener(event => {
71
- // Only log in development and for non-ignored URLs
72
- if (__DEV__ && !event.request.url.includes("symbolicate") && !event.request.url.includes(":8081")) {
73
- // Network event processed: [event.type] [method] [url] - available for debugging if needed
74
- }
75
- networkEventStore.processNetworkEvent(event);
76
- });
77
-
78
- // Check if already listening
79
- setIsEnabled(networkListener().isActive);
80
-
81
- // Start listening if not already
82
- if (!networkListener().isActive) {
83
- startNetworkListener();
84
- setIsEnabled(true);
69
+ if (isCapturing) {
70
+ unsubscribeRef.current = networkEventStore.subscribeToEvents(setEvents);
85
71
  }
86
-
87
- // Load initial events
88
- setEvents(networkEventStore.getEvents());
89
72
  return () => {
90
- unsubscribeStore();
91
- unsubscribeListener();
73
+ if (unsubscribeRef.current) {
74
+ unsubscribeRef.current();
75
+ unsubscribeRef.current = null;
76
+ }
92
77
  };
93
- }, []);
78
+ }, [isCapturing]);
94
79
 
95
- // Clear all events
80
+ // Clear all events (also update local state in case we're paused/unsubscribed)
96
81
  const clearEvents = useCallback(() => {
97
82
  networkEventStore.clearEvents();
83
+ setEvents([]);
98
84
  }, []);
99
85
 
100
- // Toggle interception
101
- const toggleInterception = useCallback(() => {
102
- if (isEnabled) {
103
- stopNetworkListener();
104
- setIsEnabled(false);
105
- } else {
106
- startNetworkListener();
107
- setIsEnabled(true);
108
- }
109
- }, [isEnabled]);
86
+ // Pause: unsubscribe this hook from the store (other subscribers unaffected)
87
+ const pauseCapturing = useCallback(() => {
88
+ setIsCapturing(false);
89
+ }, []);
90
+
91
+ // Resume: resubscribe this hook to the store
92
+ const resumeCapturing = useCallback(() => {
93
+ setIsCapturing(true);
94
+ }, []);
110
95
 
111
96
  // Memoize search text processing to avoid repeated toLowerCase calls
112
97
  // Performance: Expensive string operations repeated for every event on every filter
@@ -300,8 +285,12 @@ export function useNetworkEvents(options = {}) {
300
285
  filter,
301
286
  setFilter,
302
287
  clearEvents,
303
- isEnabled,
304
- toggleInterception,
288
+ /** Whether this hook is subscribed and receiving network events */
289
+ isCapturing,
290
+ /** Unsubscribe this hook from the network store (other subscribers unaffected) */
291
+ pauseCapturing,
292
+ /** Resubscribe this hook to the network store */
293
+ resumeCapturing,
305
294
  hosts,
306
295
  methods,
307
296
  /** Whether there are locked events due to free tier limit */
@@ -311,6 +300,8 @@ export function useNetworkEvents(options = {}) {
311
300
  /** Check if a specific event is locked (by ID) */
312
301
  isEventLocked,
313
302
  /** Free tier request limit */
314
- requestLimit: FREE_TIER_REQUEST_LIMIT
303
+ requestLimit: FREE_TIER_REQUEST_LIMIT,
304
+ /** Get subscriber counts for debugging */
305
+ getSubscriberCounts: () => networkEventStore.getSubscriberCounts()
315
306
  };
316
307
  }
@@ -1,17 +1,91 @@
1
1
  "use strict";
2
2
 
3
3
  /**
4
- * Network event store for managing captured network requests
5
- * Works with the Reactotron-style network listener
4
+ * Network Event Store
5
+ *
6
+ * Store for managing captured network requests. Uses BaseEventStore pattern -
7
+ * the network listener automatically starts when the first subscriber joins
8
+ * and stops when the last subscriber leaves.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { networkEventStore } from '@buoy-gg/network';
13
+ *
14
+ * // Subscribe to network events - automatically starts capturing!
15
+ * const unsubscribe = networkEventStore.subscribeToEvents((events) => {
16
+ * console.log('Network events:', events);
17
+ * });
18
+ *
19
+ * // Later, clean up - automatically stops if no other subscribers
20
+ * unsubscribe();
21
+ * ```
6
22
  */
7
23
 
24
+ import { BaseEventStore } from "@buoy-gg/shared-ui";
8
25
  import { extractOperationName } from "./extractOperationName";
9
- class NetworkEventStore {
10
- events = [];
26
+ import { networkListener, addNetworkListener } from "./networkListener";
27
+
28
+ /**
29
+ * Callback type for individual event notifications
30
+ */
31
+
32
+ /**
33
+ * Callback type for full events array notifications
34
+ */
35
+
36
+ class NetworkEventStore extends BaseEventStore {
11
37
  pendingRequests = new Map();
12
- listeners = new Set();
13
- maxEvents = 500; // Configurable max events to prevent memory issues
14
- recentRequests = new Map(); // Track recent requests to detect duplicates
38
+ recentRequests = new Map();
39
+ rawListenerUnsubscribe = null;
40
+ constructor() {
41
+ super({
42
+ storeName: "network",
43
+ maxEvents: 500
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Start capturing network events
49
+ */
50
+ startCapturing() {
51
+ const listener = networkListener();
52
+
53
+ // Start the network interceptor if not already active
54
+ if (!listener.isActive) {
55
+ listener.startListening();
56
+ }
57
+
58
+ // Add our listener to push raw events into the store
59
+ if (!this.rawListenerUnsubscribe) {
60
+ this.rawListenerUnsubscribe = addNetworkListener(event => {
61
+ this.processNetworkEvent(event);
62
+ });
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Stop capturing network events
68
+ */
69
+ stopCapturing() {
70
+ // Remove our raw listener
71
+ if (this.rawListenerUnsubscribe) {
72
+ this.rawListenerUnsubscribe();
73
+ this.rawListenerUnsubscribe = null;
74
+ }
75
+
76
+ // If no other listeners exist, stop the network interceptor
77
+ const listener = networkListener();
78
+ if (listener.listenerCount === 0) {
79
+ listener.stopListening();
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Check if the store is actively capturing network events
85
+ */
86
+ isCapturing() {
87
+ return this.rawListenerUnsubscribe !== null;
88
+ }
15
89
 
16
90
  /**
17
91
  * Process a network listener event
@@ -28,13 +102,13 @@ class NetworkEventStore {
28
102
 
29
103
  // If same request within 50ms, likely a duplicate from XHR/fetch dual interception
30
104
  if (lastRequestTime && now - lastRequestTime < 50) {
31
- return; // Skip duplicate
105
+ return;
32
106
  }
33
107
  this.recentRequests.set(requestKey, now);
34
108
 
35
109
  // Clean up old entries to prevent memory leak
36
110
  if (this.recentRequests.size > 100) {
37
- const cutoff = now - 5000; // Remove entries older than 5 seconds
111
+ const cutoff = now - 5000;
38
112
  for (const [key, time] of this.recentRequests.entries()) {
39
113
  if (time < cutoff) {
40
114
  this.recentRequests.delete(key);
@@ -42,7 +116,6 @@ class NetworkEventStore {
42
116
  }
43
117
  }
44
118
 
45
- // Create new network event for request
46
119
  // Build full URL with query params if present
47
120
  const queryString = request.params ? `?${new URLSearchParams(request.params).toString()}` : "";
48
121
  const fullUrl = `${request.url}${queryString}`;
@@ -50,12 +123,10 @@ class NetworkEventStore {
50
123
  // Extract GraphQL operation name and variables for searchability
51
124
  let operationName;
52
125
  let graphqlVariables;
53
- if (request.client === 'graphql') {
126
+ if (request.client === "graphql") {
54
127
  const extracted = extractOperationName(request.data);
55
128
  operationName = extracted || undefined;
56
-
57
- // Extract variables from GraphQL request
58
- if (request.data && typeof request.data === 'object' && 'variables' in request.data && request.data.variables && typeof request.data.variables === 'object') {
129
+ if (request.data && typeof request.data === "object" && "variables" in request.data && request.data.variables && typeof request.data.variables === "object") {
59
130
  graphqlVariables = request.data.variables;
60
131
  }
61
132
  }
@@ -63,7 +134,6 @@ class NetworkEventStore {
63
134
  id: request.id,
64
135
  method: request.method,
65
136
  url: fullUrl,
66
- // Store FULL URL with query params
67
137
  host: this.extractHost(request.url),
68
138
  path: this.extractPath(request.url),
69
139
  query: queryString,
@@ -74,18 +144,13 @@ class NetworkEventStore {
74
144
  responseHeaders: {},
75
145
  requestClient: request.client,
76
146
  operationName,
77
- // GraphQL operation name for search/filter
78
- graphqlVariables // GraphQL variables for display and search
147
+ graphqlVariables
79
148
  };
80
-
81
- // Store as pending
82
149
  this.pendingRequests.set(request.id, networkEvent);
83
-
84
- // Add to events list
85
150
  this.events = [networkEvent, ...this.events].slice(0, this.maxEvents);
86
- this.notifyListeners();
151
+ this.notify(networkEvent);
152
+ this.notifyArrayListeners();
87
153
  } else if (event.type === "response" || event.type === "error") {
88
- // Find and update the pending request
89
154
  const index = this.events.findIndex(e => e.id === request.id);
90
155
  if (index !== -1) {
91
156
  const updatedEvent = {
@@ -104,16 +169,13 @@ class NetworkEventStore {
104
169
  updatedEvent.error = event.error.message;
105
170
  updatedEvent.status = updatedEvent.status || 0;
106
171
  }
107
- this.events[index] = updatedEvent;
172
+ this.events = this.events.map((e, i) => i === index ? updatedEvent : e);
108
173
  this.pendingRequests.delete(request.id);
109
- this.notifyListeners();
174
+ this.notify(updatedEvent);
175
+ this.notifyArrayListeners();
110
176
  }
111
177
  }
112
178
  }
113
-
114
- /**
115
- * Extract host from URL
116
- */
117
179
  extractHost(url) {
118
180
  try {
119
181
  const urlObj = new URL(url);
@@ -123,10 +185,6 @@ class NetworkEventStore {
123
185
  return "";
124
186
  }
125
187
  }
126
-
127
- /**
128
- * Extract path from URL
129
- */
130
188
  extractPath(url) {
131
189
  try {
132
190
  const urlObj = new URL(url);
@@ -136,10 +194,6 @@ class NetworkEventStore {
136
194
  return url;
137
195
  }
138
196
  }
139
-
140
- /**
141
- * Get size of data
142
- */
143
197
  getDataSize(data) {
144
198
  if (!data) return 0;
145
199
  if (typeof data === "string") return data.length;
@@ -149,63 +203,38 @@ class NetworkEventStore {
149
203
  return 0;
150
204
  }
151
205
  }
152
-
153
- /**
154
- * Get all events
155
- */
156
- getEvents() {
157
- return [...this.events];
158
- }
159
-
160
- /**
161
- * Get event by ID
162
- */
163
206
  getEventById(id) {
164
207
  return this.events.find(e => e.id === id);
165
208
  }
166
209
 
167
210
  /**
168
- * Clear all events
211
+ * Override clearEvents to also clear pending requests
169
212
  */
170
213
  clearEvents() {
171
- this.events = [];
214
+ super.clearEvents();
172
215
  this.pendingRequests.clear();
173
216
  this.recentRequests.clear();
174
- this.notifyListeners();
175
217
  }
176
218
 
177
219
  /**
178
- * Subscribe to event changes
220
+ * Subscribe to individual events with optional replay of existing events
179
221
  */
180
- subscribe(listener) {
181
- this.listeners.add(listener);
182
- return () => {
183
- this.listeners.delete(listener);
184
- };
185
- }
186
-
187
- /**
188
- * Notify all listeners of changes
189
- */
190
- notifyListeners() {
191
- const events = this.getEvents();
192
- this.listeners.forEach(listener => listener(events));
193
- }
222
+ onEvent(callback, replayExisting = true) {
223
+ const unsubscribe = this.subscribe(callback);
194
224
 
195
- /**
196
- * Set maximum number of events to store
197
- */
198
- setMaxEvents(max) {
199
- this.maxEvents = max;
200
- if (this.events.length > max) {
201
- this.events = this.events.slice(0, max);
202
- this.notifyListeners();
225
+ // Replay existing events if requested
226
+ if (replayExisting && this.events.length > 0) {
227
+ const existingEvents = [...this.events].reverse();
228
+ for (const event of existingEvents) {
229
+ try {
230
+ callback(event);
231
+ } catch {
232
+ // Ignore callback errors
233
+ }
234
+ }
203
235
  }
236
+ return unsubscribe;
204
237
  }
205
-
206
- /**
207
- * Get statistics about network events
208
- */
209
238
  getStats() {
210
239
  const total = this.events.length;
211
240
  const successful = this.events.filter(e => e.status && e.status >= 200 && e.status < 300).length;
@@ -225,10 +254,6 @@ class NetworkEventStore {
225
254
  averageDuration: Math.round(avgDuration)
226
255
  };
227
256
  }
228
-
229
- /**
230
- * Filter events by criteria
231
- */
232
257
  filterEvents(filter) {
233
258
  let filtered = [...this.events];
234
259
  if (filter.method) {
@@ -259,7 +284,7 @@ class NetworkEventStore {
259
284
  }
260
285
 
261
286
  /**
262
- * Singleton store that aggregates captured network traffic. Components and hooks consume this
263
- * store to render histories, derive stats, and subscribe to real-time updates.
287
+ * Singleton store that aggregates captured network traffic.
288
+ * Automatically starts/stops capturing based on subscriber count.
264
289
  */
265
290
  export const networkEventStore = new NetworkEventStore();
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkModal.d.ts","sourceRoot":"","sources":["../../../../src/network/components/NetworkModal.tsx"],"names":[],"mappings":"AA4CA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AA2gCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BAMpD"}
1
+ {"version":3,"file":"NetworkModal.d.ts","sourceRoot":"","sources":["../../../../src/network/components/NetworkModal.tsx"],"names":[],"mappings":"AA4CA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AA0iCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BAMpD"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Hook for accessing network events and controls
3
- * Uses Reactotron-style listener pattern
3
+ *
4
+ * Uses self-managing Subscribable pattern - the network listener automatically
5
+ * starts when this hook mounts and stops when all subscribers unmount.
4
6
  */
5
7
  import type { NetworkEvent, NetworkStats, NetworkFilter } from "../types";
6
8
  /** Free tier limit for network requests */
@@ -9,8 +11,10 @@ export declare const FREE_TIER_REQUEST_LIMIT = 25;
9
11
  * Custom hook for accessing network events and controls
10
12
  *
11
13
  * This hook provides a complete interface for network monitoring, including
12
- * event filtering, statistics calculation, and interception control. It uses
13
- * the Reactotron-style listener pattern for network event handling.
14
+ * event filtering, statistics calculation, and interception control.
15
+ *
16
+ * The network listener automatically starts when this hook mounts and stops
17
+ * when all components using it unmount (Subscribable pattern from TanStack Query).
14
18
  *
15
19
  * @returns Object containing filtered events, statistics, controls, and utilities
16
20
  *
@@ -23,17 +27,14 @@ export declare const FREE_TIER_REQUEST_LIMIT = 25;
23
27
  * filter,
24
28
  * setFilter,
25
29
  * clearEvents,
26
- * toggleInterception,
27
- * isEnabled
30
+ * isCapturing
28
31
  * } = useNetworkEvents();
29
32
  *
30
33
  * return (
31
34
  * <div>
32
35
  * <p>Total requests: {stats.totalRequests}</p>
33
36
  * <p>Success rate: {stats.successfulRequests}/{stats.totalRequests}</p>
34
- * <button onClick={toggleInterception}>
35
- * {isEnabled ? 'Stop' : 'Start'} Monitoring
36
- * </button>
37
+ * <p>Capturing: {isCapturing ? 'Yes' : 'No'}</p>
37
38
  * </div>
38
39
  * );
39
40
  * }
@@ -56,8 +57,12 @@ export declare function useNetworkEvents(options?: {
56
57
  filter: NetworkFilter;
57
58
  setFilter: import("react").Dispatch<import("react").SetStateAction<NetworkFilter>>;
58
59
  clearEvents: () => void;
59
- isEnabled: boolean;
60
- toggleInterception: () => void;
60
+ /** Whether this hook is subscribed and receiving network events */
61
+ isCapturing: boolean;
62
+ /** Unsubscribe this hook from the network store (other subscribers unaffected) */
63
+ pauseCapturing: () => void;
64
+ /** Resubscribe this hook to the network store */
65
+ resumeCapturing: () => void;
61
66
  hosts: string[];
62
67
  methods: string[];
63
68
  /** Whether there are locked events due to free tier limit */
@@ -68,5 +73,11 @@ export declare function useNetworkEvents(options?: {
68
73
  isEventLocked: (eventId: string) => boolean;
69
74
  /** Free tier request limit */
70
75
  requestLimit: number;
76
+ /** Get subscriber counts for debugging */
77
+ getSubscriberCounts: () => {
78
+ eventCallbacks: number;
79
+ arrayListeners: number;
80
+ total: number;
81
+ };
71
82
  };
72
83
  //# sourceMappingURL=useNetworkEvents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useNetworkEvents.d.ts","sourceRoot":"","sources":["../../../../src/network/hooks/useNetworkEvents.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG1E,2CAA2C;AAC3C,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO;IAuR9D,yEAAyE;;IAEzE,8CAA8C;;;;;;;;;;IAU9C,6DAA6D;;IAE7D,qDAAqD;;IAErD,kDAAkD;6BAzFR,MAAM;IA2FhD,8BAA8B;;EAGjC"}
1
+ {"version":3,"file":"useNetworkEvents.d.ts","sourceRoot":"","sources":["../../../../src/network/hooks/useNetworkEvents.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG1E,2CAA2C;AAC3C,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO;IAqQ9D,yEAAyE;;IAEzE,8CAA8C;;;;;;IAM9C,mEAAmE;;IAEnE,kFAAkF;;IAElF,iDAAiD;;;;IAIjD,6DAA6D;;IAE7D,qDAAqD;;IAErD,kDAAkD;6BA7FR,MAAM;IA+FhD,8BAA8B;;IAE9B,0CAA0C;;;;;;EAG7C"}
@@ -7,7 +7,7 @@ export { NetworkEventItemCompact } from "./components/NetworkEventItemCompact";
7
7
  export { useNetworkEvents } from "./hooks/useNetworkEvents";
8
8
  export { TickProvider, useTickEveryMinute } from "./hooks/useTickEveryMinute";
9
9
  export { networkListener, startNetworkListener, stopNetworkListener, addNetworkListener, removeAllNetworkListeners, isNetworkListening, getNetworkListenerCount, } from "./utils/networkListener";
10
- export { networkEventStore } from "./utils/networkEventStore";
10
+ export { networkEventStore, type NetworkEventCallback } from "./utils/networkEventStore";
11
11
  export { formatBytes, formatDuration, formatHttpStatus, } from "./utils/formatting";
12
12
  export type { NetworkEvent, NetworkStats, NetworkFilter, NetworkEventStatus, NetworkInsight, } from "./types";
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAG9E,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAG/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAG9E,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,MAAM,SAAS,CAAC"}