@buoy-gg/events 2.1.10 → 2.1.13

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 (28) hide show
  1. package/lib/commonjs/components/EventsCopySettingsView.js +3 -1
  2. package/lib/commonjs/components/ReactQueryEventDetail.js +7 -3
  3. package/lib/commonjs/components/UnifiedEventDetail.js +68 -2
  4. package/lib/commonjs/components/UnifiedEventItem.js +59 -1
  5. package/lib/commonjs/hooks/useUnifiedEvents.js +23 -1
  6. package/lib/commonjs/stores/unifiedEventStore.js +59 -1
  7. package/lib/commonjs/utils/autoDiscoverEventSources.js +146 -1
  8. package/lib/commonjs/utils/eventExportFormatter.js +2 -0
  9. package/lib/module/components/EventsCopySettingsView.js +3 -1
  10. package/lib/module/components/ReactQueryEventDetail.js +7 -3
  11. package/lib/module/components/UnifiedEventDetail.js +68 -2
  12. package/lib/module/components/UnifiedEventItem.js +59 -1
  13. package/lib/module/hooks/useUnifiedEvents.js +24 -2
  14. package/lib/module/stores/unifiedEventStore.js +54 -0
  15. package/lib/module/utils/autoDiscoverEventSources.js +146 -1
  16. package/lib/module/utils/eventExportFormatter.js +2 -0
  17. package/lib/typescript/stores/unifiedEventStore.d.ts +20 -0
  18. package/lib/typescript/types/index.d.ts +1 -1
  19. package/package.json +3 -3
  20. package/src/components/EventsCopySettingsView.tsx +3 -1
  21. package/src/components/ReactQueryEventDetail.tsx +7 -3
  22. package/src/components/UnifiedEventDetail.tsx +79 -1
  23. package/src/components/UnifiedEventItem.tsx +66 -0
  24. package/src/hooks/useUnifiedEvents.ts +28 -0
  25. package/src/stores/unifiedEventStore.ts +54 -0
  26. package/src/types/index.ts +3 -1
  27. package/src/utils/autoDiscoverEventSources.ts +165 -0
  28. package/src/utils/eventExportFormatter.ts +2 -0
@@ -23,7 +23,9 @@ function tryLoadOptionalDetailComponents() {
23
23
  StorageEventDetailContent: null,
24
24
  ReduxActionDetailContent: null,
25
25
  NetworkEventDetailView: null,
26
- RenderDetailView: null
26
+ RenderDetailView: null,
27
+ ZustandStateDetailContent: null,
28
+ JotaiAtomDetailContent: null
27
29
  };
28
30
 
29
31
  // Try to load storage detail component
@@ -61,6 +63,24 @@ function tryLoadOptionalDetailComponents() {
61
63
  } catch {
62
64
  // Optional dependency not installed
63
65
  }
66
+
67
+ // Try to load zustand detail component
68
+ try {
69
+ // @ts-ignore - Dynamic import that may not exist
70
+ const zustand = require("@buoy-gg/zustand");
71
+ components.ZustandStateDetailContent = zustand.ZustandStateDetailContent;
72
+ } catch {
73
+ // Optional dependency not installed
74
+ }
75
+
76
+ // Try to load jotai detail component
77
+ try {
78
+ // @ts-ignore - Dynamic import that may not exist
79
+ const jotai = require("@buoy-gg/jotai");
80
+ components.JotaiAtomDetailContent = jotai.JotaiAtomDetailContent;
81
+ } catch {
82
+ // Optional dependency not installed
83
+ }
64
84
  return components;
65
85
  }
66
86
 
@@ -107,6 +127,14 @@ const SOURCE_CONFIG = {
107
127
  label: "Route",
108
128
  color: "#06B6D4"
109
129
  },
130
+ zustand: {
131
+ label: "Zustand",
132
+ color: "#764ABC"
133
+ },
134
+ jotai: {
135
+ label: "Jotai",
136
+ color: "#14B8A6"
137
+ },
110
138
  render: {
111
139
  label: "Render",
112
140
  color: "#F472B6"
@@ -225,6 +253,42 @@ export const UnifiedEventDetail = /*#__PURE__*/memo(function UnifiedEventDetail(
225
253
  });
226
254
  }
227
255
 
