@buoy-gg/storage 1.7.7 → 2.1.1

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 (61) hide show
  1. package/lib/commonjs/index.js +219 -16
  2. package/lib/commonjs/storage/components/DiffViewer/themes/diffThemes.js +35 -44
  3. package/lib/commonjs/storage/components/GameUIStorageBrowser.js +9 -23
  4. package/lib/commonjs/storage/components/SelectionActionBar.js +8 -22
  5. package/lib/commonjs/storage/components/StorageActionButtons.js +8 -22
  6. package/lib/commonjs/storage/components/StorageActions.js +8 -22
  7. package/lib/commonjs/storage/components/StorageEventActionButton.js +120 -0
  8. package/lib/commonjs/storage/components/StorageEventCard.js +112 -0
  9. package/lib/commonjs/storage/components/StorageEventDetailContent.js +331 -822
  10. package/lib/commonjs/storage/components/StorageModalWithTabs.js +43 -200
  11. package/lib/commonjs/storage/hooks/useStorageEvents.js +98 -0
  12. package/lib/commonjs/storage/index.js +111 -2
  13. package/lib/commonjs/storage/stores/storageEventStore.js +243 -0
  14. package/lib/commonjs/storage/utils/AsyncStorageListener.js +164 -35
  15. package/lib/commonjs/storage/utils/index.js +37 -0
  16. package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +251 -0
  17. package/lib/module/index.js +74 -3
  18. package/lib/module/storage/components/DiffViewer/themes/diffThemes.js +35 -44
  19. package/lib/module/storage/components/GameUIStorageBrowser.js +9 -23
  20. package/lib/module/storage/components/SelectionActionBar.js +9 -24
  21. package/lib/module/storage/components/StorageActionButtons.js +9 -24
  22. package/lib/module/storage/components/StorageActions.js +9 -24
  23. package/lib/module/storage/components/StorageEventActionButton.js +117 -0
  24. package/lib/module/storage/components/StorageEventCard.js +107 -0
  25. package/lib/module/storage/components/StorageEventDetailContent.js +332 -824
  26. package/lib/module/storage/components/StorageModalWithTabs.js +45 -202
  27. package/lib/module/storage/hooks/useStorageEvents.js +95 -0
  28. package/lib/module/storage/index.js +7 -1
  29. package/lib/module/storage/stores/storageEventStore.js +231 -0
  30. package/lib/module/storage/utils/AsyncStorageListener.js +159 -33
  31. package/lib/module/storage/utils/index.js +4 -1
  32. package/lib/module/storage/utils/storageTimeTravelUtils.js +245 -0
  33. package/lib/typescript/index.d.ts +36 -1
  34. package/lib/typescript/index.d.ts.map +1 -1
  35. package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts +1 -1
  36. package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +1 -1
  37. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -1
  38. package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +1 -1
  39. package/lib/typescript/storage/components/StorageActionButtons.d.ts +0 -2
  40. package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +1 -1
  41. package/lib/typescript/storage/components/StorageActions.d.ts.map +1 -1
  42. package/lib/typescript/storage/components/StorageEventActionButton.d.ts +37 -0
  43. package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +1 -0
  44. package/lib/typescript/storage/components/StorageEventCard.d.ts +40 -0
  45. package/lib/typescript/storage/components/StorageEventCard.d.ts.map +1 -0
  46. package/lib/typescript/storage/components/StorageEventDetailContent.d.ts +11 -3
  47. package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +1 -1
  48. package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
  49. package/lib/typescript/storage/hooks/useStorageEvents.d.ts +51 -0
  50. package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +1 -0
  51. package/lib/typescript/storage/index.d.ts +4 -0
  52. package/lib/typescript/storage/index.d.ts.map +1 -1
  53. package/lib/typescript/storage/stores/storageEventStore.d.ts +113 -0
  54. package/lib/typescript/storage/stores/storageEventStore.d.ts.map +1 -0
  55. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts +38 -1
  56. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +1 -1
  57. package/lib/typescript/storage/utils/index.d.ts +2 -1
  58. package/lib/typescript/storage/utils/index.d.ts.map +1 -1
  59. package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts +35 -0
  60. package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +1 -0
  61. package/package.json +20 -4
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.subscribeToStorageEvents = exports.storageEventStore = exports.stopStorageCapture = exports.startStorageCapture = exports.resumeStorageCapture = exports.pauseStorageCapture = exports.onStorageEvent = exports.isStorageCapturing = exports.getStorageEvents = exports.clearStorageEvents = void 0;
7
+ var _AsyncStorageListener = require("../utils/AsyncStorageListener");
8
+ var _MMKVListener = require("../utils/MMKVListener");
9
+ /**
10
+ * Storage Event Store
11
+ *
12
+ * Centralized store that aggregates storage events from AsyncStorage and MMKV
13
+ * into a single event stream. This provides a single source of truth for all
14
+ * storage operations, eliminating duplicate subscriptions across components.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { storageEventStore } from '@buoy-gg/storage';
19
+ *
20
+ * // Subscribe to storage events
21
+ * const unsubscribe = storageEventStore.subscribe((events) => {
22
+ * console.log('Storage events:', events);
23
+ * });
24
+ *
25
+ * // Start capturing (must be called once)
26
+ * await storageEventStore.startCapturing();
27
+ *
28
+ * // Later, clean up
29
+ * unsubscribe();
30
+ * ```
31
+ */
32
+
33
+ /**
34
+ * Unified storage event type combining AsyncStorage and MMKV events
35
+ */
36
+
37
+ /**
38
+ * Listener callback type for storage events
39
+ */
40
+
41
+ /**
42
+ * Listener callback for individual new events
43
+ */
44
+
45
+ const MAX_EVENTS = 500;
46
+ class StorageEventStore {
47
+ events = [];
48
+ listeners = new Set();
49
+ eventCallbacks = new Set();
50
+ isCapturing = false;
51
+
52
+ // Unsubscribe functions
53
+ asyncStorageUnsubscribe = null;
54
+ mmkvUnsubscribe = null;
55
+
56
+ /**
57
+ * Start capturing storage events from both AsyncStorage and MMKV
58
+ */
59
+ async startCapturing() {
60
+ if (this.isCapturing) {
61
+ return;
62
+ }
63
+
64
+ // Start AsyncStorage listening if not already active
65
+ if (!(0, _AsyncStorageListener.isListening)()) {
66
+ await (0, _AsyncStorageListener.startListening)();
67
+ }
68
+
69
+ // Subscribe to AsyncStorage events
70
+ this.asyncStorageUnsubscribe = (0, _AsyncStorageListener.addListener)(event => {
71
+ const storageEvent = {
72
+ ...event,
73
+ storageType: "async"
74
+ };
75
+ this.addEvent(storageEvent);
76
+ });
77
+
78
+ // Subscribe to MMKV events
79
+ this.mmkvUnsubscribe = (0, _MMKVListener.addMMKVListener)(event => {
80
+ const storageEvent = {
81
+ ...event,
82
+ storageType: "mmkv"
83
+ };
84
+ this.addEvent(storageEvent);
85
+ });
86
+ this.isCapturing = true;
87
+ }
88
+
89
+ /**
90
+ * Stop capturing storage events
91
+ */
92
+ stopCapturing() {
93
+ if (!this.isCapturing) {
94
+ return;
95
+ }
96
+
97
+ // Unsubscribe from AsyncStorage
98
+ if (this.asyncStorageUnsubscribe) {
99
+ this.asyncStorageUnsubscribe();
100
+ this.asyncStorageUnsubscribe = null;
101
+ }
102
+
103
+ // Unsubscribe from MMKV
104
+ if (this.mmkvUnsubscribe) {
105
+ this.mmkvUnsubscribe();
106
+ this.mmkvUnsubscribe = null;
107
+ }
108
+ this.isCapturing = false;
109
+ }
110
+
111
+ /**
112
+ * Pause event capture (used during time-travel operations)
113
+ */
114
+ pauseCapture() {
115
+ (0, _AsyncStorageListener.pauseCapture)();
116
+ // MMKV listener doesn't have pause, but it's less common for time-travel
117
+ }
118
+
119
+ /**
120
+ * Resume event capture after pausing
121
+ */
122
+ resumeCapture() {
123
+ (0, _AsyncStorageListener.resumeCapture)();
124
+ }
125
+
126
+ /**
127
+ * Add an event to the store
128
+ */
129
+ addEvent(event) {
130
+ // Add to beginning (newest first)
131
+ this.events = [event, ...this.events].slice(0, MAX_EVENTS);
132
+
133
+ // Notify event callbacks (for individual events)
134
+ this.eventCallbacks.forEach(callback => {
135
+ try {
136
+ callback(event);
137
+ } catch {
138
+ // Ignore callback errors
139
+ }
140
+ });
141
+
142
+ // Notify listeners (for full event list)
143
+ this.notifyListeners();
144
+ }
145
+
146
+ /**
147
+ * Subscribe to all storage events (receives full event array on each change)
148
+ */
149
+ subscribe(listener) {
150
+ this.listeners.add(listener);
151
+
152
+ // Immediately call with current events
153
+ listener(this.events);
154
+
155
+ // Return unsubscribe function
156
+ return () => {
157
+ this.listeners.delete(listener);
158
+ };
159
+ }
160
+
161
+ /**
162
+ * Subscribe to new events only (receives individual events as they occur)
163
+ */
164
+ onEvent(callback) {
165
+ this.eventCallbacks.add(callback);
166
+ return () => {
167
+ this.eventCallbacks.delete(callback);
168
+ };
169
+ }
170
+
171
+ /**
172
+ * Notify all listeners of changes
173
+ */
174
+ notifyListeners() {
175
+ const events = this.events;
176
+ this.listeners.forEach(listener => {
177
+ try {
178
+ listener(events);
179
+ } catch {
180
+ // Ignore listener errors
181
+ }
182
+ });
183
+ }
184
+
185
+ /**
186
+ * Get all events
187
+ */
188
+ getEvents() {
189
+ return this.events;
190
+ }
191
+
192
+ /**
193
+ * Get events filtered by storage type
194
+ */
195
+ getEventsByType(storageType) {
196
+ return this.events.filter(event => event.storageType === storageType);
197
+ }
198
+
199
+ /**
200
+ * Get event count
201
+ */
202
+ getEventCount() {
203
+ return this.events.length;
204
+ }
205
+
206
+ /**
207
+ * Clear all events
208
+ */
209
+ clearEvents() {
210
+ this.events = [];
211
+ this.notifyListeners();
212
+ }
213
+
214
+ /**
215
+ * Check if currently capturing events
216
+ */
217
+ get capturing() {
218
+ return this.isCapturing;
219
+ }
220
+ }
221
+
222
+ // Singleton instance
223
+ const storageEventStore = exports.storageEventStore = new StorageEventStore();
224
+
225
+ // Convenience exports
226
+ const startStorageCapture = () => storageEventStore.startCapturing();
227
+ exports.startStorageCapture = startStorageCapture;
228
+ const stopStorageCapture = () => storageEventStore.stopCapturing();
229
+ exports.stopStorageCapture = stopStorageCapture;
230
+ const pauseStorageCapture = () => storageEventStore.pauseCapture();
231
+ exports.pauseStorageCapture = pauseStorageCapture;
232
+ const resumeStorageCapture = () => storageEventStore.resumeCapture();
233
+ exports.resumeStorageCapture = resumeStorageCapture;
234
+ const subscribeToStorageEvents = listener => storageEventStore.subscribe(listener);
235
+ exports.subscribeToStorageEvents = subscribeToStorageEvents;
236
+ const onStorageEvent = callback => storageEventStore.onEvent(callback);
237
+ exports.onStorageEvent = onStorageEvent;
238
+ const getStorageEvents = () => storageEventStore.getEvents();
239
+ exports.getStorageEvents = getStorageEvents;
240
+ const clearStorageEvents = () => storageEventStore.clearEvents();
241
+ exports.clearStorageEvents = clearStorageEvents;
242
+ const isStorageCapturing = () => storageEventStore.capturing;
243
+ exports.isStorageCapturing = isStorageCapturing;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.stopListening = exports.startListening = exports.removeAllListeners = exports.isListening = exports.getListenerCount = exports.default = exports.addListener = void 0;
6
+ exports.stopListening = exports.startListening = exports.resumeCapture = exports.removeAllListeners = exports.pauseCapture = exports.isPaused = exports.isListening = exports.getListenerCount = exports.default = exports.addListener = void 0;
7
7
  var _asyncStorage = _interopRequireDefault(require("@react-native-async-storage/async-storage"));
