@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.
Files changed (215) hide show
  1. package/README.md +11 -86
  2. package/lib/commonjs/index.js +1 -346
  3. package/lib/commonjs/preset.js +1 -80
  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 -1258
  8. package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -257
  9. package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -418
  10. package/lib/commonjs/storage/components/SelectionActionBar.js +1 -207
  11. package/lib/commonjs/storage/components/StorageActionButtons.js +1 -241
  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 -117
  15. package/lib/commonjs/storage/components/StorageEventDetailContent.js +1 -494
  16. package/lib/commonjs/storage/components/StorageEventFilterView.js +1 -159
  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 -344
  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 -143
  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 -159
  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 -478
  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 -0
  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 -0
  43. package/lib/commonjs/storage/utils/browserStorageLifecycle.web.js +1 -0
  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 -0
  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 -0
  56. package/lib/commonjs/storage/utils/storageLabels.web.js +1 -0
  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 -112
  62. package/lib/module/preset.js +1 -76
  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 -1256
  67. package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -253
  68. package/lib/module/storage/components/MMKVInstanceSelector.js +1 -414
  69. package/lib/module/storage/components/SelectionActionBar.js +1 -204
  70. package/lib/module/storage/components/StorageActionButtons.js +1 -237
  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 -112
  74. package/lib/module/storage/components/StorageEventDetailContent.js +1 -490
  75. package/lib/module/storage/components/StorageEventFilterView.js +1 -155
  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 -341
  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 -138
  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 -156
  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 -474
  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 -0
  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 -0
  102. package/lib/module/storage/utils/browserStorageLifecycle.web.js +1 -0
  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 -0
  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 -0
  115. package/lib/module/storage/utils/storageLabels.web.js +1 -0
  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/typescript/index.d.ts +1 -0
  121. package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts +0 -8
  122. package/lib/typescript/storage/components/StorageEventCard.d.ts +0 -7
  123. package/lib/typescript/storage/components/StorageKeyRow.d.ts +2 -6
  124. package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts +0 -15
  125. package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts +2 -2
  126. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +7 -13
  127. package/lib/typescript/storage/utils/AsyncStorageListener.web.d.ts +24 -0
  128. package/lib/typescript/storage/utils/browserStorageLifecycle.d.ts +3 -0
  129. package/lib/typescript/storage/utils/browserStorageLifecycle.web.d.ts +2 -0
  130. package/lib/typescript/storage/utils/mmkvAvailability.web.d.ts +4 -0
  131. package/lib/typescript/storage/utils/storageLabels.d.ts +8 -0
  132. package/lib/typescript/storage/utils/storageLabels.web.d.ts +8 -0
  133. package/lib/web/index.mjs +4 -0
  134. package/package.json +40 -14
  135. package/lib/commonjs/storage/components/DiffViewer/DiffOptionsPanel.js +0 -356
  136. package/lib/commonjs/storage/components/DiffViewer/components/DiffSummary.js +0 -122
  137. package/lib/commonjs/storage/components/StorageKeyEditorScreen.js +0 -414
  138. package/lib/commonjs/storage/components/StorageScalarKeyEditor.js +0 -61
  139. package/lib/commonjs/storage/components/StorageValueEditModal.js +0 -24
  140. package/lib/commonjs/storage/hooks/useKeyEditor.js +0 -31
  141. package/lib/commonjs/storage/hooks/useTreeDraft.js +0 -25
  142. package/lib/module/storage/components/DiffViewer/DiffOptionsPanel.js +0 -352
  143. package/lib/module/storage/components/DiffViewer/components/DiffSummary.js +0 -118
  144. package/lib/module/storage/components/StorageKeyEditorScreen.js +0 -410
  145. package/lib/module/storage/components/StorageScalarKeyEditor.js +0 -57
  146. package/lib/module/storage/components/StorageValueEditModal.js +0 -20
  147. package/lib/module/storage/hooks/useKeyEditor.js +0 -27
  148. package/lib/module/storage/hooks/useTreeDraft.js +0 -21
  149. package/lib/typescript/index.d.ts.map +0 -1
  150. package/lib/typescript/preset.d.ts.map +0 -1
  151. package/lib/typescript/storage/components/DiffViewer/DiffOptionsPanel.d.ts +0 -18
  152. package/lib/typescript/storage/components/DiffViewer/DiffOptionsPanel.d.ts.map +0 -1
  153. package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +0 -1
  154. package/lib/typescript/storage/components/DiffViewer/components/DiffSummary.d.ts +0 -12
  155. package/lib/typescript/storage/components/DiffViewer/components/DiffSummary.d.ts.map +0 -1
  156. package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +0 -1
  157. package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +0 -1
  158. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +0 -1
  159. package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts.map +0 -1
  160. package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts.map +0 -1
  161. package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +0 -1
  162. package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +0 -1
  163. package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +0 -1
  164. package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +0 -1
  165. package/lib/typescript/storage/components/StorageEventCard.d.ts.map +0 -1
  166. package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +0 -1
  167. package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +0 -1
  168. package/lib/typescript/storage/components/StorageEventsSection.d.ts.map +0 -1
  169. package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +0 -1
  170. package/lib/typescript/storage/components/StorageKeyCard.d.ts.map +0 -1
  171. package/lib/typescript/storage/components/StorageKeyDetailScreen.d.ts.map +0 -1
  172. package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts +0 -42
  173. package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts.map +0 -1
  174. package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +0 -1
  175. package/lib/typescript/storage/components/StorageKeySection.d.ts.map +0 -1
  176. package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +0 -1
  177. package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +0 -1
  178. package/lib/typescript/storage/components/StorageSaveNotice.d.ts.map +0 -1
  179. package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts +0 -24
  180. package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts.map +0 -1
  181. package/lib/typescript/storage/components/StorageSection.d.ts.map +0 -1
  182. package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +0 -1
  183. package/lib/typescript/storage/components/StorageValueEditModal.d.ts +0 -14
  184. package/lib/typescript/storage/components/StorageValueEditModal.d.ts.map +0 -1
  185. package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +0 -1
  186. package/lib/typescript/storage/hooks/useKeyEditor.d.ts +0 -27
  187. package/lib/typescript/storage/hooks/useKeyEditor.d.ts.map +0 -1
  188. package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +0 -1
  189. package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +0 -1
  190. package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +0 -1
  191. package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +0 -1
  192. package/lib/typescript/storage/hooks/useTreeDraft.d.ts +0 -16
  193. package/lib/typescript/storage/hooks/useTreeDraft.d.ts.map +0 -1
  194. package/lib/typescript/storage/stores/storageEventStore.d.ts.map +0 -1
  195. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +0 -1
  196. package/lib/typescript/storage/types.d.ts.map +0 -1
  197. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +0 -1
  198. package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +0 -1
  199. package/lib/typescript/storage/utils/MMKVListener.d.ts.map +0 -1
  200. package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +0 -1
  201. package/lib/typescript/storage/utils/asyncStorageCompat.d.ts.map +0 -1
  202. package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +0 -1
  203. package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +0 -1
  204. package/lib/typescript/storage/utils/lineDiff.d.ts.map +0 -1
  205. package/lib/typescript/storage/utils/mmkvAvailability.d.ts.map +0 -1
  206. package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +0 -1
  207. package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts.map +0 -1
  208. package/lib/typescript/storage/utils/setStorageValue.d.ts.map +0 -1
  209. package/lib/typescript/storage/utils/snapshotProvider.d.ts.map +0 -1
  210. package/lib/typescript/storage/utils/storageActionHelpers.d.ts.map +0 -1
  211. package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +0 -1
  212. package/lib/typescript/storage/utils/storageOps.d.ts.map +0 -1
  213. package/lib/typescript/storage/utils/storageQueryUtils.d.ts.map +0 -1
  214. package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +0 -1
  215. 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}}