@buoy-gg/storage 7.0.41 → 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.
Files changed (180) hide show
  1. package/README.md +11 -90
  2. package/lib/commonjs/index.js +1 -353
  3. package/lib/commonjs/preset.js +1 -85
  4. package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +1 -36
  5. package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -12
  6. package/lib/commonjs/storage/components/DiffViewer/themes/diffThemes.js +1 -24
  7. package/lib/commonjs/storage/components/GameUIStorageBrowser.js +3 -1259
  8. package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -257
  9. package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -419
  10. package/lib/commonjs/storage/components/SelectionActionBar.js +1 -207
  11. package/lib/commonjs/storage/components/StorageActionButtons.js +1 -242
  12. package/lib/commonjs/storage/components/StorageBrowserMode.js +1 -61
  13. package/lib/commonjs/storage/components/StorageEventActionButton.js +1 -121
  14. package/lib/commonjs/storage/components/StorageEventCard.js +1 -118
  15. package/lib/commonjs/storage/components/StorageEventDetailContent.js +1 -494
  16. package/lib/commonjs/storage/components/StorageEventFilterView.js +1 -160
  17. package/lib/commonjs/storage/components/StorageEventsSection.js +1 -24
  18. package/lib/commonjs/storage/components/StorageFilterCards.js +1 -231
  19. package/lib/commonjs/storage/components/StorageKeyCard.js +1 -520
  20. package/lib/commonjs/storage/components/StorageKeyDetailScreen.js +1 -579
  21. package/lib/commonjs/storage/components/StorageKeyRow.js +1 -559
  22. package/lib/commonjs/storage/components/StorageKeySection.js +1 -160
  23. package/lib/commonjs/storage/components/StorageKeyStats.js +1 -345
  24. package/lib/commonjs/storage/components/StorageModalWithTabs.js +1 -954
  25. package/lib/commonjs/storage/components/StorageSaveNotice.js +1 -171
  26. package/lib/commonjs/storage/components/StorageSection.js +1 -43
  27. package/lib/commonjs/storage/components/StorageTypeFilterBar.js +1 -144
  28. package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +1 -141
  29. package/lib/commonjs/storage/hooks/useMMKVInstances.js +1 -210
  30. package/lib/commonjs/storage/hooks/useMMKVKeys.js +1 -376
  31. package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +1 -202
  32. package/lib/commonjs/storage/hooks/useStorageEvents.js +1 -61
  33. package/lib/commonjs/storage/stores/storageEventStore.js +1 -312
  34. package/lib/commonjs/storage/sync/storageSyncAdapter.js +1 -492
  35. package/lib/commonjs/storage/types.js +1 -5
  36. package/lib/commonjs/storage/utils/AsyncStorageListener.js +1 -691
  37. package/lib/commonjs/storage/utils/AsyncStorageListener.web.js +1 -89
  38. package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +1 -203
  39. package/lib/commonjs/storage/utils/MMKVListener.js +1 -416
  40. package/lib/commonjs/storage/utils/SecureStoreRegistry.js +1 -200
  41. package/lib/commonjs/storage/utils/asyncStorageCompat.js +1 -89
  42. package/lib/commonjs/storage/utils/browserStorageLifecycle.js +1 -10
  43. package/lib/commonjs/storage/utils/browserStorageLifecycle.web.js +1 -70
  44. package/lib/commonjs/storage/utils/clearAllStorage.js +1 -48
  45. package/lib/commonjs/storage/utils/deleteStorageKeys.js +1 -82
  46. package/lib/commonjs/storage/utils/lineDiff.js +1 -30
  47. package/lib/commonjs/storage/utils/mmkvAvailability.js +1 -62
  48. package/lib/commonjs/storage/utils/mmkvAvailability.web.js +1 -21
  49. package/lib/commonjs/storage/utils/mmkvTypeDetection.js +1 -154
  50. package/lib/commonjs/storage/utils/requiredStorageKeyScope.js +1 -17
  51. package/lib/commonjs/storage/utils/setStorageValue.js +1 -218
  52. package/lib/commonjs/storage/utils/snapshotProvider.js +1 -382
  53. package/lib/commonjs/storage/utils/storageActionHelpers.js +1 -46
  54. package/lib/commonjs/storage/utils/storageBrowserRefresh.js +1 -49
  55. package/lib/commonjs/storage/utils/storageLabels.js +1 -13
  56. package/lib/commonjs/storage/utils/storageLabels.web.js +1 -13
  57. package/lib/commonjs/storage/utils/storageOps.js +1 -53
  58. package/lib/commonjs/storage/utils/storageQueryUtils.js +1 -35
  59. package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +1 -288
  60. package/lib/commonjs/storage/utils/valueType.js +1 -83
  61. package/lib/module/index.js +1 -114
  62. package/lib/module/preset.js +1 -82
  63. package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +1 -32
  64. package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -9
  65. package/lib/module/storage/components/DiffViewer/themes/diffThemes.js +1 -10
  66. package/lib/module/storage/components/GameUIStorageBrowser.js +3 -1257
  67. package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -253
  68. package/lib/module/storage/components/MMKVInstanceSelector.js +1 -415
  69. package/lib/module/storage/components/SelectionActionBar.js +1 -204
  70. package/lib/module/storage/components/StorageActionButtons.js +1 -238
  71. package/lib/module/storage/components/StorageBrowserMode.js +1 -57
  72. package/lib/module/storage/components/StorageEventActionButton.js +1 -118
  73. package/lib/module/storage/components/StorageEventCard.js +1 -113
  74. package/lib/module/storage/components/StorageEventDetailContent.js +1 -490
  75. package/lib/module/storage/components/StorageEventFilterView.js +1 -156
  76. package/lib/module/storage/components/StorageEventsSection.js +1 -20
  77. package/lib/module/storage/components/StorageFilterCards.js +1 -227
  78. package/lib/module/storage/components/StorageKeyCard.js +1 -517
  79. package/lib/module/storage/components/StorageKeyDetailScreen.js +1 -577
  80. package/lib/module/storage/components/StorageKeyRow.js +1 -554
  81. package/lib/module/storage/components/StorageKeySection.js +1 -155
  82. package/lib/module/storage/components/StorageKeyStats.js +1 -342
  83. package/lib/module/storage/components/StorageModalWithTabs.js +1 -949
  84. package/lib/module/storage/components/StorageSaveNotice.js +1 -168
  85. package/lib/module/storage/components/StorageSection.js +1 -40
  86. package/lib/module/storage/components/StorageTypeFilterBar.js +1 -139
  87. package/lib/module/storage/hooks/useAsyncStorageKeys.js +1 -136
  88. package/lib/module/storage/hooks/useMMKVInstances.js +1 -204
  89. package/lib/module/storage/hooks/useMMKVKeys.js +1 -371
  90. package/lib/module/storage/hooks/useSecureStoreKeys.js +1 -199
  91. package/lib/module/storage/hooks/useStorageEvents.js +1 -58
  92. package/lib/module/storage/stores/storageEventStore.js +1 -301
  93. package/lib/module/storage/sync/storageSyncAdapter.js +1 -486
  94. package/lib/module/storage/types.js +1 -3
  95. package/lib/module/storage/utils/AsyncStorageListener.js +1 -679
  96. package/lib/module/storage/utils/AsyncStorageListener.web.js +1 -76
  97. package/lib/module/storage/utils/MMKVInstanceRegistry.js +1 -197
  98. package/lib/module/storage/utils/MMKVListener.js +1 -403
  99. package/lib/module/storage/utils/SecureStoreRegistry.js +1 -194
  100. package/lib/module/storage/utils/asyncStorageCompat.js +1 -81
  101. package/lib/module/storage/utils/browserStorageLifecycle.js +1 -6
  102. package/lib/module/storage/utils/browserStorageLifecycle.web.js +1 -66
  103. package/lib/module/storage/utils/clearAllStorage.js +1 -43
  104. package/lib/module/storage/utils/deleteStorageKeys.js +1 -78
  105. package/lib/module/storage/utils/lineDiff.js +1 -12
  106. package/lib/module/storage/utils/mmkvAvailability.js +1 -56
  107. package/lib/module/storage/utils/mmkvAvailability.web.js +1 -15
  108. package/lib/module/storage/utils/mmkvTypeDetection.js +1 -148
  109. package/lib/module/storage/utils/requiredStorageKeyScope.js +1 -13
  110. package/lib/module/storage/utils/setStorageValue.js +1 -209
  111. package/lib/module/storage/utils/snapshotProvider.js +1 -380
  112. package/lib/module/storage/utils/storageActionHelpers.js +1 -42
  113. package/lib/module/storage/utils/storageBrowserRefresh.js +1 -44
  114. package/lib/module/storage/utils/storageLabels.js +1 -9
  115. package/lib/module/storage/utils/storageLabels.web.js +1 -9
  116. package/lib/module/storage/utils/storageOps.js +1 -46
  117. package/lib/module/storage/utils/storageQueryUtils.js +1 -30
  118. package/lib/module/storage/utils/storageTimeTravelUtils.js +1 -281
  119. package/lib/module/storage/utils/valueType.js +1 -76
  120. package/lib/web/index.mjs +2 -3
  121. package/package.json +5 -5
  122. package/lib/typescript/index.d.ts.map +0 -1
  123. package/lib/typescript/preset.d.ts.map +0 -1
  124. package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +0 -1
  125. package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +0 -1
  126. package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +0 -1
  127. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +0 -1
  128. package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts.map +0 -1
  129. package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts.map +0 -1
  130. package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +0 -1
  131. package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +0 -1
  132. package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +0 -1
  133. package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +0 -1
  134. package/lib/typescript/storage/components/StorageEventCard.d.ts.map +0 -1
  135. package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +0 -1
  136. package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +0 -1
  137. package/lib/typescript/storage/components/StorageEventsSection.d.ts.map +0 -1
  138. package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +0 -1
  139. package/lib/typescript/storage/components/StorageKeyCard.d.ts.map +0 -1
  140. package/lib/typescript/storage/components/StorageKeyDetailScreen.d.ts.map +0 -1
  141. package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +0 -1
  142. package/lib/typescript/storage/components/StorageKeySection.d.ts.map +0 -1
  143. package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +0 -1
  144. package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +0 -1
  145. package/lib/typescript/storage/components/StorageSaveNotice.d.ts.map +0 -1
  146. package/lib/typescript/storage/components/StorageSection.d.ts.map +0 -1
  147. package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +0 -1
  148. package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +0 -1
  149. package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +0 -1
  150. package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +0 -1
  151. package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +0 -1
  152. package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +0 -1
  153. package/lib/typescript/storage/stores/storageEventStore.d.ts.map +0 -1
  154. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +0 -1
  155. package/lib/typescript/storage/types.d.ts.map +0 -1
  156. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +0 -1
  157. package/lib/typescript/storage/utils/AsyncStorageListener.web.d.ts.map +0 -1
  158. package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +0 -1
  159. package/lib/typescript/storage/utils/MMKVListener.d.ts.map +0 -1
  160. package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +0 -1
  161. package/lib/typescript/storage/utils/asyncStorageCompat.d.ts.map +0 -1
  162. package/lib/typescript/storage/utils/browserStorageLifecycle.d.ts.map +0 -1
  163. package/lib/typescript/storage/utils/browserStorageLifecycle.web.d.ts.map +0 -1
  164. package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +0 -1
  165. package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +0 -1
  166. package/lib/typescript/storage/utils/lineDiff.d.ts.map +0 -1
  167. package/lib/typescript/storage/utils/mmkvAvailability.d.ts.map +0 -1
  168. package/lib/typescript/storage/utils/mmkvAvailability.web.d.ts.map +0 -1
  169. package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +0 -1
  170. package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts.map +0 -1
  171. package/lib/typescript/storage/utils/setStorageValue.d.ts.map +0 -1
  172. package/lib/typescript/storage/utils/snapshotProvider.d.ts.map +0 -1
  173. package/lib/typescript/storage/utils/storageActionHelpers.d.ts.map +0 -1
  174. package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +0 -1
  175. package/lib/typescript/storage/utils/storageLabels.d.ts.map +0 -1
  176. package/lib/typescript/storage/utils/storageLabels.web.d.ts.map +0 -1
  177. package/lib/typescript/storage/utils/storageOps.d.ts.map +0 -1
  178. package/lib/typescript/storage/utils/storageQueryUtils.d.ts.map +0 -1
  179. package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +0 -1
  180. package/lib/typescript/storage/utils/valueType.d.ts.map +0 -1
