@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,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { HardDrive, CyberpunkSectionButton } from "@buoy-gg/shared-ui";
|
|
4
|
+
import { useAsyncStorageKeys } from "../hooks/useAsyncStorageKeys";
|
|
5
|
+
import { isDevToolsStorageKey } from "@buoy-gg/shared-ui";
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
/**
|
|
8
|
+
* Storage section component for the dev tools console.
|
|
9
|
+
* Shows storage statistics and provides access to storage browser.
|
|
10
|
+
*/
|
|
11
|
+
export function StorageSection({
|
|
12
|
+
onPress
|
|
13
|
+
}) {
|
|
14
|
+
const {
|
|
15
|
+
storageKeys
|
|
16
|
+
} = useAsyncStorageKeys();
|
|
17
|
+
|
|
18
|
+
// Filter out dev tool keys for the count
|
|
19
|
+
const appKeys = storageKeys.filter(k => !isDevToolsStorageKey(k.key));
|
|
20
|
+
const asyncCount = appKeys.length;
|
|
21
|
+
const total = asyncCount;
|
|
22
|
+
const getStorageSubtitle = () => {
|
|
23
|
+
if (total === 0) {
|
|
24
|
+
return "Empty";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// For now, only AsyncStorage is supported
|
|
28
|
+
return `${asyncCount} Async`;
|
|
29
|
+
};
|
|
30
|
+
return /*#__PURE__*/_jsx(CyberpunkSectionButton, {
|
|
31
|
+
id: "storage",
|
|
32
|
+
title: "STORAGE",
|
|
33
|
+
subtitle: getStorageSubtitle(),
|
|
34
|
+
icon: HardDrive,
|
|
35
|
+
iconColor: "#00FF88",
|
|
36
|
+
iconBackgroundColor: "rgba(0, 255, 136, 0.1)",
|
|
37
|
+
onPress: onPress,
|
|
38
|
+
index: 2
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
4
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
5
|
+
export function useAsyncStorageKeys(requiredStorageKeys = []) {
|
|
6
|
+
// State management
|
|
7
|
+
const [storageKeys, setStorageKeys] = useState([]);
|
|
8
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
9
|
+
const [error, setError] = useState(null);
|
|
10
|
+
|
|
11
|
+
// Fetch all keys and values from AsyncStorage
|
|
12
|
+
const fetchStorageData = useCallback(async () => {
|
|
13
|
+
setIsLoading(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
try {
|
|
16
|
+
// 1. Get all keys from AsyncStorage
|
|
17
|
+
const allKeys = await AsyncStorage.getAllKeys();
|
|
18
|
+
if (!allKeys || allKeys.length === 0) {
|
|
19
|
+
setStorageKeys([]);
|
|
20
|
+
setIsLoading(false);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 2. Get all values using multiGet
|
|
25
|
+
const allKeyValuePairs = await AsyncStorage.multiGet(allKeys);
|
|
26
|
+
|
|
27
|
+
// 3. Process keys into StorageKeyInfo format
|
|
28
|
+
const allStorageKeys = [];
|
|
29
|
+
allKeyValuePairs.forEach(([key, value]) => {
|
|
30
|
+
// Parse value
|
|
31
|
+
let parsedValue = value;
|
|
32
|
+
if (value) {
|
|
33
|
+
try {
|
|
34
|
+
parsedValue = JSON.parse(value);
|
|
35
|
+
} catch {
|
|
36
|
+
parsedValue = value; // Keep as string if not JSON
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Check if this is a required key
|
|
41
|
+
const requiredConfig = requiredStorageKeys.find(req => {
|
|
42
|
+
if (typeof req === 'string') return req === key;
|
|
43
|
+
return req.key === key;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Determine status
|
|
47
|
+
let status = 'optional_present';
|
|
48
|
+
if (requiredConfig) {
|
|
49
|
+
if (parsedValue === undefined || parsedValue === null) {
|
|
50
|
+
status = 'required_missing';
|
|
51
|
+
} else if (typeof requiredConfig === 'object' && 'expectedValue' in requiredConfig) {
|
|
52
|
+
status = parsedValue === requiredConfig.expectedValue ? 'required_present' : 'required_wrong_value';
|
|
53
|
+
} else if (typeof requiredConfig === 'object' && 'expectedType' in requiredConfig) {
|
|
54
|
+
const actualType = parsedValue === null ? 'null' : typeof parsedValue;
|
|
55
|
+
status = actualType.toLowerCase() === requiredConfig.expectedType.toLowerCase() ? 'required_present' : 'required_wrong_type';
|
|
56
|
+
} else {
|
|
57
|
+
status = 'required_present';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const keyInfo = {
|
|
61
|
+
key,
|
|
62
|
+
value: parsedValue,
|
|
63
|
+
storageType: 'async',
|
|
64
|
+
status,
|
|
65
|
+
category: requiredConfig ? 'required' : 'optional',
|
|
66
|
+
...(typeof requiredConfig === 'object' && 'expectedValue' in requiredConfig && {
|
|
67
|
+
expectedValue: requiredConfig.expectedValue
|
|
68
|
+
}),
|
|
69
|
+
...(typeof requiredConfig === 'object' && 'expectedType' in requiredConfig && {
|
|
70
|
+
expectedType: requiredConfig.expectedType
|
|
71
|
+
}),
|
|
72
|
+
...(typeof requiredConfig === 'object' && 'description' in requiredConfig && {
|
|
73
|
+
description: requiredConfig.description
|
|
74
|
+
})
|
|
75
|
+
};
|
|
76
|
+
allStorageKeys.push(keyInfo);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// 4. Add missing required keys
|
|
80
|
+
requiredStorageKeys.forEach(req => {
|
|
81
|
+
const key = typeof req === 'string' ? req : req.key;
|
|
82
|
+
const exists = allStorageKeys.some(k => k.key === key);
|
|
83
|
+
if (!exists) {
|
|
84
|
+
allStorageKeys.push({
|
|
85
|
+
key,
|
|
86
|
+
value: undefined,
|
|
87
|
+
storageType: 'async',
|
|
88
|
+
status: 'required_missing',
|
|
89
|
+
category: 'required',
|
|
90
|
+
...(typeof req === 'object' && 'expectedValue' in req && {
|
|
91
|
+
expectedValue: req.expectedValue
|
|
92
|
+
}),
|
|
93
|
+
...(typeof req === 'object' && 'expectedType' in req && {
|
|
94
|
+
expectedType: req.expectedType
|
|
95
|
+
}),
|
|
96
|
+
...(typeof req === 'object' && 'description' in req && {
|
|
97
|
+
description: req.description
|
|
98
|
+
})
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
setStorageKeys(allStorageKeys);
|
|
103
|
+
} catch (err) {
|
|
104
|
+
setError(err instanceof Error ? err : new Error('Failed to fetch storage data'));
|
|
105
|
+
setStorageKeys([]);
|
|
106
|
+
} finally {
|
|
107
|
+
setIsLoading(false);
|
|
108
|
+
}
|
|
109
|
+
}, [requiredStorageKeys]);
|
|
110
|
+
|
|
111
|
+
// Initial fetch
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
fetchStorageData();
|
|
114
|
+
}, [fetchStorageData]);
|
|
115
|
+
return {
|
|
116
|
+
storageKeys,
|
|
117
|
+
isLoading,
|
|
118
|
+
error,
|
|
119
|
+
refresh: fetchStorageData
|
|
120
|
+
};
|
|
121
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useMMKVInstances Hook
|
|
5
|
+
*
|
|
6
|
+
* React hook to monitor all registered MMKV instances and their metadata.
|
|
7
|
+
* Works with MMKVInstanceRegistry to provide UI components with instance information.
|
|
8
|
+
*
|
|
9
|
+
* This hook enables:
|
|
10
|
+
* - Multi-instance dropdown/selector UI
|
|
11
|
+
* - Instance metadata display (encrypted, readOnly, key count)
|
|
12
|
+
* - Dynamic updates when instances are added/removed
|
|
13
|
+
*
|
|
14
|
+
* @see MMKVInstanceRegistry.ts for instance registration
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { useState, useEffect } from 'react';
|
|
18
|
+
import { isMMKVAvailable } from '../utils/mmkvAvailability';
|
|
19
|
+
|
|
20
|
+
// Conditionally import registry
|
|
21
|
+
let mmkvInstanceRegistry;
|
|
22
|
+
if (isMMKVAvailable()) {
|
|
23
|
+
const registry = require('../utils/MMKVInstanceRegistry');
|
|
24
|
+
mmkvInstanceRegistry = registry.mmkvInstanceRegistry;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Metadata about an MMKV instance with additional runtime information
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Hook to monitor all registered MMKV instances
|
|
33
|
+
*
|
|
34
|
+
* @param autoRefresh - If true, refreshes every 1 second to detect new instances
|
|
35
|
+
*
|
|
36
|
+
* @returns Object containing instances array, count, and refresh function
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { useMMKVInstances } from '@buoy-gg/storage';
|
|
41
|
+
*
|
|
42
|
+
* function MMKVInstanceSelector() {
|
|
43
|
+
* const { instances, instanceCount, refresh } = useMMKVInstances();
|
|
44
|
+
*
|
|
45
|
+
* return (
|
|
46
|
+
* <View>
|
|
47
|
+
* <Text>Found {instanceCount} MMKV instances</Text>
|
|
48
|
+
* {instances.map(inst => (
|
|
49
|
+
* <TouchableOpacity key={inst.id} onPress={() => selectInstance(inst)}>
|
|
50
|
+
* <Text>{inst.id}</Text>
|
|
51
|
+
* <Text>{inst.keyCount} keys</Text>
|
|
52
|
+
* {inst.encrypted && <Text>🔒 Encrypted</Text>}
|
|
53
|
+
* {inst.readOnly && <Text>👁️ Read-only</Text>}
|
|
54
|
+
* </TouchableOpacity>
|
|
55
|
+
* ))}
|
|
56
|
+
* <Button onPress={refresh}>Refresh</Button>
|
|
57
|
+
* </View>
|
|
58
|
+
* );
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export function useMMKVInstances(autoRefresh = false) {
|
|
63
|
+
const [instances, setInstances] = useState([]);
|
|
64
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
65
|
+
|
|
66
|
+
// Fetch all instances and their metadata
|
|
67
|
+
const fetchInstances = () => {
|
|
68
|
+
setIsLoading(true);
|
|
69
|
+
try {
|
|
70
|
+
// Guard: Check if MMKV is available
|
|
71
|
+
if (!isMMKVAvailable() || !mmkvInstanceRegistry) {
|
|
72
|
+
setInstances([]);
|
|
73
|
+
setIsLoading(false);
|
|
74
|
+
return; // Silently return empty when MMKV not available
|
|
75
|
+
}
|
|
76
|
+
const allInstances = mmkvInstanceRegistry.getAll();
|
|
77
|
+
|
|
78
|
+
// Enhance with metadata
|
|
79
|
+
const instancesWithMetadata = allInstances.map(instanceInfo => {
|
|
80
|
+
const {
|
|
81
|
+
instance,
|
|
82
|
+
id,
|
|
83
|
+
encrypted,
|
|
84
|
+
readOnly
|
|
85
|
+
} = instanceInfo;
|
|
86
|
+
|
|
87
|
+
// Get key count
|
|
88
|
+
const keys = instance.getAllKeys();
|
|
89
|
+
const keyCount = keys?.length || 0;
|
|
90
|
+
|
|
91
|
+
// Get size if available (MMKV might not expose this directly)
|
|
92
|
+
// For now, we don't have a direct way to get size
|
|
93
|
+
const size = undefined;
|
|
94
|
+
return {
|
|
95
|
+
id,
|
|
96
|
+
instance,
|
|
97
|
+
encrypted,
|
|
98
|
+
readOnly,
|
|
99
|
+
keyCount,
|
|
100
|
+
size
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
setInstances(instancesWithMetadata);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
setInstances([]);
|
|
106
|
+
} finally {
|
|
107
|
+
setIsLoading(false);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Initial fetch
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
fetchInstances();
|
|
114
|
+
}, []);
|
|
115
|
+
|
|
116
|
+
// Auto-refresh if enabled
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
if (!autoRefresh) return;
|
|
119
|
+
const interval = setInterval(() => {
|
|
120
|
+
fetchInstances();
|
|
121
|
+
}, 1000); // Refresh every second
|
|
122
|
+
|
|
123
|
+
return () => clearInterval(interval);
|
|
124
|
+
}, [autoRefresh]);
|
|
125
|
+
return {
|
|
126
|
+
instances,
|
|
127
|
+
instanceCount: instances.length,
|
|
128
|
+
isLoading,
|
|
129
|
+
refresh: fetchInstances
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Hook to monitor a single MMKV instance by ID
|
|
135
|
+
*
|
|
136
|
+
* @param instanceId - ID of the instance to monitor
|
|
137
|
+
*
|
|
138
|
+
* @returns Instance metadata or null if not found
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* function MMKVInstanceDetail({ instanceId }: { instanceId: string }) {
|
|
143
|
+
* const instance = useMMKVInstance(instanceId);
|
|
144
|
+
*
|
|
145
|
+
* if (!instance) {
|
|
146
|
+
* return <Text>Instance not found</Text>;
|
|
147
|
+
* }
|
|
148
|
+
*
|
|
149
|
+
* return (
|
|
150
|
+
* <View>
|
|
151
|
+
* <Text>ID: {instance.id}</Text>
|
|
152
|
+
* <Text>Keys: {instance.keyCount}</Text>
|
|
153
|
+
* <Text>Encrypted: {instance.encrypted ? 'Yes' : 'No'}</Text>
|
|
154
|
+
* <Text>Read-only: {instance.readOnly ? 'Yes' : 'No'}</Text>
|
|
155
|
+
* </View>
|
|
156
|
+
* );
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export function useMMKVInstance(instanceId) {
|
|
161
|
+
const [instance, setInstance] = useState(null);
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
// Guard: Check if MMKV is available
|
|
164
|
+
if (!isMMKVAvailable() || !mmkvInstanceRegistry) {
|
|
165
|
+
setInstance(null);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const instanceInfo = mmkvInstanceRegistry.get(instanceId);
|
|
169
|
+
if (!instanceInfo) {
|
|
170
|
+
setInstance(null);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const keys = instanceInfo.instance.getAllKeys();
|
|
174
|
+
const keyCount = keys?.length || 0;
|
|
175
|
+
setInstance({
|
|
176
|
+
...instanceInfo,
|
|
177
|
+
keyCount,
|
|
178
|
+
size: undefined
|
|
179
|
+
});
|
|
180
|
+
}, [instanceId]);
|
|
181
|
+
return instance;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Hook to check if a specific instance ID is registered
|
|
186
|
+
*
|
|
187
|
+
* @param instanceId - ID to check
|
|
188
|
+
*
|
|
189
|
+
* @returns True if instance is registered
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* function MMKVStatus({ instanceId }: { instanceId: string }) {
|
|
194
|
+
* const isRegistered = useMMKVInstanceExists(instanceId);
|
|
195
|
+
*
|
|
196
|
+
* return (
|
|
197
|
+
* <View>
|
|
198
|
+
* <Text>{instanceId}</Text>
|
|
199
|
+
* <Text>{isRegistered ? '✅ Registered' : '❌ Not registered'}</Text>
|
|
200
|
+
* </View>
|
|
201
|
+
* );
|
|
202
|
+
* }
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export function useMMKVInstanceExists(instanceId) {
|
|
206
|
+
const [exists, setExists] = useState(false);
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
// Guard: Check if MMKV is available
|
|
209
|
+
if (!isMMKVAvailable() || !mmkvInstanceRegistry) {
|
|
210
|
+
setExists(false);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
setExists(mmkvInstanceRegistry.has(instanceId));
|
|
214
|
+
}, [instanceId]);
|
|
215
|
+
return exists;
|
|
216
|
+
}
|