@buoy-gg/storage 1.7.8 → 2.1.2

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 (26) hide show
  1. package/lib/commonjs/index.js +219 -16
  2. package/lib/commonjs/storage/components/StorageEventCard.js +112 -0
  3. package/lib/commonjs/storage/components/StorageModalWithTabs.js +45 -190
  4. package/lib/commonjs/storage/hooks/useStorageEvents.js +98 -0
  5. package/lib/commonjs/storage/index.js +111 -2
  6. package/lib/commonjs/storage/stores/storageEventStore.js +243 -0
  7. package/lib/module/index.js +74 -3
  8. package/lib/module/storage/components/StorageEventCard.js +107 -0
  9. package/lib/module/storage/components/StorageModalWithTabs.js +47 -193
  10. package/lib/module/storage/hooks/useStorageEvents.js +95 -0
  11. package/lib/module/storage/index.js +7 -1
  12. package/lib/module/storage/stores/storageEventStore.js +231 -0
  13. package/lib/typescript/index.d.ts +36 -1
  14. package/lib/typescript/index.d.ts.map +1 -1
  15. package/lib/typescript/storage/components/StorageActionButtons.d.ts +0 -2
  16. package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +1 -1
  17. package/lib/typescript/storage/components/StorageEventCard.d.ts +40 -0
  18. package/lib/typescript/storage/components/StorageEventCard.d.ts.map +1 -0
  19. package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
  20. package/lib/typescript/storage/hooks/useStorageEvents.d.ts +51 -0
  21. package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +1 -0
  22. package/lib/typescript/storage/index.d.ts +4 -0
  23. package/lib/typescript/storage/index.d.ts.map +1 -1
  24. package/lib/typescript/storage/stores/storageEventStore.d.ts +113 -0
  25. package/lib/typescript/storage/stores/storageEventStore.d.ts.map +1 -0
  26. package/package.json +18 -4
@@ -3,32 +3,235 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- var _exportNames = {
7
- storageToolPreset: true,
8
- createStorageTool: true
9
- };
6
+ Object.defineProperty(exports, "MMKVInstanceInfoPanel", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _MMKVInstanceInfoPanel.MMKVInstanceInfoPanel;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "MMKVInstanceSelector", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _MMKVInstanceSelector.MMKVInstanceSelector;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "StorageBrowserMode", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _StorageBrowserMode.StorageBrowserMode;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "StorageEventCard", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _StorageEventCard.StorageEventCard;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "StorageEventDetailContent", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _StorageEventDetailContent.StorageEventDetailContent;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "StorageEventDetailFooter", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _StorageEventDetailContent.StorageEventDetailFooter;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "StorageEventsSection", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _StorageEventsSection.StorageEventsSection;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "StorageKeyCard", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _StorageKeyCard.StorageKeyCard;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "StorageKeySection", {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _StorageKeySection.StorageKeySection;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "StorageKeyStatsSection", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _StorageKeyStats.StorageKeyStatsSection;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "StorageModalWithTabs", {
67
+ enumerable: true,
68
+ get: function () {
69
+ return _StorageModalWithTabs.StorageModalWithTabs;
70
+ }
71
+ });
72
+ Object.defineProperty(exports, "StorageSection", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _StorageSection.StorageSection;
76
+ }
77
+ });
78
+ Object.defineProperty(exports, "canUndo", {
79
+ enumerable: true,
80
+ get: function () {
81
+ return _storageTimeTravelUtils.canUndo;
82
+ }
83
+ });
84
+ Object.defineProperty(exports, "clearAllAppStorage", {
85
+ enumerable: true,
86
+ get: function () {
87
+ return _clearAllStorage.clearAllAppStorage;
88
+ }
89
+ });
10
90
  Object.defineProperty(exports, "createStorageTool", {
11
91
  enumerable: true,
12
92
  get: function () {
13
93
  return _preset.createStorageTool;
14
94
  }
15
95
  });