@@ -1,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,139 +1 @@
1
- "use strict";
2
-
3
- import { storageLabels } from '../utils/storageLabels';
4
- /**
5
- * "Which backend?" — the pill row shared by the Keys and Events tabs.
6
- *
7
- * Both tabs answer questions about the same three backends, so asking the
8
- * question two different ways (or, as it was, only on one tab) is a gap rather
9
- * than a simplification: you filter the key list to Keychain, switch to Events
10
- * to see what wrote to it, and you're looking at everything again.
11
- *
12
- * The selection is owned by the modal and passed to both, so switching tabs
13
- * keeps the filter you set.
14
- *
15
- * Each pill carries the count it WOULD show, computed before the type filter is
16
- * applied — a count that collapsed to zero the moment you picked another type
17
- * would tell you nothing about where to look next.
18
- */
19
-
20
- import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
21
- import { macOSColors, night, monoFont } from "@buoy-gg/shared-ui";
22
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
- /**
24
- * One entry per pill. This was four near-identical blocks of JSX differing only
25
- * in three colours and a label, which is how "All Types" ended up with a
26
- * hover-grey active state while the others used their own hue.
27
- */
28
- const SEGMENTS = [{
29
- id: "all",
30
- label: "All Types",
31
- color: null
32
- }, {
33
- id: "async",
34
- label: storageLabels.async,
35
- color: macOSColors.semantic.warning
36
- }, {
37
- id: "mmkv",
38
- label: storageLabels.mmkv,
39
- color: macOSColors.semantic.info
40
- }, {
41
- id: "secure",
42
- label: "Secure",
43
- color: macOSColors.semantic.success
44
- }];
45
- export function StorageTypeFilterBar({
46
- active,
47
- onChange,
48
- counts
49
- }) {
50
- return /*#__PURE__*/_jsx(View, {
51
- style: styles.row,
52
- children: SEGMENTS.filter(segment => storageLabels.hasSecure || segment.id !== 'secure').map(segment => {
53
- const isActive = active === segment.id;
54
- const accent = segment.color ?? night.color.accent;
55
- return /*#__PURE__*/_jsxs(TouchableOpacity, {
56
- testID: `buoy-storage-type-${segment.id}`,
57
- accessibilityRole: "button",
58
- accessibilityLabel: `Filter by ${segment.label}`,
59
- accessibilityState: {
60
- selected: isActive
61
- },
62
- activeOpacity: 0.8,
63
- onPress: () => onChange(segment.id),
64
- style: [styles.pill, {
65
- borderColor: night.color.border
66
- }, isActive && [styles.pillActive, segment.color ? {
67
- backgroundColor: segment.color + "15",
68
- borderColor: segment.color + "40"
69
- } : {
70
- backgroundColor: night.color.accentSoft,
71
- borderColor: night.color.accentBorderStrong
72
- }]],
73
- children: [/*#__PURE__*/_jsx(Text, {
74
- style: [styles.label, isActive && {
75
- color: accent,
76
- fontWeight: "600"
77
- }],
78
- children: segment.label
79
- }), /*#__PURE__*/_jsx(Text, {
80
- style: [styles.value, {
81
- color: isActive ? accent : night.color.textTertiary
82
- }],
83
- children: counts[segment.id]
84
- })]
85
- }, segment.id);
86
- })
87
- });
88
- }
89
-
90
- /** Tally a list of things that each know which backend they came from. */
91
- export function countByStorageType(items) {
92
- const counts = {
93
- all: items.length,
94
- async: 0,
95
- mmkv: 0,
96
- secure: 0
97
- };
98
- for (const item of items) counts[item.storageType] += 1;
99
- return counts;
100
- }
101
- const styles = StyleSheet.create({
102
- row: {
103
- flexDirection: "row",
104
- gap: 8,
105
- marginTop: 2
106
- },
107
- pill: {
108
- flex: 1,
109
- backgroundColor: night.color.buttonSurface,
110
- borderRadius: 8,
111
- borderWidth: 1,
112
- borderColor: night.color.border,
113
- paddingVertical: 6,
114
- paddingHorizontal: 8,
115
- alignItems: "center",
116
- justifyContent: "center",
117
- minHeight: 32
118
- },
119
- pillActive: {
120
- borderWidth: 1,
121
- transform: [{
122
- scale: 1.005
123
- }]
124
- },
125
- label: {
126
- fontSize: 9,
127
- color: night.color.textSecondary,
128
- textTransform: "uppercase",
129
- letterSpacing: 0.4,
130
- fontWeight: "500",
131
- marginBottom: 1
132
- },
133
- value: {
134
- fontSize: 12,
135
- fontWeight: "600",
136
- fontFamily: monoFont,
137
- lineHeight: 14
138
- }
139
- });
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}}