@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.
- package/README.md +11 -90
- package/lib/commonjs/index.js +1 -353
- package/lib/commonjs/preset.js +1 -85
- package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +1 -36
- package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -12
- package/lib/commonjs/storage/components/DiffViewer/themes/diffThemes.js +1 -24
- package/lib/commonjs/storage/components/GameUIStorageBrowser.js +3 -1259
- package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -257
- package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -419
- package/lib/commonjs/storage/components/SelectionActionBar.js +1 -207
- package/lib/commonjs/storage/components/StorageActionButtons.js +1 -242
- package/lib/commonjs/storage/components/StorageBrowserMode.js +1 -61
- package/lib/commonjs/storage/components/StorageEventActionButton.js +1 -121
- package/lib/commonjs/storage/components/StorageEventCard.js +1 -118
- package/lib/commonjs/storage/components/StorageEventDetailContent.js +1 -494
- package/lib/commonjs/storage/components/StorageEventFilterView.js +1 -160
- package/lib/commonjs/storage/components/StorageEventsSection.js +1 -24
- package/lib/commonjs/storage/components/StorageFilterCards.js +1 -231
- package/lib/commonjs/storage/components/StorageKeyCard.js +1 -520
- package/lib/commonjs/storage/components/StorageKeyDetailScreen.js +1 -579
- package/lib/commonjs/storage/components/StorageKeyRow.js +1 -559
- package/lib/commonjs/storage/components/StorageKeySection.js +1 -160
- package/lib/commonjs/storage/components/StorageKeyStats.js +1 -345
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +1 -954
- package/lib/commonjs/storage/components/StorageSaveNotice.js +1 -171
- package/lib/commonjs/storage/components/StorageSection.js +1 -43
- package/lib/commonjs/storage/components/StorageTypeFilterBar.js +1 -144
- package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +1 -141
- package/lib/commonjs/storage/hooks/useMMKVInstances.js +1 -210
- package/lib/commonjs/storage/hooks/useMMKVKeys.js +1 -376
- package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +1 -202
- package/lib/commonjs/storage/hooks/useStorageEvents.js +1 -61
- package/lib/commonjs/storage/stores/storageEventStore.js +1 -312
- package/lib/commonjs/storage/sync/storageSyncAdapter.js +1 -492
- package/lib/commonjs/storage/types.js +1 -5
- package/lib/commonjs/storage/utils/AsyncStorageListener.js +1 -691
- package/lib/commonjs/storage/utils/AsyncStorageListener.web.js +1 -89
- package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +1 -203
- package/lib/commonjs/storage/utils/MMKVListener.js +1 -416
- package/lib/commonjs/storage/utils/SecureStoreRegistry.js +1 -200
- package/lib/commonjs/storage/utils/asyncStorageCompat.js +1 -89
- package/lib/commonjs/storage/utils/browserStorageLifecycle.js +1 -10
- package/lib/commonjs/storage/utils/browserStorageLifecycle.web.js +1 -70
- package/lib/commonjs/storage/utils/clearAllStorage.js +1 -48
- package/lib/commonjs/storage/utils/deleteStorageKeys.js +1 -82
- package/lib/commonjs/storage/utils/lineDiff.js +1 -30
- package/lib/commonjs/storage/utils/mmkvAvailability.js +1 -62
- package/lib/commonjs/storage/utils/mmkvAvailability.web.js +1 -21
- package/lib/commonjs/storage/utils/mmkvTypeDetection.js +1 -154
- package/lib/commonjs/storage/utils/requiredStorageKeyScope.js +1 -17
- package/lib/commonjs/storage/utils/setStorageValue.js +1 -218
- package/lib/commonjs/storage/utils/snapshotProvider.js +1 -382
- package/lib/commonjs/storage/utils/storageActionHelpers.js +1 -46
- package/lib/commonjs/storage/utils/storageBrowserRefresh.js +1 -49
- package/lib/commonjs/storage/utils/storageLabels.js +1 -13
- package/lib/commonjs/storage/utils/storageLabels.web.js +1 -13
- package/lib/commonjs/storage/utils/storageOps.js +1 -53
- package/lib/commonjs/storage/utils/storageQueryUtils.js +1 -35
- package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +1 -288
- package/lib/commonjs/storage/utils/valueType.js +1 -83
- package/lib/module/index.js +1 -114
- package/lib/module/preset.js +1 -82
- package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +1 -32
- package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -9
- package/lib/module/storage/components/DiffViewer/themes/diffThemes.js +1 -10
- package/lib/module/storage/components/GameUIStorageBrowser.js +3 -1257
- package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -253
- package/lib/module/storage/components/MMKVInstanceSelector.js +1 -415
- package/lib/module/storage/components/SelectionActionBar.js +1 -204
- package/lib/module/storage/components/StorageActionButtons.js +1 -238
- package/lib/module/storage/components/StorageBrowserMode.js +1 -57
- package/lib/module/storage/components/StorageEventActionButton.js +1 -118
- package/lib/module/storage/components/StorageEventCard.js +1 -113
- package/lib/module/storage/components/StorageEventDetailContent.js +1 -490
- package/lib/module/storage/components/StorageEventFilterView.js +1 -156
- package/lib/module/storage/components/StorageEventsSection.js +1 -20
- package/lib/module/storage/components/StorageFilterCards.js +1 -227
- package/lib/module/storage/components/StorageKeyCard.js +1 -517
- package/lib/module/storage/components/StorageKeyDetailScreen.js +1 -577
- package/lib/module/storage/components/StorageKeyRow.js +1 -554
- package/lib/module/storage/components/StorageKeySection.js +1 -155
- package/lib/module/storage/components/StorageKeyStats.js +1 -342
- package/lib/module/storage/components/StorageModalWithTabs.js +1 -949
- package/lib/module/storage/components/StorageSaveNotice.js +1 -168
- package/lib/module/storage/components/StorageSection.js +1 -40
- package/lib/module/storage/components/StorageTypeFilterBar.js +1 -139
- package/lib/module/storage/hooks/useAsyncStorageKeys.js +1 -136
- package/lib/module/storage/hooks/useMMKVInstances.js +1 -204
- package/lib/module/storage/hooks/useMMKVKeys.js +1 -371
- package/lib/module/storage/hooks/useSecureStoreKeys.js +1 -199
- package/lib/module/storage/hooks/useStorageEvents.js +1 -58
- package/lib/module/storage/stores/storageEventStore.js +1 -301
- package/lib/module/storage/sync/storageSyncAdapter.js +1 -486
- package/lib/module/storage/types.js +1 -3
- package/lib/module/storage/utils/AsyncStorageListener.js +1 -679
- package/lib/module/storage/utils/AsyncStorageListener.web.js +1 -76
- package/lib/module/storage/utils/MMKVInstanceRegistry.js +1 -197
- package/lib/module/storage/utils/MMKVListener.js +1 -403
- package/lib/module/storage/utils/SecureStoreRegistry.js +1 -194
- package/lib/module/storage/utils/asyncStorageCompat.js +1 -81
- package/lib/module/storage/utils/browserStorageLifecycle.js +1 -6
- package/lib/module/storage/utils/browserStorageLifecycle.web.js +1 -66
- package/lib/module/storage/utils/clearAllStorage.js +1 -43
- package/lib/module/storage/utils/deleteStorageKeys.js +1 -78
- package/lib/module/storage/utils/lineDiff.js +1 -12
- package/lib/module/storage/utils/mmkvAvailability.js +1 -56
- package/lib/module/storage/utils/mmkvAvailability.web.js +1 -15
- package/lib/module/storage/utils/mmkvTypeDetection.js +1 -148
- package/lib/module/storage/utils/requiredStorageKeyScope.js +1 -13
- package/lib/module/storage/utils/setStorageValue.js +1 -209
- package/lib/module/storage/utils/snapshotProvider.js +1 -380
- package/lib/module/storage/utils/storageActionHelpers.js +1 -42
- package/lib/module/storage/utils/storageBrowserRefresh.js +1 -44
- package/lib/module/storage/utils/storageLabels.js +1 -9
- package/lib/module/storage/utils/storageLabels.web.js +1 -9
- package/lib/module/storage/utils/storageOps.js +1 -46
- package/lib/module/storage/utils/storageQueryUtils.js +1 -30
- package/lib/module/storage/utils/storageTimeTravelUtils.js +1 -281
- package/lib/module/storage/utils/valueType.js +1 -76
- package/lib/web/index.mjs +2 -3
- package/package.json +6 -10
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +0 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +0 -1
- package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts.map +0 -1
- package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts.map +0 -1
- package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventCard.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventsSection.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyCard.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyDetailScreen.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageSaveNotice.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageSection.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +0 -1
- package/lib/typescript/storage/stores/storageEventStore.d.ts.map +0 -1
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/storage/types.d.ts.map +0 -1
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +0 -1
- package/lib/typescript/storage/utils/AsyncStorageListener.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +0 -1
- package/lib/typescript/storage/utils/MMKVListener.d.ts.map +0 -1
- package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +0 -1
- package/lib/typescript/storage/utils/asyncStorageCompat.d.ts.map +0 -1
- package/lib/typescript/storage/utils/browserStorageLifecycle.d.ts.map +0 -1
- package/lib/typescript/storage/utils/browserStorageLifecycle.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +0 -1
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +0 -1
- package/lib/typescript/storage/utils/lineDiff.d.ts.map +0 -1
- package/lib/typescript/storage/utils/mmkvAvailability.d.ts.map +0 -1
- package/lib/typescript/storage/utils/mmkvAvailability.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +0 -1
- package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts.map +0 -1
- package/lib/typescript/storage/utils/setStorageValue.d.ts.map +0 -1
- package/lib/typescript/storage/utils/snapshotProvider.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageActionHelpers.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageLabels.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageLabels.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageOps.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageQueryUtils.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +0 -1
- package/lib/typescript/storage/utils/valueType.d.ts.map +0 -1
|
@@ -1,76 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { subscribeToBrowserStorage } from '@buoy-gg/shared-ui/utils';
|
|
4
|
-
const listeners = new Set();
|
|
5
|
-
let stop;
|
|
6
|
-
let paused = false;
|
|
7
|
-
const ignoredKeys = new Set(['@react_buoy_storage_event_filters', '@react_buoy_storage_key_filters', '@react_buoy_storage_is_monitoring', 'REACT_QUERY_OFFLINE_CACHE']);
|
|
8
|
-
const ignored = key => [...ignoredKeys].some(prefix => key.startsWith(prefix));
|
|
9
|
-
export async function startListening() {
|
|
10
|
-
if (stop || typeof window === 'undefined') return;
|
|
11
|
-
stop = subscribeToBrowserStorage(change => {
|
|
12
|
-
if (paused || change.area !== 'localStorage' || change.key !== undefined && ignored(change.key)) return;
|
|
13
|
-
const {
|
|
14
|
-
area: _,
|
|
15
|
-
action,
|
|
16
|
-
...data
|
|
17
|
-
} = change;
|
|
18
|
-
if (data.prevPairs) data.prevPairs = data.prevPairs.filter(([key]) => !ignored(key));
|
|
19
|
-
const event = {
|
|
20
|
-
action,
|
|
21
|
-
data,
|
|
22
|
-
timestamp: new Date()
|
|
23
|
-
};
|
|
24
|
-
for (const listener of [...listeners]) {
|
|
25
|
-
try {
|
|
26
|
-
listener(event);
|
|
27
|
-
} catch {/* Keep observing other consumers. */}
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
export function stopListening() {
|
|
32
|
-
stop?.();
|
|
33
|
-
stop = undefined;
|
|
34
|
-
}
|
|
35
|
-
export function addListener(listener) {
|
|
36
|
-
listeners.add(listener);
|
|
37
|
-
return () => {
|
|
38
|
-
listeners.delete(listener);
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
export function removeAllListeners() {
|
|
42
|
-
listeners.clear();
|
|
43
|
-
}
|
|
44
|
-
export function isListening() {
|
|
45
|
-
return !!stop;
|
|
46
|
-
}
|
|
47
|
-
export function getListenerCount() {
|
|
48
|
-
return listeners.size;
|
|
49
|
-
}
|
|
50
|
-
export function pauseCapture() {
|
|
51
|
-
paused = true;
|
|
52
|
-
}
|
|
53
|
-
export function resumeCapture() {
|
|
54
|
-
paused = false;
|
|
55
|
-
}
|
|
56
|
-
export function isPaused() {
|
|
57
|
-
return paused;
|
|
58
|
-
}
|
|
59
|
-
const asyncStorageListener = {
|
|
60
|
-
startListening,
|
|
61
|
-
stopListening,
|
|
62
|
-
addListener,
|
|
63
|
-
removeAllListeners,
|
|
64
|
-
pause: pauseCapture,
|
|
65
|
-
resume: resumeCapture,
|
|
66
|
-
get isActive() {
|
|
67
|
-
return isListening();
|
|
68
|
-
},
|
|
69
|
-
get listenerCount() {
|
|
70
|
-
return listeners.size;
|
|
71
|
-
},
|
|
72
|
-
get paused() {
|
|
73
|
-
return paused;
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
export default asyncStorageListener;
|
|
1
|
+
"use strict";import{subscribeToBrowserStorage as f}from"@buoy-gg/shared-ui/utils";const t=new Set;let r;let n=false;const p=new Set(["@react_buoy_storage_event_filters","@react_buoy_storage_key_filters","@react_buoy_storage_is_monitoring","REACT_QUERY_OFFLINE_CACHE"]);const u=e=>[...p].some(i=>e.startsWith(i));export async function startListening(){if(r||typeof window==="undefined")return;r=f(e=>{if(n||e.area!=="localStorage"||e.key!==void 0&&u(e.key))return;const{area:i,action:a,...s}=e;if(s.prevPairs)s.prevPairs=s.prevPairs.filter(([o])=>!u(o));const c={action:a,data:s,timestamp:new Date};for(const o of[...t]){try{o(c)}catch{}}})}export function stopListening(){r?.();r=void 0}export function addListener(e){t.add(e);return()=>{t.delete(e)}}export function removeAllListeners(){t.clear()}export function isListening(){return!!r}export function getListenerCount(){return t.size}export function pauseCapture(){n=true}export function resumeCapture(){n=false}export function isPaused(){return n}const d={startListening,stopListening,addListener,removeAllListeners,pause:pauseCapture,resume:resumeCapture,get isActive(){return isListening()},get listenerCount(){return t.size},get paused(){return n}};export default d;
|
|
@@ -1,197 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MMKV Instance Registry
|
|
5
|
-
*
|
|
6
|
-
* Centralized registry for tracking all MMKV instances in the application.
|
|
7
|
-
* Provides a singleton pattern to manage multiple MMKV instances and their metadata.
|
|
8
|
-
*
|
|
9
|
-
* @module MMKVInstanceRegistry
|
|
10
|
-
* @since 1.0.0
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
// Static ESM import. This was previously a dynamic `require('./MMKVListener')`
|
|
14
|
-
// inside register/unregister "to avoid a circular dependency" — but MMKVListener
|
|
15
|
-
// imports only ./mmkvTypeDetection, never this file, so there is no cycle. The
|
|
16
|
-
// require() form threw `ReferenceError: require is not defined` when this source
|
|
17
|
-
// is bundled as ESM (the desktop dashboard imports it through Vite), crashing on
|
|
18
|
-
// StorageInline unmount. A static import behaves identically on Metro and Vite.
|
|
19
|
-
import { mmkvListener } from "./MMKVListener";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Type-safe representation of an MMKV instance.
|
|
23
|
-
* Uses conditional typing to avoid hard dependency on react-native-mmkv.
|
|
24
|
-
*
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Metadata about a registered MMKV instance
|
|
30
|
-
*
|
|
31
|
-
* @public
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Configuration options for registering an MMKV instance
|
|
36
|
-
*
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
class MMKVInstanceRegistry {
|
|
41
|
-
instances = new Map();
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Register an MMKV instance for monitoring
|
|
45
|
-
*
|
|
46
|
-
* @param id - Unique identifier for this instance
|
|
47
|
-
* @param instance - The MMKV instance to register
|
|
48
|
-
* @param config - Optional configuration (e.g., encrypted flag)
|
|
49
|
-
*/
|
|
50
|
-
register(id, instance, config) {
|
|
51
|
-
const instanceInfo = {
|
|
52
|
-
id,
|
|
53
|
-
instance,
|
|
54
|
-
encrypted: config?.encrypted ?? false,
|
|
55
|
-
readOnly: instance.isReadOnly ?? false
|
|
56
|
-
};
|
|
57
|
-
this.instances.set(id, instanceInfo);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Unregister an MMKV instance
|
|
62
|
-
*/
|
|
63
|
-
unregister(id) {
|
|
64
|
-
this.instances.delete(id);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Get a specific instance by ID
|
|
69
|
-
*/
|
|
70
|
-
get(id) {
|
|
71
|
-
return this.instances.get(id);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Get all registered instances
|
|
76
|
-
*/
|
|
77
|
-
getAll() {
|
|
78
|
-
return Array.from(this.instances.values());
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Check if an instance is registered
|
|
83
|
-
*/
|
|
84
|
-
has(id) {
|
|
85
|
-
return this.instances.has(id);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Get count of registered instances
|
|
90
|
-
*/
|
|
91
|
-
count() {
|
|
92
|
-
return this.instances.size;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Singleton instance
|
|
97
|
-
export const mmkvInstanceRegistry = new MMKVInstanceRegistry();
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Register an MMKV instance with React Buoy DevTools for monitoring and debugging.
|
|
101
|
-
*
|
|
102
|
-
* **⚠️ REQUIRED**: Manual registration is required for `react-native-mmkv` v4.
|
|
103
|
-
* Auto-detection is not possible due to Metro bundler and ES6 module limitations.
|
|
104
|
-
*
|
|
105
|
-
* Call this function immediately after creating each MMKV instance you want to monitor.
|
|
106
|
-
* The DevTools will then be able to:
|
|
107
|
-
* - Display all keys and values
|
|
108
|
-
* - Show real-time updates when data changes
|
|
109
|
-
* - Allow editing values directly from the DevTools
|
|
110
|
-
* - Track storage size and performance
|
|
111
|
-
*
|
|
112
|
-
* @param id - Unique identifier for this MMKV instance. Should match the `id` you used when creating the instance.
|
|
113
|
-
* @param instance - The MMKV instance returned from `createMMKV()`
|
|
114
|
-
* @param config - Optional configuration
|
|
115
|
-
* @param config.encrypted - Set to `true` if this instance uses encryption (has an `encryptionKey`)
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* **Basic usage:**
|
|
119
|
-
* ```typescript
|
|
120
|
-
* import { createMMKV } from 'react-native-mmkv';
|
|
121
|
-
* import { registerMMKVInstance } from '@buoy-gg/storage';
|
|
122
|
-
*
|
|
123
|
-
* // Create and register default instance
|
|
124
|
-
* export const storage = createMMKV({ id: 'mmkv.default' });
|
|
125
|
-
* registerMMKVInstance('mmkv.default', storage);
|
|
126
|
-
* ```
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
129
|
-
* **With encryption:**
|
|
130
|
-
* ```typescript
|
|
131
|
-
* import { createMMKV } from 'react-native-mmkv';
|
|
132
|
-
* import { registerMMKVInstance } from '@buoy-gg/storage';
|
|
133
|
-
*
|
|
134
|
-
* // Create encrypted instance
|
|
135
|
-
* export const secureStorage = createMMKV({
|
|
136
|
-
* id: 'secure-storage',
|
|
137
|
-
* encryptionKey: 'my-encryption-key'
|
|
138
|
-
* });
|
|
139
|
-
*
|
|
140
|
-
* // Register with encrypted flag
|
|
141
|
-
* registerMMKVInstance('secure-storage', secureStorage, { encrypted: true });
|
|
142
|
-
* ```
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* **Multiple instances:**
|
|
146
|
-
* ```typescript
|
|
147
|
-
* import { createMMKV } from 'react-native-mmkv';
|
|
148
|
-
* import { registerMMKVInstance } from '@buoy-gg/storage';
|
|
149
|
-
*
|
|
150
|
-
* // User preferences
|
|
151
|
-
* export const userPrefs = createMMKV({ id: 'user-prefs' });
|
|
152
|
-
* registerMMKVInstance('user-prefs', userPrefs);
|
|
153
|
-
*
|
|
154
|
-
* // Cache
|
|
155
|
-
* export const cache = createMMKV({ id: 'cache' });
|
|
156
|
-
* registerMMKVInstance('cache', cache);
|
|
157
|
-
*
|
|
158
|
-
* // Auth (encrypted)
|
|
159
|
-
* export const auth = createMMKV({ id: 'auth', encryptionKey: 'key' });
|
|
160
|
-
* registerMMKVInstance('auth', auth, { encrypted: true });
|
|
161
|
-
* ```
|
|
162
|
-
*
|
|
163
|
-
* @public
|
|
164
|
-
* @since 1.0.0
|
|
165
|
-
*/
|
|
166
|
-
export function registerMMKVInstance(id, instance, config) {
|
|
167
|
-
// Register in registry
|
|
168
|
-
mmkvInstanceRegistry.register(id, instance, config);
|
|
169
|
-
|
|
170
|
-
// Add listener for real-time monitoring (CRITICAL: enables event emission)
|
|
171
|
-
// v4: Use ONLY native listener (addOnValueChangedListener), skip method wrapping
|
|
172
|
-
mmkvListener.addInstance(instance, id);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Unregister an MMKV instance from DevTools monitoring.
|
|
177
|
-
*
|
|
178
|
-
* This stops the DevTools from tracking changes to this instance.
|
|
179
|
-
* Typically not needed unless you're dynamically creating/destroying instances.
|
|
180
|
-
*
|
|
181
|
-
* @param id - The instance ID to unregister
|
|
182
|
-
*
|
|
183
|
-
* @example
|
|
184
|
-
* ```typescript
|
|
185
|
-
* unregisterMMKVInstance('cache');
|
|
186
|
-
* ```
|
|
187
|
-
*
|
|
188
|
-
* @public
|
|
189
|
-
* @since 1.0.0
|
|
190
|
-
*/
|
|
191
|
-
export function unregisterMMKVInstance(id) {
|
|
192
|
-
// Remove listener first
|
|
193
|
-
mmkvListener.removeInstance(id);
|
|
194
|
-
|
|
195
|
-
// Then remove from registry
|
|
196
|
-
mmkvInstanceRegistry.unregister(id);
|
|
197
|
-
}
|
|
1
|
+
"use strict";import{mmkvListener as n}from"./MMKVListener";class a{instances=new Map;register(e,s,r){const i={id:e,instance:s,encrypted:r?.encrypted??false,readOnly:s.isReadOnly??false};this.instances.set(e,i)}unregister(e){this.instances.delete(e)}get(e){return this.instances.get(e)}getAll(){return Array.from(this.instances.values())}has(e){return this.instances.has(e)}count(){return this.instances.size}}export const mmkvInstanceRegistry=new a;export function registerMMKVInstance(t,e,s){mmkvInstanceRegistry.register(t,e,s);n.addInstance(e,t)}export function unregisterMMKVInstance(t){n.removeInstance(t);mmkvInstanceRegistry.unregister(t)}
|
|
@@ -1,403 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MMKVListener - Hybrid Monitoring Strategy
|
|
5
|
-
*
|
|
6
|
-
* This module provides comprehensive monitoring for MMKV storage instances using
|
|
7
|
-
* a hybrid approach that combines:
|
|
8
|
-
*
|
|
9
|
-
* 1. MMKV's built-in addOnValueChangedListener() - for write operations
|
|
10
|
-
* 2. Method wrapping - for read operations and type detection
|
|
11
|
-
*
|
|
12
|
-
* Why Hybrid Strategy?
|
|
13
|
-
* - MMKV listeners only fire on writes (set/delete), not reads
|
|
14
|
-
* - MMKV listeners don't provide value type information
|
|
15
|
-
* - Method wrapping captures ALL operations with full context
|
|
16
|
-
* - Combining both gives complete observability
|
|
17
|
-
*
|
|
18
|
-
* Key Differences from AsyncStorage:
|
|
19
|
-
* - Synchronous API (no async/await needed)
|
|
20
|
-
* - Multi-instance support (track multiple MMKV instances)
|
|
21
|
-
* - Native types (string, number, boolean, buffer)
|
|
22
|
-
* - Built-in listener support (MMKV.addOnValueChangedListener)
|
|
23
|
-
*
|
|
24
|
-
* @see AsyncStorageListener.ts for AsyncStorage equivalent
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
// Use 'any' type for MMKV to avoid hard dependency on react-native-mmkv
|
|
28
|
-
|
|
29
|
-
import { detectMMKVType } from "./mmkvTypeDetection";
|
|
30
|
-
|
|
31
|
-
// MMKV method signatures
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Event types for MMKV operations
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Instance tracking for MMKV monitoring
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Singleton class for monitoring MMKV operations across multiple instances
|
|
43
|
-
*
|
|
44
|
-
* Uses a hybrid monitoring strategy:
|
|
45
|
-
* 1. MMKV's built-in listener API for write notifications
|
|
46
|
-
* 2. Method wrapping for read operations and type information
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* import { MMKV } from 'react-native-mmkv';
|
|
51
|
-
* import { mmkvListener } from './MMKVListener';
|
|
52
|
-
*
|
|
53
|
-
* const storage = new MMKV();
|
|
54
|
-
*
|
|
55
|
-
* // Start monitoring this instance
|
|
56
|
-
* mmkvListener.addInstance(storage, 'mmkv.default');
|
|
57
|
-
*
|
|
58
|
-
* // Add listener for all MMKV events
|
|
59
|
-
* const unsubscribe = mmkvListener.addListener((event) => {
|
|
60
|
-
* console.log(`[${event.instanceId}] ${event.action}:`, event.data);
|
|
61
|
-
* });
|
|
62
|
-
*
|
|
63
|
-
* // Cleanup
|
|
64
|
-
* unsubscribe();
|
|
65
|
-
* mmkvListener.removeInstance('mmkv.default');
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
class MMKVListener {
|
|
69
|
-
listeners = [];
|
|
70
|
-
instances = new Map();
|
|
71
|
-
|
|
72
|
-
// Keys to ignore to prevent dev tools from triggering self-events
|
|
73
|
-
ignoredKeys = new Set(["@react_buoy_storage_event_filters", "@react_buoy_storage_key_filters", "@react_buoy_storage_is_monitoring", "REACT_QUERY_OFFLINE_CACHE"]);
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Determines if a storage key should be ignored
|
|
77
|
-
*/
|
|
78
|
-
shouldIgnoreKey(key) {
|
|
79
|
-
if (this.ignoredKeys.has(key)) return true;
|
|
80
|
-
for (const ignoredKey of this.ignoredKeys) {
|
|
81
|
-
if (key.startsWith(ignoredKey)) return true;
|
|
82
|
-
}
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Emit an MMKV event to all registered listeners
|
|
88
|
-
*/
|
|
89
|
-
emit(event) {
|
|
90
|
-
if (this.listeners.length === 0) return;
|
|
91
|
-
this.listeners.forEach(listener => {
|
|
92
|
-
try {
|
|
93
|
-
listener(event);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
// Error in MMKV event listener - continuing with others
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Add an MMKV instance for monitoring
|
|
102
|
-
*
|
|
103
|
-
* This method sets up both native MMKV listeners and method wrapping
|
|
104
|
-
* to provide complete observability.
|
|
105
|
-
*
|
|
106
|
-
* @param instance - MMKV instance to monitor
|
|
107
|
-
* @param instanceId - Unique identifier for this instance
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```typescript
|
|
111
|
-
* const storage = new MMKV();
|
|
112
|
-
* mmkvListener.addInstance(storage, 'mmkv.default');
|
|
113
|
-
*
|
|
114
|
-
* const secureStorage = new MMKV({ id: 'secure', encryptionKey: key });
|
|
115
|
-
* mmkvListener.addInstance(secureStorage, 'secure');
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
|
-
addInstance(instance, instanceId) {
|
|
119
|
-
// Check if already monitoring this instance
|
|
120
|
-
if (this.instances.has(instanceId)) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// v4 COMPATIBILITY: Use ONLY native listener (no method wrapping)
|
|
125
|
-
// react-native-mmkv v4 instances have frozen/read-only methods that cannot be wrapped
|
|
126
|
-
// The native listener (addOnValueChangedListener) is sufficient for monitoring writes
|
|
127
|
-
|
|
128
|
-
let nativeListenerUnsubscribe;
|
|
129
|
-
|
|
130
|
-
// Seed the shadow copy so the FIRST observed write already knows what it
|
|
131
|
-
// replaced. Without this, every key's first event would claim the key never
|
|
132
|
-
// existed even when it was carried over from a previous launch.
|
|
133
|
-
const lastKnownValues = new Map();
|
|
134
|
-
try {
|
|
135
|
-
for (const key of instance.getAllKeys() ?? []) {
|
|
136
|
-
if (this.shouldIgnoreKey(key)) continue;
|
|
137
|
-
lastKnownValues.set(key, detectMMKVType(instance, key).value);
|
|
138
|
-
}
|
|
139
|
-
} catch {
|
|
140
|
-
// Key scan unavailable — prevValue is simply absent until each key is
|
|
141
|
-
// written once, which is strictly better than reporting a wrong value.
|
|
142
|
-
}
|
|
143
|
-
if (typeof instance.addOnValueChangedListener === "function") {
|
|
144
|
-
try {
|
|
145
|
-
nativeListenerUnsubscribe = instance.addOnValueChangedListener(key => {
|
|
146
|
-
// Ignore dev tools keys
|
|
147
|
-
if (this.shouldIgnoreKey(key)) return;
|
|
148
|
-
|
|
149
|
-
// Detect the value type
|
|
150
|
-
const {
|
|
151
|
-
value,
|
|
152
|
-
type
|
|
153
|
-
} = detectMMKVType(instance, key);
|
|
154
|
-
|
|
155
|
-
// Read the shadow copy BEFORE overwriting it — this is the value the
|
|
156
|
-
// write replaced. `undefined` means the key did not exist.
|
|
157
|
-
const prevValue = lastKnownValues.get(key);
|
|
158
|
-
|
|
159
|
-
// Determine action: if value is undefined/unknown, it was deleted
|
|
160
|
-
const isDelete = type === "unknown" || value === undefined;
|
|
161
|
-
if (isDelete) {
|
|
162
|
-
lastKnownValues.delete(key);
|
|
163
|
-
|
|
164
|
-
// Key was deleted
|
|
165
|
-
const event = {
|
|
166
|
-
action: "delete",
|
|
167
|
-
timestamp: new Date(),
|
|
168
|
-
instanceId,
|
|
169
|
-
data: {
|
|
170
|
-
key,
|
|
171
|
-
prevValue,
|
|
172
|
-
success: true
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
this.emit(event);
|
|
176
|
-
} else {
|
|
177
|
-
lastKnownValues.set(key, value);
|
|
178
|
-
|
|
179
|
-
// Key was set/updated
|
|
180
|
-
const action = type === "string" ? "set.string" : type === "number" ? "set.number" : type === "boolean" ? "set.boolean" : type === "buffer" ? "set.buffer" : "set.string"; // fallback
|
|
181
|
-
|
|
182
|
-
const event = {
|
|
183
|
-
action,
|
|
184
|
-
timestamp: new Date(),
|
|
185
|
-
instanceId,
|
|
186
|
-
data: {
|
|
187
|
-
key,
|
|
188
|
-
value,
|
|
189
|
-
prevValue,
|
|
190
|
-
valueType: type,
|
|
191
|
-
success: true
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
this.emit(event);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
} catch (error) {
|
|
198
|
-
// Could not add native listener
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Store instance tracking (no originalMethods needed for v4)
|
|
203
|
-
this.instances.set(instanceId, {
|
|
204
|
-
instance,
|
|
205
|
-
instanceId,
|
|
206
|
-
originalMethods: {},
|
|
207
|
-
// Not used in v4
|
|
208
|
-
nativeListenerUnsubscribe,
|
|
209
|
-
lastKnownValues
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Remove an MMKV instance from monitoring
|
|
215
|
-
*
|
|
216
|
-
* Restores original methods and removes native listener.
|
|
217
|
-
*
|
|
218
|
-
* @param instanceId - Identifier of instance to stop monitoring
|
|
219
|
-
*/
|
|
220
|
-
removeInstance(instanceId) {
|
|
221
|
-
const tracked = this.instances.get(instanceId);
|
|
222
|
-
if (!tracked) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
const {
|
|
226
|
-
nativeListenerUnsubscribe
|
|
227
|
-
} = tracked;
|
|
228
|
-
|
|
229
|
-
// Remove native listener. The return of addOnValueChangedListener varies by
|
|
230
|
-
// implementation: a bare unsubscribe function, or a Listener object with a
|
|
231
|
-
// `.remove()` method (react-native-mmkv v4 and the desktop RemoteMMKV
|
|
232
|
-
// back-end). Handle both, and never let teardown throw — this runs during
|
|
233
|
-
// React unmount, where an exception escapes every error boundary and blanks
|
|
234
|
-
// the whole app.
|
|
235
|
-
try {
|
|
236
|
-
if (typeof nativeListenerUnsubscribe === "function") {
|
|
237
|
-
nativeListenerUnsubscribe();
|
|
238
|
-
} else if (typeof nativeListenerUnsubscribe?.remove === "function") {
|
|
239
|
-
nativeListenerUnsubscribe.remove();
|
|
240
|
-
}
|
|
241
|
-
} catch {
|
|
242
|
-
/* listener already gone / back-end offline — nothing to clean up */
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Remove from tracking
|
|
246
|
-
this.instances.delete(instanceId);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Remove all monitored instances
|
|
251
|
-
*/
|
|
252
|
-
removeAllInstances() {
|
|
253
|
-
const instanceIds = Array.from(this.instances.keys());
|
|
254
|
-
instanceIds.forEach(id => this.removeInstance(id));
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Add a listener for MMKV events across all monitored instances
|
|
259
|
-
*
|
|
260
|
-
* @param listener - Callback function to handle MMKV events
|
|
261
|
-
* @returns Unsubscribe function to remove the listener
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* ```typescript
|
|
265
|
-
* const unsubscribe = mmkvListener.addListener((event) => {
|
|
266
|
-
* console.log(`[${event.instanceId}] ${event.action}:`, event.data);
|
|
267
|
-
* });
|
|
268
|
-
*
|
|
269
|
-
* // Later, remove the listener
|
|
270
|
-
* unsubscribe();
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
addListener(listener) {
|
|
274
|
-
this.listeners.push(listener);
|
|
275
|
-
|
|
276
|
-
// Return unsubscribe function
|
|
277
|
-
return () => {
|
|
278
|
-
const index = this.listeners.indexOf(listener);
|
|
279
|
-
if (index > -1) {
|
|
280
|
-
this.listeners.splice(index, 1);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Remove all registered event listeners
|
|
287
|
-
*/
|
|
288
|
-
removeAllListeners() {
|
|
289
|
-
this.listeners = [];
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Check if an instance is currently being monitored
|
|
294
|
-
*/
|
|
295
|
-
hasInstance(instanceId) {
|
|
296
|
-
return this.instances.has(instanceId);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Get list of all monitored instance IDs
|
|
301
|
-
*/
|
|
302
|
-
getMonitoredInstances() {
|
|
303
|
-
return Array.from(this.instances.keys());
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Get the number of currently monitored instances
|
|
308
|
-
*/
|
|
309
|
-
get instanceCount() {
|
|
310
|
-
return this.instances.size;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Get the number of currently registered event listeners
|
|
315
|
-
*/
|
|
316
|
-
get listenerCount() {
|
|
317
|
-
return this.listeners.length;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Check if any instances are being monitored
|
|
322
|
-
*/
|
|
323
|
-
get isActive() {
|
|
324
|
-
return this.instances.size > 0;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Singleton instance of MMKVListener
|
|
330
|
-
*
|
|
331
|
-
* This ensures only one listener manager exists across the entire application.
|
|
332
|
-
*/
|
|
333
|
-
export const mmkvListener = new MMKVListener();
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Add an MMKV instance for monitoring
|
|
337
|
-
*
|
|
338
|
-
* @param instance - MMKV instance to monitor
|
|
339
|
-
* @param instanceId - Unique identifier for this instance
|
|
340
|
-
*
|
|
341
|
-
* @example
|
|
342
|
-
* ```typescript
|
|
343
|
-
* import { MMKV } from 'react-native-mmkv';
|
|
344
|
-
* import { addMMKVInstance } from '@buoy-gg/storage';
|
|
345
|
-
*
|
|
346
|
-
* const storage = new MMKV();
|
|
347
|
-
* addMMKVInstance(storage, 'mmkv.default');
|
|
348
|
-
* ```
|
|
349
|
-
*/
|
|
350
|
-
export const addMMKVInstance = (instance, instanceId) => mmkvListener.addInstance(instance, instanceId);
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Remove an MMKV instance from monitoring
|
|
354
|
-
*/
|
|
355
|
-
export const removeMMKVInstance = instanceId => mmkvListener.removeInstance(instanceId);
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Remove all monitored MMKV instances
|
|
359
|
-
*/
|
|
360
|
-
export const removeAllMMKVInstances = () => mmkvListener.removeAllInstances();
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Add an event listener for MMKV operations
|
|
364
|
-
*
|
|
365
|
-
* @param listener - Callback function to handle events
|
|
366
|
-
* @returns Unsubscribe function to remove the listener
|
|
367
|
-
*/
|
|
368
|
-
export const addMMKVListener = listener => mmkvListener.addListener(listener);
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Remove all registered event listeners
|
|
372
|
-
*/
|
|
373
|
-
export const removeAllMMKVListeners = () => mmkvListener.removeAllListeners();
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Check if an MMKV instance is currently being monitored
|
|
377
|
-
*/
|
|
378
|
-
export const isMMKVInstanceMonitored = instanceId => mmkvListener.hasInstance(instanceId);
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Get list of all monitored MMKV instance IDs
|
|
382
|
-
*/
|
|
383
|
-
export const getMonitoredMMKVInstances = () => mmkvListener.getMonitoredInstances();
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Get the current number of monitored MMKV instances
|
|
387
|
-
*/
|
|
388
|
-
export const getMMKVInstanceCount = () => mmkvListener.instanceCount;
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Get the current number of registered event listeners
|
|
392
|
-
*/
|
|
393
|
-
export const getMMKVListenerCount = () => mmkvListener.listenerCount;
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Check if any MMKV instances are being monitored
|
|
397
|
-
*/
|
|
398
|
-
export const isMMKVListening = () => mmkvListener.isActive;
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Export the singleton instance for advanced usage
|
|
402
|
-
*/
|
|
403
|
-
export default mmkvListener;
|
|
1
|
+
"use strict";import{detectMMKVType as l}from"./mmkvTypeDetection";class f{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 o=new Map;try{for(const s of e.getAllKeys()??[]){if(this.shouldIgnoreKey(s))continue;o.set(s,l(e,s).value)}}catch{}if(typeof e.addOnValueChangedListener==="function"){try{r=e.addOnValueChangedListener(s=>{if(this.shouldIgnoreKey(s))return;const{value:a,type:i}=l(e,s);const u=o.get(s);const h=i==="unknown"||a===void 0;if(h){o.delete(s);const c={action:"delete",timestamp:new Date,instanceId:t,data:{key:s,prevValue:u,success:true}};this.emit(c)}else{o.set(s,a);const c=i==="string"?"set.string":i==="number"?"set.number":i==="boolean"?"set.boolean":i==="buffer"?"set.buffer":"set.string";const d={action:c,timestamp:new Date,instanceId:t,data:{key:s,value:a,prevValue:u,valueType:i,success:true}};this.emit(d)}})}catch(s){}}this.instances.set(t,{instance:e,instanceId:t,originalMethods:{},nativeListenerUnsubscribe:r,lastKnownValues:o})}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}}export const mmkvListener=new f;export const addMMKVInstance=(n,e)=>mmkvListener.addInstance(n,e);export const removeMMKVInstance=n=>mmkvListener.removeInstance(n);export const removeAllMMKVInstances=()=>mmkvListener.removeAllInstances();export const addMMKVListener=n=>mmkvListener.addListener(n);export const removeAllMMKVListeners=()=>mmkvListener.removeAllListeners();export const isMMKVInstanceMonitored=n=>mmkvListener.hasInstance(n);export const getMonitoredMMKVInstances=()=>mmkvListener.getMonitoredInstances();export const getMMKVInstanceCount=()=>mmkvListener.instanceCount;export const getMMKVListenerCount=()=>mmkvListener.listenerCount;export const isMMKVListening=()=>mmkvListener.isActive;export default mmkvListener;
|