@buoy-gg/storage 3.0.2 → 4.0.1

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 (56) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/storage/components/GameUIStorageBrowser.js +24 -3
  3. package/lib/commonjs/storage/components/SelectionActionBar.js +16 -3
  4. package/lib/commonjs/storage/components/StorageBrowserMode.js +6 -2
  5. package/lib/commonjs/storage/components/StorageKeyRow.js +95 -6
  6. package/lib/commonjs/storage/components/StorageKeySection.js +8 -2
  7. package/lib/commonjs/storage/components/StorageModalWithTabs.js +47 -1
  8. package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +3 -2
  9. package/lib/commonjs/storage/stores/storageEventStore.js +7 -4
  10. package/lib/commonjs/storage/sync/storageSyncAdapter.js +7 -3
  11. package/lib/commonjs/storage/utils/AsyncStorageListener.js +148 -160
  12. package/lib/commonjs/storage/utils/asyncStorageCompat.js +89 -0
  13. package/lib/commonjs/storage/utils/clearAllStorage.js +2 -1
  14. package/lib/commonjs/storage/utils/mmkvTypeDetection.js +20 -5
  15. package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +3 -2
  16. package/lib/commonjs/storage/utils/valueType.js +41 -0
  17. package/lib/module/storage/components/GameUIStorageBrowser.js +24 -3
  18. package/lib/module/storage/components/SelectionActionBar.js +17 -3
  19. package/lib/module/storage/components/StorageBrowserMode.js +6 -2
  20. package/lib/module/storage/components/StorageKeyRow.js +97 -8
  21. package/lib/module/storage/components/StorageKeySection.js +8 -2
  22. package/lib/module/storage/components/StorageModalWithTabs.js +47 -1
  23. package/lib/module/storage/hooks/useAsyncStorageKeys.js +3 -2
  24. package/lib/module/storage/stores/storageEventStore.js +7 -4
  25. package/lib/module/storage/sync/storageSyncAdapter.js +7 -3
  26. package/lib/module/storage/utils/AsyncStorageListener.js +124 -135
  27. package/lib/module/storage/utils/asyncStorageCompat.js +81 -0
  28. package/lib/module/storage/utils/clearAllStorage.js +2 -1
  29. package/lib/module/storage/utils/mmkvTypeDetection.js +20 -5
  30. package/lib/module/storage/utils/storageTimeTravelUtils.js +3 -2
  31. package/lib/module/storage/utils/valueType.js +39 -0
  32. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts +5 -1
  33. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -1
  34. package/lib/typescript/storage/components/SelectionActionBar.d.ts +3 -1
  35. package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +1 -1
  36. package/lib/typescript/storage/components/StorageBrowserMode.d.ts +3 -1
  37. package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +1 -1
  38. package/lib/typescript/storage/components/StorageKeyRow.d.ts +7 -1
  39. package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -1
  40. package/lib/typescript/storage/components/StorageKeySection.d.ts +7 -1
  41. package/lib/typescript/storage/components/StorageKeySection.d.ts.map +1 -1
  42. package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
  43. package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +1 -1
  44. package/lib/typescript/storage/stores/storageEventStore.d.ts.map +1 -1
  45. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +1 -1
  46. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +1 -1
  47. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts +20 -0
  48. package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +1 -1
  49. package/lib/typescript/storage/utils/asyncStorageCompat.d.ts +30 -0
  50. package/lib/typescript/storage/utils/asyncStorageCompat.d.ts.map +1 -0
  51. package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +1 -1
  52. package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +1 -1
  53. package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +1 -1
  54. package/lib/typescript/storage/utils/valueType.d.ts +13 -0
  55. package/lib/typescript/storage/utils/valueType.d.ts.map +1 -1
  56. package/package.json +6 -6