96
+ Object.defineProperty(exports, "detectMMKVType", {
97
+ enumerable: true,
98
+ get: function () {
99
+ return _mmkvTypeDetection.detectMMKVType;
100
+ }
101
+ });
102
+ Object.defineProperty(exports, "formatMMKVValue", {
103
+ enumerable: true,
104
+ get: function () {
105
+ return _mmkvTypeDetection.formatMMKVValue;
106
+ }
107
+ });
108
+ Object.defineProperty(exports, "getMMKVClass", {
109
+ enumerable: true,
110
+ get: function () {
111
+ return _mmkvAvailability.getMMKVClass;
112
+ }
113
+ });
114
+ Object.defineProperty(exports, "getMMKVUnavailableMessage", {
115
+ enumerable: true,
116
+ get: function () {
117
+ return _mmkvAvailability.getMMKVUnavailableMessage;
118
+ }
119
+ });
120
+ Object.defineProperty(exports, "getValueType", {
121
+ enumerable: true,
122
+ get: function () {
123
+ return _StorageEventCard.getValueType;
124
+ }
125
+ });
126
+ Object.defineProperty(exports, "isMMKVAvailable", {
127
+ enumerable: true,
128
+ get: function () {
129
+ return _mmkvAvailability.isMMKVAvailable;
130
+ }
131
+ });
132
+ Object.defineProperty(exports, "isTypeMatch", {
133
+ enumerable: true,
134
+ get: function () {
135
+ return _mmkvTypeDetection.isTypeMatch;
136
+ }
137
+ });
138
+ Object.defineProperty(exports, "jumpToState", {
139
+ enumerable: true,
140
+ get: function () {
141
+ return _storageTimeTravelUtils.jumpToState;
142
+ }
143
+ });
144
+ Object.defineProperty(exports, "registerMMKVInstance", {
145
+ enumerable: true,
146
+ get: function () {
147
+ return _MMKVInstanceRegistry.registerMMKVInstance;
148
+ }
149
+ });
150
+ Object.defineProperty(exports, "storageEventStore", {
151
+ enumerable: true,
152
+ get: function () {
153
+ return _storageEventStore.storageEventStore;
154
+ }
155
+ });
16
156
  Object.defineProperty(exports, "storageToolPreset", {
17
157
  enumerable: true,
18
158
  get: function () {
19
159
  return _preset.storageToolPreset;
20
160
  }
21
161
  });
162
+ Object.defineProperty(exports, "undoOperation", {
163
+ enumerable: true,
164
+ get: function () {
165
+ return _storageTimeTravelUtils.undoOperation;
166
+ }
167
+ });
168
+ Object.defineProperty(exports, "unregisterMMKVInstance", {
169
+ enumerable: true,
170
+ get: function () {
171
+ return _MMKVInstanceRegistry.unregisterMMKVInstance;
172
+ }
173
+ });
174
+ Object.defineProperty(exports, "useAsyncStorageKeys", {
175
+ enumerable: true,
176
+ get: function () {
177
+ return _useAsyncStorageKeys.useAsyncStorageKeys;
178
+ }
179
+ });
180
+ Object.defineProperty(exports, "useMMKVInstance", {
181
+ enumerable: true,
182
+ get: function () {
183
+ return _useMMKVInstances.useMMKVInstance;
184
+ }
185
+ });
186
+ Object.defineProperty(exports, "useMMKVInstanceExists", {
187
+ enumerable: true,
188
+ get: function () {
189
+ return _useMMKVInstances.useMMKVInstanceExists;
190
+ }
191
+ });
192
+ Object.defineProperty(exports, "useMMKVInstances", {
193
+ enumerable: true,
194
+ get: function () {
195
+ return _useMMKVInstances.useMMKVInstances;
196
+ }
197
+ });
198
+ Object.defineProperty(exports, "useMMKVKeys", {
199
+ enumerable: true,
200
+ get: function () {
201
+ return _useMMKVKeys.useMMKVKeys;
202
+ }
203
+ });
204
+ Object.defineProperty(exports, "useMultiMMKVKeys", {
205
+ enumerable: true,
206
+ get: function () {
207
+ return _useMMKVKeys.useMultiMMKVKeys;
208
+ }
209
+ });
210
+ Object.defineProperty(exports, "useStorageEvents", {
211
+ enumerable: true,
212
+ get: function () {
213
+ return _useStorageEvents.useStorageEvents;
214
+ }
215
+ });
22
216
  var _preset = require("./preset");
