@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,577 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * One storage key, on a screen of its own — the React Query detail-screen
5
- * shape (and the Zustand tool's twin), pointed at a stored value.
6
- *
7
- * Tapping a key card opens this instead of expanding in place. Top to bottom:
8
- *
9
- * 1. VALUE EDITOR — the shared LiveExplorer. No draft, no Save: an edit
10
- * re-serializes the whole value and writes it as you make it. Typing
11
- * commits on a short debounce (~300ms, flushed on blur) so a word is one
12
- * storage write, not one per keystroke — storage writes hit disk and
13
- * land in the events timeline, which is the one way this tool differs
14
- * from RQ's unlogged cache writes. A scalar key is just the root leaf's
15
- * input; a boolean key is a one-tap toggle.
16
- * 2. KEY DETAILS — what the expanded card used to say: status, backend,
17
- * MMKV instance, updates (with the road to history), schema diagnostics.
18
- * 3. RAW VALUE — the serialized string exactly as the backend holds it.
19
- * 4. The card's housekeeping actions: pin, hide, delete.
20
- *
21
- * THE ROUND-TRIP WRINKLE zustand doesn't have: a storage write is async —
22
- * write, device event, snapshot, refreshed prop. Between an edit and its
23
- * echo, `storageKey.value` is STALE, so basing the next edit on the prop
24
- * would silently revert the previous one (edit qty, then name, and qty snaps
25
- * back). `lastWrittenRef` holds the most recent written document and is the
26
- * base for every edit until the prop catches up to it — last-write-wins
27
- * against the app, exactly once, and never against the editor itself.
28
- */
29
-
30
- import { useCallback, useMemo, useRef, useState } from "react";
31
- import { Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
32
- import { EyeOff, FileJson, HardDrive, night, macOSColors, Pin, PillBadge, Trash2, TypeBadge, useSafeAreaInsets, monoFont } from "@buoy-gg/shared-ui";
33
- import { DataViewer, LiveExplorer, ValueEditModal, updateNestedDataByPath, deleteNestedDataByPath } from "@buoy-gg/shared-ui/dataViewer";
34
- import { getStorageTypeLabel } from "../utils/storageQueryUtils";
35
- import { getValueTypeLabel, parseStorageValue } from "../utils/valueType";
36
- import { getStatusConfig, getStorageTypeColor } from "./StorageKeyRow";
37
-
38
- /** How long typed edits coalesce before the single write fires. */
39
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
40
- const TYPING_COMMIT_MS = 300;
41
- const DETAIL_ID = "buoy-storage-detail";
42
- function detailExplorerTestID(dataPath) {
43
- const slug = part => part.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
44
- return dataPath.length === 0 ? `${DETAIL_ID}-explorer-root` : `${DETAIL_ID}-explorer-${dataPath.map(slug).filter(Boolean).join("-")}`;
45
- }
46
-
47
- /** Same MMKV instance-color rule the card uses. */
48
- const INSTANCE_COLORS = [macOSColors.semantic.info, macOSColors.semantic.success, macOSColors.semantic.warning, macOSColors.semantic.debug, "#FF6B9D", "#00D9FF"];
49
- function getInstanceColor(instanceId) {
50
- const hash = instanceId.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
51
- return INSTANCE_COLORS[hash % INSTANCE_COLORS.length];
52
- }
53
- export function StorageKeyDetailScreen({
54
- storageKey,
55
- editBlockedReason,
56
- eventCount,
57
- onSave,
58
- onViewHistory,
59
- onDeleteKey,
60
- onHideKey,
61
- isPinned = false,
62
- onTogglePin,
63
- applySafeAreaInset
64
- }) {
65
- const insets = useSafeAreaInsets();
66
- const bottomInset = applySafeAreaInset ? insets.bottom : 0;
67
- const canEdit = editBlockedReason == null;
68
- const config = getStatusConfig(storageKey.status);
69
- const storageTypeLabel = getStorageTypeLabel(storageKey.storageType);
70
- const [rawOpen, setRawOpen] = useState(false);
71
- // Force the explorer to re-sync focused inputs after a Raw-hatch apply.
72
- const [rawVersion, setRawVersion] = useState(0);
73
-
74
- /**
75
- * The most recent document THIS screen wrote, until the refreshed prop
76
- * catches up to it — see the module docstring's round-trip wrinkle. Held
77
- * as its serialized form so "caught up" is one string compare against the
78
- * same serialization the write used.
79
- */
80
- const lastWrittenRef = useRef(null);
81
- const propParsed = useMemo(() => parseStorageValue(storageKey.value), [storageKey.value]);
82
- const propRaw = typeof storageKey.value === "string" ? storageKey.value : JSON.stringify(storageKey.value);
83
- if (lastWrittenRef.current && lastWrittenRef.current.raw === propRaw) {
84
- // The device echoed our write back — the prop is current again.
85
- lastWrittenRef.current = null;
86
- }
87
- const baseValue = lastWrittenRef.current ? lastWrittenRef.current.value : propParsed;
88
- const write = useCallback(next => {
89
- // A string is stored AS ITSELF. `JSON.stringify` on a string adds
90
- // quotes the backend keeps (AsyncStorage) or shows natively (MMKV), and
91
- // they compound on every edit: "hello" → "\"hello\"" → ... The old
92
- // scalar editor had this rule (serializeScalar); the live editor must
93
- // keep it, and it matches propRaw above, so an echo still reads as
94
- // caught up.
95
- const raw = typeof next === "string" ? next : JSON.stringify(next);
96
- lastWrittenRef.current = {
97
- raw,
98
- value: next
99
- };
100
- onSave(raw).catch(e => {
101
- // The write was refused (the Pro gate, a dead backend) — the base
102
- // must fall back to what's actually stored, or the tree keeps
103
- // showing an edit that never landed.
104
- lastWrittenRef.current = null;
105
- Alert.alert("Couldn't save", e instanceof Error ? e.message : String(e));
106
- });
107
- }, [onSave]);
108
- const baseRef = useRef(baseValue);
109
- baseRef.current = baseValue;
110
- const writer = useMemo(() => {
111
- if (!canEdit) return undefined;
112
- return {
113
- update: (path, value) => {
114
- const next = path.length === 0 ? value : updateNestedDataByPath(baseRef.current, path, value);
115
- write(next);
116
- },
117
- remove: path => {
118
- if (path.length === 0) return;
119
- write(deleteNestedDataByPath(baseRef.current, path));
120
- }
121
- // Storage replaces the whole key on every write, so any node may go.
122
- };
123
- }, [canEdit, write]);
124
- const showHousekeeping = onTogglePin || onHideKey || canEdit && onDeleteKey;
125
- return /*#__PURE__*/_jsxs(View, {
126
- style: styles.screen,
127
- children: [/*#__PURE__*/_jsx(View, {
128
- testID: `${DETAIL_ID}-key`,
129
- accessibilityLabel: storageKey.key
130
- }), /*#__PURE__*/_jsxs(ScrollView, {
131
- testID: `${DETAIL_ID}-scroll`,
132
- style: styles.scroll,
133
- contentContainerStyle: [styles.scrollContent, {
134
- paddingBottom: 24 + bottomInset
135
- }],
136
- keyboardShouldPersistTaps: "handled",
137
- children: [/*#__PURE__*/_jsx(View, {
138
- style: styles.section,
139
- children: /*#__PURE__*/_jsxs(View, {
140
- style: styles.editorContainer,
141
- children: [/*#__PURE__*/_jsxs(View, {
142
- style: styles.sectionHeaderRow,
143
- children: [/*#__PURE__*/_jsx(Text, {
144
- testID: `${DETAIL_ID}-editor-header`,
145
- style: styles.sectionHeaderAccentText,
146
- children: "Value Editor"
147
- }), canEdit ? /*#__PURE__*/_jsxs(TouchableOpacity, {
148
- onPress: () => setRawOpen(true),
149
- testID: `${DETAIL_ID}-raw`,
150
- accessibilityRole: "button",
151
- accessibilityLabel: "Edit raw JSON",
152
- style: styles.rawButton,
153
- hitSlop: {
154
- top: 6,
155
- bottom: 6,
156
- left: 6,
157
- right: 6
158
- },
159
- children: [/*#__PURE__*/_jsx(FileJson, {
160
- size: 13,
161
- color: night.color.accent
162
- }), /*#__PURE__*/_jsx(Text, {
163
- style: styles.rawButtonText,
164
- children: "Raw"
165
- })]
166
- }) : null]
167
- }), /*#__PURE__*/_jsxs(View, {
168
- style: styles.sectionBody,
169
- children: [/*#__PURE__*/_jsx(LiveExplorer, {
170
- editable: canEdit,
171
- label: "Value",
172
- value: baseValue,
173
- defaultExpanded: ["Value"],
174
- writer: writer,
175
- dataVersion: rawVersion,
176
- testIDForPath: detailExplorerTestID,
177
- debounceMs: TYPING_COMMIT_MS
178
- }), canEdit ? /*#__PURE__*/_jsx(Text, {
179
- style: styles.editorHint,
180
- children: "Edits write to the device as you make them \u2014 undo lives in the key's history."
181
- }) : /*#__PURE__*/_jsx(Text, {
182
- style: styles.blockedText,
183
- testID: `${DETAIL_ID}-edit-blocked`,
184
- children: editBlockedReason
185
- })]
186
- })]
187
- })
188
- }), /*#__PURE__*/_jsx(View, {
189
- style: styles.section,
190
- children: /*#__PURE__*/_jsxs(View, {
191
- style: styles.infoContainer,
192
- children: [/*#__PURE__*/_jsx(Text, {
193
- style: styles.sectionHeaderPlain,
194
- children: "Key Details"
195
- }), /*#__PURE__*/_jsxs(View, {
196
- style: styles.infoBody,
197
- children: [/*#__PURE__*/_jsxs(View, {
198
- style: styles.infoRow,
199
- children: [/*#__PURE__*/_jsx(Text, {
200
- style: styles.infoLabel,
201
- children: "Status:"
202
- }), /*#__PURE__*/_jsx(PillBadge, {
203
- color: config.color,
204
- testID: `${DETAIL_ID}-status`,
205
- children: config.label
206
- }), /*#__PURE__*/_jsx(Text, {
207
- style: styles.infoDim,
208
- children: config.sublabel
209
- })]
210
- }), /*#__PURE__*/_jsxs(View, {
211
- style: styles.infoRow,
212
- children: [/*#__PURE__*/_jsx(Text, {
213
- style: styles.infoLabel,
214
- children: "Storage:"
215
- }), /*#__PURE__*/_jsx(PillBadge, {
216
- color: getStorageTypeColor(storageKey.storageType),
217
- testID: `${DETAIL_ID}-backend`,
218
- children: storageTypeLabel
219
- }), /*#__PURE__*/_jsx(Text, {
220
- style: styles.infoDim,
221
- children: getValueTypeLabel(storageKey.value)
222
- })]
223
- }), storageKey.storageType === "mmkv" && storageKey.instanceId && /*#__PURE__*/_jsxs(View, {
224
- style: styles.infoRow,
225
- children: [/*#__PURE__*/_jsx(Text, {
226
- style: styles.infoLabel,
227
- children: "Instance:"
228
- }), /*#__PURE__*/_jsx(PillBadge, {
229
- color: getInstanceColor(storageKey.instanceId),
230
- icon: /*#__PURE__*/_jsx(HardDrive, {
231
- size: 9,
232
- color: getInstanceColor(storageKey.instanceId)
233
- }),
234
- children: storageKey.instanceId
235
- })]
236
- }), eventCount != null && eventCount > 0 && /*#__PURE__*/_jsxs(View, {
237
- style: styles.infoRow,
238
- children: [/*#__PURE__*/_jsx(Text, {
239
- style: styles.infoLabel,
240
- children: "Updates:"
241
- }), /*#__PURE__*/_jsx(PillBadge, {
242
- color: macOSColors.semantic.warning,
243
- children: String(eventCount)
244
- }), eventCount > 1 && onViewHistory && /*#__PURE__*/_jsx(TouchableOpacity, {
245
- onPress: onViewHistory,
246
- testID: "buoy-storage-key-history",
247
- accessibilityLabel: `View history for ${storageKey.key}`,
248
- accessibilityRole: "button",
249
- style: styles.inlineLinkButton,
250
- hitSlop: {
251
- top: 6,
252
- bottom: 6,
253
- left: 6,
254
- right: 6
255
- },
256
- children: /*#__PURE__*/_jsx(Text, {
257
- style: styles.inlineLinkText,
258
- children: "view history \u2192"
259
- })
260
- })]
261
- }), storageKey.status === "required_wrong_type" && storageKey.expectedType && /*#__PURE__*/_jsxs(View, {
262
- style: styles.infoRow,
263
- children: [/*#__PURE__*/_jsx(Text, {
264
- style: styles.infoLabel,
265
- children: "Expected:"
266
- }), /*#__PURE__*/_jsx(TypeBadge, {
267
- type: storageKey.expectedType
268
- }), /*#__PURE__*/_jsxs(Text, {
269
- style: styles.infoDim,
270
- children: ["got ", getValueTypeLabel(storageKey.value)]
271
- })]
272
- }), storageKey.status === "required_wrong_value" && storageKey.expectedValue && /*#__PURE__*/_jsxs(View, {
273
- style: styles.infoRow,
274
- children: [/*#__PURE__*/_jsx(Text, {
275
- style: styles.infoLabel,
276
- children: "Expected:"
277
- }), /*#__PURE__*/_jsx(Text, {
278
- style: styles.infoExpected,
279
- children: String(storageKey.expectedValue)
280
- })]
281
- }), storageKey.description ? /*#__PURE__*/_jsxs(View, {
282
- style: styles.infoRow,
283
- children: [/*#__PURE__*/_jsx(Text, {
284
- style: styles.infoLabel,
285
- children: "Info:"
286
- }), /*#__PURE__*/_jsx(Text, {
287
- style: styles.infoDescription,
288
- children: storageKey.description
289
- })]
290
- }) : null]
291
- })]
292
- })
293
- }), /*#__PURE__*/_jsx(View, {
294
- style: styles.section,
295
- children: /*#__PURE__*/_jsxs(View, {
296
- style: styles.infoContainer,
297
- children: [/*#__PURE__*/_jsx(Text, {
298
- style: styles.sectionHeaderPlain,
299
- children: "Value Explorer"
300
- }), /*#__PURE__*/_jsx(View, {
301
- style: styles.viewerBody,
302
- testID: `${DETAIL_ID}-viewer`,
303
- children: baseValue !== null && typeof baseValue === "object" ? /*#__PURE__*/_jsx(DataViewer, {
304
- title: "",
305
- data: baseValue,
306
- showTypeFilter: true,
307
- rawMode: true,
308
- initialExpanded: false
309
- }) : /*#__PURE__*/_jsx(Text, {
310
- style: styles.rawValueText,
311
- selectable: true,
312
- children: propRaw ?? "undefined"
313
- })
314
- })]
315
- })
316
- }), showHousekeeping ? /*#__PURE__*/_jsxs(View, {
317
- style: styles.actionRow,
318
- children: [onTogglePin ? /*#__PURE__*/_jsxs(TouchableOpacity, {
319
- style: [styles.actionChip, isPinned && styles.actionChipActive],
320
- testID: "buoy-storage-key-pin",
321
- accessibilityLabel: isPinned ? `Unpin ${storageKey.key}` : `Pin ${storageKey.key} to top`,
322
- accessibilityRole: "button",
323
- onPress: () => onTogglePin(storageKey.key),
324
- hitSlop: {
325
- top: 6,
326
- bottom: 6,
327
- left: 6,
328
- right: 6
329
- },
330
- children: [/*#__PURE__*/_jsx(Pin, {
331
- size: 12,
332
- active: isPinned,
333
- color: night.color.accent
334
- }), /*#__PURE__*/_jsx(Text, {
335
- style: [styles.actionChipText, {
336
- color: night.color.accent
337
- }],
338
- children: isPinned ? "Unpin" : "Pin to top"
339
- })]
340
- }) : null, onHideKey ? /*#__PURE__*/_jsxs(TouchableOpacity, {
341
- style: styles.actionChip,
342
- testID: "buoy-storage-key-hide",
343
- accessibilityLabel: `Hide ${storageKey.key} from list`,
344
- accessibilityRole: "button",
345
- onPress: () => onHideKey(storageKey),
346
- hitSlop: {
347
- top: 6,
348
- bottom: 6,
349
- left: 6,
350
- right: 6
351
- },
352
- children: [/*#__PURE__*/_jsx(EyeOff, {
353
- size: 12,
354
- color: night.color.warning
355
- }), /*#__PURE__*/_jsx(Text, {
356
- style: [styles.actionChipText, {
357
- color: night.color.warning
358
- }],
359
- children: "Hide from list"
360
- })]
361
- }) : null, canEdit && onDeleteKey ? /*#__PURE__*/_jsxs(TouchableOpacity, {
362
- style: [styles.actionChip, styles.dangerChip],
363
- testID: "buoy-storage-key-delete",
364
- accessibilityLabel: `Delete key ${storageKey.key}`,
365
- accessibilityRole: "button",
366
- onPress: () => onDeleteKey(storageKey),
367
- hitSlop: {
368
- top: 6,
369
- bottom: 6,
370
- left: 6,
371
- right: 6
372
- },
373
- children: [/*#__PURE__*/_jsx(Trash2, {
374
- size: 12,
375
- color: night.color.danger
376
- }), /*#__PURE__*/_jsx(Text, {
377
- style: [styles.actionChipText, {
378
- color: night.color.danger
379
- }],
380
- children: "Delete key"
381
- })]
382
- }) : null]
383
- }) : null]
384
- }), rawOpen && canEdit ? /*#__PURE__*/_jsx(ValueEditModal, {
385
- path: [],
386
- value: baseValue,
387
- onSave: next => {
388
- write(next);
389
- setRawVersion(v => v + 1);
390
- setRawOpen(false);
391
- },
392
- onCancel: () => setRawOpen(false),
393
- saveLabel: "Apply",
394
- testIDPrefix: "buoy-storage-value"
395
- }) : null]
396
- });
397
- }
398
- const styles = StyleSheet.create({
399
- screen: {
400
- flex: 1,
401
- minHeight: 0
402
- // Transparent — this is the modal's body, and the modal paints its own
403
- // background (the same contract as the Zustand detail screen).
404
- },
405
- scroll: {
406
- flex: 1
407
- },
408
- scrollContent: {
409
- paddingHorizontal: 8,
410
- paddingTop: 8
411
- },
412
- section: {
413
- marginBottom: 16
414
- },
415
- editorContainer: {
416
- minWidth: 200,
417
- backgroundColor: night.color.surface,
418
- borderRadius: 6,
419
- borderWidth: 1,
420
- borderColor: night.color.accent + "4D",
421
- overflow: "hidden",
422
- shadowColor: night.color.accent,
423
- shadowOffset: {
424
- width: 0,
425
- height: 0
426
- },
427
- shadowOpacity: 0.1,
428
- shadowRadius: 6
429
- },
430
- sectionHeaderRow: {
431
- flexDirection: "row",
432
- alignItems: "center",
433
- justifyContent: "space-between",
434
- backgroundColor: night.color.accent + "1A",
435
- paddingHorizontal: 12,
436
- paddingVertical: 8,
437
- borderBottomWidth: 1,
438
- borderBottomColor: night.color.accent + "33"
439
- },
440
- sectionHeaderAccentText: {
441
- fontWeight: "600",
442
- fontSize: 12,
443
- color: night.color.accent,
444
- letterSpacing: 0.5,
445
- textTransform: "uppercase",
446
- fontFamily: monoFont
447
- },
448
- rawButton: {
449
- flexDirection: "row",
450
- alignItems: "center",
451
- gap: 4
452
- },
453
- rawButtonText: {
454
- color: night.color.accent,
455
- fontSize: 11,
456
- fontWeight: "700"
457
- },
458
- sectionBody: {
459
- padding: 8
460
- },
461
- editorHint: {
462
- color: night.color.textTertiary,
463
- fontSize: 10,
464
- paddingTop: 8,
465
- paddingHorizontal: 4,
466
- lineHeight: 14
467
- },
468
- blockedText: {
469
- color: night.color.textSecondary,
470
- fontSize: 12,
471
- padding: 12,
472
- lineHeight: 18
473
- },
474
- infoContainer: {
475
- minWidth: 200,
476
- backgroundColor: night.color.surface,
477
- borderRadius: 6,
478
- borderWidth: 1,
479
- borderColor: night.color.border,
480
- overflow: "hidden"
481
- },
482
- sectionHeaderPlain: {
483
- backgroundColor: night.color.surfaceElevated,
484
- paddingHorizontal: 12,
485
- paddingVertical: 8,
486
- fontWeight: "600",
487
- fontSize: 12,
488
- color: night.color.textSecondary,
489
- borderBottomWidth: 1,
490
- borderBottomColor: night.color.border,
491
- letterSpacing: 0.5,
492
- textTransform: "uppercase",
493
- fontFamily: monoFont
494
- },
495
- infoBody: {
496
- padding: 12,
497
- gap: 10
498
- },
499
- infoRow: {
500
- flexDirection: "row",
501
- alignItems: "center",
502
- gap: 8
503
- },
504
- infoLabel: {
505
- fontSize: 10,
506
- color: night.color.textTertiary,
507
- fontWeight: "600",
508
- minWidth: 64,
509
- fontFamily: monoFont
510
- },
511
- infoDim: {
512
- color: night.color.textTertiary,
513
- fontSize: 10,
514
- fontFamily: monoFont
515
- },
516
- infoExpected: {
517
- fontSize: 11,
518
- color: macOSColors.semantic.warning,
519
- fontFamily: monoFont,
520
- flex: 1
521
- },
522
- infoDescription: {
523
- fontSize: 11,
524
- color: night.color.textSecondary,
525
- flex: 1
526
- },
527
- rawValueText: {
528
- color: night.color.textSecondary,
529
- fontSize: 11,
530
- fontFamily: monoFont,
531
- lineHeight: 16,
532
- padding: 12
533
- },
534
- viewerBody: {
535
- backgroundColor: night.color.bg,
536
- minHeight: 48
537
- },
538
- inlineLinkButton: {
539
- marginLeft: 4
540
- },
541
- inlineLinkText: {
542
- fontSize: 10,
543
- fontWeight: "600",
544
- fontFamily: monoFont,
545
- color: night.color.accent
546
- },
547
- actionRow: {
548
- flexDirection: "row",
549
- alignItems: "center",
550
- flexWrap: "wrap",
551
- gap: 8,
552
- paddingHorizontal: 4
553
- },
554
- actionChip: {
555
- flexDirection: "row",
556
- alignItems: "center",
557
- gap: 6,
558
- paddingVertical: 6,
559
- paddingHorizontal: 10,
560
- borderRadius: 6,
561
- backgroundColor: night.color.surface,
562
- borderWidth: 1,
563
- borderColor: night.color.border
564
- },
565
- dangerChip: {
566
- borderColor: night.color.danger + "55"
567
- },
568
- actionChipActive: {
569
- backgroundColor: night.color.accentSoft,
570
- borderColor: night.color.accentBorderStrong
571
- },
572
- actionChipText: {
573
- fontSize: 11,
574
- fontWeight: "600",
575
- fontFamily: monoFont
576
- }
577
- });
1
+ "use strict";import{useCallback as q,useMemo as B,useRef as H,useState as V}from"react";import{Alert as G,ScrollView as Y,StyleSheet as Q,Text as n,TouchableOpacity as m,View as l}from"react-native";import{EyeOff as X,FileJson as Z,HardDrive as K,night as i,macOSColors as b,Pin as ee,PillBadge as C,Trash2 as te,TypeBadge as oe,useSafeAreaInsets as ie,monoFont as h}from"@buoy-gg/shared-ui";import{DataViewer as ne,LiveExplorer as re,ValueEditModal as le,updateNestedDataByPath as ce,deleteNestedDataByPath as ae}from"@buoy-gg/shared-ui/dataViewer";import{getStorageTypeLabel as se}from"../utils/storageQueryUtils";import{getValueTypeLabel as E,parseStorageValue as de}from"../utils/valueType";import{getStatusConfig as he,getStorageTypeColor as fe}from"./StorageKeyRow";import{jsx as t,jsxs as r}from"react/jsx-runtime";const ue=300;const a="buoy-storage-detail";function pe(o){const y=s=>s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return o.length===0?`${a}-explorer-root`:`${a}-explorer-${o.map(y).filter(Boolean).join("-")}`}const $=[b.semantic.info,b.semantic.success,b.semantic.warning,b.semantic.debug,"#FF6B9D","#00D9FF"];function F(o){const y=o.split("").reduce((s,w)=>s+w.charCodeAt(0),0);return $[y%$.length]}export function StorageKeyDetailScreen({storageKey:o,editBlockedReason:y,eventCount:s,onSave:w,onViewHistory:L,onDeleteKey:T,onHideKey:D,isPinned:x=false,onTogglePin:k,applySafeAreaInset:W}){const O=ie();const P=W?O.bottom:0;const d=y==null;const I=he(o.status);const A=se(o.storageType);const[_,R]=V(false);const[N,j]=V(0);const f=H(null);const M=B(()=>de(o.value),[o.value]);const z=typeof o.value==="string"?o.value:JSON.stringify(o.value);if(f.current&&f.current.raw===z){f.current=null}const u=f.current?f.current.value:M;const S=q(c=>{const p=typeof c==="string"?c:JSON.stringify(c);f.current={raw:p,value:c};w(p).catch(g=>{f.current=null;G.alert("Couldn't save",g instanceof Error?g.message:String(g))})},[w]);const v=H(u);v.current=u;const J=B(()=>{if(!d)return void 0;return{update:(c,p)=>{const g=c.length===0?p:ce(v.current,c,p);S(g)},remove:c=>{if(c.length===0)return;S(ae(v.current,c))}}},[d,S]);const U=k||D||d&&T;return r(l,{style:e.screen,children:[t(l,{testID:`${a}-key`,accessibilityLabel:o.key}),r(Y,{testID:`${a}-scroll`,style:e.scroll,contentContainerStyle:[e.scrollContent,{paddingBottom:24+P}],keyboardShouldPersistTaps:"handled",children:[t(l,{style:e.section,children:r(l,{style:e.editorContainer,children:[r(l,{style:e.sectionHeaderRow,children:[t(n,{testID:`${a}-editor-header`,style:e.sectionHeaderAccentText,children:"Value Editor"}),d?r(m,{onPress:()=>R(true),testID:`${a}-raw`,accessibilityRole:"button",accessibilityLabel:"Edit raw JSON",style:e.rawButton,hitSlop:{top:6,bottom:6,left:6,right:6},children:[t(Z,{size:13,color:i.color.accent}),t(n,{style:e.rawButtonText,children:"Raw"})]}):null]}),r(l,{style:e.sectionBody,children:[t(re,{editable:d,label:"Value",value:u,defaultExpanded:["Value"],writer:J,dataVersion:N,testIDForPath:pe,debounceMs:ue}),d?t(n,{style:e.editorHint,children:"Edits write to the device as you make them \u2014 undo lives in the key's history."}):t(n,{style:e.blockedText,testID:`${a}-edit-blocked`,children:y})]})]})}),t(l,{style:e.section,children:r(l,{style:e.infoContainer,children:[t(n,{style:e.sectionHeaderPlain,children:"Key Details"}),r(l,{style:e.infoBody,children:[r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Status:"}),t(C,{color:I.color,testID:`${a}-status`,children:I.label}),t(n,{style:e.infoDim,children:I.sublabel})]}),r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Storage:"}),t(C,{color:fe(o.storageType),testID:`${a}-backend`,children:A}),t(n,{style:e.infoDim,children:E(o.value)})]}),o.storageType==="mmkv"&&o.instanceId&&r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Instance:"}),t(C,{color:F(o.instanceId),icon:t(K,{size:9,color:F(o.instanceId)}),children:o.instanceId})]}),s!=null&&s>0&&r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Updates:"}),t(C,{color:b.semantic.warning,children:String(s)}),s>1&&L&&t(m,{onPress:L,testID:"buoy-storage-key-history",accessibilityLabel:`View history for ${o.key}`,accessibilityRole:"button",style:e.inlineLinkButton,hitSlop:{top:6,bottom:6,left:6,right:6},children:t(n,{style:e.inlineLinkText,children:"view history \u2192"})})]}),o.status==="required_wrong_type"&&o.expectedType&&r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Expected:"}),t(oe,{type:o.expectedType}),r(n,{style:e.infoDim,children:["got ",E(o.value)]})]}),o.status==="required_wrong_value"&&o.expectedValue&&r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Expected:"}),t(n,{style:e.infoExpected,children:String(o.expectedValue)})]}),o.description?r(l,{style:e.infoRow,children:[t(n,{style:e.infoLabel,children:"Info:"}),t(n,{style:e.infoDescription,children:o.description})]}):null]})]})}),t(l,{style:e.section,children:r(l,{style:e.infoContainer,children:[t(n,{style:e.sectionHeaderPlain,children:"Value Explorer"}),t(l,{style:e.viewerBody,testID:`${a}-viewer`,children:u!==null&&typeof u==="object"?t(ne,{title:"",data:u,showTypeFilter:true,rawMode:true,initialExpanded:false}):t(n,{style:e.rawValueText,selectable:true,children:z??"undefined"})})]})}),U?r(l,{style:e.actionRow,children:[k?r(m,{style:[e.actionChip,x&&e.actionChipActive],testID:"buoy-storage-key-pin",accessibilityLabel:x?`Unpin ${o.key}`:`Pin ${o.key} to top`,accessibilityRole:"button",onPress:()=>k(o.key),hitSlop:{top:6,bottom:6,left:6,right:6},children:[t(ee,{size:12,active:x,color:i.color.accent}),t(n,{style:[e.actionChipText,{color:i.color.accent}],children:x?"Unpin":"Pin to top"})]}):null,D?r(m,{style:e.actionChip,testID:"buoy-storage-key-hide",accessibilityLabel:`Hide ${o.key} from list`,accessibilityRole:"button",onPress:()=>D(o),hitSlop:{top:6,bottom:6,left:6,right:6},children:[t(X,{size:12,color:i.color.warning}),t(n,{style:[e.actionChipText,{color:i.color.warning}],children:"Hide from list"})]}):null,d&&T?r(m,{style:[e.actionChip,e.dangerChip],testID:"buoy-storage-key-delete",accessibilityLabel:`Delete key ${o.key}`,accessibilityRole:"button",onPress:()=>T(o),hitSlop:{top:6,bottom:6,left:6,right:6},children:[t(te,{size:12,color:i.color.danger}),t(n,{style:[e.actionChipText,{color:i.color.danger}],children:"Delete key"})]}):null]}):null]}),_&&d?t(le,{path:[],value:u,onSave:c=>{S(c);j(p=>p+1);R(false)},onCancel:()=>R(false),saveLabel:"Apply",testIDPrefix:"buoy-storage-value"}):null]})}const e=Q.create({screen:{flex:1,minHeight:0},scroll:{flex:1},scrollContent:{paddingHorizontal:8,paddingTop:8},section:{marginBottom:16},editorContainer:{minWidth:200,backgroundColor:i.color.surface,borderRadius:6,borderWidth:1,borderColor:i.color.accent+"4D",overflow:"hidden",shadowColor:i.color.accent,shadowOffset:{width:0,height:0},shadowOpacity:.1,shadowRadius:6},sectionHeaderRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.accent+"1A",paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:i.color.accent+"33"},sectionHeaderAccentText:{fontWeight:"600",fontSize:12,color:i.color.accent,letterSpacing:.5,textTransform:"uppercase",fontFamily:h},rawButton:{flexDirection:"row",alignItems:"center",gap:4},rawButtonText:{color:i.color.accent,fontSize:11,fontWeight:"700"},sectionBody:{padding:8},editorHint:{color:i.color.textTertiary,fontSize:10,paddingTop:8,paddingHorizontal:4,lineHeight:14},blockedText:{color:i.color.textSecondary,fontSize:12,padding:12,lineHeight:18},infoContainer:{minWidth:200,backgroundColor:i.color.surface,borderRadius:6,borderWidth:1,borderColor:i.color.border,overflow:"hidden"},sectionHeaderPlain:{backgroundColor:i.color.surfaceElevated,paddingHorizontal:12,paddingVertical:8,fontWeight:"600",fontSize:12,color:i.color.textSecondary,borderBottomWidth:1,borderBottomColor:i.color.border,letterSpacing:.5,textTransform:"uppercase",fontFamily:h},infoBody:{padding:12,gap:10},infoRow:{flexDirection:"row",alignItems:"center",gap:8},infoLabel:{fontSize:10,color:i.color.textTertiary,fontWeight:"600",minWidth:64,fontFamily:h},infoDim:{color:i.color.textTertiary,fontSize:10,fontFamily:h},infoExpected:{fontSize:11,color:b.semantic.warning,fontFamily:h,flex:1},infoDescription:{fontSize:11,color:i.color.textSecondary,flex:1},rawValueText:{color:i.color.textSecondary,fontSize:11,fontFamily:h,lineHeight:16,padding:12},viewerBody:{backgroundColor:i.color.bg,minHeight:48},inlineLinkButton:{marginLeft:4},inlineLinkText:{fontSize:10,fontWeight:"600",fontFamily:h,color:i.color.accent},actionRow:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",gap:8,paddingHorizontal:4},actionChip:{flexDirection:"row",alignItems:"center",gap:6,paddingVertical:6,paddingHorizontal:10,borderRadius:6,backgroundColor:i.color.surface,borderWidth:1,borderColor:i.color.border},dangerChip:{borderColor:i.color.danger+"55"},actionChipActive:{backgroundColor:i.color.accentSoft,borderColor:i.color.accentBorderStrong},actionChipText:{fontSize:11,fontWeight:"600",fontFamily:h}});