@buoy-gg/storage 7.0.41 → 7.0.43

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 (180) hide show
  1. package/README.md +11 -90
  2. package/lib/commonjs/index.js +1 -353
  3. package/lib/commonjs/preset.js +1 -85
  4. package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +1 -36
  5. package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -12
  6. package/lib/commonjs/storage/components/DiffViewer/themes/diffThemes.js +1 -24
  7. package/lib/commonjs/storage/components/GameUIStorageBrowser.js +3 -1259
  8. package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -257
  9. package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -419
  10. package/lib/commonjs/storage/components/SelectionActionBar.js +1 -207
  11. package/lib/commonjs/storage/components/StorageActionButtons.js +1 -242
  12. package/lib/commonjs/storage/components/StorageBrowserMode.js +1 -61
  13. package/lib/commonjs/storage/components/StorageEventActionButton.js +1 -121
  14. package/lib/commonjs/storage/components/StorageEventCard.js +1 -118
  15. package/lib/commonjs/storage/components/StorageEventDetailContent.js +1 -494
  16. package/lib/commonjs/storage/components/StorageEventFilterView.js +1 -160
  17. package/lib/commonjs/storage/components/StorageEventsSection.js +1 -24
  18. package/lib/commonjs/storage/components/StorageFilterCards.js +1 -231
  19. package/lib/commonjs/storage/components/StorageKeyCard.js +1 -520
  20. package/lib/commonjs/storage/components/StorageKeyDetailScreen.js +1 -579
  21. package/lib/commonjs/storage/components/StorageKeyRow.js +1 -559
  22. package/lib/commonjs/storage/components/StorageKeySection.js +1 -160
  23. package/lib/commonjs/storage/components/StorageKeyStats.js +1 -345
  24. package/lib/commonjs/storage/components/StorageModalWithTabs.js +1 -954
  25. package/lib/commonjs/storage/components/StorageSaveNotice.js +1 -171
  26. package/lib/commonjs/storage/components/StorageSection.js +1 -43
  27. package/lib/commonjs/storage/components/StorageTypeFilterBar.js +1 -144
  28. package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +1 -141
  29. package/lib/commonjs/storage/hooks/useMMKVInstances.js +1 -210
  30. package/lib/commonjs/storage/hooks/useMMKVKeys.js +1 -376
  31. package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +1 -202
  32. package/lib/commonjs/storage/hooks/useStorageEvents.js +1 -61
  33. package/lib/commonjs/storage/stores/storageEventStore.js +1 -312
  34. package/lib/commonjs/storage/sync/storageSyncAdapter.js +1 -492
  35. package/lib/commonjs/storage/types.js +1 -5
  36. package/lib/commonjs/storage/utils/AsyncStorageListener.js +1 -691
  37. package/lib/commonjs/storage/utils/AsyncStorageListener.web.js +1 -89
  38. package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +1 -203
  39. package/lib/commonjs/storage/utils/MMKVListener.js +1 -416
  40. package/lib/commonjs/storage/utils/SecureStoreRegistry.js +1 -200
  41. package/lib/commonjs/storage/utils/asyncStorageCompat.js +1 -89
  42. package/lib/commonjs/storage/utils/browserStorageLifecycle.js +1 -10
  43. package/lib/commonjs/storage/utils/browserStorageLifecycle.web.js +1 -70
  44. package/lib/commonjs/storage/utils/clearAllStorage.js +1 -48
  45. package/lib/commonjs/storage/utils/deleteStorageKeys.js +1 -82
  46. package/lib/commonjs/storage/utils/lineDiff.js +1 -30
  47. package/lib/commonjs/storage/utils/mmkvAvailability.js +1 -62
  48. package/lib/commonjs/storage/utils/mmkvAvailability.web.js +1 -21
  49. package/lib/commonjs/storage/utils/mmkvTypeDetection.js +1 -154
  50. package/lib/commonjs/storage/utils/requiredStorageKeyScope.js +1 -17
  51. package/lib/commonjs/storage/utils/setStorageValue.js +1 -218
  52. package/lib/commonjs/storage/utils/snapshotProvider.js +1 -382
  53. package/lib/commonjs/storage/utils/storageActionHelpers.js +1 -46
  54. package/lib/commonjs/storage/utils/storageBrowserRefresh.js +1 -49
  55. package/lib/commonjs/storage/utils/storageLabels.js +1 -13
  56. package/lib/commonjs/storage/utils/storageLabels.web.js +1 -13
  57. package/lib/commonjs/storage/utils/storageOps.js +1 -53
  58. package/lib/commonjs/storage/utils/storageQueryUtils.js +1 -35
  59. package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +1 -288
  60. package/lib/commonjs/storage/utils/valueType.js +1 -83
  61. package/lib/module/index.js +1 -114
  62. package/lib/module/preset.js +1 -82
  63. package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +1 -32
  64. package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -9
  65. package/lib/module/storage/components/DiffViewer/themes/diffThemes.js +1 -10
  66. package/lib/module/storage/components/GameUIStorageBrowser.js +3 -1257
  67. package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -253
  68. package/lib/module/storage/components/MMKVInstanceSelector.js +1 -415
  69. package/lib/module/storage/components/SelectionActionBar.js +1 -204
  70. package/lib/module/storage/components/StorageActionButtons.js +1 -238
  71. package/lib/module/storage/components/StorageBrowserMode.js +1 -57
  72. package/lib/module/storage/components/StorageEventActionButton.js +1 -118
  73. package/lib/module/storage/components/StorageEventCard.js +1 -113
  74. package/lib/module/storage/components/StorageEventDetailContent.js +1 -490
  75. package/lib/module/storage/components/StorageEventFilterView.js +1 -156
  76. package/lib/module/storage/components/StorageEventsSection.js +1 -20
  77. package/lib/module/storage/components/StorageFilterCards.js +1 -227
  78. package/lib/module/storage/components/StorageKeyCard.js +1 -517
  79. package/lib/module/storage/components/StorageKeyDetailScreen.js +1 -577
  80. package/lib/module/storage/components/StorageKeyRow.js +1 -554
  81. package/lib/module/storage/components/StorageKeySection.js +1 -155
  82. package/lib/module/storage/components/StorageKeyStats.js +1 -342
  83. package/lib/module/storage/components/StorageModalWithTabs.js +1 -949
  84. package/lib/module/storage/components/StorageSaveNotice.js +1 -168
  85. package/lib/module/storage/components/StorageSection.js +1 -40
  86. package/lib/module/storage/components/StorageTypeFilterBar.js +1 -139
  87. package/lib/module/storage/hooks/useAsyncStorageKeys.js +1 -136
  88. package/lib/module/storage/hooks/useMMKVInstances.js +1 -204
  89. package/lib/module/storage/hooks/useMMKVKeys.js +1 -371
  90. package/lib/module/storage/hooks/useSecureStoreKeys.js +1 -199
  91. package/lib/module/storage/hooks/useStorageEvents.js +1 -58
  92. package/lib/module/storage/stores/storageEventStore.js +1 -301
  93. package/lib/module/storage/sync/storageSyncAdapter.js +1 -486
  94. package/lib/module/storage/types.js +1 -3
  95. package/lib/module/storage/utils/AsyncStorageListener.js +1 -679
  96. package/lib/module/storage/utils/AsyncStorageListener.web.js +1 -76
  97. package/lib/module/storage/utils/MMKVInstanceRegistry.js +1 -197
  98. package/lib/module/storage/utils/MMKVListener.js +1 -403
  99. package/lib/module/storage/utils/SecureStoreRegistry.js +1 -194
  100. package/lib/module/storage/utils/asyncStorageCompat.js +1 -81
  101. package/lib/module/storage/utils/browserStorageLifecycle.js +1 -6
  102. package/lib/module/storage/utils/browserStorageLifecycle.web.js +1 -66
  103. package/lib/module/storage/utils/clearAllStorage.js +1 -43
  104. package/lib/module/storage/utils/deleteStorageKeys.js +1 -78
  105. package/lib/module/storage/utils/lineDiff.js +1 -12
  106. package/lib/module/storage/utils/mmkvAvailability.js +1 -56
  107. package/lib/module/storage/utils/mmkvAvailability.web.js +1 -15
  108. package/lib/module/storage/utils/mmkvTypeDetection.js +1 -148
  109. package/lib/module/storage/utils/requiredStorageKeyScope.js +1 -13
  110. package/lib/module/storage/utils/setStorageValue.js +1 -209
  111. package/lib/module/storage/utils/snapshotProvider.js +1 -380
  112. package/lib/module/storage/utils/storageActionHelpers.js +1 -42
  113. package/lib/module/storage/utils/storageBrowserRefresh.js +1 -44
  114. package/lib/module/storage/utils/storageLabels.js +1 -9
  115. package/lib/module/storage/utils/storageLabels.web.js +1 -9
  116. package/lib/module/storage/utils/storageOps.js +1 -46
  117. package/lib/module/storage/utils/storageQueryUtils.js +1 -30
  118. package/lib/module/storage/utils/storageTimeTravelUtils.js +1 -281
  119. package/lib/module/storage/utils/valueType.js +1 -76
  120. package/lib/web/index.mjs +2 -3
  121. package/package.json +6 -10
  122. package/lib/typescript/index.d.ts.map +0 -1
  123. package/lib/typescript/preset.d.ts.map +0 -1
  124. package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +0 -1
  125. package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +0 -1
  126. package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +0 -1
  127. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +0 -1
  128. package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts.map +0 -1
  129. package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts.map +0 -1
  130. package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +0 -1
  131. package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +0 -1
  132. package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +0 -1
  133. package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +0 -1
  134. package/lib/typescript/storage/components/StorageEventCard.d.ts.map +0 -1
  135. package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +0 -1
  136. package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +0 -1
  137. package/lib/typescript/storage/components/StorageEventsSection.d.ts.map +0 -1
  138. package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +0 -1
  139. package/lib/typescript/storage/components/StorageKeyCard.d.ts.map +0 -1
  140. package/lib/typescript/storage/components/StorageKeyDetailScreen.d.ts.map +0 -1
  141. package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +0 -1
  142. package/lib/typescript/storage/components/StorageKeySection.d.ts.map +0 -1
  143. package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +0 -1
  144. package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +0 -1
  145. package/lib/typescript/storage/components/StorageSaveNotice.d.ts.map +0 -1
  146. package/lib/typescript/storage/components/StorageSection.d.ts.map +0 -1
  147. package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +0 -1
  148. package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +0 -1
  149. package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +0 -1
  150. package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +0 -1
  151. package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +0 -1
  152. package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +0 -1
  153. package/lib/typescript/storage/stores/storageEventStore.d.ts.map +0 -1
  154. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +0 -1
  155. package/lib/typescript/storage/types.d.ts.map +0 -1
  156. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +0 -1
  157. package/lib/typescript/storage/utils/AsyncStorageListener.web.d.ts.map +0 -1
  158. package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +0 -1
  159. package/lib/typescript/storage/utils/MMKVListener.d.ts.map +0 -1
  160. package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +0 -1
  161. package/lib/typescript/storage/utils/asyncStorageCompat.d.ts.map +0 -1
  162. package/lib/typescript/storage/utils/browserStorageLifecycle.d.ts.map +0 -1
  163. package/lib/typescript/storage/utils/browserStorageLifecycle.web.d.ts.map +0 -1
  164. package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +0 -1
  165. package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +0 -1
  166. package/lib/typescript/storage/utils/lineDiff.d.ts.map +0 -1
  167. package/lib/typescript/storage/utils/mmkvAvailability.d.ts.map +0 -1
  168. package/lib/typescript/storage/utils/mmkvAvailability.web.d.ts.map +0 -1
  169. package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +0 -1
  170. package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts.map +0 -1
  171. package/lib/typescript/storage/utils/setStorageValue.d.ts.map +0 -1
  172. package/lib/typescript/storage/utils/snapshotProvider.d.ts.map +0 -1
  173. package/lib/typescript/storage/utils/storageActionHelpers.d.ts.map +0 -1
  174. package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +0 -1
  175. package/lib/typescript/storage/utils/storageLabels.d.ts.map +0 -1
  176. package/lib/typescript/storage/utils/storageLabels.web.d.ts.map +0 -1
  177. package/lib/typescript/storage/utils/storageOps.d.ts.map +0 -1
  178. package/lib/typescript/storage/utils/storageQueryUtils.d.ts.map +0 -1
  179. package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +0 -1
  180. package/lib/typescript/storage/utils/valueType.d.ts.map +0 -1