256
+ // For Zustand events, use the shared ZustandStateDetailContent if available
257
+ if (event.source === "zustand" && optionalComponents.ZustandStateDetailContent) {
258
+ const {
259
+ ZustandStateDetailContent
260
+ } = optionalComponents;
261
+ const zustandChange = event.originalEvent;
262
+ return /*#__PURE__*/_jsx(View, {
263
+ style: styles.container,
264
+ children: /*#__PURE__*/_jsx(ZustandStateDetailContent, {
265
+ change: zustandChange,
266
+ changes: [zustandChange],
267
+ selectedIndex: 0,
268
+ onIndexChange: () => {},
269
+ disableInternalFooter: true
270
+ })
271
+ });
272
+ }
273
+
274
+ // For Jotai events, use the shared JotaiAtomDetailContent if available
275
+ if (event.source === "jotai" && optionalComponents.JotaiAtomDetailContent) {
276
+ const {
277
+ JotaiAtomDetailContent
278
+ } = optionalComponents;
279
+ const jotaiChange = event.originalEvent;
280
+ return /*#__PURE__*/_jsx(View, {
281
+ style: styles.container,
282
+ children: /*#__PURE__*/_jsx(JotaiAtomDetailContent, {
283
+ change: jotaiChange,
284
+ changes: [jotaiChange],
285
+ selectedIndex: 0,
286
+ onIndexChange: () => {},
287
+ disableInternalFooter: true
288
+ })
289
+ });
290
+ }
291
+
228
292
  // For render events, use the RenderDetailView if available
229
293
  if (event.source === "render" && optionalComponents.RenderDetailView) {
230
294
  const {
@@ -305,7 +369,9 @@ export const UnifiedEventDetail = /*#__PURE__*/memo(function UnifiedEventDetail(
305
369
  children: /*#__PURE__*/_jsx(DataViewer, {
306
370
  data: getEventData(),
307
371
  title: "",
308
- showTypeFilter: false
372
+ showTypeFilter: true,
373
+ rawMode: true,
374
+ initialExpanded: true
309
375
  })
310
376
  })]
311
377
  })]
@@ -22,7 +22,9 @@ function tryLoadOptionalComponents() {
22
22
  getValueType: null,
23
23
  ReduxActionItem: null,
24
24
  NetworkEventItemCompact: null,
25
- RouteEventItemCompact: null
25
+ RouteEventItemCompact: null,
26
+ ZustandStateChangeItem: null,
27
+ JotaiAtomChangeItem: null
26
28
  };
27
29
 
28
30
  // Try to load storage components
@@ -61,6 +63,24 @@ function tryLoadOptionalComponents() {
61
63
  } catch {
62
64
  // Optional dependency not installed
63
65
  }
66
+
67
+ // Try to load zustand components
68
+ try {
69
+ // @ts-ignore - Dynamic import that may not exist
70
+ const zustand = require("@buoy-gg/zustand");
71
+ components.ZustandStateChangeItem = zustand.ZustandStateChangeItem;
72
+ } catch {
73
+ // Optional dependency not installed
74
+ }
75
+
76
+ // Try to load jotai components
77
+ try {
78
+ // @ts-ignore - Dynamic import that may not exist
79
+ const jotai = require("@buoy-gg/jotai");
80
+ components.JotaiAtomChangeItem = jotai.JotaiAtomChangeItem;
81
+ } catch {
82
+ // Optional dependency not installed
83
+ }
64
84
  return components;
65
85
  }
66
86
 
@@ -107,6 +127,14 @@ const SOURCE_CONFIG = {
107
127
  label: "Route",
108
128
  color: "#06B6D4" // Cyan
109
129
  },
