@buoy-gg/events 2.1.1 → 2.1.3
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/components/EventsCopySettingsView.js +39 -8
- package/lib/commonjs/components/EventsModal.js +4 -7
- package/lib/commonjs/components/UnifiedEventDetail.js +32 -1
- package/lib/commonjs/components/UnifiedEventFilters.js +50 -21
- package/lib/commonjs/components/UnifiedEventItem.js +6 -1
- package/lib/commonjs/hooks/useUnifiedEvents.js +137 -28
- package/lib/commonjs/index.js +6 -0
- package/lib/commonjs/stores/unifiedEventStore.js +61 -16
- package/lib/commonjs/types/copySettings.js +29 -0
- package/lib/commonjs/utils/autoDiscoverEventSources.js +261 -39
- package/lib/commonjs/utils/badgeSelectionStorage.js +32 -0
- package/lib/commonjs/utils/eventExportFormatter.js +778 -1
- package/lib/module/components/EventsCopySettingsView.js +40 -9
- package/lib/module/components/EventsModal.js +5 -8
- package/lib/module/components/UnifiedEventDetail.js +32 -1
- package/lib/module/components/UnifiedEventFilters.js +50 -21
- package/lib/module/components/UnifiedEventItem.js +6 -1
- package/lib/module/hooks/useUnifiedEvents.js +140 -31
- package/lib/module/index.js +4 -1
- package/lib/module/stores/unifiedEventStore.js +58 -16
- package/lib/module/types/copySettings.js +29 -0
- package/lib/module/utils/autoDiscoverEventSources.js +260 -39
- package/lib/module/utils/badgeSelectionStorage.js +30 -0
- package/lib/module/utils/eventExportFormatter.js +777 -1
- package/lib/typescript/components/UnifiedEventFilters.d.ts +3 -0
- package/lib/typescript/hooks/useUnifiedEvents.d.ts +2 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/stores/unifiedEventStore.d.ts +18 -2
- package/lib/typescript/types/copySettings.d.ts +25 -1
- package/lib/typescript/types/index.d.ts +3 -1
- package/lib/typescript/utils/autoDiscoverEventSources.d.ts +17 -0
- package/lib/typescript/utils/badgeSelectionStorage.d.ts +9 -0
- package/lib/typescript/utils/eventExportFormatter.d.ts +4 -0
- package/package.json +3 -3
- package/src/components/EventsCopySettingsView.tsx +41 -5
- package/src/components/EventsModal.tsx +6 -17
- package/src/components/UnifiedEventDetail.tsx +28 -0
- package/src/components/UnifiedEventFilters.tsx +88 -21
- package/src/components/UnifiedEventItem.tsx +5 -0
- package/src/hooks/useUnifiedEvents.ts +153 -25
- package/src/index.tsx +4 -0
- package/src/stores/unifiedEventStore.ts +58 -12
- package/src/types/copySettings.ts +31 -1
- package/src/types/index.ts +4 -1
- package/src/utils/autoDiscoverEventSources.ts +268 -44
- package/src/utils/badgeSelectionStorage.ts +30 -0
- package/src/utils/eventExportFormatter.ts +797 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.unsubscribeFromStorage = exports.unsubscribeFromRoutes = exports.unsubscribeFromRedux = exports.unsubscribeFromReactQuery = exports.unsubscribeFromNetwork = exports.unsubscribeAll = exports.unifiedEventStore = exports.subscribeToStorage = exports.subscribeToRoutes = exports.subscribeToRedux = exports.subscribeToReactQuery = exports.subscribeToNetwork = exports.subscribeToAll = exports.subscribe = exports.isSourceSubscribed = exports.getSubscriptionStatus = exports.getSourceCounts = exports.getEvents = exports.getEventCount = exports.getDiscoveredSources = exports.getAvailableEventSources = exports.getActiveSources = exports.clearEvents = void 0;
|
|
6
|
+
exports.unsubscribeFromStorage = exports.unsubscribeFromRoutes = exports.unsubscribeFromRender = exports.unsubscribeFromRedux = exports.unsubscribeFromReactQuery = exports.unsubscribeFromNetwork = exports.unsubscribeAll = exports.unifiedEventStore = exports.subscribeToStorage = exports.subscribeToRoutes = exports.subscribeToRender = exports.subscribeToRedux = exports.subscribeToReactQuery = exports.subscribeToNetwork = exports.subscribeToAll = exports.subscribe = exports.isSourceSubscribed = exports.getSubscriptionStatus = exports.getSubscriberCounts = exports.getSourceCounts = exports.getEvents = exports.getEventCount = exports.getDiscoveredSources = exports.getAvailableEventSources = exports.getActiveSources = exports.clearEvents = void 0;
|
|
7
7
|
var _autoDiscoverEventSources = require("../utils/autoDiscoverEventSources");
|
|
8
8
|
/**
|
|
9
9
|
* Unified Event Store
|
|
@@ -59,18 +59,21 @@ class UnifiedEventStore {
|
|
|
59
59
|
if (this.sourceUnsubscribers.has(source.id)) {
|
|
60
60
|
return; // Already subscribed
|
|
61
61
|
}
|
|
62
|
+
try {
|
|
63
|
+
// Run setup if needed
|
|
64
|
+
if (source.setup) {
|
|
65
|
+
await source.setup();
|
|
66
|
+
}
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (unsubscribe) {
|
|
73
|
-
this.sourceUnsubscribers.set(source.id, unsubscribe);
|
|
68
|
+
// Subscribe and track the unsubscriber
|
|
69
|
+
const unsubscribe = await source.subscribe(event => {
|
|
70
|
+
this.addEvent(event);
|
|
71
|
+
});
|
|
72
|
+
if (unsubscribe) {
|
|
73
|
+
this.sourceUnsubscribers.set(source.id, unsubscribe);
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
// Silently fail - source may not be available
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
|
|
@@ -147,7 +150,8 @@ class UnifiedEventStore {
|
|
|
147
150
|
unsubscribeFromNetwork() {
|
|
148
151
|
this.unsubscribeFromSource("network");
|
|
149
152
|
this.activeSources.delete("network");
|
|
150
|
-
|
|
153
|
+
// Don't clear networkEventIdMap - it's needed to deduplicate events
|
|
154
|
+
// when resubscribing while requests are still in flight
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
/**
|
|
@@ -194,6 +198,27 @@ class UnifiedEventStore {
|
|
|
194
198
|
this.activeSources.delete("route");
|
|
195
199
|
}
|
|
196
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Subscribe to render events (if @buoy-gg/highlight-updates is installed)
|
|
203
|
+
*/
|
|
204
|
+
subscribeToRender() {
|
|
205
|
+
const {
|
|
206
|
+
sources
|
|
207
|
+
} = (0, _autoDiscoverEventSources.getCachedDiscovery)();
|
|
208
|
+
const renderSource = sources.find(s => s.id === "render");
|
|
209
|
+
if (renderSource) {
|
|
210
|
+
this.subscribeToSource(renderSource);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Unsubscribe from render events
|
|
216
|
+
*/
|
|
217
|
+
unsubscribeFromRender() {
|
|
218
|
+
this.unsubscribeFromSource("render");
|
|
219
|
+
this.activeSources.delete("render");
|
|
220
|
+
}
|
|
221
|
+
|
|
197
222
|
/**
|
|
198
223
|
* Add an event to the store
|
|
199
224
|
*/
|
|
@@ -257,7 +282,8 @@ class UnifiedEventStore {
|
|
|
257
282
|
"react-query": 0,
|
|
258
283
|
"react-query-query": 0,
|
|
259
284
|
"react-query-mutation": 0,
|
|
260
|
-
route: 0
|
|
285
|
+
route: 0,
|
|
286
|
+
render: 0
|
|
261
287
|
};
|
|
262
288
|
for (const event of this.events) {
|
|
263
289
|
counts[event.source]++;
|
|
@@ -310,7 +336,7 @@ class UnifiedEventStore {
|
|
|
310
336
|
*/
|
|
311
337
|
unsubscribeAll() {
|
|
312
338
|
// Unsubscribe from all tracked sources
|
|
313
|
-
for (const [
|
|
339
|
+
for (const [, unsubscribe] of this.sourceUnsubscribers) {
|
|
314
340
|
unsubscribe();
|
|
315
341
|
}
|
|
316
342
|
this.sourceUnsubscribers.clear();
|
|
@@ -338,6 +364,8 @@ class UnifiedEventStore {
|
|
|
338
364
|
return this.sourceUnsubscribers.has("react-query");
|
|
339
365
|
case "route":
|
|
340
366
|
return this.sourceUnsubscribers.has("route-events");
|
|
367
|
+
case "render":
|
|
368
|
+
return this.sourceUnsubscribers.has("render");
|
|
341
369
|
default:
|
|
342
370
|
return false;
|
|
343
371
|
}
|
|
@@ -355,9 +383,18 @@ class UnifiedEventStore {
|
|
|
355
383
|
"react-query": this.sourceUnsubscribers.has("react-query"),
|
|
356
384
|
"react-query-query": this.sourceUnsubscribers.has("react-query"),
|
|
357
385
|
"react-query-mutation": this.sourceUnsubscribers.has("react-query"),
|
|
358
|
-
route: this.sourceUnsubscribers.has("route-events")
|
|
386
|
+
route: this.sourceUnsubscribers.has("route-events"),
|
|
387
|
+
render: this.sourceUnsubscribers.has("render")
|
|
359
388
|
};
|
|
360
389
|
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Get subscriber counts from all underlying event stores.
|
|
393
|
+
* Useful for debugging the event system.
|
|
394
|
+
*/
|
|
395
|
+
getSubscriberCounts() {
|
|
396
|
+
return (0, _autoDiscoverEventSources.getAggregatedSubscriberCounts)();
|
|
397
|
+
}
|
|
361
398
|
}
|
|
362
399
|
|
|
363
400
|
// Singleton instance
|
|
@@ -384,6 +421,10 @@ const subscribeToRoutes = () => unifiedEventStore.subscribeToRoutes();
|
|
|
384
421
|
exports.subscribeToRoutes = subscribeToRoutes;
|
|
385
422
|
const unsubscribeFromRoutes = () => unifiedEventStore.unsubscribeFromRoutes();
|
|
386
423
|
exports.unsubscribeFromRoutes = unsubscribeFromRoutes;
|
|
424
|
+
const subscribeToRender = () => unifiedEventStore.subscribeToRender();
|
|
425
|
+
exports.subscribeToRender = subscribeToRender;
|
|
426
|
+
const unsubscribeFromRender = () => unifiedEventStore.unsubscribeFromRender();
|
|
427
|
+
exports.unsubscribeFromRender = unsubscribeFromRender;
|
|
387
428
|
const getEvents = enabledSources => unifiedEventStore.getEvents(enabledSources);
|
|
388
429
|
exports.getEvents = getEvents;
|
|
389
430
|
const getActiveSources = () => unifiedEventStore.getActiveSources();
|
|
@@ -410,4 +451,8 @@ const getAvailableEventSources = () => unifiedEventStore.getAvailableEventSource
|
|
|
410
451
|
exports.getAvailableEventSources = getAvailableEventSources;
|
|
411
452
|
const subscribeToAll = () => unifiedEventStore.subscribeToAll();
|
|
412
453
|
exports.subscribeToAll = subscribeToAll;
|
|
454
|
+
const getSubscriberCounts = () => unifiedEventStore.getSubscriberCounts();
|
|
455
|
+
|
|
456
|
+
// Re-export type for convenience
|
|
457
|
+
exports.getSubscriberCounts = getSubscriberCounts;
|
|
413
458
|
//# sourceMappingURL=unifiedEventStore.js.map
|
|
@@ -165,6 +165,30 @@ const COPY_PRESETS = exports.COPY_PRESETS = {
|
|
|
165
165
|
reduxChangedOnly: true,
|
|
166
166
|
showStorageDiff: false,
|
|
167
167
|
stripVerboseFields: true
|
|
168
|
+
},
|
|
169
|
+
/**
|
|
170
|
+
* Mermaid Diagram - Visual sequence diagram for flow visualization
|
|
171
|
+
*/
|
|
172
|
+
mermaid: {
|
|
173
|
+
timestampFormat: "relative",
|
|
174
|
+
includeSource: true,
|
|
175
|
+
includeStatus: true,
|
|
176
|
+
includeTitle: true,
|
|
177
|
+
includeSubtitle: false,
|
|
178
|
+
includeCorrelation: true,
|
|
179
|
+
includeDuration: true,
|
|
180
|
+
includeSummaryHeader: false,
|
|
181
|
+
includeTotalDuration: false,
|
|
182
|
+
includeEventData: false,
|
|
183
|
+
dataSizeThreshold: 1,
|
|
184
|
+
format: "mermaid",
|
|
185
|
+
filterMode: "all",
|
|
186
|
+
filterSources: [],
|
|
187
|
+
compactMode: false,
|
|
188
|
+
smartJsonParsing: true,
|
|
189
|
+
reduxChangedOnly: true,
|
|
190
|
+
showStorageDiff: true,
|
|
191
|
+
stripVerboseFields: true
|
|
168
192
|
}
|
|
169
193
|
};
|
|
170
194
|
/**
|
|
@@ -215,6 +239,11 @@ const PRESET_METADATA = exports.PRESET_METADATA = {
|
|
|
215
239
|
label: "Minimal",
|
|
216
240
|
description: "Quick reference",
|
|
217
241
|
color: "#6B7280" // Gray
|
|
242
|
+
},
|
|
243
|
+
mermaid: {
|
|
244
|
+
label: "Diagram",
|
|
245
|
+
description: "Visual flow",
|
|
246
|
+
color: "#A855F7" // Purple
|
|
218
247
|
}
|
|
219
248
|
};
|
|
220
249
|
//# sourceMappingURL=copySettings.js.map
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.autoDiscoverEventSources = autoDiscoverEventSources;
|
|
7
7
|
exports.clearDiscoveryCache = clearDiscoveryCache;
|
|
8
|
+
exports.getAggregatedSubscriberCounts = getAggregatedSubscriberCounts;
|
|
8
9
|
exports.getCachedDiscovery = getCachedDiscovery;
|
|
9
10
|
exports.getSourceDisplayConfig = getSourceDisplayConfig;
|
|
10
11
|
/**
|
|
@@ -54,9 +55,7 @@ function tryLoadStorageSource() {
|
|
|
54
55
|
name: "Storage",
|
|
55
56
|
eventSources: ["storage-async", "storage-mmkv"],
|
|
56
57
|
available: true,
|
|
57
|
-
setup
|
|
58
|
-
await storageEventStore.startCapturing();
|
|
59
|
-
},
|
|
58
|
+
// No setup needed - onEvent() auto-starts capturing via Subscribable pattern
|
|
60
59
|
subscribe: onEvent => {
|
|
61
60
|
return storageEventStore.onEvent(event => {
|
|
62
61
|
const unifiedEvent = transformStorageEvent(event);
|
|
@@ -214,55 +213,55 @@ function transformReduxAction(action) {
|
|
|
214
213
|
function tryLoadNetworkSource() {
|
|
215
214
|
try {
|
|
216
215
|
// @ts-ignore - Dynamic import that may not exist
|
|
216
|
+
// Note: We use networkListener (the getter) instead of startNetworkListener
|
|
217
|
+
// because startNetworkListener is not exported from the main package
|
|
217
218
|
const {
|
|
218
219
|
networkEventStore,
|
|
219
|
-
|
|
220
|
+
networkListener,
|
|
220
221
|
addNetworkListener
|
|
221
222
|
} = require("@buoy-gg/network");
|
|
222
223
|
|
|
223
|
-
// Map network event IDs to unified event IDs for updates
|
|
224
|
+
// Map network event IDs to unified event IDs for updates (request -> response)
|
|
224
225
|
const networkEventIdMap = new Map();
|
|
225
|
-
let storeUnsubscribe = null;
|
|
226
|
-
let listenerUnsubscribe = null;
|
|
227
226
|
return {
|
|
228
227
|
id: "network",
|
|
229
228
|
name: "Network",
|
|
230
229
|
eventSources: ["network"],
|
|
231
230
|
available: true,
|
|
232
231
|
setup: () => {
|
|
233
|
-
|
|
232
|
+
// Get the network listener singleton and start it if not already active
|
|
233
|
+
const listener = networkListener();
|
|
234
|
+
if (!listener.isActive) {
|
|
235
|
+
listener.startListening();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Ensure events flow into the store. The network panel does this via
|
|
239
|
+
// addNetworkListener, but if events package loads first, we need to
|
|
240
|
+
// set it up ourselves.
|
|
241
|
+
if (listener.listenerCount === 0) {
|
|
242
|
+
addNetworkListener(event => {
|
|
243
|
+
networkEventStore.processNetworkEvent(event);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
234
246
|
},
|
|
235
247
|
subscribe: onEvent => {
|
|
236
|
-
//
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
} else {
|
|
252
|
-
// Existing event updated (e.g., pending -> success/error)
|
|
253
|
-
// Create updated unified event with same ID so store can update it
|
|
254
|
-
const unifiedEvent = transformNetworkEvent(networkEvent);
|
|
255
|
-
unifiedEvent.id = existingUnifiedId; // Keep the same unified ID
|
|
256
|
-
onEvent(unifiedEvent);
|
|
257
|
-
}
|
|
248
|
+
// Use onEvent() pattern - same as storage
|
|
249
|
+
// This fires for each individual event (request or response/error update)
|
|
250
|
+
return networkEventStore.onEvent(event => {
|
|
251
|
+
const ne = event;
|
|
252
|
+
const existingUnifiedId = networkEventIdMap.get(ne.id);
|
|
253
|
+
if (!existingUnifiedId) {
|
|
254
|
+
// New event (request started)
|
|
255
|
+
const unifiedEvent = transformNetworkEvent(event);
|
|
256
|
+
networkEventIdMap.set(ne.id, unifiedEvent.id);
|
|
257
|
+
onEvent(unifiedEvent);
|
|
258
|
+
} else {
|
|
259
|
+
// Existing event updated (response received or error)
|
|
260
|
+
const unifiedEvent = transformNetworkEvent(event);
|
|
261
|
+
unifiedEvent.id = existingUnifiedId; // Keep the same unified ID
|
|
262
|
+
onEvent(unifiedEvent);
|
|
258
263
|
}
|
|
259
264
|
});
|
|
260
|
-
return () => {
|
|
261
|
-
listenerUnsubscribe?.();
|
|
262
|
-
storeUnsubscribe?.();
|
|
263
|
-
listenerUnsubscribe = null;
|
|
264
|
-
storeUnsubscribe = null;
|
|
265
|
-
};
|
|
266
265
|
}
|
|
267
266
|
};
|
|
268
267
|
} catch {
|
|
@@ -467,15 +466,16 @@ function tryLoadRouteEventsSource() {
|
|
|
467
466
|
try {
|
|
468
467
|
// @ts-ignore - Dynamic import that may not exist
|
|
469
468
|
const {
|
|
470
|
-
|
|
469
|
+
routeEventStore
|
|
471
470
|
} = require("@buoy-gg/route-events");
|
|
472
471
|
return {
|
|
473
472
|
id: "route-events",
|
|
474
473
|
name: "Routes",
|
|
475
474
|
eventSources: ["route"],
|
|
476
475
|
available: true,
|
|
476
|
+
// No setup needed - onEvent() auto-starts listening via Subscribable pattern
|
|
477
477
|
subscribe: onEvent => {
|
|
478
|
-
return
|
|
478
|
+
return routeEventStore.onEvent(event => {
|
|
479
479
|
const unifiedEvent = transformRouteEvent(event);
|
|
480
480
|
onEvent(unifiedEvent);
|
|
481
481
|
});
|
|
@@ -523,6 +523,134 @@ function transformRouteEvent(event) {
|
|
|
523
523
|
};
|
|
524
524
|
}
|
|
525
525
|
|
|
526
|
+
// ============================================================================
|
|
527
|
+
// Render Events Source Discovery (Highlight Updates)
|
|
528
|
+
// ============================================================================
|
|
529
|
+
|
|
530
|
+
function tryLoadHighlightUpdatesSource() {
|
|
531
|
+
try {
|
|
532
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
533
|
+
const highlightUpdates = require("@buoy-gg/highlight-updates");
|
|
534
|
+
|
|
535
|
+
// Verify the required exports exist
|
|
536
|
+
if (!highlightUpdates.RenderTracker || !highlightUpdates.HighlightUpdatesController) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
return {
|
|
540
|
+
id: "render",
|
|
541
|
+
name: "Render",
|
|
542
|
+
eventSources: ["render"],
|
|
543
|
+
available: true,
|
|
544
|
+
setup: () => {
|
|
545
|
+
// @ts-ignore
|
|
546
|
+
const {
|
|
547
|
+
HighlightUpdatesController
|
|
548
|
+
} = require("@buoy-gg/highlight-updates");
|
|
549
|
+
// Enable background tracking (NOT the visual toggle) - this sets up render
|
|
550
|
+
// interception without affecting the user's visual highlight toggle state
|
|
551
|
+
if (HighlightUpdatesController) {
|
|
552
|
+
HighlightUpdatesController.enableBackgroundTracking();
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
subscribe: onEvent => {
|
|
556
|
+
// @ts-ignore
|
|
557
|
+
const {
|
|
558
|
+
RenderTracker,
|
|
559
|
+
HighlightUpdatesController
|
|
560
|
+
} = require("@buoy-gg/highlight-updates");
|
|
561
|
+
|
|
562
|
+
// Ensure background tracking is enabled (separate from visual toggle)
|
|
563
|
+
if (HighlightUpdatesController && !HighlightUpdatesController.isBackgroundTrackingEnabled()) {
|
|
564
|
+
HighlightUpdatesController.enableBackgroundTracking();
|
|
565
|
+
}
|
|
566
|
+
const unsubscribeCallback = RenderTracker.onRenderEvent((event, render) => {
|
|
567
|
+
const unifiedEvent = transformRenderEvent(event, render);
|
|
568
|
+
onEvent(unifiedEvent);
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
// Return a wrapped unsubscribe that also disables background tracking
|
|
572
|
+
return () => {
|
|
573
|
+
unsubscribeCallback();
|
|
574
|
+
HighlightUpdatesController.disableBackgroundTracking();
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
} catch {
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
function transformRenderEvent(event, render) {
|
|
583
|
+
const e = event;
|
|
584
|
+
const r = render;
|
|
585
|
+
|
|
586
|
+
// Use component name if available, otherwise display name (View, Text, etc.)
|
|
587
|
+
const title = r.componentName || r.displayName || r.viewType;
|
|
588
|
+
|
|
589
|
+
// Build subtitle from cause info
|
|
590
|
+
const subtitleParts = [];
|
|
591
|
+
|
|
592
|
+
// Add cause type
|
|
593
|
+
const causeLabels = {
|
|
594
|
+
mount: "mounted",
|
|
595
|
+
props: "props changed",
|
|
596
|
+
state: "state changed",
|
|
597
|
+
hooks: "hooks changed",
|
|
598
|
+
context: "context changed",
|
|
599
|
+
parent: "parent re-rendered",
|
|
600
|
+
unknown: "re-rendered"
|
|
601
|
+
};
|
|
602
|
+
subtitleParts.push(causeLabels[e.cause.type] || e.cause.type);
|
|
603
|
+
|
|
604
|
+
// Add changed keys if props changed
|
|
605
|
+
if (e.cause.type === "props" && e.cause.changedKeys?.length) {
|
|
606
|
+
const keys = e.cause.changedKeys.slice(0, 3).join(", ");
|
|
607
|
+
const more = e.cause.changedKeys.length > 3 ? ` +${e.cause.changedKeys.length - 3}` : "";
|
|
608
|
+
subtitleParts.push(`[${keys}${more}]`);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Add hook change description if available
|
|
612
|
+
if (e.cause.hookChanges?.length) {
|
|
613
|
+
const firstChange = e.cause.hookChanges[0];
|
|
614
|
+
if (firstChange.description) {
|
|
615
|
+
subtitleParts.push(firstChange.description);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Add render number
|
|
620
|
+
subtitleParts.push(`#${e.renderNumber}`);
|
|
621
|
+
|
|
622
|
+
// Determine status based on cause type
|
|
623
|
+
let status = "neutral";
|
|
624
|
+
switch (e.cause.type) {
|
|
625
|
+
case "mount":
|
|
626
|
+
status = "neutral"; // First render is expected
|
|
627
|
+
break;
|
|
628
|
+
case "props":
|
|
629
|
+
case "state":
|
|
630
|
+
case "hooks":
|
|
631
|
+
case "context":
|
|
632
|
+
status = "success"; // Intentional re-renders
|
|
633
|
+
break;
|
|
634
|
+
case "parent":
|
|
635
|
+
status = "pending"; // Potentially wasteful (yellow highlight)
|
|
636
|
+
break;
|
|
637
|
+
default:
|
|
638
|
+
status = "neutral";
|
|
639
|
+
}
|
|
640
|
+
return {
|
|
641
|
+
id: generateEventId("render"),
|
|
642
|
+
source: "render",
|
|
643
|
+
timestamp: e.timestamp,
|
|
644
|
+
title,
|
|
645
|
+
subtitle: subtitleParts.join(" · "),
|
|
646
|
+
status,
|
|
647
|
+
originalEvent: {
|
|
648
|
+
event: e,
|
|
649
|
+
render: r
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
|
|
526
654
|
// ============================================================================
|
|
527
655
|
// Main Auto-Discovery Function
|
|
528
656
|
// ============================================================================
|
|
@@ -549,7 +677,7 @@ function autoDiscoverEventSources() {
|
|
|
549
677
|
const availableEventSources = new Set();
|
|
550
678
|
|
|
551
679
|
// Try to load each source
|
|
552
|
-
const loaders = [tryLoadStorageSource, tryLoadReduxSource, tryLoadNetworkSource, tryLoadReactQuerySource, tryLoadRouteEventsSource];
|
|
680
|
+
const loaders = [tryLoadStorageSource, tryLoadReduxSource, tryLoadNetworkSource, tryLoadReactQuerySource, tryLoadRouteEventsSource, tryLoadHighlightUpdatesSource];
|
|
553
681
|
for (const loader of loaders) {
|
|
554
682
|
const source = loader();
|
|
555
683
|
if (source && source.available) {
|
|
@@ -608,6 +736,11 @@ function getSourceDisplayConfig(source) {
|
|
|
608
736
|
label: "Route",
|
|
609
737
|
color: "#06B6D4",
|
|
610
738
|
icon: "navigate-outline"
|
|
739
|
+
},
|
|
740
|
+
render: {
|
|
741
|
+
label: "Render",
|
|
742
|
+
color: "#F472B6",
|
|
743
|
+
icon: "layers-outline"
|
|
611
744
|
}
|
|
612
745
|
};
|
|
613
746
|
return configs[source] || {
|
|
@@ -637,4 +770,93 @@ function getCachedDiscovery() {
|
|
|
637
770
|
function clearDiscoveryCache() {
|
|
638
771
|
cachedDiscovery = null;
|
|
639
772
|
}
|
|
773
|
+
|
|
774
|
+
// ============================================================================
|
|
775
|
+
// Subscriber Count Aggregation
|
|
776
|
+
// ============================================================================
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Get subscriber counts from all discovered event stores.
|
|
780
|
+
* Useful for debugging and monitoring the event system.
|
|
781
|
+
*/
|
|
782
|
+
function getAggregatedSubscriberCounts() {
|
|
783
|
+
const sources = [];
|
|
784
|
+
let totalSubscribers = 0;
|
|
785
|
+
|
|
786
|
+
// Try to get counts from storage store
|
|
787
|
+
try {
|
|
788
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
789
|
+
const {
|
|
790
|
+
storageEventStore
|
|
791
|
+
} = require("@buoy-gg/storage");
|
|
792
|
+
const counts = storageEventStore.getSubscriberCounts();
|
|
793
|
+
sources.push({
|
|
794
|
+
sourceId: "storage",
|
|
795
|
+
counts
|
|
796
|
+
});
|
|
797
|
+
totalSubscribers += counts.total;
|
|
798
|
+
} catch {
|
|
799
|
+
// Package not installed
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// Try to get counts from network store
|
|
803
|
+
try {
|
|
804
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
805
|
+
const {
|
|
806
|
+
networkEventStore
|
|
807
|
+
} = require("@buoy-gg/network");
|
|
808
|
+
const counts = networkEventStore.getSubscriberCounts();
|
|
809
|
+
sources.push({
|
|
810
|
+
sourceId: "network",
|
|
811
|
+
counts
|
|
812
|
+
});
|
|
813
|
+
totalSubscribers += counts.total;
|
|
814
|
+
} catch {
|
|
815
|
+
// Package not installed
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// Try to get counts from route events store
|
|
819
|
+
try {
|
|
820
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
821
|
+
const {
|
|
822
|
+
routeEventStore
|
|
823
|
+
} = require("@buoy-gg/route-events");
|
|
824
|
+
const counts = routeEventStore.getSubscriberCounts();
|
|
825
|
+
sources.push({
|
|
826
|
+
sourceId: "route-events",
|
|
827
|
+
counts
|
|
828
|
+
});
|
|
829
|
+
totalSubscribers += counts.total;
|
|
830
|
+
} catch {
|
|
831
|
+
// Package not installed
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// Try to get counts from render tracker (highlight-updates)
|
|
835
|
+
try {
|
|
836
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
837
|
+
const {
|
|
838
|
+
RenderTracker,
|
|
839
|
+
HighlightUpdatesController
|
|
840
|
+
} = require("@buoy-gg/highlight-updates");
|
|
841
|
+
const callbackCount = RenderTracker.getRenderEventCallbackCount();
|
|
842
|
+
// Also count the visual highlight tool as a subscriber when enabled
|
|
843
|
+
const visualToolEnabled = HighlightUpdatesController?.isEnabled?.() ? 1 : 0;
|
|
844
|
+
const counts = {
|
|
845
|
+
eventCallbacks: callbackCount,
|
|
846
|
+
arrayListeners: visualToolEnabled,
|
|
847
|
+
total: callbackCount + visualToolEnabled
|
|
848
|
+
};
|
|
849
|
+
sources.push({
|
|
850
|
+
sourceId: "render",
|
|
851
|
+
counts
|
|
852
|
+
});
|
|
853
|
+
totalSubscribers += counts.total;
|
|
854
|
+
} catch {
|
|
855
|
+
// Package not installed
|
|
856
|
+
}
|
|
857
|
+
return {
|
|
858
|
+
sources,
|
|
859
|
+
totalSubscribers
|
|
860
|
+
};
|
|
861
|
+
}
|
|
640
862
|
//# sourceMappingURL=autoDiscoverEventSources.js.map
|
|
@@ -4,7 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.clearEnabledSources = clearEnabledSources;
|
|
7
|
+
exports.loadCapturingState = loadCapturingState;
|
|
7
8
|
exports.loadEnabledSources = loadEnabledSources;
|
|
9
|
+
exports.saveCapturingState = saveCapturingState;
|
|
8
10
|
exports.saveEnabledSources = saveEnabledSources;
|
|
9
11
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
12
|
/**
|
|
@@ -55,4 +57,34 @@ async function clearEnabledSources() {
|
|
|
55
57
|
// Silently fail
|
|
56
58
|
}
|
|
57
59
|
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Save the capturing state to persistent storage
|
|
63
|
+
*/
|
|
64
|
+
async function saveCapturingState(isCapturing) {
|
|
65
|
+
try {
|
|
66
|
+
const key = _sharedUi.devToolsStorageKeys.events.isCapturing();
|
|
67
|
+
await _sharedUi.persistentStorage.setItem(key, JSON.stringify(isCapturing));
|
|
68
|
+
} catch {
|
|
69
|
+
// Silently fail - persistence is optional
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Load the capturing state from persistent storage
|
|
75
|
+
* Returns null if no saved state exists (defaults to true on first load)
|
|
76
|
+
*/
|
|
77
|
+
async function loadCapturingState() {
|
|
78
|
+
try {
|
|
79
|
+
const key = _sharedUi.devToolsStorageKeys.events.isCapturing();
|
|
80
|
+
const value = await _sharedUi.persistentStorage.getItem(key);
|
|
81
|
+
if (value !== null && value !== "") {
|
|
82
|
+
return JSON.parse(value);
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
} catch {
|
|
86
|
+
// Silently fail - return null to use defaults
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
58
90
|
//# sourceMappingURL=badgeSelectionStorage.js.map
|