@buoy-gg/storage 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +607 -0
- package/lib/commonjs/index.js +34 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/preset.js +94 -0
- package/lib/commonjs/storage/components/DiffViewer/DiffOptionsPanel.js +356 -0
- package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +29 -0
- package/lib/commonjs/storage/components/DiffViewer/components/DiffSummary.js +121 -0
- package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +419 -0
- package/lib/commonjs/storage/components/DiffViewer/themes/diffThemes.js +122 -0
- package/lib/commonjs/storage/components/GameUIStorageBrowser.js +924 -0
- package/lib/commonjs/storage/components/GameUIStorageStats.js +746 -0
- package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +257 -0
- package/lib/commonjs/storage/components/MMKVInstanceSelector.js +418 -0
- package/lib/commonjs/storage/components/SelectionActionBar.js +224 -0
- package/lib/commonjs/storage/components/StorageActionButtons.js +239 -0
- package/lib/commonjs/storage/components/StorageActions.js +192 -0
- package/lib/commonjs/storage/components/StorageBrowserMode.js +31 -0
- package/lib/commonjs/storage/components/StorageEventDetailContent.js +1025 -0
- package/lib/commonjs/storage/components/StorageEventFilterView.js +141 -0
- package/lib/commonjs/storage/components/StorageEventListener.js +357 -0
- package/lib/commonjs/storage/components/StorageEventsSection.js +24 -0
- package/lib/commonjs/storage/components/StorageFilterCards.js +345 -0
- package/lib/commonjs/storage/components/StorageFilterViewV2.js +42 -0
- package/lib/commonjs/storage/components/StorageKeyCard.js +516 -0
- package/lib/commonjs/storage/components/StorageKeyRow.js +356 -0
- package/lib/commonjs/storage/components/StorageKeySection.js +105 -0
- package/lib/commonjs/storage/components/StorageKeyStats.js +344 -0
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +871 -0
- package/lib/commonjs/storage/components/StorageSection.js +43 -0
- package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +126 -0
- package/lib/commonjs/storage/hooks/useMMKVInstances.js +221 -0
- package/lib/commonjs/storage/hooks/useMMKVKeys.js +362 -0
- package/lib/commonjs/storage/hooks/useTickEverySecond.js +21 -0
- package/lib/commonjs/storage/index.js +148 -0
- package/lib/commonjs/storage/types.js +5 -0
- package/lib/commonjs/storage/utils/AsyncStorageListener.js +510 -0
- package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +202 -0
- package/lib/commonjs/storage/utils/MMKVListener.js +380 -0
- package/lib/commonjs/storage/utils/clearAllStorage.js +47 -0
- package/lib/commonjs/storage/utils/index.js +180 -0
- package/lib/commonjs/storage/utils/lineDiff.js +363 -0
- package/lib/commonjs/storage/utils/mmkvAvailability.js +62 -0
- package/lib/commonjs/storage/utils/mmkvTypeDetection.js +139 -0
- package/lib/commonjs/storage/utils/objectDiff.js +157 -0
- package/lib/commonjs/storage/utils/safeAsyncStorage.js +140 -0
- package/lib/commonjs/storage/utils/storageActionHelpers.js +46 -0
- package/lib/commonjs/storage/utils/storageQueryUtils.js +35 -0
- package/lib/commonjs/storage/utils/valueType.js +18 -0
- package/lib/module/index.js +7 -0
- package/lib/module/preset.js +89 -0
- package/lib/module/storage/components/DiffViewer/DiffOptionsPanel.js +352 -0
- package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +25 -0
- package/lib/module/storage/components/DiffViewer/components/DiffSummary.js +117 -0
- package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +415 -0
- package/lib/module/storage/components/DiffViewer/themes/diffThemes.js +118 -0
- package/lib/module/storage/components/GameUIStorageBrowser.js +922 -0
- package/lib/module/storage/components/GameUIStorageStats.js +742 -0
- package/lib/module/storage/components/MMKVInstanceInfoPanel.js +253 -0
- package/lib/module/storage/components/MMKVInstanceSelector.js +414 -0
- package/lib/module/storage/components/SelectionActionBar.js +221 -0
- package/lib/module/storage/components/StorageActionButtons.js +236 -0
- package/lib/module/storage/components/StorageActions.js +189 -0
- package/lib/module/storage/components/StorageBrowserMode.js +27 -0
- package/lib/module/storage/components/StorageEventDetailContent.js +1020 -0
- package/lib/module/storage/components/StorageEventFilterView.js +137 -0
- package/lib/module/storage/components/StorageEventListener.js +354 -0
- package/lib/module/storage/components/StorageEventsSection.js +20 -0
- package/lib/module/storage/components/StorageFilterCards.js +341 -0
- package/lib/module/storage/components/StorageFilterViewV2.js +38 -0
- package/lib/module/storage/components/StorageKeyCard.js +513 -0
- package/lib/module/storage/components/StorageKeyRow.js +353 -0
- package/lib/module/storage/components/StorageKeySection.js +101 -0
- package/lib/module/storage/components/StorageKeyStats.js +340 -0
- package/lib/module/storage/components/StorageModalWithTabs.js +867 -0
- package/lib/module/storage/components/StorageSection.js +40 -0
- package/lib/module/storage/hooks/useAsyncStorageKeys.js +121 -0
- package/lib/module/storage/hooks/useMMKVInstances.js +216 -0
- package/lib/module/storage/hooks/useMMKVKeys.js +359 -0
- package/lib/module/storage/hooks/useTickEverySecond.js +18 -0
- package/lib/module/storage/index.js +25 -0
- package/lib/module/storage/types.js +3 -0
- package/lib/module/storage/utils/AsyncStorageListener.js +500 -0
- package/lib/module/storage/utils/MMKVInstanceRegistry.js +196 -0
- package/lib/module/storage/utils/MMKVListener.js +367 -0
- package/lib/module/storage/utils/clearAllStorage.js +42 -0
- package/lib/module/storage/utils/index.js +22 -0
- package/lib/module/storage/utils/lineDiff.js +359 -0
- package/lib/module/storage/utils/mmkvAvailability.js +56 -0
- package/lib/module/storage/utils/mmkvTypeDetection.js +133 -0
- package/lib/module/storage/utils/objectDiff.js +153 -0
- package/lib/module/storage/utils/safeAsyncStorage.js +134 -0
- package/lib/module/storage/utils/storageActionHelpers.js +42 -0
- package/lib/module/storage/utils/storageQueryUtils.js +30 -0
- package/lib/module/storage/utils/valueType.js +14 -0
- package/lib/typescript/index.d.ts +3 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts +90 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/lib/typescript/storage/components/DiffViewer/DiffOptionsPanel.d.ts +18 -0
- package/lib/typescript/storage/components/DiffViewer/DiffOptionsPanel.d.ts.map +1 -0
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts +7 -0
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +1 -0
- package/lib/typescript/storage/components/DiffViewer/components/DiffSummary.d.ts +12 -0
- package/lib/typescript/storage/components/DiffViewer/components/DiffSummary.d.ts.map +1 -0
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts +13 -0
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +1 -0
- package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts +64 -0
- package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +1 -0
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts +16 -0
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -0
- package/lib/typescript/storage/components/GameUIStorageStats.d.ts +7 -0
- package/lib/typescript/storage/components/GameUIStorageStats.d.ts.map +1 -0
- package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts +42 -0
- package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts.map +1 -0
- package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts +35 -0
- package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts.map +1 -0
- package/lib/typescript/storage/components/SelectionActionBar.d.ts +21 -0
- package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageActionButtons.d.ts +21 -0
- package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageActions.d.ts +10 -0
- package/lib/typescript/storage/components/StorageActions.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts +18 -0
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts +40 -0
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageEventFilterView.d.ts +11 -0
- package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageEventListener.d.ts +6 -0
- package/lib/typescript/storage/components/StorageEventListener.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageEventsSection.d.ts +7 -0
- package/lib/typescript/storage/components/StorageEventsSection.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageFilterCards.d.ts +36 -0
- package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageFilterViewV2.d.ts +9 -0
- package/lib/typescript/storage/components/StorageFilterViewV2.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageKeyCard.d.ts +17 -0
- package/lib/typescript/storage/components/StorageKeyCard.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts +15 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageKeySection.d.ts +25 -0
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageKeyStats.d.ts +15 -0
- package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts +13 -0
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageSection.d.ts +10 -0
- package/lib/typescript/storage/components/StorageSection.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts +10 -0
- package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useMMKVInstances.d.ts +114 -0
- package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useMMKVKeys.d.ts +94 -0
- package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useTickEverySecond.d.ts +6 -0
- package/lib/typescript/storage/hooks/useTickEverySecond.d.ts.map +1 -0
- package/lib/typescript/storage/index.d.ts +15 -0
- package/lib/typescript/storage/index.d.ts.map +1 -0
- package/lib/typescript/storage/types.d.ts +41 -0
- package/lib/typescript/storage/types.d.ts.map +1 -0
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts +195 -0
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +1 -0
- package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts +224 -0
- package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +1 -0
- package/lib/typescript/storage/utils/MMKVListener.d.ts +218 -0
- package/lib/typescript/storage/utils/MMKVListener.d.ts.map +1 -0
- package/lib/typescript/storage/utils/clearAllStorage.d.ts +11 -0
- package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +1 -0
- package/lib/typescript/storage/utils/index.d.ts +8 -0
- package/lib/typescript/storage/utils/index.d.ts.map +1 -0
- package/lib/typescript/storage/utils/lineDiff.d.ts +34 -0
- package/lib/typescript/storage/utils/lineDiff.d.ts.map +1 -0
- package/lib/typescript/storage/utils/mmkvAvailability.d.ts +23 -0
- package/lib/typescript/storage/utils/mmkvAvailability.d.ts.map +1 -0
- package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts +71 -0
- package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +1 -0
- package/lib/typescript/storage/utils/objectDiff.d.ts +35 -0
- package/lib/typescript/storage/utils/objectDiff.d.ts.map +1 -0
- package/lib/typescript/storage/utils/safeAsyncStorage.d.ts +56 -0
- package/lib/typescript/storage/utils/safeAsyncStorage.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageActionHelpers.d.ts +5 -0
- package/lib/typescript/storage/utils/storageActionHelpers.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageQueryUtils.d.ts +6 -0
- package/lib/typescript/storage/utils/storageQueryUtils.d.ts.map +1 -0
- package/lib/typescript/storage/utils/valueType.d.ts +3 -0
- package/lib/typescript/storage/utils/valueType.d.ts.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useMMKVKeys Hook
|
|
5
|
+
*
|
|
6
|
+
* Fetch and validate MMKV keys from a specific MMKV instance.
|
|
7
|
+
* Equivalent to useAsyncStorageKeys but for MMKV storage.
|
|
8
|
+
*
|
|
9
|
+
* Key Differences from AsyncStorage:
|
|
10
|
+
* - Synchronous API (getAllKeys(), getString(), etc.)
|
|
11
|
+
* - Native types (string, number, boolean, buffer) vs string-only
|
|
12
|
+
* - Multi-instance support (requires instanceId parameter)
|
|
13
|
+
* - No multiGet - must fetch keys individually
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
17
|
+
import { isMMKVAvailable } from '../utils/mmkvAvailability';
|
|
18
|
+
|
|
19
|
+
// Conditionally import MMKV types
|
|
20
|
+
|
|
21
|
+
// Use 'any' to avoid hard dependency on react-native-mmkv
|
|
22
|
+
|
|
23
|
+
// Conditionally import utilities only if MMKV is available
|
|
24
|
+
let detectMMKVType;
|
|
25
|
+
let isTypeMatch;
|
|
26
|
+
if (isMMKVAvailable()) {
|
|
27
|
+
const typeDetection = require('../utils/mmkvTypeDetection');
|
|
28
|
+
detectMMKVType = typeDetection.detectMMKVType;
|
|
29
|
+
isTypeMatch = typeDetection.isTypeMatch;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Hook to fetch and monitor keys from an MMKV instance
|
|
33
|
+
*
|
|
34
|
+
* @param instance - MMKV instance to monitor
|
|
35
|
+
* @param instanceId - Unique identifier for this instance (e.g., "mmkv.default", "secure")
|
|
36
|
+
* @param requiredStorageKeys - Optional array of required keys for validation
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { MMKV } from 'react-native-mmkv';
|
|
41
|
+
* import { useMMKVKeys } from '@buoy-gg/storage';
|
|
42
|
+
*
|
|
43
|
+
* const storage = new MMKV();
|
|
44
|
+
*
|
|
45
|
+
* function MyComponent() {
|
|
46
|
+
* const { storageKeys, isLoading, error, refresh } = useMMKVKeys(
|
|
47
|
+
* storage,
|
|
48
|
+
* 'mmkv.default',
|
|
49
|
+
* [
|
|
50
|
+
* 'user.token',
|
|
51
|
+
* { key: 'user.id', expectedType: 'number' },
|
|
52
|
+
* { key: 'app.theme', expectedValue: 'dark' }
|
|
53
|
+
* ]
|
|
54
|
+
* );
|
|
55
|
+
*
|
|
56
|
+
* if (isLoading) return <LoadingSpinner />;
|
|
57
|
+
* if (error) return <ErrorMessage error={error} />;
|
|
58
|
+
*
|
|
59
|
+
* return (
|
|
60
|
+
* <View>
|
|
61
|
+
* {storageKeys.map(keyInfo => (
|
|
62
|
+
* <StorageKeyCard key={keyInfo.key} keyInfo={keyInfo} />
|
|
63
|
+
* ))}
|
|
64
|
+
* <Button onPress={refresh}>Refresh</Button>
|
|
65
|
+
* </View>
|
|
66
|
+
* );
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export function useMMKVKeys(instance, instanceId, requiredStorageKeys = []) {
|
|
71
|
+
// State management
|
|
72
|
+
const [storageKeys, setStorageKeys] = useState([]);
|
|
73
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
74
|
+
const [error, setError] = useState(null);
|
|
75
|
+
|
|
76
|
+
// Fetch all keys and values from MMKV instance
|
|
77
|
+
const fetchStorageData = useCallback(() => {
|
|
78
|
+
setIsLoading(true);
|
|
79
|
+
setError(null);
|
|
80
|
+
try {
|
|
81
|
+
// Guard: Check if MMKV is available
|
|
82
|
+
if (!isMMKVAvailable()) {
|
|
83
|
+
setStorageKeys([]);
|
|
84
|
+
setIsLoading(false);
|
|
85
|
+
return; // Silently return empty when MMKV not available
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Guard: Check if instance is provided
|
|
89
|
+
if (!instance) {
|
|
90
|
+
setStorageKeys([]);
|
|
91
|
+
setIsLoading(false);
|
|
92
|
+
return; // Silently return empty when no instance
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 1. Get all keys from MMKV (synchronous)
|
|
96
|
+
const allKeys = instance.getAllKeys();
|
|
97
|
+
if (!allKeys || allKeys.length === 0) {
|
|
98
|
+
// Still need to check for missing required keys
|
|
99
|
+
const missingRequiredKeys = requiredStorageKeys.map(req => {
|
|
100
|
+
const key = typeof req === 'string' ? req : req.key;
|
|
101
|
+
const description = typeof req === 'object' && 'description' in req ? req.description : undefined;
|
|
102
|
+
const expectedValue = typeof req === 'object' && 'expectedValue' in req ? req.expectedValue : undefined;
|
|
103
|
+
const expectedType = typeof req === 'object' && 'expectedType' in req ? req.expectedType : undefined;
|
|
104
|
+
return {
|
|
105
|
+
key,
|
|
106
|
+
value: undefined,
|
|
107
|
+
valueType: undefined,
|
|
108
|
+
storageType: 'mmkv',
|
|
109
|
+
instanceId,
|
|
110
|
+
status: 'required_missing',
|
|
111
|
+
category: 'required',
|
|
112
|
+
description,
|
|
113
|
+
expectedValue,
|
|
114
|
+
expectedType
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
setStorageKeys(missingRequiredKeys);
|
|
118
|
+
setIsLoading(false);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 2. Process each key to get value and type
|
|
123
|
+
const allStorageKeys = [];
|
|
124
|
+
allKeys.forEach(key => {
|
|
125
|
+
// Detect value and type using type detection utility
|
|
126
|
+
const {
|
|
127
|
+
value,
|
|
128
|
+
type
|
|
129
|
+
} = detectMMKVType(instance, key);
|
|
130
|
+
|
|
131
|
+
// Check if this is a required key
|
|
132
|
+
const requiredConfig = requiredStorageKeys.find(req => {
|
|
133
|
+
if (typeof req === 'string') return req === key;
|
|
134
|
+
return req.key === key;
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Determine status based on validation rules
|
|
138
|
+
let status = 'optional_present';
|
|
139
|
+
if (requiredConfig) {
|
|
140
|
+
if (value === undefined) {
|
|
141
|
+
status = 'required_missing';
|
|
142
|
+
} else if (typeof requiredConfig === 'object' && 'expectedValue' in requiredConfig) {
|
|
143
|
+
// Value validation
|
|
144
|
+
status = String(value) === String(requiredConfig.expectedValue) ? 'required_present' : 'required_wrong_value';
|
|
145
|
+
} else if (typeof requiredConfig === 'object' && 'expectedType' in requiredConfig) {
|
|
146
|
+
// Type validation
|
|
147
|
+
status = isTypeMatch(type, requiredConfig.expectedType) ? 'required_present' : 'required_wrong_type';
|
|
148
|
+
} else {
|
|
149
|
+
// Key exists and is required (no specific validation)
|
|
150
|
+
status = 'required_present';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Build StorageKeyInfo object
|
|
155
|
+
const keyInfo = {
|
|
156
|
+
key,
|
|
157
|
+
value,
|
|
158
|
+
valueType: type !== 'unknown' ? type : undefined,
|
|
159
|
+
storageType: 'mmkv',
|
|
160
|
+
instanceId,
|
|
161
|
+
status,
|
|
162
|
+
category: requiredConfig ? 'required' : 'optional',
|
|
163
|
+
lastUpdated: new Date(),
|
|
164
|
+
...(typeof requiredConfig === 'object' && 'expectedValue' in requiredConfig && {
|
|
165
|
+
expectedValue: requiredConfig.expectedValue
|
|
166
|
+
}),
|
|
167
|
+
...(typeof requiredConfig === 'object' && 'expectedType' in requiredConfig && {
|
|
168
|
+
expectedType: requiredConfig.expectedType
|
|
169
|
+
}),
|
|
170
|
+
...(typeof requiredConfig === 'object' && 'description' in requiredConfig && {
|
|
171
|
+
description: requiredConfig.description
|
|
172
|
+
})
|
|
173
|
+
};
|
|
174
|
+
allStorageKeys.push(keyInfo);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// 3. Add missing required keys that weren't found in storage
|
|
178
|
+
requiredStorageKeys.forEach(req => {
|
|
179
|
+
const key = typeof req === 'string' ? req : req.key;
|
|
180
|
+
const exists = allStorageKeys.some(k => k.key === key);
|
|
181
|
+
if (!exists) {
|
|
182
|
+
allStorageKeys.push({
|
|
183
|
+
key,
|
|
184
|
+
value: undefined,
|
|
185
|
+
valueType: undefined,
|
|
186
|
+
storageType: 'mmkv',
|
|
187
|
+
instanceId,
|
|
188
|
+
status: 'required_missing',
|
|
189
|
+
category: 'required',
|
|
190
|
+
...(typeof req === 'object' && 'expectedValue' in req && {
|
|
191
|
+
expectedValue: req.expectedValue
|
|
192
|
+
}),
|
|
193
|
+
...(typeof req === 'object' && 'expectedType' in req && {
|
|
194
|
+
expectedType: req.expectedType
|
|
195
|
+
}),
|
|
196
|
+
...(typeof req === 'object' && 'description' in req && {
|
|
197
|
+
description: req.description
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
setStorageKeys(allStorageKeys);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
setError(err instanceof Error ? err : new Error('Failed to fetch MMKV storage data'));
|
|
205
|
+
setStorageKeys([]);
|
|
206
|
+
} finally {
|
|
207
|
+
setIsLoading(false);
|
|
208
|
+
}
|
|
209
|
+
}, [instance, instanceId, requiredStorageKeys]);
|
|
210
|
+
|
|
211
|
+
// Initial fetch
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
fetchStorageData();
|
|
214
|
+
}, [fetchStorageData]);
|
|
215
|
+
return {
|
|
216
|
+
storageKeys,
|
|
217
|
+
isLoading,
|
|
218
|
+
error,
|
|
219
|
+
refresh: fetchStorageData
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Hook to fetch keys from multiple MMKV instances
|
|
225
|
+
*
|
|
226
|
+
* @param instances - Array of MMKV instances with their IDs
|
|
227
|
+
* @param requiredStorageKeys - Optional array of required keys for validation
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* import { MMKV } from 'react-native-mmkv';
|
|
232
|
+
* import { useMultiMMKVKeys } from '@buoy-gg/storage';
|
|
233
|
+
*
|
|
234
|
+
* const defaultStorage = new MMKV();
|
|
235
|
+
* const secureStorage = new MMKV({ id: 'secure', encryptionKey: key });
|
|
236
|
+
*
|
|
237
|
+
* function MyComponent() {
|
|
238
|
+
* const { storageKeys, isLoading, error } = useMultiMMKVKeys(
|
|
239
|
+
* [
|
|
240
|
+
* { instance: defaultStorage, id: 'mmkv.default' },
|
|
241
|
+
* { instance: secureStorage, id: 'secure' }
|
|
242
|
+
* ],
|
|
243
|
+
* ['user.token', 'app.theme']
|
|
244
|
+
* );
|
|
245
|
+
*
|
|
246
|
+
* // storageKeys will contain keys from both instances
|
|
247
|
+
* // with instanceId field to identify which instance each key belongs to
|
|
248
|
+
* }
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
export function useMultiMMKVKeys(instances, requiredStorageKeys = []) {
|
|
252
|
+
const [storageKeys, setStorageKeys] = useState([]);
|
|
253
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
254
|
+
const [error, setError] = useState(null);
|
|
255
|
+
const fetchStorageData = useCallback(() => {
|
|
256
|
+
setIsLoading(true);
|
|
257
|
+
setError(null);
|
|
258
|
+
try {
|
|
259
|
+
const allStorageKeys = [];
|
|
260
|
+
|
|
261
|
+
// Fetch keys from each instance
|
|
262
|
+
instances.forEach(({
|
|
263
|
+
instance,
|
|
264
|
+
id
|
|
265
|
+
}) => {
|
|
266
|
+
const allKeys = instance.getAllKeys();
|
|
267
|
+
if (!allKeys || allKeys.length === 0) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
allKeys.forEach(key => {
|
|
271
|
+
const {
|
|
272
|
+
value,
|
|
273
|
+
type
|
|
274
|
+
} = detectMMKVType(instance, key);
|
|
275
|
+
const requiredConfig = requiredStorageKeys.find(req => {
|
|
276
|
+
if (typeof req === 'string') return req === key;
|
|
277
|
+
return req.key === key;
|
|
278
|
+
});
|
|
279
|
+
let status = 'optional_present';
|
|
280
|
+
if (requiredConfig) {
|
|
281
|
+
if (value === undefined) {
|
|
282
|
+
status = 'required_missing';
|
|
283
|
+
} else if (typeof requiredConfig === 'object' && 'expectedValue' in requiredConfig) {
|
|
284
|
+
status = String(value) === String(requiredConfig.expectedValue) ? 'required_present' : 'required_wrong_value';
|
|
285
|
+
} else if (typeof requiredConfig === 'object' && 'expectedType' in requiredConfig) {
|
|
286
|
+
status = isTypeMatch(type, requiredConfig.expectedType) ? 'required_present' : 'required_wrong_type';
|
|
287
|
+
} else {
|
|
288
|
+
status = 'required_present';
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const keyInfo = {
|
|
292
|
+
key,
|
|
293
|
+
value,
|
|
294
|
+
valueType: type !== 'unknown' ? type : undefined,
|
|
295
|
+
storageType: 'mmkv',
|
|
296
|
+
instanceId: id,
|
|
297
|
+
status,
|
|
298
|
+
category: requiredConfig ? 'required' : 'optional',
|
|
299
|
+
lastUpdated: new Date(),
|
|
300
|
+
...(typeof requiredConfig === 'object' && 'expectedValue' in requiredConfig && {
|
|
301
|
+
expectedValue: requiredConfig.expectedValue
|
|
302
|
+
}),
|
|
303
|
+
...(typeof requiredConfig === 'object' && 'expectedType' in requiredConfig && {
|
|
304
|
+
expectedType: requiredConfig.expectedType
|
|
305
|
+
}),
|
|
306
|
+
...(typeof requiredConfig === 'object' && 'description' in requiredConfig && {
|
|
307
|
+
description: requiredConfig.description
|
|
308
|
+
})
|
|
309
|
+
};
|
|
310
|
+
allStorageKeys.push(keyInfo);
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Add missing required keys
|
|
315
|
+
requiredStorageKeys.forEach(req => {
|
|
316
|
+
const key = typeof req === 'string' ? req : req.key;
|
|
317
|
+
const exists = allStorageKeys.some(k => k.key === key);
|
|
318
|
+
if (!exists) {
|
|
319
|
+
// Add missing key for first instance (or all instances?)
|
|
320
|
+
// For now, add to first instance
|
|
321
|
+
const firstInstanceId = instances[0]?.id || 'mmkv.default';
|
|
322
|
+
allStorageKeys.push({
|
|
323
|
+
key,
|
|
324
|
+
value: undefined,
|
|
325
|
+
valueType: undefined,
|
|
326
|
+
storageType: 'mmkv',
|
|
327
|
+
instanceId: firstInstanceId,
|
|
328
|
+
status: 'required_missing',
|
|
329
|
+
category: 'required',
|
|
330
|
+
...(typeof req === 'object' && 'expectedValue' in req && {
|
|
331
|
+
expectedValue: req.expectedValue
|
|
332
|
+
}),
|
|
333
|
+
...(typeof req === 'object' && 'expectedType' in req && {
|
|
334
|
+
expectedType: req.expectedType
|
|
335
|
+
}),
|
|
336
|
+
...(typeof req === 'object' && 'description' in req && {
|
|
337
|
+
description: req.description
|
|
338
|
+
})
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
setStorageKeys(allStorageKeys);
|
|
343
|
+
} catch (err) {
|
|
344
|
+
setError(err instanceof Error ? err : new Error('Failed to fetch multi-MMKV storage data'));
|
|
345
|
+
setStorageKeys([]);
|
|
346
|
+
} finally {
|
|
347
|
+
setIsLoading(false);
|
|
348
|
+
}
|
|
349
|
+
}, [instances, requiredStorageKeys]);
|
|
350
|
+
useEffect(() => {
|
|
351
|
+
fetchStorageData();
|
|
352
|
+
}, [fetchStorageData]);
|
|
353
|
+
return {
|
|
354
|
+
storageKeys,
|
|
355
|
+
isLoading,
|
|
356
|
+
error,
|
|
357
|
+
refresh: fetchStorageData
|
|
358
|
+
};
|
|
359
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook that forces a re-render every second
|
|
7
|
+
* Used to update relative timestamps (e.g., "2s ago", "1m ago")
|
|
8
|
+
*/
|
|
9
|
+
export function useTickEverySecond(enabled = true) {
|
|
10
|
+
const [, setTick] = useState(0);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!enabled) return;
|
|
13
|
+
const interval = setInterval(() => {
|
|
14
|
+
setTick(prev => prev + 1);
|
|
15
|
+
}, 1000);
|
|
16
|
+
return () => clearInterval(interval);
|
|
17
|
+
}, [enabled]);
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Storage section components
|
|
4
|
+
export { StorageSection } from "./components/StorageSection";
|
|
5
|
+
export { StorageModalWithTabs } from "./components/StorageModalWithTabs";
|
|
6
|
+
export { StorageKeyCard } from "./components/StorageKeyCard";
|
|
7
|
+
export { StorageKeyStatsSection } from "./components/StorageKeyStats";
|
|
8
|
+
export { StorageKeySection } from "./components/StorageKeySection";
|
|
9
|
+
export { StorageBrowserMode } from "./components/StorageBrowserMode";
|
|
10
|
+
export { StorageEventsSection } from "./components/StorageEventsSection";
|
|
11
|
+
|
|
12
|
+
// Storage hooks
|
|
13
|
+
export { useAsyncStorageKeys } from "./hooks/useAsyncStorageKeys";
|
|
14
|
+
export { useMMKVKeys, useMultiMMKVKeys } from "./hooks/useMMKVKeys";
|
|
15
|
+
export { useMMKVInstances, useMMKVInstance, useMMKVInstanceExists } from "./hooks/useMMKVInstances";
|
|
16
|
+
|
|
17
|
+
// MMKV Components
|
|
18
|
+
export { MMKVInstanceSelector } from "./components/MMKVInstanceSelector";
|
|
19
|
+
export { MMKVInstanceInfoPanel } from "./components/MMKVInstanceInfoPanel";
|
|
20
|
+
|
|
21
|
+
// Storage types
|
|
22
|
+
export * from "./types";
|
|
23
|
+
|
|
24
|
+
// Storage utilities
|
|
25
|
+
export * from "./utils";
|