130
+ zustand: {
131
+ label: "Zustand",
132
+ color: "#764ABC" // Purple
133
+ },
134
+ jotai: {
135
+ label: "Jotai",
136
+ color: "#14B8A6" // Teal
137
+ },
110
138
  render: {
111
139
  label: "Render",
112
140
  color: "#F472B6" // Pink
@@ -178,6 +206,8 @@ const SOURCE_BADGE_LABELS = {
178
206
  "react-query-query": "QUERY",
179
207
  "react-query-mutation": "MUTATION",
180
208
  route: "ROUTE",
209
+ zustand: "ZUSTAND",
210
+ jotai: "JOTAI",
181
211
  render: "RENDER"
182
212
  };
183
213
 
@@ -289,6 +319,34 @@ export const UnifiedEventItem = /*#__PURE__*/memo(function UnifiedEventItem({
289
319
  });
290
320
  }
291
321
 
322
+ // For Zustand events, try to use the shared ZustandStateChangeItem component
323
+ if (event.source === "zustand" && optionalComponents.ZustandStateChangeItem) {
324
+ const {
325
+ ZustandStateChangeItem
326
+ } = optionalComponents;
327
+ return /*#__PURE__*/_jsx(SourceBadgeWrapper, {
328
+ source: event.source,
329
+ children: /*#__PURE__*/_jsx(ZustandStateChangeItem, {
330
+ change: event.originalEvent,
331
+ onPress: () => onPress()
332
+ })
333
+ });
334
+ }
335
+
336
+ // For Jotai events, try to use the shared JotaiAtomChangeItem component
337
+ if (event.source === "jotai" && optionalComponents.JotaiAtomChangeItem) {
338
+ const {
339
+ JotaiAtomChangeItem
340
+ } = optionalComponents;
341
+ return /*#__PURE__*/_jsx(SourceBadgeWrapper, {
342
+ source: event.source,
343
+ children: /*#__PURE__*/_jsx(JotaiAtomChangeItem, {
344
+ change: event.originalEvent,
345
+ onPress: () => onPress()
346
+ })
347
+ });
348
+ }
349
+
292
350
  // Fallback: Use CompactRow for all events when specific components aren't available
293
351
  const customBadge = correlationLabel && correlationColor ? /*#__PURE__*/_jsx(CorrelationBadge, {
294
352
  label: correlationLabel,
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { useState, useEffect, useCallback, useMemo, useRef } from "react";
11
11
  import { useFeatureGate, subscribeToSubscriberCountChanges, isDevToolsStorageKey } from "@buoy-gg/shared-ui";
12
- import { subscribe, subscribeToStorage, subscribeToRedux, subscribeToNetwork, subscribeToReactQuery, subscribeToRoutes, subscribeToRender, unsubscribeFromStorage, unsubscribeFromRedux, unsubscribeFromNetwork, unsubscribeFromReactQuery, unsubscribeFromRoutes, unsubscribeFromRender, unsubscribeAll, getSourceCounts, clearEvents as clearStoreEvents, getAvailableEventSources, getSubscriberCounts } from "../stores/unifiedEventStore";
12
+ import { subscribe, subscribeToStorage, subscribeToRedux, subscribeToNetwork, subscribeToReactQuery, subscribeToRoutes, subscribeToZustand, subscribeToJotai, subscribeToRender, unsubscribeFromStorage, unsubscribeFromRedux, unsubscribeFromNetwork, unsubscribeFromReactQuery, unsubscribeFromRoutes, unsubscribeFromZustand, unsubscribeFromJotai, unsubscribeFromRender, unsubscribeAll, getSourceCounts, clearEvents as clearStoreEvents, getAvailableEventSources, getSubscriberCounts } from "../stores/unifiedEventStore";
13
13
  import { saveEnabledSources, loadEnabledSources, saveCapturingState, loadCapturingState } from "../utils/badgeSelectionStorage";
14
14
  import { getSourceDisplayConfig } from "../utils/autoDiscoverEventSources";
15
15
 
@@ -51,7 +51,7 @@ function isBuoyInternalEvent(event) {
51
51
  /**
52
52
  * All possible sources for display
53
53
  */
54
- const ALL_DISPLAY_SOURCES = ["storage-async", "redux", "network", "react-query-query", "react-query-mutation", "route", "render"];
54
+ const ALL_DISPLAY_SOURCES = ["storage-async", "redux", "network", "react-query-query", "react-query-mutation", "route", "zustand", "jotai", "render"];
55
55
 
56
56
  /**
57
57
  * Sources enabled by default on first load.
@@ -72,6 +72,8 @@ const SOURCE_TO_EVENT_SOURCES = {
72
72
  "react-query-query": ["react-query", "react-query-query"],
73
73
  "react-query-mutation": ["react-query-mutation"],
74
74
  route: ["route"],
75
+ zustand: ["zustand"],
76
+ jotai: ["jotai"],
75
77
  render: ["render"]
76
78
  };
77
79
 
@@ -87,6 +89,8 @@ const EVENT_SOURCE_TO_DISCOVERY_ID = {
87
89
  "react-query-query": "react-query",
88
90
  "react-query-mutation": "react-query",
89
91
  route: "route-events",
92
+ zustand: "zustand",
93
+ jotai: "jotai",
90
94
  render: "render"
91
95
  };
92
96
  export function useUnifiedEvents() {
@@ -166,6 +170,8 @@ export function useUnifiedEvents() {
166
170
  subscribeToReactQuery();
167
171
  }
168
172
  if (sourcesToEnable.has("route")) subscribeToRoutes();
173
+ if (sourcesToEnable.has("zustand")) subscribeToZustand();
174
+ if (sourcesToEnable.has("jotai")) subscribeToJotai();
169
175
  if (sourcesToEnable.has("render")) subscribeToRender();
170
176
  }
171
177
  isStateRestoredRef.current = true;
@@ -246,6 +252,8 @@ export function useUnifiedEvents() {
246
252
  "react-query-query": "react-query",
247
253
  "react-query-mutation": "react-query",
248
254
  route: "route-events",
255
+ zustand: "zustand",
256
+ jotai: "jotai",
249
257
  render: "render"
250
258
  };
251
259
  const sources = availableDisplaySources.map(source => {
@@ -296,6 +304,12 @@ export function useUnifiedEvents() {
296
304
  case "route":
297
305
  unsubscribeFromRoutes();
298
306
  break;
307
+ case "zustand":
308
+ unsubscribeFromZustand();
309
+ break;
310
+ case "jotai":
311
+ unsubscribeFromJotai();
312
+ break;
299
313
  case "render":
300
314
  unsubscribeFromRender();
301
315
  break;
@@ -321,6 +335,12 @@ export function useUnifiedEvents() {
321
335
  case "route":
322
336
  subscribeToRoutes();
323
337
  break;
338
+ case "zustand":
339
+ subscribeToZustand();
340
+ break;
341
+ case "jotai":
342
+ subscribeToJotai();
343
+ break;
324
344
  case "render":
325
345
  subscribeToRender();
326
346
  break;
@@ -345,6 +365,8 @@ export function useUnifiedEvents() {
345
365
  subscribeToReactQuery();
346
366
  }
347
367
  if (enabledSources.has("route")) subscribeToRoutes();
368
+ if (enabledSources.has("zustand")) subscribeToZustand();
369
+ if (enabledSources.has("jotai")) subscribeToJotai();
348
370
  if (enabledSources.has("render")) subscribeToRender();
349
371
  setIsCapturing(true);
350
372
  }, [enabledSources]);
@@ -194,6 +194,48 @@ class UnifiedEventStore {
194
194
  this.activeSources.delete("route");
195
195
  }
196
196
 
197
+ /**
198
+ * Subscribe to Zustand state changes (if @buoy-gg/zustand is installed)
199
+ */
200
+ subscribeToZustand() {
201
+ const {
202
+ sources
203
+ } = getCachedDiscovery();
204
+ const zustandSource = sources.find(s => s.id === "zustand");
205
+ if (zustandSource) {
206
+ this.subscribeToSource(zustandSource);
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Unsubscribe from Zustand state changes
212
+ */
213
+ unsubscribeFromZustand() {
214
+ this.unsubscribeFromSource("zustand");
215
+ this.activeSources.delete("zustand");
216
+ }
217
+
218
+ /**
219
+ * Subscribe to Jotai atom changes (if @buoy-gg/jotai is installed)
220
+ */
221
+ subscribeToJotai() {
222
+ const {
223
+ sources
224
+ } = getCachedDiscovery();
225
+ const jotaiSource = sources.find(s => s.id === "jotai");
226
+ if (jotaiSource) {
227
+ this.subscribeToSource(jotaiSource);
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Unsubscribe from Jotai atom changes
233
+ */
234
+ unsubscribeFromJotai() {
235
+ this.unsubscribeFromSource("jotai");
236
+ this.activeSources.delete("jotai");
237
+ }
238
+
197
239
  /**
198
240
  * Subscribe to render events (if @buoy-gg/highlight-updates is installed)
199
241
  */
@@ -279,6 +321,8 @@ class UnifiedEventStore {
279
321
  "react-query-query": 0,
280
322
  "react-query-mutation": 0,
281
323
  route: 0,
324
+ zustand: 0,
325
+ jotai: 0,
282
326
  render: 0
283
327
  };
284
328
  for (const event of this.events) {
@@ -360,6 +404,10 @@ class UnifiedEventStore {
360
404
  return this.sourceUnsubscribers.has("react-query");
361
405
  case "route":
362
406
  return this.sourceUnsubscribers.has("route-events");
407
+ case "zustand":
408
+ return this.sourceUnsubscribers.has("zustand");
409
+ case "jotai":
410
+ return this.sourceUnsubscribers.has("jotai");
363
411
  case "render":
364
412
  return this.sourceUnsubscribers.has("render");
365
413
  default:
@@ -380,6 +428,8 @@ class UnifiedEventStore {
380
428
  "react-query-query": this.sourceUnsubscribers.has("react-query"),
381
429
  "react-query-mutation": this.sourceUnsubscribers.has("react-query"),
382
430
  route: this.sourceUnsubscribers.has("route-events"),
431
+ zustand: this.sourceUnsubscribers.has("zustand"),
432
+ jotai: this.sourceUnsubscribers.has("jotai"),
383
433
  render: this.sourceUnsubscribers.has("render")
384
434
  };
385
435
  }
@@ -407,6 +457,10 @@ export const subscribeToReactQuery = () => unifiedEventStore.subscribeToReactQue
407
457
  export const unsubscribeFromReactQuery = () => unifiedEventStore.unsubscribeFromReactQuery();
408
458
  export const subscribeToRoutes = () => unifiedEventStore.subscribeToRoutes();
409
459
  export const unsubscribeFromRoutes = () => unifiedEventStore.unsubscribeFromRoutes();
460
+ export const subscribeToZustand = () => unifiedEventStore.subscribeToZustand();
461
+ export const unsubscribeFromZustand = () => unifiedEventStore.unsubscribeFromZustand();
462
+ export const subscribeToJotai = () => unifiedEventStore.subscribeToJotai();
463
+ export const unsubscribeFromJotai = () => unifiedEventStore.unsubscribeFromJotai();
410
464
  export const subscribeToRender = () => unifiedEventStore.subscribeToRender();
411
465
  export const unsubscribeFromRender = () => unifiedEventStore.unsubscribeFromRender();
412
466
  export const getEvents = enabledSources => unifiedEventStore.getEvents(enabledSources);
@@ -517,6 +517,141 @@ function transformRouteEvent(event) {
517
517
  };
518
518
  }
519
519
 
520
+ // ============================================================================
521
+ // Zustand Event Source Discovery
522
+ // ============================================================================
523
+
524
+ function tryLoadZustandSource() {
525
+ try {
526
+ // @ts-ignore - Dynamic import that may not exist
527
+ const {
528
+ zustandStateStore
529
+ } = require("@buoy-gg/zustand");
530
+ let lastChangeId = null;
531
+ return {
532
+ id: "zustand",
533
+ name: "Zustand",
534
+ eventSources: ["zustand"],
535
+ available: true,
536
+ subscribe: onEvent => {
537
+ return zustandStateStore.subscribe(changes => {
538
+ if (changes.length > 0) {
539
+ const latestChange = changes[0];
540
+ if (latestChange.id !== lastChangeId) {
541
+ lastChangeId = latestChange.id;
542
+ const unifiedEvent = transformZustandChange(latestChange);
543
+ onEvent(unifiedEvent);
544
+ }
545
+ }
546
+ });
547
+ }
548
+ };
549
+ } catch {
550
+ return null;
551
+ }
552
+ }
553
+ function transformZustandChange(change) {
554
+ const c = change;
555
+
556
+ // Get status
557
+ let status = "neutral";
558
+ if (c.isSlowUpdate) {
559
+ status = "pending"; // Yellow for slow updates
560
+ } else if (c.hasStateChange) {
561
+ status = "success";
562
+ }
563
+
564
+ // Get subtitle
565
+ const parts = [];
566
+ if (c.changedKeys && c.changedKeys.length > 0) {
567
+ const keys = c.changedKeys.slice(0, 3).join(", ");
568
+ const more = c.changedKeys.length > 3 ? ` +${c.changedKeys.length - 3}` : "";
569
+ parts.push(`${keys}${more}`);
570
+ } else if (c.diffSummary) {
571
+ parts.push(c.diffSummary);
572
+ }
573
+ if (c.duration !== undefined) {
574
+ parts.push(`${c.duration.toFixed(1)}ms`);
575
+ }
576
+ if (c.category === "replace") {
577
+ parts.push("replace");
578
+ }
579
+ return {
580
+ id: generateEventId("zustand"),
581
+ source: "zustand",
582
+ timestamp: c.timestamp,
583
+ title: c.storeName,
584
+ subtitle: parts.join(" · ") || (c.hasStateChange ? "state changed" : "no change"),
585
+ status,
586
+ originalEvent: change
587
+ };
588
+ }
589
+
590
+ // ============================================================================
591
+ // Jotai Event Source Discovery
592
+ // ============================================================================
593
+
594
+ function tryLoadJotaiSource() {
595
+ try {
596
+ // @ts-ignore - Dynamic import that may not exist
597
+ const {
598
+ jotaiStateStore
599
+ } = require("@buoy-gg/jotai");
600
+ let lastChangeId = null;
601
+ return {
602
+ id: "jotai",
603
+ name: "Jotai",
604
+ eventSources: ["jotai"],
605
+ available: true,
606
+ subscribe: onEvent => {
607
+ return jotaiStateStore.subscribe(changes => {
608
+ if (changes.length > 0) {
609
+ const latestChange = changes[0];
610
+ if (latestChange.id !== lastChangeId) {
611
+ lastChangeId = latestChange.id;
612
+ const unifiedEvent = transformJotaiChange(latestChange);
613
+ onEvent(unifiedEvent);
614
+ }
615
+ }
616
+ });
617
+ }
618
+ };
619
+ } catch {
620
+ return null;
621
+ }
622
+ }
623
+ function transformJotaiChange(change) {
624
+ const c = change;
625
+
626
+ // Get status
627
+ let status = "neutral";
628
+ if (c.category === "write" && c.hasValueChange) {
629
+ status = "success";
630
+ } else if (c.category === "read") {
631
+ status = "neutral";
632
+ }
633
+
634
+ // Get subtitle
635
+ const parts = [];
636
+ if (c.valuePreview) {
637
+ parts.push(c.valuePreview);
638
+ } else if (c.diffSummary) {
639
+ parts.push(c.diffSummary);
640
+ }
641
+ if (c.category) {
642
+ parts.push(c.category);
643
+ }
644
+ return {
645
+ id: generateEventId("jotai"),
646
+ source: "jotai",
647
+ timestamp: c.timestamp,
648
+ title: c.atomLabel,
649
+ subtitle: parts.join(" · ") || (c.hasValueChange ? "value changed" : "no change"),
650
+ status,
651
+ originalEvent: change
652
+ };
653
+ }
654
+
520
655
  // ============================================================================
521
656
  // Render Events Source Discovery (Highlight Updates)
522
657
  // ============================================================================
@@ -671,7 +806,7 @@ export function autoDiscoverEventSources() {
671
806
  const availableEventSources = new Set();
672
807
 
673
808
  // Try to load each source
674
- const loaders = [tryLoadStorageSource, tryLoadReduxSource, tryLoadNetworkSource, tryLoadReactQuerySource, tryLoadRouteEventsSource, tryLoadHighlightUpdatesSource];
809
+ const loaders = [tryLoadStorageSource, tryLoadReduxSource, tryLoadNetworkSource, tryLoadReactQuerySource, tryLoadRouteEventsSource, tryLoadZustandSource, tryLoadJotaiSource, tryLoadHighlightUpdatesSource];
675
810
  for (const loader of loaders) {
676
811
  const source = loader();
677
812
  if (source && source.available) {
@@ -731,6 +866,16 @@ export function getSourceDisplayConfig(source) {
731
866
  color: "#06B6D4",
732
867
  icon: "navigate-outline"
733
868
  },
869
+ zustand: {
870
+ label: "Zustand",
871
+ color: "#764ABC",
872
+ icon: "cube-outline"
873
+ },
874
+ jotai: {
875
+ label: "Jotai",
876
+ color: "#14B8A6",
877
+ icon: "ellipse-outline"
878
+ },
734
879
  render: {
735
880
  label: "Render",
736
881
  color: "#F472B6",
@@ -46,6 +46,8 @@ const SOURCE_LABELS = {
46
46
  "react-query-query": "Query",
47
47
  "react-query-mutation": "Mutation",
48
48
  route: "Route",
49
+ zustand: "Zustand",
50
+ jotai: "Jotai",
49
51
  render: "Render"
50
52
  };
51
53
 
@@ -74,6 +74,22 @@ declare class UnifiedEventStore {
74
74
  * Unsubscribe from route events
75
75
  */
76
76
  unsubscribeFromRoutes(): void;
77
+ /**
78
+ * Subscribe to Zustand state changes (if @buoy-gg/zustand is installed)
79
+ */
80
+ subscribeToZustand(): void;
81
+ /**
82
+ * Unsubscribe from Zustand state changes
83
+ */
84
+ unsubscribeFromZustand(): void;
85
+ /**
86
+ * Subscribe to Jotai atom changes (if @buoy-gg/jotai is installed)
87
+ */
88
+ subscribeToJotai(): void;
89
+ /**
90
+ * Unsubscribe from Jotai atom changes
91
+ */
92
+ unsubscribeFromJotai(): void;
77
93
  /**
78
94
  * Subscribe to render events (if @buoy-gg/highlight-updates is installed)
79
95
  */
@@ -143,6 +159,10 @@ export declare const subscribeToReactQuery: () => void;
143
159
  export declare const unsubscribeFromReactQuery: () => void;
144
160
  export declare const subscribeToRoutes: () => void;
145
161
  export declare const unsubscribeFromRoutes: () => void;
162
+ export declare const subscribeToZustand: () => void;
163
+ export declare const unsubscribeFromZustand: () => void;
164
+ export declare const subscribeToJotai: () => void;
165
+ export declare const unsubscribeFromJotai: () => void;
146
166
  export declare const subscribeToRender: () => void;
147
167
  export declare const unsubscribeFromRender: () => void;
148
168
  export declare const getEvents: (enabledSources?: Set<EventSource>) => UnifiedEvent[];
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * Event source identifiers
8
8
  */
9
- export type EventSource = "storage-async" | "storage-mmkv" | "redux" | "network" | "react-query" | "react-query-query" | "react-query-mutation" | "route" | "render";
9
+ export type EventSource = "storage-async" | "storage-mmkv" | "redux" | "network" | "react-query" | "react-query-query" | "react-query-mutation" | "route" | "render" | "zustand" | "jotai";
10
10
  /**
11
11
  * Event status for visual indicators
12
12
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/events",
3
- "version": "2.1.10",
3
+ "version": "2.1.13",
4
4
  "description": "events package",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -27,8 +27,8 @@
27
27
  ],
28
28
  "sideEffects": false,
29
29
  "dependencies": {
30
- "@buoy-gg/floating-tools-core": "2.1.10",
31
- "@buoy-gg/shared-ui": "2.1.10"
30
+ "@buoy-gg/floating-tools-core": "2.1.13",
31
+ "@buoy-gg/shared-ui": "2.1.13"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "*",
@@ -308,7 +308,9 @@ export function EventsCopySettingsView({
308
308
  <DataViewer
309
309
  data={JSON.parse(exportText)}
310
310
  title=""
311
- showTypeFilter={false}
311
+ showTypeFilter={true}
312
+ rawMode={true}
313
+ initialExpanded={true}
312
314
  />
313
315
  ) : (
314
316
  <View>
@@ -184,7 +184,8 @@ export const ReactQueryEventDetail = memo(function ReactQueryEventDetail({
184
184
  <DataViewer
185
185
  title=""
186
186
  data={reactQueryEvent.mutationVariables}
187
- showTypeFilter={false}
187
+ showTypeFilter={true}
188
+ rawMode={true}
188
189
  initialExpanded={true}
189
190
  />
190
191
  </View>
@@ -203,7 +204,8 @@ export const ReactQueryEventDetail = memo(function ReactQueryEventDetail({
203
204
  <DataViewer
204
205
  title=""
205
206
  data={isQuery ? reactQueryEvent.queryData : reactQueryEvent.mutationData}
206
- showTypeFilter={false}
207
+ showTypeFilter={true}
208
+ rawMode={true}
207
209
  initialExpanded={true}
208
210
  />
209
211
  </View>
@@ -220,7 +222,8 @@ export const ReactQueryEventDetail = memo(function ReactQueryEventDetail({
220
222
  <DataViewer
221
223
  title=""
222
224
  data={isQuery ? reactQueryEvent.queryError : reactQueryEvent.mutationError}
223
- showTypeFilter={false}
225
+ showTypeFilter={true}
226
+ rawMode={true}
224
227
  initialExpanded={true}
225
228
  />
226
229
  </View>
@@ -237,6 +240,7 @@ export const ReactQueryEventDetail = memo(function ReactQueryEventDetail({
237
240
  title=""
238
241
  data={reactQueryEvent}
239
242
  showTypeFilter={true}
243
+ rawMode={true}
240
244
  initialExpanded={false}
241
245
  />
242
246
  </View>