@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.
- package/lib/commonjs/network/components/NetworkModal.js +42 -7
- package/lib/commonjs/network/hooks/useNetworkEvents.js +46 -55
- package/lib/commonjs/network/utils/networkEventStore.js +108 -84
- package/lib/module/network/components/NetworkModal.js +42 -7
- package/lib/module/network/hooks/useNetworkEvents.js +47 -56
- package/lib/module/network/utils/networkEventStore.js +109 -84
- package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -1
- package/lib/typescript/network/hooks/useNetworkEvents.d.ts +21 -10
- package/lib/typescript/network/hooks/useNetworkEvents.d.ts.map +1 -1
- package/lib/typescript/network/index.d.ts +1 -1
- package/lib/typescript/network/index.d.ts.map +1 -1
- package/lib/typescript/network/utils/networkEventStore.d.ts +45 -39
- package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Hook for accessing network events and controls
|
|
5
|
-
*
|
|
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.
|
|
21
|
-
*
|
|
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
|
-
*
|
|
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
|
-
* <
|
|
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 [
|
|
62
|
+
const [isCapturing, setIsCapturing] = useState(true);
|
|
63
|
+
const unsubscribeRef = useRef(null);
|
|
63
64
|
|
|
64
|
-
// Subscribe to event store
|
|
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
|
-
|
|
67
|
-
|
|
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
|
-
|
|
91
|
-
|
|
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
|
-
//
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
304
|
-
|
|
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
|
|
5
|
-
*
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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;
|
|
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;
|
|
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 ===
|
|
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
|
-
|
|
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.
|
|
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
|
|
172
|
+
this.events = this.events.map((e, i) => i === index ? updatedEvent : e);
|
|
108
173
|
this.pendingRequests.delete(request.id);
|
|
109
|
-
this.
|
|
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
|
-
*
|
|
211
|
+
* Override clearEvents to also clear pending requests
|
|
169
212
|
*/
|
|
170
213
|
clearEvents() {
|
|
171
|
-
|
|
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
|
|
220
|
+
* Subscribe to individual events with optional replay of existing events
|
|
179
221
|
*/
|
|
180
|
-
|
|
181
|
-
this.
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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.
|
|
263
|
-
*
|
|
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;
|
|
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
|
-
*
|
|
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.
|
|
13
|
-
*
|
|
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
|
-
*
|
|
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
|
-
* <
|
|
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
|
-
|
|
60
|
-
|
|
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
|
|
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;
|
|
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"}
|