8
8
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
9
  // AsyncStorage method signatures - matching the actual AsyncStorage API
@@ -40,6 +40,7 @@ class AsyncStorageListener {
40
40
  listeners = [];
41
41
  isListening = false;
42
42
  isInitialized = false;
43
+ isPaused = false;
43
44
 
44
45
  // Keys to ignore for dev tools to prevent self-triggering
45
46
  // Only ignore specific keys that would cause infinite loops in the storage browser
@@ -153,9 +154,14 @@ class AsyncStorageListener {
153
154
  *
154
155
  * @param event - The AsyncStorage event to emit
155
156
  *
156
- * @performance Skips processing when no listeners are registered
157
+ * @performance Skips processing when no listeners are registered or when paused
157
158
  */
158
159
  emit(event) {
160
+ // Skip emitting if paused (used during time-travel operations)
161
+ if (this.isPaused) {
162
+ return;
163
+ }
164
+
159
165
  // Skip emitting if there are no listeners
160
166
  if (this.listeners.length === 0) {
161
167
  return;
@@ -198,16 +204,25 @@ class AsyncStorageListener {
198
204
 
199
205
  // Swizzle setItem
200
206
  const swizzled_setItem = async (key, value) => {
201
- // Only emit event if key is not ignored
207
+ // Only capture and emit if key is not ignored
202
208
  if (!this.shouldIgnoreKey(key)) {
209
+ // Capture previous value before the operation
210
+ const prevValue = this.originalSetItem ? await _asyncStorage.default.getItem(key) : null;
211
+
212
+ // Execute the operation
213
+ const result = this.originalSetItem ? await this.originalSetItem(key, value) : undefined;
214
+
215
+ // Emit event with previous value
203
216
  this.emit({
204
217
  action: "setItem",
205
218
  timestamp: new Date(),
206
219
  data: {
207
220
  key,
208
- value
221
+ value,
222
+ prevValue
209
223
  }
210
224
  });
225
+ return result;
211
226
  }
212
227
  return this.originalSetItem ? this.originalSetItem(key, value) : Promise.resolve();
213
228
  };
@@ -221,19 +236,24 @@ class AsyncStorageListener {
221
236
  // Swizzle removeItem
222
237
  if (_asyncStorage.default) {
223
238
  _asyncStorage.default.removeItem = async key => {
224
- // Intercepted removeItem
225
-
226
- // Only emit event if key is not ignored
239
+ // Only capture and emit if key is not ignored
227
240
  if (!this.shouldIgnoreKey(key)) {
241
+ // Capture previous value before the operation
242
+ const prevValue = this.originalRemoveItem ? await _asyncStorage.default.getItem(key) : null;
243
+
244
+ // Execute the operation
245
+ const result = this.originalRemoveItem ? await this.originalRemoveItem(key) : undefined;
246
+
247
+ // Emit event with previous value
228
248
  this.emit({
229
249
  action: "removeItem",
230
250
  timestamp: new Date(),
231
251
  data: {
232
- key
252
+ key,
253
+ prevValue
233
254
  }
234
255
  });
235
- } else {
236
- // Ignoring removeItem for ignored key
256
+ return result;
237
257
  }
238
258
  return this.originalRemoveItem ? this.originalRemoveItem(key) : Promise.resolve();
239
259
  };
@@ -242,20 +262,25 @@ class AsyncStorageListener {
242
262
  // Swizzle mergeItem
243
263
  if (_asyncStorage.default) {
244
264
  _asyncStorage.default.mergeItem = async (key, value) => {
245
- // Intercepted mergeItem operation
246
-
247
- // Only emit event if key is not ignored
265
+ // Only capture and emit if key is not ignored
248
266
  if (!this.shouldIgnoreKey(key)) {
267
+ // Capture previous value before the operation
268
+ const prevValue = this.originalMergeItem ? await _asyncStorage.default.getItem(key) : null;
269
+
270
+ // Execute the operation
271
+ const result = this.originalMergeItem ? await this.originalMergeItem(key, value) : undefined;
272
+
273
+ // Emit event with previous value
249
274
  this.emit({
250
275
  action: "mergeItem",
251
276
  timestamp: new Date(),
252
277
  data: {
253
278
  key,
254
- value
279
+ value,
280
+ prevValue
255
281
  }
256
282
  });
257
- } else {
258
- // Ignoring mergeItem for ignored key
283
+ return result;
259
284
  }
260
285
  return this.originalMergeItem ? this.originalMergeItem(key, value) : Promise.resolve();
261
286
  };
@@ -264,32 +289,64 @@ class AsyncStorageListener {
264
289
  // Swizzle clear
265
290
  if (_asyncStorage.default) {
266
291
  _asyncStorage.default.clear = async () => {
267
- // Intercepted clear operation
292
+ // Capture all key-value pairs before clearing
293
+ let prevPairs = [];
294
+ try {
295
+ const allKeys = await _asyncStorage.default.getAllKeys();
296
+ // Filter out ignored keys
297
+ const keysToCapture = allKeys.filter(key => !this.shouldIgnoreKey(key));
298
+ if (keysToCapture.length > 0) {
299
+ const keyValuePairs = await _asyncStorage.default.multiGet(keysToCapture);
300
+ prevPairs = keyValuePairs;
301
+ }
302
+ } catch {
303
+ // Failed to capture previous state
304
+ }
305
+
306
+ // Execute the operation
307
+ const result = this.originalClear ? await this.originalClear() : undefined;
308
+
309
+ // Emit event with previous pairs
268
310
  this.emit({
269
311
  action: "clear",
270
- timestamp: new Date()
312
+ timestamp: new Date(),
313
+ data: {
314
+ prevPairs
315
+ }
271
316
  });
272
- return this.originalClear ? this.originalClear() : Promise.resolve();
317
+ return result;
273
318
  };
274
319
  }
275
320
 
276
321
  // Swizzle multiSet
277
322
  if (_asyncStorage.default) {
278
323
  _asyncStorage.default.multiSet = async keyValuePairs => {
279
- // Intercepted multiSet operation with multiple pairs
280
-
281
324
  // Filter out ignored keys
282
325
  const filteredPairs = keyValuePairs.filter(([key]) => !this.shouldIgnoreKey(key));
283
326
  if (filteredPairs.length > 0) {
327
+ // Capture previous values for all keys being set
328
+ const keysToSet = filteredPairs.map(([key]) => key);
329
+ let prevPairs = [];
330
+ try {
331
+ const existingValues = await _asyncStorage.default.multiGet(keysToSet);
332
+ prevPairs = existingValues;
333
+ } catch {
334
+ // Failed to capture previous values
335
+ }
336
+
337
+ // Execute the operation
338
+ const result = this.originalMultiSet ? await this.originalMultiSet(keyValuePairs) : undefined;
339
+
340
+ // Emit event with previous values
284
341
  this.emit({
285
342
  action: "multiSet",
286
343
  timestamp: new Date(),
287
344
  data: {
288
- pairs: filteredPairs
345
+ pairs: filteredPairs,
346
+ prevPairs
289
347
  }
290
348
  });
291
- } else {
292
- // All keys in multiSet are ignored
349
+ return result;
293
350
  }
294
351
  return this.originalMultiSet ? this.originalMultiSet(keyValuePairs) : Promise.resolve();
295
352
  };
@@ -298,20 +355,31 @@ class AsyncStorageListener {
298
355
  // Swizzle multiRemove
299
356
  if (_asyncStorage.default) {
300
357
  _asyncStorage.default.multiRemove = async keys => {
301
- // Intercepted multiRemove operation with multiple keys
302
-
303
358
  // Filter out ignored keys
304
359
  const filteredKeys = keys.filter(key => !this.shouldIgnoreKey(key));
305
360
  if (filteredKeys.length > 0) {
361
+ // Capture previous values for all keys being removed
362
+ let prevPairs = [];
363
+ try {
364
+ const existingValues = await _asyncStorage.default.multiGet(filteredKeys);
365
+ prevPairs = existingValues;
366
+ } catch {
367
+ // Failed to capture previous values
368
+ }
369
+
370
+ // Execute the operation
371
+ const result = this.originalMultiRemove ? await this.originalMultiRemove(keys) : undefined;
372
+
373
+ // Emit event with previous values
306
374
  this.emit({
307
375
  action: "multiRemove",
308
376
  timestamp: new Date(),
309
377
  data: {
310
- keys: filteredKeys
378
+ keys: filteredKeys,
379
+ prevPairs
311
380
  }
312
381
  });
313
- } else {
314
- // All keys in multiRemove are ignored
382
+ return result;
315
383
  }
316
384
  return this.originalMultiRemove ? this.originalMultiRemove(keys) : Promise.resolve();
317
385
  };
@@ -320,20 +388,32 @@ class AsyncStorageListener {
320
388
  // Swizzle multiMerge if available
321
389
  if (this.originalMultiMerge && _asyncStorage.default) {
322
390
  _asyncStorage.default.multiMerge = async keyValuePairs => {
323
- // Intercepted multiMerge operation with multiple pairs
324
-
325
391
  // Filter out ignored keys
326
392
  const filteredPairs = keyValuePairs.filter(([key]) => !this.shouldIgnoreKey(key));
327
393
  if (filteredPairs.length > 0) {
394
+ // Capture previous values for all keys being merged
395
+ const keysToMerge = filteredPairs.map(([key]) => key);
396
+ let prevPairs = [];
397
+ try {
398
+ const existingValues = await _asyncStorage.default.multiGet(keysToMerge);
399
+ prevPairs = existingValues;
400
+ } catch {
401
+ // Failed to capture previous values
402
+ }
403
+
404
+ // Execute the operation
405
+ const result = this.originalMultiMerge ? await this.originalMultiMerge(keyValuePairs) : undefined;
406
+
407
+ // Emit event with previous values
328
408
  this.emit({
329
409
  action: "multiMerge",
330
410
  timestamp: new Date(),
331
411
  data: {
332
- pairs: filteredPairs
412
+ pairs: filteredPairs,
413
+ prevPairs
333
414
  }
334
415
  });
335
- } else {
336
- // All keys in multiMerge are ignored
416
+ return result;
337
417
  }
338
418
  return this.originalMultiMerge ? this.originalMultiMerge(keyValuePairs) : Promise.resolve();
339
419
  };
@@ -439,6 +519,32 @@ class AsyncStorageListener {
439
519
  get listenerCount() {
440
520
  return this.listeners.length;
441
521
  }
522
+
523
+ /**
524
+ * Pause event emission (used during time-travel operations)
525
+ *
526
+ * When paused, storage operations still execute but events are not emitted.
527
+ * This prevents circular event triggering during replay/jump operations.
528
+ */
529
+ pause() {
530
+ this.isPaused = true;
531
+ }
532
+
533
+ /**
534
+ * Resume event emission after pausing
535
+ */
536
+ resume() {
537
+ this.isPaused = false;
538
+ }
539
+
540
+ /**
541
+ * Check if event emission is currently paused
542
+ *
543
+ * @returns True if paused, false otherwise
544
+ */
545
+ get paused() {
546
+ return this.isPaused;
547
+ }
442
548
  }
443
549
 
444
550
  /**
@@ -493,6 +599,29 @@ const isListening = () => asyncStorageListener.isActive;
493
599
  exports.isListening = isListening;
494
600
  const getListenerCount = () => asyncStorageListener.listenerCount;
495
601
 
602
+ /**
603
+ * Pause event emission (used during time-travel operations)
604
+ *
605
+ * When paused, storage operations still execute but events are not emitted.
606
+ * This prevents circular event triggering during replay/jump operations.
607
+ */
608
+ exports.getListenerCount = getListenerCount;
609
+ const pauseCapture = () => asyncStorageListener.pause();
610
+
611
+ /**
612
+ * Resume event emission after pausing
613
+ */
614
+ exports.pauseCapture = pauseCapture;
615
+ const resumeCapture = () => asyncStorageListener.resume();
616
+
617
+ /**
618
+ * Check if event emission is currently paused
619
+ *
620
+ * @returns True if paused, false otherwise
621
+ */
622
+ exports.resumeCapture = resumeCapture;
623
+ const isPaused = () => asyncStorageListener.paused;
624
+
496
625
  /**
497
626
  * Export the singleton instance for advanced usage
498
627
  *
@@ -506,5 +635,5 @@ const getListenerCount = () => asyncStorageListener.listenerCount;
506
635
  * }
507
636
  * ```
508
637
  */
509
- exports.getListenerCount = getListenerCount;
638
+ exports.isPaused = isPaused;
510
639
  var _default = exports.default = asyncStorageListener;
@@ -27,6 +27,12 @@ Object.defineProperty(exports, "asyncStorageListener", {
27
27
  return _AsyncStorageListener.default;
28
28
  }
29
29
  });
30
+ Object.defineProperty(exports, "canUndo", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _storageTimeTravelUtils.canUndo;
34
+ }
35
+ });
30
36
  Object.defineProperty(exports, "clearAllAppStorage", {
31
37
  enumerable: true,
32
38
  get: function () {
@@ -105,12 +111,24 @@ Object.defineProperty(exports, "isMMKVListening", {
105
111
  return _MMKVListener.isMMKVListening;
106
112
  }
107
113
  });
114
+ Object.defineProperty(exports, "isPaused", {
115
+ enumerable: true,
116
+ get: function () {
117
+ return _AsyncStorageListener.isPaused;
118
+ }
119
+ });
108
120
  Object.defineProperty(exports, "isTypeMatch", {
109
121
  enumerable: true,
110
122
  get: function () {
111
123
  return _mmkvTypeDetection.isTypeMatch;
112
124
  }
113
125
  });
126
+ Object.defineProperty(exports, "jumpToState", {
127
+ enumerable: true,
128
+ get: function () {
129
+ return _storageTimeTravelUtils.jumpToState;
130
+ }
131
+ });
114
132
  Object.defineProperty(exports, "mmkvInstanceRegistry", {
115
133
  enumerable: true,
116
134
  get: function () {
@@ -123,6 +141,12 @@ Object.defineProperty(exports, "mmkvListener", {
123
141
  return _MMKVListener.mmkvListener;
124
142
  }
125
143
  });
144
+ Object.defineProperty(exports, "pauseCapture", {
145
+ enumerable: true,
146
+ get: function () {
147
+ return _AsyncStorageListener.pauseCapture;
148
+ }
149
+ });
126
150
  Object.defineProperty(exports, "registerMMKVInstance", {
127
151
  enumerable: true,
128
152
  get: function () {
@@ -153,6 +177,12 @@ Object.defineProperty(exports, "removeMMKVInstance", {
153
177
  return _MMKVListener.removeMMKVInstance;
154
178
  }
155
179
  });
180
+ Object.defineProperty(exports, "resumeCapture", {
181
+ enumerable: true,
182
+ get: function () {
183
+ return _AsyncStorageListener.resumeCapture;
184
+ }
185
+ });
156
186
  Object.defineProperty(exports, "startListening", {
157
187
  enumerable: true,
158
188
  get: function () {
@@ -165,6 +195,12 @@ Object.defineProperty(exports, "stopListening", {
165
195
  return _AsyncStorageListener.stopListening;
166
196
  }
167
197
  });
198
+ Object.defineProperty(exports, "undoOperation", {
199
+ enumerable: true,
200
+ get: function () {
201
+ return _storageTimeTravelUtils.undoOperation;
202
+ }
203
+ });
168
204
  Object.defineProperty(exports, "unregisterMMKVInstance", {
169
205
  enumerable: true,
170
206
  get: function () {
@@ -174,6 +210,7 @@ Object.defineProperty(exports, "unregisterMMKVInstance", {
174
210
  var _clearAllStorage = require("./clearAllStorage");
175
211
  var _mmkvAvailability = require("./mmkvAvailability");
176
212
  var _AsyncStorageListener = _interopRequireWildcard(require("./AsyncStorageListener"));
213
+ var _storageTimeTravelUtils = require("./storageTimeTravelUtils");
177
214
  var _MMKVInstanceRegistry = require("./MMKVInstanceRegistry");
178
215
  var _MMKVListener = require("./MMKVListener");
179
216
  var _mmkvTypeDetection = require("./mmkvTypeDetection");