@buoy-gg/storage 7.0.40 → 7.0.42
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 -86
- package/lib/commonjs/index.js +1 -346
- package/lib/commonjs/preset.js +1 -80
- 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 -1258
- package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -257
- package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -418
- package/lib/commonjs/storage/components/SelectionActionBar.js +1 -207
- package/lib/commonjs/storage/components/StorageActionButtons.js +1 -241
- 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 -117
- package/lib/commonjs/storage/components/StorageEventDetailContent.js +1 -494
- package/lib/commonjs/storage/components/StorageEventFilterView.js +1 -159
- 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 -344
- 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 -143
- 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 -159
- 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 -478
- 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 -0
- 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 -0
- package/lib/commonjs/storage/utils/browserStorageLifecycle.web.js +1 -0
- 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 -0
- 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 -0
- package/lib/commonjs/storage/utils/storageLabels.web.js +1 -0
- 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 -112
- package/lib/module/preset.js +1 -76
- 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 -1256
- package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -253
- package/lib/module/storage/components/MMKVInstanceSelector.js +1 -414
- package/lib/module/storage/components/SelectionActionBar.js +1 -204
- package/lib/module/storage/components/StorageActionButtons.js +1 -237
- 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 -112
- package/lib/module/storage/components/StorageEventDetailContent.js +1 -490
- package/lib/module/storage/components/StorageEventFilterView.js +1 -155
- 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 -341
- 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 -138
- 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 -156
- 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 -474
- 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 -0
- 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 -0
- package/lib/module/storage/utils/browserStorageLifecycle.web.js +1 -0
- 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 -0
- 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 -0
- package/lib/module/storage/utils/storageLabels.web.js +1 -0
- 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/typescript/index.d.ts +1 -0
- package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts +0 -8
- package/lib/typescript/storage/components/StorageEventCard.d.ts +0 -7
- package/lib/typescript/storage/components/StorageKeyRow.d.ts +2 -6
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts +0 -15
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts +2 -2
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +7 -13
- package/lib/typescript/storage/utils/AsyncStorageListener.web.d.ts +24 -0
- package/lib/typescript/storage/utils/browserStorageLifecycle.d.ts +3 -0
- package/lib/typescript/storage/utils/browserStorageLifecycle.web.d.ts +2 -0
- package/lib/typescript/storage/utils/mmkvAvailability.web.d.ts +4 -0
- package/lib/typescript/storage/utils/storageLabels.d.ts +8 -0
- package/lib/typescript/storage/utils/storageLabels.web.d.ts +8 -0
- package/lib/web/index.mjs +4 -0
- package/package.json +40 -14
- package/lib/commonjs/storage/components/DiffViewer/DiffOptionsPanel.js +0 -356
- package/lib/commonjs/storage/components/DiffViewer/components/DiffSummary.js +0 -122
- package/lib/commonjs/storage/components/StorageKeyEditorScreen.js +0 -414
- package/lib/commonjs/storage/components/StorageScalarKeyEditor.js +0 -61
- package/lib/commonjs/storage/components/StorageValueEditModal.js +0 -24
- package/lib/commonjs/storage/hooks/useKeyEditor.js +0 -31
- package/lib/commonjs/storage/hooks/useTreeDraft.js +0 -25
- package/lib/module/storage/components/DiffViewer/DiffOptionsPanel.js +0 -352
- package/lib/module/storage/components/DiffViewer/components/DiffSummary.js +0 -118
- package/lib/module/storage/components/StorageKeyEditorScreen.js +0 -410
- package/lib/module/storage/components/StorageScalarKeyEditor.js +0 -57
- package/lib/module/storage/components/StorageValueEditModal.js +0 -20
- package/lib/module/storage/hooks/useKeyEditor.js +0 -27
- package/lib/module/storage/hooks/useTreeDraft.js +0 -21
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/DiffOptionsPanel.d.ts +0 -18
- package/lib/typescript/storage/components/DiffViewer/DiffOptionsPanel.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/components/DiffSummary.d.ts +0 -12
- package/lib/typescript/storage/components/DiffViewer/components/DiffSummary.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/StorageKeyEditorScreen.d.ts +0 -42
- package/lib/typescript/storage/components/StorageKeyEditorScreen.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/StorageScalarKeyEditor.d.ts +0 -24
- package/lib/typescript/storage/components/StorageScalarKeyEditor.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/components/StorageValueEditModal.d.ts +0 -14
- package/lib/typescript/storage/components/StorageValueEditModal.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useKeyEditor.d.ts +0 -27
- package/lib/typescript/storage/hooks/useKeyEditor.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/hooks/useTreeDraft.d.ts +0 -16
- package/lib/typescript/storage/hooks/useTreeDraft.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/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/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/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/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,168 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* What a storage edit actually did, as a toast.
|
|
5
|
-
*
|
|
6
|
-
* ONE SENTENCE, EVERY TIME, NO DETECTION. Saving used to report success and
|
|
7
|
-
* stop, which is misleading for any key an app has already read into memory:
|
|
8
|
-
* the write lands on disk, the screen does not move, and the next time the
|
|
9
|
-
* owner saves it writes its own copy back over the edit.
|
|
10
|
-
*
|
|
11
|
-
* The obvious fix — work out which live store owns the key and offer to make it
|
|
12
|
-
* re-read — was built and then removed on purpose. It required knowing what is
|
|
13
|
-
* linked to what, and every route to that knowledge is a guess: key names
|
|
14
|
-
* collide across backends, only zustand stores register with Buoy at all, and a
|
|
15
|
-
* store can register after the lookup ran. A tool that is right most of the
|
|
16
|
-
* time is the problem here, not the fix. There is also no general mechanism to
|
|
17
|
-
* reach for — the app owns its cache, and only the app can invalidate it.
|
|
18
|
-
*
|
|
19
|
-
* So it promises the one thing true for every key, every backend and every
|
|
20
|
-
* persistence library, in dev and in release — "applies on next launch" — and
|
|
21
|
-
* says it in five words, because a toast is read at a glance or not at all.
|
|
22
|
-
* Making a change live NOW is a different operation and lives in the state
|
|
23
|
-
* tools, where the store you mean is the one you are already looking at.
|
|
24
|
-
*
|
|
25
|
-
* WHY IT FLOATS. It first shipped inline, above the filter cards and INSIDE the
|
|
26
|
-
* scroller — so it scrolled away with the content and you had to go looking for
|
|
27
|
-
* the thing that was meant to catch your eye. It is pinned over the top of the
|
|
28
|
-
* tool now, and takes itself away, because a message about a save you just made
|
|
29
|
-
* has a short useful life and should not need dismissing.
|
|
30
|
-
*/
|
|
31
|
-
import { useEffect, useRef } from "react";
|
|
32
|
-
import { Animated, Easing, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
33
|
-
import { Check, macOSColors } from "@buoy-gg/shared-ui";
|
|
34
|
-
|
|
35
|
-
/** Five words is one glance, so it does not need to linger like a sentence. */
|
|
36
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
37
|
-
const VISIBLE_MS = 2600;
|
|
38
|
-
const FADE_MS = 180;
|
|
39
|
-
export function StorageSaveNotice({
|
|
40
|
-
onDone
|
|
41
|
-
}) {
|
|
42
|
-
const progress = useRef(new Animated.Value(0)).current;
|
|
43
|
-
|
|
44
|
-
// Latest-ref: the host passes an inline arrow, and depending on it directly
|
|
45
|
-
// would restart the animation on every parent render — the toast would never
|
|
46
|
-
// reach its own fade-out.
|
|
47
|
-
const onDoneRef = useRef(onDone);
|
|
48
|
-
onDoneRef.current = onDone;
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
const animation = Animated.sequence([Animated.timing(progress, {
|
|
51
|
-
toValue: 1,
|
|
52
|
-
duration: FADE_MS,
|
|
53
|
-
easing: Easing.out(Easing.quad),
|
|
54
|
-
useNativeDriver: true
|
|
55
|
-
}), Animated.delay(VISIBLE_MS), Animated.timing(progress, {
|
|
56
|
-
toValue: 0,
|
|
57
|
-
duration: FADE_MS,
|
|
58
|
-
easing: Easing.in(Easing.quad),
|
|
59
|
-
useNativeDriver: true
|
|
60
|
-
})]);
|
|
61
|
-
animation.start(({
|
|
62
|
-
finished
|
|
63
|
-
}) => {
|
|
64
|
-
// Only when it ran to the end: a stop() from unmount must not call back
|
|
65
|
-
// into a host that is already tearing this down.
|
|
66
|
-
if (finished) onDoneRef.current();
|
|
67
|
-
});
|
|
68
|
-
return () => animation.stop();
|
|
69
|
-
}, [progress]);
|
|
70
|
-
return /*#__PURE__*/_jsx(Animated.View, {
|
|
71
|
-
pointerEvents: "box-none",
|
|
72
|
-
style: [styles.wrap, {
|
|
73
|
-
opacity: progress,
|
|
74
|
-
transform: [{
|
|
75
|
-
translateY: progress.interpolate({
|
|
76
|
-
inputRange: [0, 1],
|
|
77
|
-
outputRange: [-10, 0]
|
|
78
|
-
})
|
|
79
|
-
}]
|
|
80
|
-
}],
|
|
81
|
-
testID: "buoy-storage-save-notice",
|
|
82
|
-
children: /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
83
|
-
activeOpacity: 0.85,
|
|
84
|
-
onPress: () => onDoneRef.current(),
|
|
85
|
-
style: styles.toast,
|
|
86
|
-
accessibilityRole: "button"
|
|
87
|
-
// The visible text is a fragment; the label is the whole thought, for
|
|
88
|
-
// anyone who gets this read aloud rather than glanced at.
|
|
89
|
-
,
|
|
90
|
-
accessibilityLabel: "Saved. Applies on the app's next launch. Tap to dismiss.",
|
|
91
|
-
testID: "buoy-storage-save-notice-dismiss",
|
|
92
|
-
children: [/*#__PURE__*/_jsx(View, {
|
|
93
|
-
style: styles.tick,
|
|
94
|
-
children: /*#__PURE__*/_jsx(Check, {
|
|
95
|
-
size: 10,
|
|
96
|
-
color: macOSColors.semantic.success
|
|
97
|
-
})
|
|
98
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
99
|
-
style: styles.saved,
|
|
100
|
-
children: "Saved"
|
|
101
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
102
|
-
style: styles.divider
|
|
103
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
104
|
-
style: styles.detail,
|
|
105
|
-
children: "applies on next launch"
|
|
106
|
-
})]
|
|
107
|
-
})
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
const styles = StyleSheet.create({
|
|
111
|
-
wrap: {
|
|
112
|
-
// Pinned over the tool rather than laid out in it, so the scroller cannot
|
|
113
|
-
// carry it away. `box-none` keeps the untouched margins clickable.
|
|
114
|
-
position: "absolute",
|
|
115
|
-
top: 10,
|
|
116
|
-
left: 12,
|
|
117
|
-
right: 12,
|
|
118
|
-
// Above the list, the filter cards and the sticky headers.
|
|
119
|
-
zIndex: 100,
|
|
120
|
-
elevation: 100,
|
|
121
|
-
alignItems: "center"
|
|
122
|
-
},
|
|
123
|
-
toast: {
|
|
124
|
-
// Sized to its content: a five-word toast that spans the tool reads as a
|
|
125
|
-
// banner, which is the thing this stopped being.
|
|
126
|
-
flexDirection: "row",
|
|
127
|
-
alignItems: "center",
|
|
128
|
-
paddingVertical: 7,
|
|
129
|
-
paddingLeft: 8,
|
|
130
|
-
paddingRight: 12,
|
|
131
|
-
borderRadius: 999,
|
|
132
|
-
backgroundColor: macOSColors.background.card,
|
|
133
|
-
borderWidth: StyleSheet.hairlineWidth,
|
|
134
|
-
borderColor: macOSColors.border.default,
|
|
135
|
-
shadowColor: "#000",
|
|
136
|
-
shadowOpacity: 0.4,
|
|
137
|
-
shadowRadius: 14,
|
|
138
|
-
shadowOffset: {
|
|
139
|
-
width: 0,
|
|
140
|
-
height: 5
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
tick: {
|
|
144
|
-
width: 16,
|
|
145
|
-
height: 16,
|
|
146
|
-
borderRadius: 8,
|
|
147
|
-
marginRight: 7,
|
|
148
|
-
alignItems: "center",
|
|
149
|
-
justifyContent: "center",
|
|
150
|
-
backgroundColor: macOSColors.semantic.successBackground
|
|
151
|
-
},
|
|
152
|
-
saved: {
|
|
153
|
-
color: macOSColors.text.primary,
|
|
154
|
-
fontSize: 12,
|
|
155
|
-
fontWeight: "600"
|
|
156
|
-
},
|
|
157
|
-
divider: {
|
|
158
|
-
width: StyleSheet.hairlineWidth,
|
|
159
|
-
alignSelf: "stretch",
|
|
160
|
-
marginHorizontal: 8,
|
|
161
|
-
backgroundColor: macOSColors.border.default
|
|
162
|
-
},
|
|
163
|
-
// The consequence is the part people already half-know, so it recedes.
|
|
164
|
-
detail: {
|
|
165
|
-
color: macOSColors.text.muted,
|
|
166
|
-
fontSize: 12
|
|
167
|
-
}
|
|
168
|
-
});
|
|
1
|
+
"use strict";import{useEffect as m,useRef as l}from"react";import{Animated as t,Easing as a,StyleSheet as n,Text as u,TouchableOpacity as f,View as h}from"react-native";import{Check as b,macOSColors as e}from"@buoy-gg/shared-ui";import{jsx as i,jsxs as y}from"react/jsx-runtime";const v=2600;const g=180;export function StorageSaveNotice({onDone:c}){const o=l(new t.Value(0)).current;const s=l(c);s.current=c;m(()=>{const d=t.sequence([t.timing(o,{toValue:1,duration:g,easing:a.out(a.quad),useNativeDriver:true}),t.delay(v),t.timing(o,{toValue:0,duration:g,easing:a.in(a.quad),useNativeDriver:true})]);d.start(({finished:p})=>{if(p)s.current()});return()=>d.stop()},[o]);return i(t.View,{pointerEvents:"box-none",style:[r.wrap,{opacity:o,transform:[{translateY:o.interpolate({inputRange:[0,1],outputRange:[-10,0]})}]}],testID:"buoy-storage-save-notice",children:y(f,{activeOpacity:.85,onPress:()=>s.current(),style:r.toast,accessibilityRole:"button",accessibilityLabel:"Saved. Applies on the app's next launch. Tap to dismiss.",testID:"buoy-storage-save-notice-dismiss",children:[i(h,{style:r.tick,children:i(b,{size:10,color:e.semantic.success})}),i(u,{style:r.saved,children:"Saved"}),i(h,{style:r.divider}),i(u,{style:r.detail,children:"applies on next launch"})]})})}const r=n.create({wrap:{position:"absolute",top:10,left:12,right:12,zIndex:100,elevation:100,alignItems:"center"},toast:{flexDirection:"row",alignItems:"center",paddingVertical:7,paddingLeft:8,paddingRight:12,borderRadius:999,backgroundColor:e.background.card,borderWidth:n.hairlineWidth,borderColor:e.border.default,shadowColor:"#000",shadowOpacity:.4,shadowRadius:14,shadowOffset:{width:0,height:5}},tick:{width:16,height:16,borderRadius:8,marginRight:7,alignItems:"center",justifyContent:"center",backgroundColor:e.semantic.successBackground},saved:{color:e.text.primary,fontSize:12,fontWeight:"600"},divider:{width:n.hairlineWidth,alignSelf:"stretch",marginHorizontal:8,backgroundColor:e.border.default},detail:{color:e.text.muted,fontSize:12}});
|
|
@@ -1,40 +1 @@
|
|
|
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
|
-
}
|
|
1
|
+
"use strict";import{HardDrive as c,CyberpunkSectionButton as a}from"@buoy-gg/shared-ui";import{useAsyncStorageKeys as u}from"../hooks/useAsyncStorageKeys";import{isDevToolsStorageKey as g}from"@buoy-gg/shared-ui";import{jsx as y}from"react/jsx-runtime";export function StorageSection({onPress:o}){const{storageKeys:r}=u();const e=r.filter(i=>!g(i.key));const t=e.length;const n=t;const s=()=>{if(n===0){return"Empty"}return`${t} Async`};return y(a,{id:"storage",title:"STORAGE",subtitle:s(),icon:c,iconColor:"#00FF88",iconBackgroundColor:"rgba(0, 255, 136, 0.1)",onPress:o,index:2})}
|
|
@@ -1,138 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* "Which backend?" — the pill row shared by the Keys and Events tabs.
|
|
5
|
-
*
|
|
6
|
-
* Both tabs answer questions about the same three backends, so asking the
|
|
7
|
-
* question two different ways (or, as it was, only on one tab) is a gap rather
|
|
8
|
-
* than a simplification: you filter the key list to Keychain, switch to Events
|
|
9
|
-
* to see what wrote to it, and you're looking at everything again.
|
|
10
|
-
*
|
|
11
|
-
* The selection is owned by the modal and passed to both, so switching tabs
|
|
12
|
-
* keeps the filter you set.
|
|
13
|
-
*
|
|
14
|
-
* Each pill carries the count it WOULD show, computed before the type filter is
|
|
15
|
-
* applied — a count that collapsed to zero the moment you picked another type
|
|
16
|
-
* would tell you nothing about where to look next.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
20
|
-
import { macOSColors, night, monoFont } from "@buoy-gg/shared-ui";
|
|
21
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
|
-
/**
|
|
23
|
-
* One entry per pill. This was four near-identical blocks of JSX differing only
|
|
24
|
-
* in three colours and a label, which is how "All Types" ended up with a
|
|
25
|
-
* hover-grey active state while the others used their own hue.
|
|
26
|
-
*/
|
|
27
|
-
const SEGMENTS = [{
|
|
28
|
-
id: "all",
|
|
29
|
-
label: "All Types",
|
|
30
|
-
color: null
|
|
31
|
-
}, {
|
|
32
|
-
id: "async",
|
|
33
|
-
label: "Async",
|
|
34
|
-
color: macOSColors.semantic.warning
|
|
35
|
-
}, {
|
|
36
|
-
id: "mmkv",
|
|
37
|
-
label: "MMKV",
|
|
38
|
-
color: macOSColors.semantic.info
|
|
39
|
-
}, {
|
|
40
|
-
id: "secure",
|
|
41
|
-
label: "Secure",
|
|
42
|
-
color: macOSColors.semantic.success
|
|
43
|
-
}];
|
|
44
|
-
export function StorageTypeFilterBar({
|
|
45
|
-
active,
|
|
46
|
-
onChange,
|
|
47
|
-
counts
|
|
48
|
-
}) {
|
|
49
|
-
return /*#__PURE__*/_jsx(View, {
|
|
50
|
-
style: styles.row,
|
|
51
|
-
children: SEGMENTS.map(segment => {
|
|
52
|
-
const isActive = active === segment.id;
|
|
53
|
-
const accent = segment.color ?? night.color.accent;
|
|
54
|
-
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
55
|
-
testID: `buoy-storage-type-${segment.id}`,
|
|
56
|
-
accessibilityRole: "button",
|
|
57
|
-
accessibilityLabel: `Filter by ${segment.label}`,
|
|
58
|
-
accessibilityState: {
|
|
59
|
-
selected: isActive
|
|
60
|
-
},
|
|
61
|
-
activeOpacity: 0.8,
|
|
62
|
-
onPress: () => onChange(segment.id),
|
|
63
|
-
style: [styles.pill, {
|
|
64
|
-
borderColor: night.color.border
|
|
65
|
-
}, isActive && [styles.pillActive, segment.color ? {
|
|
66
|
-
backgroundColor: segment.color + "15",
|
|
67
|
-
borderColor: segment.color + "40"
|
|
68
|
-
} : {
|
|
69
|
-
backgroundColor: night.color.accentSoft,
|
|
70
|
-
borderColor: night.color.accentBorderStrong
|
|
71
|
-
}]],
|
|
72
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
73
|
-
style: [styles.label, isActive && {
|
|
74
|
-
color: accent,
|
|
75
|
-
fontWeight: "600"
|
|
76
|
-
}],
|
|
77
|
-
children: segment.label
|
|
78
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
79
|
-
style: [styles.value, {
|
|
80
|
-
color: isActive ? accent : night.color.textTertiary
|
|
81
|
-
}],
|
|
82
|
-
children: counts[segment.id]
|
|
83
|
-
})]
|
|
84
|
-
}, segment.id);
|
|
85
|
-
})
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** Tally a list of things that each know which backend they came from. */
|
|
90
|
-
export function countByStorageType(items) {
|
|
91
|
-
const counts = {
|
|
92
|
-
all: items.length,
|
|
93
|
-
async: 0,
|
|
94
|
-
mmkv: 0,
|
|
95
|
-
secure: 0
|
|
96
|
-
};
|
|
97
|
-
for (const item of items) counts[item.storageType] += 1;
|
|
98
|
-
return counts;
|
|
99
|
-
}
|
|
100
|
-
const styles = StyleSheet.create({
|
|
101
|
-
row: {
|
|
102
|
-
flexDirection: "row",
|
|
103
|
-
gap: 8,
|
|
104
|
-
marginTop: 2
|
|
105
|
-
},
|
|
106
|
-
pill: {
|
|
107
|
-
flex: 1,
|
|
108
|
-
backgroundColor: night.color.buttonSurface,
|
|
109
|
-
borderRadius: 8,
|
|
110
|
-
borderWidth: 1,
|
|
111
|
-
borderColor: night.color.border,
|
|
112
|
-
paddingVertical: 6,
|
|
113
|
-
paddingHorizontal: 8,
|
|
114
|
-
alignItems: "center",
|
|
115
|
-
justifyContent: "center",
|
|
116
|
-
minHeight: 32
|
|
117
|
-
},
|
|
118
|
-
pillActive: {
|
|
119
|
-
borderWidth: 1,
|
|
120
|
-
transform: [{
|
|
121
|
-
scale: 1.005
|
|
122
|
-
}]
|
|
123
|
-
},
|
|
124
|
-
label: {
|
|
125
|
-
fontSize: 9,
|
|
126
|
-
color: night.color.textSecondary,
|
|
127
|
-
textTransform: "uppercase",
|
|
128
|
-
letterSpacing: 0.4,
|
|
129
|
-
fontWeight: "500",
|
|
130
|
-
marginBottom: 1
|
|
131
|
-
},
|
|
132
|
-
value: {
|
|
133
|
-
fontSize: 12,
|
|
134
|
-
fontWeight: "600",
|
|
135
|
-
fontFamily: monoFont,
|
|
136
|
-
lineHeight: 14
|
|
137
|
-
}
|
|
138
|
-
});
|
|
1
|
+
"use strict";import{storageLabels as a}from"../utils/storageLabels";import{StyleSheet as u,Text as b,TouchableOpacity as y,View as p}from"react-native";import{macOSColors as n,night as r,monoFont as f}from"@buoy-gg/shared-ui";import{jsx as s,jsxs as m}from"react/jsx-runtime";const S=[{id:"all",label:"All Types",color:null},{id:"async",label:a.async,color:n.semantic.warning},{id:"mmkv",label:a.mmkv,color:n.semantic.info},{id:"secure",label:"Secure",color:n.semantic.success}];export function StorageTypeFilterBar({active:t,onChange:l,counts:i}){return s(p,{style:e.row,children:S.filter(o=>a.hasSecure||o.id!=="secure").map(o=>{const c=t===o.id;const d=o.color??r.color.accent;return m(y,{testID:`buoy-storage-type-${o.id}`,accessibilityRole:"button",accessibilityLabel:`Filter by ${o.label}`,accessibilityState:{selected:c},activeOpacity:.8,onPress:()=>l(o.id),style:[e.pill,{borderColor:r.color.border},c&&[e.pillActive,o.color?{backgroundColor:o.color+"15",borderColor:o.color+"40"}:{backgroundColor:r.color.accentSoft,borderColor:r.color.accentBorderStrong}]],children:[s(b,{style:[e.label,c&&{color:d,fontWeight:"600"}],children:o.label}),s(b,{style:[e.value,{color:c?d:r.color.textTertiary}],children:i[o.id]})]},o.id)})})}export function countByStorageType(t){const l={all:t.length,async:0,mmkv:0,secure:0};for(const i of t)l[i.storageType]+=1;return l}const e=u.create({row:{flexDirection:"row",gap:8,marginTop:2},pill:{flex:1,backgroundColor:r.color.buttonSurface,borderRadius:8,borderWidth:1,borderColor:r.color.border,paddingVertical:6,paddingHorizontal:8,alignItems:"center",justifyContent:"center",minHeight:32},pillActive:{borderWidth:1,transform:[{scale:1.005}]},label:{fontSize:9,color:r.color.textSecondary,textTransform:"uppercase",letterSpacing:.4,fontWeight:"500",marginBottom:1},value:{fontSize:12,fontWeight:"600",fontFamily:f,lineHeight:14}});
|
|
@@ -1,136 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
4
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
5
|
-
import { readMany } from '../utils/asyncStorageCompat';
|
|
6
|
-
import { requiredKeyAppliesTo } from '../utils/requiredStorageKeyScope';
|
|
7
|
-
export function useAsyncStorageKeys(requiredStorageKeys = []) {
|
|
8
|
-
// State management
|
|
9
|
-
const [storageKeys, setStorageKeys] = useState([]);
|
|
10
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
11
|
-
const [error, setError] = useState(null);
|
|
12
|
-
|
|
13
|
-
// Callers routinely pass a fresh array literal (or rely on the `= []`
|
|
14
|
-
// default, which is a new array every render). Depending on its identity
|
|
15
|
-
// would recreate `fetchStorageData` each render, re-fire the effect, and
|
|
16
|
-
// loop AsyncStorage.getAllKeys/multiGet forever. Depend on a stable content
|
|
17
|
-
// signature instead, and read the latest array via a ref inside the fetch.
|
|
18
|
-
const requiredSignature = JSON.stringify(requiredStorageKeys);
|
|
19
|
-
const requiredRef = useRef(requiredStorageKeys);
|
|
20
|
-
requiredRef.current = requiredStorageKeys;
|
|
21
|
-
|
|
22
|
-
// Fetch all keys and values from AsyncStorage
|
|
23
|
-
const fetchStorageData = useCallback(async () => {
|
|
24
|
-
const requiredStorageKeys = requiredRef.current;
|
|
25
|
-
setIsLoading(true);
|
|
26
|
-
setError(null);
|
|
27
|
-
try {
|
|
28
|
-
// 1. Get all keys from AsyncStorage
|
|
29
|
-
const allKeys = await AsyncStorage.getAllKeys();
|
|
30
|
-
if (!allKeys || allKeys.length === 0) {
|
|
31
|
-
setStorageKeys([]);
|
|
32
|
-
setIsLoading(false);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 2. Get all values (compat helper normalizes v2 multiGet / v3 getMany)
|
|
37
|
-
const allKeyValuePairs = await readMany(allKeys);
|
|
38
|
-
|
|
39
|
-
// 3. Process keys into StorageKeyInfo format
|
|
40
|
-
const allStorageKeys = [];
|
|
41
|
-
allKeyValuePairs.forEach(([key, value]) => {
|
|
42
|
-
// Parse value
|
|
43
|
-
let parsedValue = value;
|
|
44
|
-
if (value) {
|
|
45
|
-
try {
|
|
46
|
-
parsedValue = JSON.parse(value);
|
|
47
|
-
} catch {
|
|
48
|
-
parsedValue = value; // Keep as string if not JSON
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Check if this is a required key scoped to AsyncStorage
|
|
53
|
-
const requiredConfig = requiredStorageKeys.find(req => {
|
|
54
|
-
if (!requiredKeyAppliesTo(req, 'async')) return false;
|
|
55
|
-
if (typeof req === 'string') return req === key;
|
|
56
|
-
return req.key === key;
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Determine status
|
|
60
|
-
let status = 'optional_present';
|
|
61
|
-
if (requiredConfig) {
|
|
62
|
-
if (parsedValue === undefined || parsedValue === null) {
|
|
63
|
-
status = 'required_missing';
|
|
64
|
-
} else if (typeof requiredConfig === 'object' && requiredConfig.expectedValue !== undefined) {
|
|
65
|
-
status = parsedValue === requiredConfig.expectedValue ? 'required_present' : 'required_wrong_value';
|
|
66
|
-
} else if (typeof requiredConfig === 'object' && requiredConfig.expectedType !== undefined) {
|
|
67
|
-
const actualType = parsedValue === null ? 'null' : typeof parsedValue;
|
|
68
|
-
status = actualType.toLowerCase() === requiredConfig.expectedType.toLowerCase() ? 'required_present' : 'required_wrong_type';
|
|
69
|
-
} else {
|
|
70
|
-
status = 'required_present';
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
const keyInfo = {
|
|
74
|
-
key,
|
|
75
|
-
value: parsedValue,
|
|
76
|
-
storageType: 'async',
|
|
77
|
-
status,
|
|
78
|
-
category: requiredConfig ? 'required' : 'optional',
|
|
79
|
-
...(typeof requiredConfig === 'object' && requiredConfig.expectedValue !== undefined && {
|
|
80
|
-
expectedValue: requiredConfig.expectedValue
|
|
81
|
-
}),
|
|
82
|
-
...(typeof requiredConfig === 'object' && requiredConfig.expectedType !== undefined && {
|
|
83
|
-
expectedType: requiredConfig.expectedType
|
|
84
|
-
}),
|
|
85
|
-
...(typeof requiredConfig === 'object' && requiredConfig.description !== undefined && {
|
|
86
|
-
description: requiredConfig.description
|
|
87
|
-
})
|
|
88
|
-
};
|
|
89
|
-
allStorageKeys.push(keyInfo);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// 4. Add missing required keys (Async-scoped only)
|
|
93
|
-
requiredStorageKeys.forEach(req => {
|
|
94
|
-
if (!requiredKeyAppliesTo(req, 'async')) return;
|
|
95
|
-
const key = typeof req === 'string' ? req : req.key;
|
|
96
|
-
const exists = allStorageKeys.some(k => k.key === key);
|
|
97
|
-
if (!exists) {
|
|
98
|
-
allStorageKeys.push({
|
|
99
|
-
key,
|
|
100
|
-
value: undefined,
|
|
101
|
-
storageType: 'async',
|
|
102
|
-
status: 'required_missing',
|
|
103
|
-
category: 'required',
|
|
104
|
-
...(typeof req === 'object' && req.expectedValue !== undefined && {
|
|
105
|
-
expectedValue: req.expectedValue
|
|
106
|
-
}),
|
|
107
|
-
...(typeof req === 'object' && req.expectedType !== undefined && {
|
|
108
|
-
expectedType: req.expectedType
|
|
109
|
-
}),
|
|
110
|
-
...(typeof req === 'object' && req.description !== undefined && {
|
|
111
|
-
description: req.description
|
|
112
|
-
})
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
setStorageKeys(allStorageKeys);
|
|
117
|
-
} catch (err) {
|
|
118
|
-
setError(err instanceof Error ? err : new Error('Failed to fetch storage data'));
|
|
119
|
-
setStorageKeys([]);
|
|
120
|
-
} finally {
|
|
121
|
-
setIsLoading(false);
|
|
122
|
-
}
|
|
123
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
|
-
}, [requiredSignature]);
|
|
125
|
-
|
|
126
|
-
// Initial fetch
|
|
127
|
-
useEffect(() => {
|
|
128
|
-
fetchStorageData();
|
|
129
|
-
}, [fetchStorageData]);
|
|
130
|
-
return {
|
|
131
|
-
storageKeys,
|
|
132
|
-
isLoading,
|
|
133
|
-
error,
|
|
134
|
-
refresh: fetchStorageData
|
|
135
|
-
};
|
|
136
|
-
}
|
|
1
|
+
"use strict";import{useState as f,useEffect as j,useCallback as S,useRef as w}from"react";import K from"@react-native-async-storage/async-storage";import{readMany as E}from"../utils/asyncStorageCompat";import{requiredKeyAppliesTo as x}from"../utils/requiredStorageKeyScope";export function useAsyncStorageKeys(a=[]){const[T,p]=f([]);const[m,d]=f(true);const[h,y]=f(null);const V=JSON.stringify(a);const l=w(a);l.current=a;const u=S(async()=>{const g=l.current;d(true);y(null);try{const o=await K.getAllKeys();if(!o||o.length===0){p([]);d(false);return}const _=await E(o);const c=[];_.forEach(([t,n])=>{let r=n;if(n){try{r=JSON.parse(n)}catch{r=n}}const e=g.find(s=>{if(!x(s,"async"))return false;if(typeof s==="string")return s===t;return s.key===t});let i="optional_present";if(e){if(r===void 0||r===null){i="required_missing"}else if(typeof e==="object"&&e.expectedValue!==void 0){i=r===e.expectedValue?"required_present":"required_wrong_value"}else if(typeof e==="object"&&e.expectedType!==void 0){const s=r===null?"null":typeof r;i=s.toLowerCase()===e.expectedType.toLowerCase()?"required_present":"required_wrong_type"}else{i="required_present"}}const b={key:t,value:r,storageType:"async",status:i,category:e?"required":"optional",...typeof e==="object"&&e.expectedValue!==void 0&&{expectedValue:e.expectedValue},...typeof e==="object"&&e.expectedType!==void 0&&{expectedType:e.expectedType},...typeof e==="object"&&e.description!==void 0&&{description:e.description}};c.push(b)});g.forEach(t=>{if(!x(t,"async"))return;const n=typeof t==="string"?t:t.key;const r=c.some(e=>e.key===n);if(!r){c.push({key:n,value:void 0,storageType:"async",status:"required_missing",category:"required",...typeof t==="object"&&t.expectedValue!==void 0&&{expectedValue:t.expectedValue},...typeof t==="object"&&t.expectedType!==void 0&&{expectedType:t.expectedType},...typeof t==="object"&&t.description!==void 0&&{description:t.description}})}});p(c)}catch(o){y(o instanceof Error?o:new Error("Failed to fetch storage data"));p([])}finally{d(false)}},[V]);j(()=>{u()},[u]);return{storageKeys:T,isLoading:m,error:h,refresh:u}}
|