@@ -1,416 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.removeMMKVInstance = exports.removeAllMMKVListeners = exports.removeAllMMKVInstances = exports.mmkvListener = exports.isMMKVListening = exports.isMMKVInstanceMonitored = exports.getMonitoredMMKVInstances = exports.getMMKVListenerCount = exports.getMMKVInstanceCount = exports.default = exports.addMMKVListener = exports.addMMKVInstance = void 0;
7
- var _mmkvTypeDetection = require("./mmkvTypeDetection");
8
- /**
9
- * MMKVListener - Hybrid Monitoring Strategy
10
- *
11
- * This module provides comprehensive monitoring for MMKV storage instances using
12
- * a hybrid approach that combines:
13
- *
14
- * 1. MMKV's built-in addOnValueChangedListener() - for write operations
15
- * 2. Method wrapping - for read operations and type detection
16
- *
17
- * Why Hybrid Strategy?
18
- * - MMKV listeners only fire on writes (set/delete), not reads
19
- * - MMKV listeners don't provide value type information
20
- * - Method wrapping captures ALL operations with full context
21
- * - Combining both gives complete observability
22
- *
23
- * Key Differences from AsyncStorage:
24
- * - Synchronous API (no async/await needed)
25
- * - Multi-instance support (track multiple MMKV instances)
26
- * - Native types (string, number, boolean, buffer)
27
- * - Built-in listener support (MMKV.addOnValueChangedListener)
28
- *
29
- * @see AsyncStorageListener.ts for AsyncStorage equivalent
30
- */
31
-
32
- // Use 'any' type for MMKV to avoid hard dependency on react-native-mmkv
33
-
34
- // MMKV method signatures
35
-
36
- /**
37
- * Event types for MMKV operations
38
- */
39
-
40
- /**
41
- * Instance tracking for MMKV monitoring
42
- */
43
-
44
- /**
45
- * Singleton class for monitoring MMKV operations across multiple instances
46
- *
47
- * Uses a hybrid monitoring strategy:
48
- * 1. MMKV's built-in listener API for write notifications
49
- * 2. Method wrapping for read operations and type information
50
- *
51
- * @example
52
- * ```typescript
53
- * import { MMKV } from 'react-native-mmkv';
54
- * import { mmkvListener } from './MMKVListener';
55
- *
56
- * const storage = new MMKV();
57
- *
58
- * // Start monitoring this instance
59
- * mmkvListener.addInstance(storage, 'mmkv.default');
60
- *
61
- * // Add listener for all MMKV events
62
- * const unsubscribe = mmkvListener.addListener((event) => {
63
- * console.log(`[${event.instanceId}] ${event.action}:`, event.data);
64
- * });
65
- *
66
- * // Cleanup
67
- * unsubscribe();
68
- * mmkvListener.removeInstance('mmkv.default');
69
- * ```
70
- */
71
- class MMKVListener {
72
- listeners = [];
73
- instances = new Map();
74
-
75
- // Keys to ignore to prevent dev tools from triggering self-events
76
- ignoredKeys = new Set(["@react_buoy_storage_event_filters", "@react_buoy_storage_key_filters", "@react_buoy_storage_is_monitoring", "REACT_QUERY_OFFLINE_CACHE"]);
77
-
78
- /**
79
- * Determines if a storage key should be ignored
80
- */
81
- shouldIgnoreKey(key) {
82
- if (this.ignoredKeys.has(key)) return true;
83
- for (const ignoredKey of this.ignoredKeys) {
84
- if (key.startsWith(ignoredKey)) return true;
85
- }
86
- return false;
87
- }
88
-
89
- /**
90
- * Emit an MMKV event to all registered listeners
91
- */
92
- emit(event) {
93
- if (this.listeners.length === 0) return;
94
- this.listeners.forEach(listener => {
95
- try {
96
- listener(event);
97
- } catch (error) {
98
- // Error in MMKV event listener - continuing with others
99
- }
100
- });
101
- }
102
-
103
- /**
104
- * Add an MMKV instance for monitoring
105
- *
106
- * This method sets up both native MMKV listeners and method wrapping
107
- * to provide complete observability.
108
- *
109
- * @param instance - MMKV instance to monitor
110
- * @param instanceId - Unique identifier for this instance
111
- *
112
- * @example
113
- * ```typescript
114
- * const storage = new MMKV();
115
- * mmkvListener.addInstance(storage, 'mmkv.default');
116
- *
117
- * const secureStorage = new MMKV({ id: 'secure', encryptionKey: key });
118
- * mmkvListener.addInstance(secureStorage, 'secure');
119
- * ```
120
- */
121
- addInstance(instance, instanceId) {
122
- // Check if already monitoring this instance
123
- if (this.instances.has(instanceId)) {
124
- return;
125
- }
126
-
127
- // v4 COMPATIBILITY: Use ONLY native listener (no method wrapping)
128
- // react-native-mmkv v4 instances have frozen/read-only methods that cannot be wrapped
129
- // The native listener (addOnValueChangedListener) is sufficient for monitoring writes
130
-
131
- let nativeListenerUnsubscribe;
132
-
133
- // Seed the shadow copy so the FIRST observed write already knows what it
134
- // replaced. Without this, every key's first event would claim the key never
135
- // existed even when it was carried over from a previous launch.
136
- const lastKnownValues = new Map();
137
- try {
138
- for (const key of instance.getAllKeys() ?? []) {
139
- if (this.shouldIgnoreKey(key)) continue;
140
- lastKnownValues.set(key, (0, _mmkvTypeDetection.detectMMKVType)(instance, key).value);
141
- }
142
- } catch {
143
- // Key scan unavailable — prevValue is simply absent until each key is
144
- // written once, which is strictly better than reporting a wrong value.
145
- }
146
- if (typeof instance.addOnValueChangedListener === "function") {
147
- try {
148
- nativeListenerUnsubscribe = instance.addOnValueChangedListener(key => {
149
- // Ignore dev tools keys
150
- if (this.shouldIgnoreKey(key)) return;
151
-
152
- // Detect the value type
153
- const {
154
- value,
155
- type
156
- } = (0, _mmkvTypeDetection.detectMMKVType)(instance, key);
157
-
158
- // Read the shadow copy BEFORE overwriting it — this is the value the
159
- // write replaced. `undefined` means the key did not exist.
160
- const prevValue = lastKnownValues.get(key);
161
-
162
- // Determine action: if value is undefined/unknown, it was deleted
163
- const isDelete = type === "unknown" || value === undefined;
164
- if (isDelete) {
165
- lastKnownValues.delete(key);
166
-
167
- // Key was deleted
168
- const event = {
169
- action: "delete",
170
- timestamp: new Date(),
171
- instanceId,
172
- data: {
173
- key,
174
- prevValue,
175
- success: true
176
- }
177
- };
178
- this.emit(event);
179
- } else {
180
- lastKnownValues.set(key, value);
181
-
182
- // Key was set/updated
183
- const action = type === "string" ? "set.string" : type === "number" ? "set.number" : type === "boolean" ? "set.boolean" : type === "buffer" ? "set.buffer" : "set.string"; // fallback
184
-
185
- const event = {
186
- action,
187
- timestamp: new Date(),
188
- instanceId,
189
- data: {
190
- key,
191
- value,
192
- prevValue,
193
- valueType: type,
194
- success: true
195
- }
196
- };
197
- this.emit(event);
198
- }
199
- });
200
- } catch (error) {
201
- // Could not add native listener
202
- }
203
- }
204
-
205
- // Store instance tracking (no originalMethods needed for v4)
206
- this.instances.set(instanceId, {
207
- instance,
208
- instanceId,
209
- originalMethods: {},
210
- // Not used in v4
211
- nativeListenerUnsubscribe,
212
- lastKnownValues
213
- });
214
- }
215
-
216
- /**
217
- * Remove an MMKV instance from monitoring
218
- *
219
- * Restores original methods and removes native listener.
220
- *
221
- * @param instanceId - Identifier of instance to stop monitoring
222
- */
223
- removeInstance(instanceId) {
224
- const tracked = this.instances.get(instanceId);
225
- if (!tracked) {
226
- return;
227
- }
228
- const {
229
- nativeListenerUnsubscribe
230
- } = tracked;
231
-
232
- // Remove native listener. The return of addOnValueChangedListener varies by
233
- // implementation: a bare unsubscribe function, or a Listener object with a
234
- // `.remove()` method (react-native-mmkv v4 and the desktop RemoteMMKV
235
- // back-end). Handle both, and never let teardown throw — this runs during
236
- // React unmount, where an exception escapes every error boundary and blanks
237
- // the whole app.
238
- try {
239
- if (typeof nativeListenerUnsubscribe === "function") {
240
- nativeListenerUnsubscribe();
241
- } else if (typeof nativeListenerUnsubscribe?.remove === "function") {
242
- nativeListenerUnsubscribe.remove();
243
- }
244
- } catch {
245
- /* listener already gone / back-end offline — nothing to clean up */
246
- }
247
-
248
- // Remove from tracking
249
- this.instances.delete(instanceId);
250
- }
251
-
252
- /**
253
- * Remove all monitored instances
254
- */
255
- removeAllInstances() {
256
- const instanceIds = Array.from(this.instances.keys());
257
- instanceIds.forEach(id => this.removeInstance(id));
258
- }
259
-
260
- /**
261
- * Add a listener for MMKV events across all monitored instances
262
- *
263
- * @param listener - Callback function to handle MMKV events
264
- * @returns Unsubscribe function to remove the listener
265
- *
266
- * @example
267
- * ```typescript
268
- * const unsubscribe = mmkvListener.addListener((event) => {
269
- * console.log(`[${event.instanceId}] ${event.action}:`, event.data);
270
- * });
271
- *
272
- * // Later, remove the listener
273
- * unsubscribe();
274
- * ```
275
- */
276
- addListener(listener) {
277
- this.listeners.push(listener);
278
-
279
- // Return unsubscribe function
280
- return () => {
281
- const index = this.listeners.indexOf(listener);
282
- if (index > -1) {
283
- this.listeners.splice(index, 1);
284
- }
285
- };
286
- }
287
-
288
- /**
289
- * Remove all registered event listeners
290
- */
291
- removeAllListeners() {
292
- this.listeners = [];
293
- }
294
-
295
- /**
296
- * Check if an instance is currently being monitored
297
- */
298
- hasInstance(instanceId) {
299
- return this.instances.has(instanceId);
300
- }
301
-
302
- /**
303
- * Get list of all monitored instance IDs
304
- */
305
- getMonitoredInstances() {
306
- return Array.from(this.instances.keys());
307
- }
308
-
309
- /**
310
- * Get the number of currently monitored instances
311
- */
312
- get instanceCount() {
313
- return this.instances.size;
314
- }
315
-
316
- /**
317
- * Get the number of currently registered event listeners
318
- */
319
- get listenerCount() {
320
- return this.listeners.length;
321
- }
322
-
323
- /**
324
- * Check if any instances are being monitored
325
- */
326
- get isActive() {
327
- return this.instances.size > 0;
328
- }
329
- }
330
-
331
- /**
332
- * Singleton instance of MMKVListener
333
- *
334
- * This ensures only one listener manager exists across the entire application.
335
- */
336
- const mmkvListener = exports.mmkvListener = new MMKVListener();
337
-
338
- /**
339
- * Add an MMKV instance for monitoring
340
- *
341
- * @param instance - MMKV instance to monitor
342
- * @param instanceId - Unique identifier for this instance
343
- *
344
- * @example
345
- * ```typescript
346
- * import { MMKV } from 'react-native-mmkv';
347
- * import { addMMKVInstance } from '@buoy-gg/storage';
348
- *
349
- * const storage = new MMKV();
350
- * addMMKVInstance(storage, 'mmkv.default');
351
- * ```
352
- */
353
- const addMMKVInstance = (instance, instanceId) => mmkvListener.addInstance(instance, instanceId);
354
-
355
- /**
356
- * Remove an MMKV instance from monitoring
357
- */
358
- exports.addMMKVInstance = addMMKVInstance;
359
- const removeMMKVInstance = instanceId => mmkvListener.removeInstance(instanceId);
360
-
361
- /**
362
- * Remove all monitored MMKV instances
363
- */
364
- exports.removeMMKVInstance = removeMMKVInstance;
365
- const removeAllMMKVInstances = () => mmkvListener.removeAllInstances();
366
-
367
- /**
368
- * Add an event listener for MMKV operations
369
- *
370
- * @param listener - Callback function to handle events
371
- * @returns Unsubscribe function to remove the listener
372
- */
373
- exports.removeAllMMKVInstances = removeAllMMKVInstances;
374
- const addMMKVListener = listener => mmkvListener.addListener(listener);
375
-
376
- /**
377
- * Remove all registered event listeners
378
- */
379
- exports.addMMKVListener = addMMKVListener;
380
- const removeAllMMKVListeners = () => mmkvListener.removeAllListeners();
381
-
382
- /**
383
- * Check if an MMKV instance is currently being monitored
384
- */
385
- exports.removeAllMMKVListeners = removeAllMMKVListeners;
386
- const isMMKVInstanceMonitored = instanceId => mmkvListener.hasInstance(instanceId);
387
-
388
- /**
389
- * Get list of all monitored MMKV instance IDs
390
- */
391
- exports.isMMKVInstanceMonitored = isMMKVInstanceMonitored;
392
- const getMonitoredMMKVInstances = () => mmkvListener.getMonitoredInstances();
393
-
394
- /**
395
- * Get the current number of monitored MMKV instances
396
- */
397
- exports.getMonitoredMMKVInstances = getMonitoredMMKVInstances;
398
- const getMMKVInstanceCount = () => mmkvListener.instanceCount;
399
-
400
- /**
401
- * Get the current number of registered event listeners
402
- */
403
- exports.getMMKVInstanceCount = getMMKVInstanceCount;
404
- const getMMKVListenerCount = () => mmkvListener.listenerCount;
405
-
406
- /**
407
- * Check if any MMKV instances are being monitored
408
- */
409
- exports.getMMKVListenerCount = getMMKVListenerCount;
410
- const isMMKVListening = () => mmkvListener.isActive;
411
-
412
- /**
413
- * Export the singleton instance for advanced usage
414
- */
415
- exports.isMMKVListening = isMMKVListening;
416
- var _default = exports.default = mmkvListener;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.removeMMKVInstance=exports.removeAllMMKVListeners=exports.removeAllMMKVInstances=exports.mmkvListener=exports.isMMKVListening=exports.isMMKVInstanceMonitored=exports.getMonitoredMMKVInstances=exports.getMMKVListenerCount=exports.getMMKVInstanceCount=exports.default=exports.addMMKVListener=exports.addMMKVInstance=void 0;var _mmkvTypeDetection=require("./mmkvTypeDetection");class MMKVListener{listeners=[];instances=new Map;ignoredKeys=new Set(["@react_buoy_storage_event_filters","@react_buoy_storage_key_filters","@react_buoy_storage_is_monitoring","REACT_QUERY_OFFLINE_CACHE"]);shouldIgnoreKey(e){if(this.ignoredKeys.has(e))return true;for(const t of this.ignoredKeys){if(e.startsWith(t))return true}return false}emit(e){if(this.listeners.length===0)return;this.listeners.forEach(t=>{try{t(e)}catch(r){}})}addInstance(e,t){if(this.instances.has(t)){return}let r;const i=new Map;try{for(const s of e.getAllKeys()??[]){if(this.shouldIgnoreKey(s))continue;i.set(s,(0,_mmkvTypeDetection.detectMMKVType)(e,s).value)}}catch{}if(typeof e.addOnValueChangedListener==="function"){try{r=e.addOnValueChangedListener(s=>{if(this.shouldIgnoreKey(s))return;const{value:a,type:o}=(0,_mmkvTypeDetection.detectMMKVType)(e,s);const M=i.get(s);const l=o==="unknown"||a===void 0;if(l){i.delete(s);const c={action:"delete",timestamp:new Date,instanceId:t,data:{key:s,prevValue:M,success:true}};this.emit(c)}else{i.set(s,a);const c=o==="string"?"set.string":o==="number"?"set.number":o==="boolean"?"set.boolean":o==="buffer"?"set.buffer":"set.string";const u={action:c,timestamp:new Date,instanceId:t,data:{key:s,value:a,prevValue:M,valueType:o,success:true}};this.emit(u)}})}catch(s){}}this.instances.set(t,{instance:e,instanceId:t,originalMethods:{},nativeListenerUnsubscribe:r,lastKnownValues:i})}removeInstance(e){const t=this.instances.get(e);if(!t){return}const{nativeListenerUnsubscribe:r}=t;try{if(typeof r==="function"){r()}else if(typeof r?.remove==="function"){r.remove()}}catch{}this.instances.delete(e)}removeAllInstances(){const e=Array.from(this.instances.keys());e.forEach(t=>this.removeInstance(t))}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}hasInstance(e){return this.instances.has(e)}getMonitoredInstances(){return Array.from(this.instances.keys())}get instanceCount(){return this.instances.size}get listenerCount(){return this.listeners.length}get isActive(){return this.instances.size>0}}const mmkvListener=exports.mmkvListener=new MMKVListener;const addMMKVInstance=(n,e)=>mmkvListener.addInstance(n,e);exports.addMMKVInstance=addMMKVInstance;const removeMMKVInstance=n=>mmkvListener.removeInstance(n);exports.removeMMKVInstance=removeMMKVInstance;const removeAllMMKVInstances=()=>mmkvListener.removeAllInstances();exports.removeAllMMKVInstances=removeAllMMKVInstances;const addMMKVListener=n=>mmkvListener.addListener(n);exports.addMMKVListener=addMMKVListener;const removeAllMMKVListeners=()=>mmkvListener.removeAllListeners();exports.removeAllMMKVListeners=removeAllMMKVListeners;const isMMKVInstanceMonitored=n=>mmkvListener.hasInstance(n);exports.isMMKVInstanceMonitored=isMMKVInstanceMonitored;const getMonitoredMMKVInstances=()=>mmkvListener.getMonitoredInstances();exports.getMonitoredMMKVInstances=getMonitoredMMKVInstances;const getMMKVInstanceCount=()=>mmkvListener.instanceCount;exports.getMMKVInstanceCount=getMMKVInstanceCount;const getMMKVListenerCount=()=>mmkvListener.listenerCount;exports.getMMKVListenerCount=getMMKVListenerCount;const isMMKVListening=()=>mmkvListener.isActive;exports.isMMKVListening=isMMKVListening;var _default=exports.default=mmkvListener;
@@ -1,200 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.registerSecureStoreKeys = registerSecureStoreKeys;
7
- exports.secureStoreRegistry = void 0;
8
- exports.unregisterSecureStoreKey = unregisterSecureStoreKey;
9
- /**
10
- * Expo SecureStore Registry
11
- *
12
- * SecureStore (iOS Keychain / Android KeyStore) has NO key-enumeration API —
13
- * unlike AsyncStorage (`getAllKeys`) and MMKV (`getAllKeys()`), there is no way
14
- * to ask "what's stored?". Apps must therefore register the keys they want
15
- * visible in the Storage tool.
16
- *
17
- * The SecureStore module itself is passed in at registration (never imported
18
- * here) — the same Metro-safe pattern as `registerMMKVInstance`: this package
19
- * has zero dependency on `expo-secure-store`, so bare RN apps without it
20
- * bundle fine.
21
- *
22
- * @module SecureStoreRegistry
23
- */
24
-
25
- /**
26
- * Subset of expo-secure-store's SecureStoreOptions that the tool tracks.
27
- * `keychainService` MUST match what the value was written with, or reads
28
- * return null. `requireAuthentication` keys trigger a biometric prompt on
29
- * read, so the tool never auto-reads them.
30
- *
31
- * @public
32
- */
33
-
34
- /**
35
- * Structural type for the expo-secure-store module. Matches
36
- * `import * as SecureStore from "expo-secure-store"` without depending on it.
37
- *
38
- * @public
39
- */
40
-
41
- /**
42
- * A key to expose in the Storage tool: either a bare key name, or a key with
43
- * the SecureStore options it was written with (+ optional description shown
44
- * in the expanded card).
45
- *
46
- * @public
47
- */
48
-
49
- /**
50
- * Normalized info for a registered SecureStore key.
51
- *
52
- * @public
53
- */
54
-
55
- class SecureStoreRegistry {
56
- module = null;
57
- keys = new Map();
58
- listeners = new Set();
59
-
60
- /**
61
- * Register the SecureStore module and the keys to expose. Callable multiple
62
- * times — keys accumulate, the latest module wins.
63
- */
64
- register(module, descriptors) {
65
- const before = this.signature();
66
- this.module = module;
67
- for (const d of descriptors) {
68
- const entry = typeof d === "string" ? {
69
- key: d,
70
- options: {}
71
- } : {
72
- key: d.key,
73
- description: d.description,
74
- options: {
75
- keychainService: d.keychainService,
76
- requireAuthentication: d.requireAuthentication,
77
- authenticationPrompt: d.authenticationPrompt
78
- }
79
- };
80
- this.keys.set(entry.key, entry);
81
- }
82
- // Only announce a real change. The desktop dashboard re-registers the same
83
- // key set on every device snapshot, and subscribers re-read the keychain on
84
- // notify — signature-comparing keeps that from turning into a read storm.
85
- if (this.signature() !== before) this.notify();
86
- }
87
-
88
- /** Remove a key from the registry (does not delete the stored value). */
89
- unregister(key) {
90
- if (this.keys.delete(key)) this.notify();
91
- }
92
-
93
- /**
94
- * Subscribe to registry changes (keys registered/unregistered). Lets the
95
- * browser pick up keys that register after the tool is already open.
96
- * Returns an unsubscribe function.
97
- */
98
- subscribe(listener) {
99
- this.listeners.add(listener);
100
- return () => {
101
- this.listeners.delete(listener);
102
- };
103
- }
104
-
105
- /** Content signature of the registered entries (module identity excluded). */
106
- signature() {
107
- return JSON.stringify(Array.from(this.keys.values()));
108
- }
109
- notify() {
110
- this.listeners.forEach(listener => {
111
- try {
112
- listener();
113
- } catch {
114
- // Listener errors are not ours
115
- }
116
- });
117
- }
118
-
119
- /** The registered SecureStore module, or null if none registered yet. */
120
- getModule() {
121
- return this.module;
122
- }
123
-
124
- /** All registered key entries. */
125
- getAll() {
126
- return Array.from(this.keys.values());
127
- }
128
-
129
- /** Number of registered keys. */
130
- count() {
131
- return this.keys.size;
132
- }
133
-
134
- /**
135
- * Delete a stored value via the registered module, using the options the
136
- * key was registered with (required for keychainService-scoped keys).
137
- */
138
- async deleteValue(key) {
139
- const entry = this.keys.get(key);
140
- if (!this.module || !entry) return;
141
- await this.module.deleteItemAsync(key, entry.options);
142
- }
143
-
144
- /**
145
- * Write a stored value via the registered module, using the options the key
146
- * was registered with — writing with different `keychainService` options than
147
- * the value was created with silently creates a SECOND entry the app can't
148
- * read, so the registered options are the only safe ones to use.
149
- *
150
- * Throws rather than no-ops: unlike a delete, a write that quietly did
151
- * nothing would leave the UI showing a value that was never stored.
152
- */
153
- async setValue(key, value) {
154
- const entry = this.keys.get(key);
155
- if (!this.module) throw new Error("No SecureStore module is registered");
156
- if (!entry) throw new Error(`SecureStore key "${key}" is not registered`);
157
- if (entry.options.requireAuthentication) {
158
- throw new Error(`SecureStore key "${key}" is biometric-protected — DevTools never writes it`);
159
- }
160
- await this.module.setItemAsync(key, value, entry.options);
161
- }
162
- }
163
-
164
- /**
165
- * Singleton registry instance (advanced usage — most apps only need
166
- * {@link registerSecureStoreKeys}).
167
- */
168
- const secureStoreRegistry = exports.secureStoreRegistry = new SecureStoreRegistry();
169
-
170
- /**
171
- * Register Expo SecureStore keys with React Buoy DevTools.
172
- *
173
- * **⚠️ REQUIRED for SecureStore visibility**: SecureStore has no
174
- * key-enumeration API, so the tool can only show keys you declare here.
175
- * Pass the module itself so this package never has to import
176
- * `expo-secure-store`.
177
- *
178
- * @example
179
- * ```typescript
180
- * import * as SecureStore from "expo-secure-store";
181
- * import { registerSecureStoreKeys } from "@buoy-gg/storage";
182
- *
183
- * registerSecureStoreKeys(SecureStore, [
184
- * "auth.token",
185
- * { key: "session", keychainService: "com.myapp.auth" },
186
- * // Never auto-read; shown as biometric-protected:
187
- * { key: "pin", requireAuthentication: true },
188
- * ]);
189
- * ```
190
- */
191
- function registerSecureStoreKeys(module, keys) {
192
- secureStoreRegistry.register(module, keys);
193
- }
194
-
195
- /**
196
- * Remove a key from the DevTools registry (the stored value is untouched).
197
- */
198
- function unregisterSecureStoreKey(key) {
199
- secureStoreRegistry.unregister(key);
200
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.registerSecureStoreKeys=registerSecureStoreKeys;exports.secureStoreRegistry=void 0;exports.unregisterSecureStoreKey=unregisterSecureStoreKey;class SecureStoreRegistry{module=null;keys=new Map;listeners=new Set;register(e,r){const s=this.signature();this.module=e;for(const t of r){const o=typeof t==="string"?{key:t,options:{}}:{key:t.key,description:t.description,options:{keychainService:t.keychainService,requireAuthentication:t.requireAuthentication,authenticationPrompt:t.authenticationPrompt}};this.keys.set(o.key,o)}if(this.signature()!==s)this.notify()}unregister(e){if(this.keys.delete(e))this.notify()}subscribe(e){this.listeners.add(e);return()=>{this.listeners.delete(e)}}signature(){return JSON.stringify(Array.from(this.keys.values()))}notify(){this.listeners.forEach(e=>{try{e()}catch{}})}getModule(){return this.module}getAll(){return Array.from(this.keys.values())}count(){return this.keys.size}async deleteValue(e){const r=this.keys.get(e);if(!this.module||!r)return;await this.module.deleteItemAsync(e,r.options)}async setValue(e,r){const s=this.keys.get(e);if(!this.module)throw new Error("No SecureStore module is registered");if(!s)throw new Error(`SecureStore key "${e}" is not registered`);if(s.options.requireAuthentication){throw new Error(`SecureStore key "${e}" is biometric-protected \u2014 DevTools never writes it`)}await this.module.setItemAsync(e,r,s.options)}}const secureStoreRegistry=exports.secureStoreRegistry=new SecureStoreRegistry;function registerSecureStoreKeys(i,e){secureStoreRegistry.register(i,e)}function unregisterSecureStoreKey(i){secureStoreRegistry.unregister(i)}