@@ -62,7 +62,9 @@ export function GameUIStorageBrowser({
62
62
  storageDataRef,
63
63
  eventCountByKey,
64
64
  onViewHistory,
65
- enabledStorageTypes
65
+ enabledStorageTypes,
66
+ pinnedKeys,
67
+ onTogglePin
66
68
  }) {
67
69
  const isPro = useIsPro();
68
70
  const [showUpgradeModal, setShowUpgradeModal] = useState(false);
@@ -172,6 +174,15 @@ export function GameUIStorageBrowser({
172
174
  refresh();
173
175
  }, [refresh]);
174
176
 
177
+ // Hide the selected keys by adding each to the ignored-pattern filter store,
178
+ // then exit selection mode. Non-destructive — keys can be unhidden from the
179
+ // filters UI.
180
+ const handleHideKeys = useCallback(keys => {
181
+ keys.forEach(k => onAddPattern?.(k.key));
182
+ setSelectedKeyIds(new Set());
183
+ setIsSelectMode(false);
184
+ }, [onAddPattern]);
185
+
175
186
  // Memoized export data for copy functionality
176
187
  const copyExportData = useMemo(() => {
177
188
  const allKeys = allStorageKeys;
@@ -394,8 +405,14 @@ export function GameUIStorageBrowser({
394
405
  // NOTE: MMKV instance filtering is now handled in mmkvStorageKeys memo (line 128)
395
406
  // No need to filter again here
396
407
 
408
+ // Float pinned keys to the top (stable — preserves existing order otherwise)
409
+ if (pinnedKeys && pinnedKeys.size > 0) {
410
+ const pinned = keys.filter(k => pinnedKeys.has(k.key));
411
+ const rest = keys.filter(k => !pinnedKeys.has(k.key));
412
+ keys = [...pinned, ...rest];
413
+ }
397
414
  return keys;
398
- }, [sortedKeys, activeFilter, activeStorageType, ignoredPatterns, searchQuery, selectedMMKVInstance, enabledStorageTypes]);
415
+ }, [sortedKeys, activeFilter, activeStorageType, ignoredPatterns, searchQuery, selectedMMKVInstance, enabledStorageTypes, pinnedKeys]);
399
416
 
400
417
  // For free users, limit visible keys to FREE_TIER_KEY_LIMIT
401
418
  const visibleKeys = useMemo(() => {
@@ -617,6 +634,7 @@ export function GameUIStorageBrowser({
617
634
  instance: inst.instance
618
635
  })),
619
636
  onDeleteComplete: handleDeleteComplete,
637
+ onHideKeys: handleHideKeys,
620
638
  onSelectAll: handleSelectAll,
621
639
  onClearSelection: handleClearSelection,
622
640
  totalVisibleKeys: visibleKeys.length
@@ -629,7 +647,10 @@ export function GameUIStorageBrowser({
629
647
  selectedKeys: selectedKeyIds,
630
648
  onSelectionChange: handleSelectionChange,
631
649
  eventCountByKey: eventCountByKey,
632
- onViewHistory: onViewHistory
650
+ onViewHistory: onViewHistory,
651
+ onHideKey: key => handleHideKeys([key]),
652
+ pinnedKeys: pinnedKeys,
653
+ onTogglePin: onTogglePin
633
654
  }), hasLockedKeys && /*#__PURE__*/_jsxs(TouchableOpacity, {
634
655
  style: styles.limitBanner,
635
656
  onPress: () => setShowUpgradeModal(true),
@@ -2,15 +2,16 @@
2
2
 
3
3
  import { useState, useEffect } from "react";
4
4
  import { View, Text, StyleSheet, TouchableOpacity, Alert } from "react-native";
5
- import { Trash2, CopyButton, CheckSquare, ProUpgradeModal } from "@buoy-gg/shared-ui";
5
+ import { Trash2, CopyButton, CheckSquare, EyeOff, ProUpgradeModal } from "@buoy-gg/shared-ui";
6
6
  import { macOSColors } from "@buoy-gg/shared-ui";
7
7
  import { useIsPro } from "@buoy-gg/license";
8
- import AsyncStorage from "@react-native-async-storage/async-storage";
8
+ import { removeMany } from "../utils/asyncStorageCompat";
9
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  export function SelectionActionBar({
11
11
  selectedKeys,
12
12
  mmkvInstances,
13
13
  onDeleteComplete,
14
+ onHideKeys,
14
15
  onSelectAll,
15
16
  onClearSelection,
16
17
  totalVisibleKeys
@@ -41,6 +42,12 @@ export function SelectionActionBar({
41
42
  };
42
43
  };
43
44
 
45
+ // Hide selected keys (adds them to the filter store; non-destructive)
46
+ const handleHideSelected = () => {
47
+ if (selectedCount === 0) return;
48
+ onHideKeys?.(selectedKeys);
49
+ };
50
+
44
51
  // Handle delete selected keys
45
52
  const handleDeleteSelected = () => {
46
53
  if (selectedCount === 0) return;
@@ -64,7 +71,7 @@ export function SelectionActionBar({
64
71
 
65
72
  // Delete AsyncStorage keys
66
73
  if (asyncKeys.length > 0) {
67
- await AsyncStorage.multiRemove(asyncKeys.map(k => k.key));
74
+ await removeMany(asyncKeys.map(k => k.key));
68
75
  }
69
76
 
70
77
  // Delete MMKV keys
@@ -127,6 +134,13 @@ export function SelectionActionBar({
127
134
  success: macOSColors.semantic.success,
128
135
  error: macOSColors.semantic.error
129
136
  }
137
+ }), onHideKeys && /*#__PURE__*/_jsx(TouchableOpacity, {
138
+ style: styles.actionButton,
139
+ onPress: handleHideSelected,
140
+ children: /*#__PURE__*/_jsx(EyeOff, {
141
+ size: 14,
142
+ color: macOSColors.semantic.warning
143
+ })
130
144
  }), /*#__PURE__*/_jsx(TouchableOpacity, {
131
145
  style: styles.actionButton,
132
146
  onPress: handleDeleteSelected,
@@ -16,7 +16,9 @@ export function StorageBrowserMode({
16
16
  storageDataRef,
17
17
  eventCountByKey,
18
18
  onViewHistory,
19
- enabledStorageTypes
19
+ enabledStorageTypes,
20
+ pinnedKeys,
21
+ onTogglePin
20
22
  }) {
21
23
  return /*#__PURE__*/_jsx(GameUIStorageBrowser, {
22
24
  requiredStorageKeys: requiredStorageKeys,
@@ -28,6 +30,8 @@ export function StorageBrowserMode({
28
30
  storageDataRef: storageDataRef,
29
31
  eventCountByKey: eventCountByKey,
30
32
  onViewHistory: onViewHistory,
31
- enabledStorageTypes: enabledStorageTypes
33
+ enabledStorageTypes: enabledStorageTypes,
34
+ pinnedKeys: pinnedKeys,
35
+ onTogglePin: onTogglePin
32
36
  });
33
37
  }
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
 
3
3
  import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
4
- import { macOSColors, CompactRow, TypeBadge, HardDrive, Square, CheckSquare, ExpandedInfoRow, PillBadge } from "@buoy-gg/shared-ui";
4
+ import { macOSColors, CompactRow, TypeBadge, HardDrive, Square, CheckSquare, EyeOff, Pin, ExpandedInfoRow, PillBadge } from "@buoy-gg/shared-ui";
5
5
  import { getStorageTypeLabel } from "../utils/storageQueryUtils";
6
- import { getValueTypeLabel } from "../utils/valueType";
6
+ import { getValueTypeLabel, getValueTypeWithPreview } from "../utils/valueType";
7
7
  import { DataViewer } from "@buoy-gg/shared-ui/dataViewer";
8
8
 
9
9
  // MMKV Instance color palette - consistent colors per instance
@@ -78,11 +78,18 @@ export function StorageKeyRow({
78
78
  isSelected = false,
79
79
  onSelectionChange,
80
80
  eventCount,
81
- onViewHistory
81
+ onViewHistory,
82
+ onHideKey,
83
+ isPinned = false,
84
+ onTogglePin
82
85
  }) {
83
86
  const config = getStatusConfig(storageKey.status);
84
87
  const hasValue = storageKey.value !== undefined && storageKey.value !== null;
85
88
 
89
+ // Booleans get a dedicated colored badge instead of an inline text preview so
90
+ // their value is scannable at a glance.
91
+ const isBoolean = hasValue && typeof storageKey.value === "boolean";
92
+
86
93
  // Format primary text - show the key
87
94
  const primaryText = storageKey.key;
88
95
 
@@ -195,6 +202,45 @@ export function StorageKeyRow({
195
202
  style: styles.expandedDescription,
196
203
  children: storageKey.description
197
204
  })]
205
+ }) : null, onTogglePin || onHideKey ? /*#__PURE__*/_jsxs(View, {
206
+ style: styles.actionRow,
207
+ children: [onTogglePin ? /*#__PURE__*/_jsxs(TouchableOpacity, {
208
+ style: [styles.actionChip, isPinned && styles.actionChipActive],
209
+ onPress: () => onTogglePin(storageKey.key),
210
+ hitSlop: {
211
+ top: 6,
212
+ bottom: 6,
213
+ left: 6,
214
+ right: 6
215
+ },
216
+ children: [/*#__PURE__*/_jsx(Pin, {
217
+ size: 12,
218
+ color: macOSColors.semantic.info
219
+ }), /*#__PURE__*/_jsx(Text, {
220
+ style: [styles.actionChipText, {
221
+ color: macOSColors.semantic.info
222
+ }],
223
+ children: isPinned ? "Unpin" : "Pin to top"
224
+ })]
225
+ }) : null, onHideKey ? /*#__PURE__*/_jsxs(TouchableOpacity, {
226
+ style: styles.actionChip,
227
+ onPress: () => onHideKey(storageKey),
228
+ hitSlop: {
229
+ top: 6,
230
+ bottom: 6,
231
+ left: 6,
232
+ right: 6
233
+ },
234
+ children: [/*#__PURE__*/_jsx(EyeOff, {
235
+ size: 12,
236
+ color: macOSColors.semantic.warning
237
+ }), /*#__PURE__*/_jsx(Text, {
238
+ style: [styles.actionChipText, {
239
+ color: macOSColors.semantic.warning
240
+ }],
241
+ children: "Hide from list"
242
+ })]
243
+ }) : null]
198
244
  }) : null]
199
245
  });
200
246
 
@@ -230,17 +276,28 @@ export function StorageKeyRow({
230
276
  statusLabel: config.label,
231
277
  statusSublabel: config.sublabel,
232
278
  primaryText: primaryText,
233
- secondaryText: hasValue ? getValueTypeLabel(storageKey.value) : undefined,
279
+ secondaryText: hasValue ? isBoolean ? getValueTypeLabel(storageKey.value) : getValueTypeWithPreview(storageKey.value) : undefined,
280
+ secondaryAccessory: isBoolean ? /*#__PURE__*/_jsx(PillBadge, {
281
+ size: "sm",
282
+ color: storageKey.value ? macOSColors.semantic.success : macOSColors.semantic.error,
283
+ children: storageKey.value ? "true" : "false"
284
+ }) : undefined,
234
285
  expandedContent: expandedContent,
235
286
  isExpanded: isExpanded,
236
287
  expandedGlowColor: config.color,
237
- customBadge: /*#__PURE__*/_jsx(PillBadge, {
238
- color: getStorageTypeColor(storageKey.storageType),
239
- children: storageTypeLabel
288
+ customBadge: /*#__PURE__*/_jsxs(View, {
289
+ style: styles.badgeRow,
290
+ children: [isPinned && /*#__PURE__*/_jsx(Pin, {
291
+ size: 12,
292
+ color: macOSColors.semantic.info
293
+ }), /*#__PURE__*/_jsx(PillBadge, {
294
+ color: getStorageTypeColor(storageKey.storageType),
295
+ children: storageTypeLabel
296
+ })]
240
297
  }),
241
298
  showChevron: !isSelectMode,
242
299
  onPress: isSelectMode ? handleCheckboxPress : onPress ? () => onPress(storageKey) : undefined
243
- }), eventCount != null && eventCount > 0 && /*#__PURE__*/_jsx(View, {
300
+ }), eventCount != null && eventCount > 1 && /*#__PURE__*/_jsx(View, {
244
301
  style: [styles.absCountBadge, {
245
302
  backgroundColor: macOSColors.semantic.warning + "22",
246
303
  borderColor: macOSColors.semantic.warning + "55"
@@ -269,6 +326,11 @@ const getStorageTypeColor = storageType => {
269
326
  }
270
327
  };
271
328
  const styles = StyleSheet.create({
329
+ badgeRow: {
330
+ flexDirection: "row",
331
+ alignItems: "center",
332
+ gap: 6
333
+ },
272
334
  expandedContainer: {
273
335
  gap: 8
274
336
  },
@@ -342,6 +404,33 @@ const styles = StyleSheet.create({
342
404
  fontWeight: "700",
343
405
  fontFamily: "monospace"
344
406
  },
407
+ actionRow: {
408
+ flexDirection: "row",
409
+ alignItems: "center",
410
+ flexWrap: "wrap",
411
+ gap: 8,
412
+ marginTop: 4
413
+ },
414
+ actionChip: {
415
+ flexDirection: "row",
416
+ alignItems: "center",
417
+ gap: 6,
418
+ paddingVertical: 6,
419
+ paddingHorizontal: 10,
420
+ borderRadius: 6,
421
+ backgroundColor: macOSColors.background.card,
422
+ borderWidth: 1,
423
+ borderColor: macOSColors.border.default
424
+ },
425
+ actionChipActive: {
426
+ backgroundColor: macOSColors.semantic.info + "15",
427
+ borderColor: macOSColors.semantic.info + "44"
428
+ },
429
+ actionChipText: {
430
+ fontSize: 11,
431
+ fontWeight: "600",
432
+ fontFamily: "monospace"
433
+ },
345
434
  viewHistoryButton: {
346
435
  marginLeft: 4
347
436
  },
@@ -23,7 +23,10 @@ export function StorageKeySection({
23
23
  selectedKeys = new Set(),
24
24
  onSelectionChange,
25
25
  eventCountByKey,
26
- onViewHistory
26
+ onViewHistory,
27
+ onHideKey,
28
+ pinnedKeys,
29
+ onTogglePin
27
30
  }) {
28
31
  const [expandedKey, setExpandedKey] = useState(null);
29
32
  const handleKeyPress = useCallback(storageKey => {
@@ -76,7 +79,10 @@ export function StorageKeySection({
76
79
  isSelected: selectedKeys.has(uniqueKey),
77
80
  onSelectionChange: onSelectionChange,
78
81
  eventCount: eventCountByKey?.[storageKey.key],
79
- onViewHistory: onViewHistory ? () => onViewHistory(storageKey.key) : undefined
82
+ onViewHistory: onViewHistory ? () => onViewHistory(storageKey.key) : undefined,
83
+ onHideKey: onHideKey,
84
+ isPinned: pinnedKeys?.has(storageKey.key),
85
+ onTogglePin: onTogglePin
80
86
  }, uniqueKey);
81
87
  })
82
88
  })]
@@ -56,8 +56,10 @@ export function StorageModalWithTabs({
56
56
  );
57
57
  const [enabledStorageTypes, setEnabledStorageTypes] = useState(new Set(['async', 'mmkv', 'secure']) // All enabled by default
58
58
  );
59
+ const [pinnedKeys, setPinnedKeys] = useState(new Set());
59
60
  const lastEventRef = useRef(null);
60
61
  const hasLoadedFilters = useRef(false);
62
+ const hasLoadedPins = useRef(false);
61
63
  const hasLoadedTabState = useRef(false);
62
64
  const hasLoadedMonitoringState = useRef(false);
63
65
 
@@ -172,6 +174,37 @@ export function StorageModalWithTabs({
172
174
  saveFilters();
173
175
  }, [ignoredPatterns]);
174
176
 
177
+ // Load persisted pinned keys on mount
178
+ useEffect(() => {
179
+ if (!visible || hasLoadedPins.current) return;
180
+ const loadPins = async () => {
181
+ try {
182
+ const stored = await AsyncStorage.getItem(devToolsStorageKeys.storage.pinnedKeys());
183
+ if (stored) {
184
+ setPinnedKeys(new Set(JSON.parse(stored)));
185
+ }
186
+ hasLoadedPins.current = true;
187
+ } catch (error) {
188
+ // Failed to load pinned keys
189
+ }
190
+ };
191
+ loadPins();
192
+ }, [visible]);
193
+
194
+ // Save pinned keys when they change
195
+ useEffect(() => {
196
+ if (!hasLoadedPins.current) return; // Don't save on initial load
197
+
198
+ const savePins = async () => {
199
+ try {
200
+ await AsyncStorage.setItem(devToolsStorageKeys.storage.pinnedKeys(), JSON.stringify(Array.from(pinnedKeys)));
201
+ } catch (error) {
202
+ // Failed to save pinned keys
203
+ }
204
+ };
205
+ savePins();
206
+ }, [pinnedKeys]);
207
+
175
208
  // Event listener setup - now handled by useStorageEvents hook
176
209
  // The hook subscribes to the centralized storageEventStore
177
210
 
@@ -206,6 +239,17 @@ export function StorageModalWithTabs({
206
239
  const handleAddPattern = useCallback(pattern => {
207
240
  setIgnoredPatterns(prev => new Set([...prev, pattern]));
208
241
  }, []);
242
+ const handleTogglePin = useCallback(key => {
243
+ setPinnedKeys(prev => {
244
+ const next = new Set(prev);
245
+ if (next.has(key)) {
246
+ next.delete(key);
247
+ } else {
248
+ next.add(key);
249
+ }
250
+ return next;
251
+ });
252
+ }, []);
209
253
  const handleToggleFilters = useCallback(() => {
210
254
  setShowFilters(!showFilters);
211
255
  }, [showFilters]);
@@ -504,7 +548,9 @@ export function StorageModalWithTabs({
504
548
  storageDataRef: storageDataRef,
505
549
  eventCountByKey: eventCountByKey,
506
550
  onViewHistory: handleViewHistoryFromBrowser,
507
- enabledStorageTypes: enabledStorageTypes
551
+ enabledStorageTypes: enabledStorageTypes,
552
+ pinnedKeys: pinnedKeys,
553
+ onTogglePin: handleTogglePin
508
554
  });
509
555
  }
510
556
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useState, useEffect, useCallback, useRef } from 'react';
4
4
  import AsyncStorage from '@react-native-async-storage/async-storage';
5
+ import { readMany } from '../utils/asyncStorageCompat';
5
6
  export function useAsyncStorageKeys(requiredStorageKeys = []) {
6
7
  // State management
7
8
  const [storageKeys, setStorageKeys] = useState([]);
@@ -31,8 +32,8 @@ export function useAsyncStorageKeys(requiredStorageKeys = []) {
31
32
  return;
32
33
  }
33
34
 
34
- // 2. Get all values using multiGet
35
- const allKeyValuePairs = await AsyncStorage.multiGet(allKeys);
35
+ // 2. Get all values (compat helper normalizes v2 multiGet / v3 getMany)
36
+ const allKeyValuePairs = await readMany(allKeys);
36
37
 
37
38
  // 3. Process keys into StorageKeyInfo format
38
39
  const allStorageKeys = [];
@@ -111,11 +111,14 @@ class StorageEventStore extends BaseEventStore {
111
111
 
112
112
  // ── AsyncStorage: async scan ──
113
113
  try {
114
- const AsyncStorage = require("@react-native-async-storage/async-storage").default;
115
- if (AsyncStorage) {
116
- const allKeys = await AsyncStorage.getAllKeys();
114
+ const {
115
+ asyncStorage,
116
+ readMany
117
+ } = require("../utils/asyncStorageCompat");
118
+ if (asyncStorage) {
119
+ const allKeys = await asyncStorage.getAllKeys();
117
120
  if (allKeys.length > 0) {
118
- const pairs = await AsyncStorage.multiGet(allKeys);
121
+ const pairs = await readMany(allKeys);
119
122
  for (const [key, rawValue] of pairs) {
120
123
  this.addEvent({
121
124
  action: "setItem",
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import AsyncStorage from "@react-native-async-storage/async-storage";
4
+ import { readMany, writeMany, removeMany } from "../utils/asyncStorageCompat";
4
5
  import { storageEventStore } from "../stores/storageEventStore";
5
6
  import { clearAllAppStorage } from "../utils/clearAllStorage";
6
7
  /**
@@ -26,8 +27,11 @@ export const storageSyncAdapter = {
26
27
  /** Clears all app storage keys, preserving dev tools settings. */
27
28
  clearAppStorage: () => clearAllAppStorage(),
28
29
  // ── Remote AsyncStorage proxy (desktop browse/edit mode) ──
30
+ // Single-item methods share the same signature across async-storage v2/v3;
31
+ // batch methods go through the compat helpers (which translate to v3's
32
+ // getMany/setMany/removeMany) and keep the v2 tuple/pairs shape on the wire.
29
33
  "async.getAllKeys": () => AsyncStorage.getAllKeys(),
30
- "async.multiGet": params => AsyncStorage.multiGet(params.keys),
34
+ "async.multiGet": params => readMany(params.keys),
31
35
  "async.getItem": params => AsyncStorage.getItem(params.key),
32
36
  "async.setItem": params => {
33
37
  const {
@@ -37,8 +41,8 @@ export const storageSyncAdapter = {
37
41
  return AsyncStorage.setItem(key, value);
38
42
  },
39
43
  "async.removeItem": params => AsyncStorage.removeItem(params.key),
40
- "async.multiRemove": params => AsyncStorage.multiRemove(params.keys),
41
- "async.multiSet": params => AsyncStorage.multiSet(params.pairs),
44
+ "async.multiRemove": params => removeMany(params.keys),
45
+ "async.multiSet": params => writeMany(params.pairs),
42
46
  "async.clear": () => AsyncStorage.clear()
43
47
  }
44
48
  };