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