23
- var _storage = require("./storage");
24
- Object.keys(_storage).forEach(function (key) {
25
- if (key === "default" || key === "__esModule") return;
26
- if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
27
- if (key in exports && exports[key] === _storage[key]) return;
28
- Object.defineProperty(exports, key, {
29
- enumerable: true,
30
- get: function () {
31
- return _storage[key];
32
- }
33
- });
34
- });
217
+ var _StorageSection = require("./storage/components/StorageSection");
218
+ var _StorageModalWithTabs = require("./storage/components/StorageModalWithTabs");
219
+ var _StorageKeyCard = require("./storage/components/StorageKeyCard");
220
+ var _StorageKeyStats = require("./storage/components/StorageKeyStats");
221
+ var _StorageKeySection = require("./storage/components/StorageKeySection");
222
+ var _StorageBrowserMode = require("./storage/components/StorageBrowserMode");
223
+ var _StorageEventsSection = require("./storage/components/StorageEventsSection");
224
+ var _StorageEventCard = require("./storage/components/StorageEventCard");
225
+ var _StorageEventDetailContent = require("./storage/components/StorageEventDetailContent");
226
+ var _MMKVInstanceSelector = require("./storage/components/MMKVInstanceSelector");
227
+ var _MMKVInstanceInfoPanel = require("./storage/components/MMKVInstanceInfoPanel");
228
+ var _useAsyncStorageKeys = require("./storage/hooks/useAsyncStorageKeys");
229
+ var _useMMKVKeys = require("./storage/hooks/useMMKVKeys");
230
+ var _useMMKVInstances = require("./storage/hooks/useMMKVInstances");
231
+ var _useStorageEvents = require("./storage/hooks/useStorageEvents");
232
+ var _clearAllStorage = require("./storage/utils/clearAllStorage");
233
+ var _mmkvAvailability = require("./storage/utils/mmkvAvailability");
234
+ var _mmkvTypeDetection = require("./storage/utils/mmkvTypeDetection");
235
+ var _storageTimeTravelUtils = require("./storage/utils/storageTimeTravelUtils");
236
+ var _MMKVInstanceRegistry = require("./storage/utils/MMKVInstanceRegistry");
237
+ var _storageEventStore = require("./storage/stores/storageEventStore");
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StorageEventCard = void 0;
7
+ exports.getValueType = getValueType;
8
+ var _react = require("react");
9
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
+ var _storageActionHelpers = require("../utils/storageActionHelpers");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ /**
13
+ * StorageEventCard
14
+ *
15
+ * Shared card component for displaying storage events.
16
+ * Used by both Storage DevTools and Events DevTools for consistent UI.
17
+ * Uses CompactRow for consistent layout with Redux/React Query cards.
18
+ */
19
+
20
+ /** Value type for storage events */
21
+
22
+ /**
23
+ * Compute value type from a value
24
+ */
25
+ function getValueType(value) {
26
+ const parsed = (0, _sharedUi.parseValue)(value);
27
+ if (parsed === null) return "null";
28
+ if (parsed === undefined) return "undefined";
29
+ if (Array.isArray(parsed)) return "array";
30
+ if (typeof parsed === "boolean") return "boolean";
31
+ if (typeof parsed === "number") return "number";
32
+ if (typeof parsed === "string") return "string";
33
+ if (typeof parsed === "object") return "object";
34
+ return "undefined";
35
+ }
36
+ /**
37
+ * Get color for action type
38
+ */
39
+ function getActionColor(action) {
40
+ switch (action) {
41
+ // AsyncStorage & MMKV - Set operations
42
+ case "setItem":
43
+ case "multiSet":
44
+ case "set.string":
45
+ case "set.number":
46
+ case "set.boolean":
47
+ case "set.buffer":
48
+ return _sharedUi.macOSColors.semantic.success;
49
+
50
+ // AsyncStorage & MMKV - Remove/Delete operations
51
+ case "removeItem":
52
+ case "multiRemove":
53
+ case "clear":
54
+ case "delete":
55
+ case "clearAll":
56
+ return _sharedUi.macOSColors.semantic.error;
57
+
58
+ // AsyncStorage - Merge operations
59
+ case "mergeItem":
60
+ case "multiMerge":
61
+ return _sharedUi.macOSColors.semantic.info;
62
+
63
+ // MMKV - Get operations
64
+ case "get.string":
65
+ case "get.number":
66
+ case "get.boolean":
67
+ case "get.buffer":
68
+ return _sharedUi.macOSColors.semantic.warning;
69
+ default:
70
+ return _sharedUi.macOSColors.text.muted;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Get storage type label for sublabel
76
+ */
77
+ function getStorageTypeSublabel(storageTypes, totalOps) {
78
+ const types = Array.from(storageTypes).map(t => t === "async" ? "Async" : "MMKV").join("/");
79
+ return `${types} · ${totalOps} op${totalOps !== 1 ? "s" : ""}`;
80
+ }
81
+ const StorageEventCard = exports.StorageEventCard = /*#__PURE__*/(0, _react.memo)(function StorageEventCard({
82
+ data,
83
+ onPress,
84
+ isSelected = false,
85
+ showChevron = true
86
+ }) {
87
+ const actionColor = getActionColor(data.lastAction);
88
+ const actionLabel = (0, _storageActionHelpers.translateStorageAction)(data.lastAction);
89
+ const totalOps = data.totalOperations ?? 1;
90
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow
91
+ // Status section (left) - shows "Storage" with action-colored dot
92
+ , {
93
+ statusDotColor: actionColor,
94
+ statusLabel: "Storage",
95
+ statusSublabel: getStorageTypeSublabel(data.storageTypes, totalOps)
96
+ // Content section (middle) - shows the key name
97
+ ,
98
+ primaryText: data.key
99
+ // Badge section (right) - shows action label (SET, REMOVE, etc.)
100
+ ,
101
+ badgeText: actionLabel,
102
+ badgeColor: actionColor,
103
+ showChevron: showChevron
104
+ // Bottom right - timestamp
105
+ ,
106
+ bottomRightText: (0, _sharedUi.formatRelativeTime)(data.lastEventTimestamp)
107
+ // Interaction
108
+ ,
109
+ isSelected: isSelected,
110
+ onPress: onPress
111
+ });
112
+ });
@@ -12,22 +12,16 @@ var _sharedUi = require("@buoy-gg/shared-ui");
12
12
  var _StorageBrowserMode = require("./StorageBrowserMode");
13
13
  var _clearAllStorage = require("../utils/clearAllStorage");
14
14
  var _AsyncStorageListener = require("../utils/AsyncStorageListener");
15
+ var _useStorageEvents = require("../hooks/useStorageEvents");
15
16
  var _StorageEventDetailContent = require("./StorageEventDetailContent");
16
17
  var _StorageFilterViewV = require("./StorageFilterViewV2");
17
18
  var _StorageEventFilterView = require("./StorageEventFilterView");
18
- var _storageActionHelpers = require("../utils/storageActionHelpers");
19
- var _mmkvAvailability = require("../utils/mmkvAvailability");
19
+ var _StorageEventCard = require("./StorageEventCard");
20
20
  var _license = require("@buoy-gg/license");
21
21
  var _jsxRuntime = require("react/jsx-runtime");
22
22
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
- // Conditionally import MMKV listener
24
- let addMMKVListener;
25
- if ((0, _mmkvAvailability.isMMKVAvailable)()) {
26
- const mmkvListener = require("../utils/MMKVListener");
27
- addMMKVListener = mmkvListener.addMMKVListener;
28
- }
29
-
30
- // Unified storage event type
23
+ // Note: StorageEvent type is now imported from useStorageEvents hook
24
+ // which handles both AsyncStorage and MMKV events via the centralized store
31
25
 
32
26
  // Free tier limit for storage events/conversations
33
27
  const FREE_TIER_EVENT_LIMIT = exports.FREE_TIER_EVENT_LIMIT = 25;
@@ -50,8 +44,16 @@ function StorageModalWithTabs({
50
44
  const [isSearchActive, setIsSearchActive] = (0, _react.useState)(false);
51
45
  const hasLoadedStorageFilters = (0, _react.useRef)(false);
52
46
 
53
- // Event Listener state
54
- const [events, setEvents] = (0, _react.useState)([]);
47
+ // Event Listener state - using centralized store via hook
48
+ const {
49
+ events,
50
+ clearEvents: clearStorageEvents,
51
+ isCapturing,
52
+ startCapturing,
53
+ stopCapturing
54
+ } = (0, _useStorageEvents.useStorageEvents)({
55
+ autoStart: false
56
+ }); // Don't auto-start, we manage it
55
57
  const [isListening, setIsListening] = (0, _react.useState)(false);
56
58
  const [selectedConversationKey, setSelectedConversationKey] = (0, _react.useState)(null);
57
59
  const [selectedEventIndex, setSelectedEventIndex] = (0, _react.useState)(0);
@@ -64,6 +66,11 @@ function StorageModalWithTabs({
64
66
  const hasLoadedFilters = (0, _react.useRef)(false);
65
67
  const hasLoadedTabState = (0, _react.useRef)(false);
66
68
  const hasLoadedMonitoringState = (0, _react.useRef)(false);
69
+
70
+ // Sync isListening state with hook's isCapturing
71
+ (0, _react.useEffect)(() => {
72
+ setIsListening(isCapturing);
73
+ }, [isCapturing]);
67
74
  const handleModeChange = (0, _react.useCallback)(_mode => {
68
75
  // Mode changes handled by JsModal
69
76
  }, []);
@@ -95,9 +102,8 @@ function StorageModalWithTabs({
95
102
  const storedMonitoring = await _asyncStorage.default.getItem(_sharedUi.devToolsStorageKeys.storage.isMonitoring());
96
103
  if (storedMonitoring !== null) {
97
104
  const shouldMonitor = storedMonitoring === "true";
98
- if (shouldMonitor && !(0, _AsyncStorageListener.isListening)()) {
99
- await (0, _AsyncStorageListener.startListening)();
100
- setIsListening(true);
105
+ if (shouldMonitor && !isCapturing) {
106
+ await startCapturing();
101
107
  }
102
108
  }
103
109
  hasLoadedMonitoringState.current = true;
@@ -106,7 +112,7 @@ function StorageModalWithTabs({
106
112
  }
107
113
  };
108
114
  loadMonitoringState();
109
- }, [visible]);
115
+ }, [visible, isCapturing, startCapturing]);
110
116
 
111
117
  // Note: Conversations will appear when storage events are triggered
112
118
  // Click on any conversation to see the unified view with toggle cards
@@ -172,65 +178,21 @@ function StorageModalWithTabs({
172
178
  saveFilters();
173
179
  }, [ignoredPatterns]);
174
180
 
175
- // Sync isListening state with actual listener state on mount
176
- (0, _react.useEffect)(() => {
177
- if (!visible) return;
178
-
179
- // Check if already listening and sync state
180
- const listening = (0, _AsyncStorageListener.isListening)();
181
- setIsListening(listening);
182
- }, [visible]);
181
+ // Event listener setup - now handled by useStorageEvents hook
182
+ // The hook subscribes to the centralized storageEventStore
183
183
 
184
- // Event listener setup - only collect events when isListening is true
185
- (0, _react.useEffect)(() => {
186
- if (!visible || !isListening) return;
187
-
188
- // Set up AsyncStorage event listener
189
- const unsubscribeAsync = (0, _AsyncStorageListener.addListener)(event => {
190
- const storageEvent = {
191
- ...event,
192
- storageType: 'async'
193
- };
194
- lastEventRef.current = storageEvent;
195
- setEvents(prev => {
196
- const updated = [storageEvent, ...prev];
197
- return updated.slice(0, 500);
198
- });
199
- });
200
-
201
- // Set up MMKV event listener (if available)
202
- let unsubscribeMMKV = () => {};
203
- if ((0, _mmkvAvailability.isMMKVAvailable)() && addMMKVListener) {
204
- unsubscribeMMKV = addMMKVListener(event => {
205
- const storageEvent = {
206
- ...event,
207
- storageType: 'mmkv'
208
- };
209
- lastEventRef.current = storageEvent;
210
- setEvents(prev => {
211
- const updated = [storageEvent, ...prev];
212
- return updated.slice(0, 500);
213
- });
214
- });
215
- }
216
- return () => {
217
- unsubscribeAsync();
218
- unsubscribeMMKV();
219
- };
220
- }, [visible, isListening]);
221
184
  const handleToggleListening = (0, _react.useCallback)(async () => {
222
185
  if (isListening) {
223
- (0, _AsyncStorageListener.stopListening)();
224
- setIsListening(false);
186
+ stopCapturing();
187
+ (0, _AsyncStorageListener.stopListening)(); // Also stop the underlying AsyncStorage listener
225
188
  } else {
226
- await (0, _AsyncStorageListener.startListening)();
227
- setIsListening(true);
189
+ await startCapturing();
228
190
  }
229
- }, [isListening]);
191
+ }, [isListening, startCapturing, stopCapturing]);
230
192
  const handleClearEvents = (0, _react.useCallback)(() => {
231
- setEvents([]);
193
+ clearStorageEvents();
232
194
  setSelectedConversationKey(null);
233
- }, []);
195
+ }, [clearStorageEvents]);
234
196
  const handleConversationPress = (0, _react.useCallback)(conversation => {
235
197
  setSelectedConversationKey(conversation.key);
236
198
  setSelectedEventIndex(0);
@@ -407,44 +369,6 @@ function StorageModalWithTabs({
407
369
  if (isPro) return 0;
408
370
  return Math.max(0, conversations.length - FREE_TIER_EVENT_LIMIT);
409
371
  }, [conversations.length, isPro]);
410
- const getActionColor = action => {
411
- switch (action) {
412
- // AsyncStorage - Set operations
413
- case "setItem":
414
- case "multiSet":
415
- // MMKV - Set operations
416
- // falls through
417
- case "set.string":
418
- case "set.number":
419
- case "set.boolean":
420
- case "set.buffer":
421
- return _sharedUi.macOSColors.semantic.success;
422
-
423
- // AsyncStorage - Remove operations
424
- case "removeItem":
425
- case "multiRemove":
426
- case "clear":
427
- // MMKV - Delete operations
428
- // falls through
429
- case "delete":
430
- case "clearAll":
431
- return _sharedUi.macOSColors.semantic.error;
432
-
433
- // AsyncStorage - Merge operations
434
- case "mergeItem":
435
- case "multiMerge":
436
- return _sharedUi.macOSColors.semantic.info;
437
-
438
- // MMKV - Get operations
439
- case "get.string":
440
- case "get.number":
441
- case "get.boolean":
442
- case "get.buffer":
443
- return _sharedUi.macOSColors.semantic.warning;
444
- default:
445
- return _sharedUi.macOSColors.text.muted;
446
- }
447
- };
448
372
 
449
373
  // FlatList optimization constants
450
374
  const END_REACHED_THRESHOLD = 0.8;
@@ -464,35 +388,17 @@ function StorageModalWithTabs({
464
388
  const renderConversationItem = (0, _react.useCallback)(({
465
389
  item
466
390
  }) => {
467
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
468
- onPress: () => selectConversationRef.current?.(item),
469
- style: styles.conversationItem,
470
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
471
- style: styles.conversationHeader,
472
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
473
- style: styles.keyText,
474
- numberOfLines: 1,
475
- children: item.key
476
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
477
- style: [styles.actionText, {
478
- color: getActionColor(item.lastEvent.action)
479
- }],
480
- children: (0, _storageActionHelpers.translateStorageAction)(item.lastEvent.action)
481
- })]
482
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
483
- style: styles.conversationDetails,
484
- children: [item.storageTypes && Array.from(item.storageTypes).map(storageType => /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.StorageTypeBadge, {
485
- type: storageType
486
- }, storageType)), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ValueTypeBadge, {
487
- type: item.valueType
488
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
489
- style: styles.operationCount,
490
- children: [item.totalOperations, " operation", item.totalOperations !== 1 ? "s" : ""]
491
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
492
- style: styles.timestamp,
493
- children: (0, _sharedUi.formatRelativeTime)(item.lastEvent.timestamp)
494
- })]
495
- })]
391
+ const cardData = {
392
+ key: item.key,
393
+ lastAction: item.lastEvent.action,
394
+ totalOperations: item.totalOperations,
395
+ lastEventTimestamp: item.lastEvent.timestamp,
396
+ storageTypes: item.storageTypes,
397
+ valueType: item.valueType
398
+ };
399
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventCard.StorageEventCard, {
400
+ data: cardData,
401
+ onPress: () => selectConversationRef.current?.(item)
496
402
  });
497
403
  }, []);
498
404
  if (!visible) return null;
@@ -671,16 +577,10 @@ function StorageModalWithTabs({
671
577
  size: 14,
672
578
  color: ignoredPatterns.size > 0 ? _sharedUi.macOSColors.semantic.debug : _sharedUi.macOSColors.text.secondary
673
579
  })
674
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
675
- onPress: handleToggleListening,
676
- style: [styles.iconButton, isListening && styles.activeButton],
677
- children: isListening ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Pause, {
678
- size: 14,
679
- color: _sharedUi.macOSColors.semantic.success
680
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Play, {
681
- size: 14,
682
- color: _sharedUi.macOSColors.semantic.success
683
- })
580
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PowerToggleButton, {
581
+ isEnabled: isListening,
582
+ onToggle: handleToggleListening,
583
+ accessibilityLabel: "Toggle storage event monitoring"
684
584
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
685
585
  onPress: handleClearEvents,
686
586
  style: styles.iconButton,
@@ -717,54 +617,9 @@ const styles = _reactNative.StyleSheet.create({
717
617
  alignItems: "center",
718
618
  justifyContent: "center"
719
619
  },
720
- activeButton: {
721
- backgroundColor: _sharedUi.macOSColors.semantic.successBackground
722
- },
723
620
  activeFilterButton: {
724
621
  backgroundColor: _sharedUi.macOSColors.semantic.infoBackground
725
622
  },
726
- conversationItem: {
727
- padding: 12,
728
- backgroundColor: _sharedUi.macOSColors.background.card,
729
- borderRadius: 8,
730
- marginHorizontal: 16
731
- },
732
- conversationHeader: {
733
- flexDirection: "row",
734
- justifyContent: "space-between",
735
- alignItems: "center",
736
- marginBottom: 8
737
- },
738
- keyText: {
739
- color: _sharedUi.macOSColors.text.primary,
740
- fontSize: 14,
741
- fontWeight: "600",
742
- flex: 1,
743
- marginRight: 8,
744
- fontFamily: "monospace"
745
- },
746
- actionText: {
747
- fontSize: 11,
748
- fontWeight: "600",
749
- fontFamily: "monospace",
750
- textTransform: "uppercase"
751
- },
752
- conversationDetails: {
753
- flexDirection: "row",
754
- alignItems: "center",
755
- gap: 8
756
- },
757
- operationCount: {
758
- color: _sharedUi.macOSColors.text.secondary,
759
- fontSize: 11,
760
- flex: 1,
761
- fontFamily: "monospace"
762
- },
763
- timestamp: {
764
- color: _sharedUi.macOSColors.text.muted,
765
- fontSize: 11,
766
- fontFamily: "monospace"
767
- },
768
623
  separator: {
769
624
  height: 8
770
625
  },