@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,117 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.StorageEventCard = void 0;
7
- exports.getValueType = getValueType;
8
- var _react = require("react");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _storageActionHelpers = require("../utils/storageActionHelpers");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- /**
13
- * StorageEventCard
14
- *
15
- * Shared card component for displaying storage events.
16
- * Used by both Storage DevTools and Events DevTools for consistent UI.
17
- * Uses CompactRow for consistent layout with Redux/React Query cards.
18
- */
19
-
20
- /** Value type for storage events */
21
-
22
- /**
23
- * Compute value type from a value
24
- */
25
- function getValueType(value) {
26
- const parsed = (0, _sharedUi.parseValue)(value);
27
- if (parsed === null) return "null";
28
- if (parsed === undefined) return "undefined";
29
- if (Array.isArray(parsed)) return "array";
30
- if (typeof parsed === "boolean") return "boolean";
31
- if (typeof parsed === "number") return "number";
32
- if (typeof parsed === "string") return "string";
33
- if (typeof parsed === "object") return "object";
34
- return "undefined";
35
- }
36
- /**
37
- * Get color for action type
38
- */
39
- function getActionColor(action) {
40
- switch (action) {
41
- // AsyncStorage & MMKV - Set operations
42
- case "setItem":
43
- case "multiSet":
44
- case "set.string":
45
- case "set.number":
46
- case "set.boolean":
47
- case "set.buffer":
48
- return _sharedUi.macOSColors.semantic.success;
49
-
50
- // AsyncStorage & MMKV - Remove/Delete operations
51
- case "removeItem":
52
- case "multiRemove":
53
- case "clear":
54
- case "delete":
55
- case "clearAll":
56
- return _sharedUi.macOSColors.semantic.error;
57
-
58
- // AsyncStorage - Merge operations
59
- case "mergeItem":
60
- case "multiMerge":
61
- return _sharedUi.macOSColors.semantic.info;
62
-
63
- // MMKV - Get operations
64
- case "get.string":
65
- case "get.number":
66
- case "get.boolean":
67
- case "get.buffer":
68
- return _sharedUi.macOSColors.semantic.warning;
69
- default:
70
- return _sharedUi.macOSColors.text.muted;
71
- }
72
- }
73
-
74
- /**
75
- * Get storage type label for sublabel
76
- */
77
- function getStorageTypeSublabel(storageTypes, totalOps) {
78
- const types = Array.from(storageTypes).map(t => t === "async" ? "Async" : "MMKV").join("/");
79
- return `${types} · ${totalOps} op${totalOps !== 1 ? "s" : ""}`;
80
- }
81
- const StorageEventCard = exports.StorageEventCard = /*#__PURE__*/(0, _react.memo)(function StorageEventCard({
82
- data,
83
- onPress,
84
- isSelected = false,
85
- showChevron = true,
86
- testID
87
- }) {
88
- const actionColor = getActionColor(data.lastAction);
89
- const actionLabel = (0, _storageActionHelpers.translateStorageAction)(data.lastAction);
90
- const totalOps = data.totalOperations ?? 1;
91
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow
92
- // Status section (left) - shows "Storage" with action-colored dot
93
- , {
94
- statusDotColor: actionColor,
95
- statusLabel: "Storage",
96
- statusSublabel: getStorageTypeSublabel(data.storageTypes, totalOps)
97
- // Content section (middle) - shows the key name
98
- ,
99
- primaryText: data.key
100
- // Badge section (right) - shows action label (SET, REMOVE, etc.)
101
- ,
102
- badgeText: actionLabel,
103
- badgeColor: actionColor,
104
- showChevron: showChevron
105
- // Bottom right - timestamp
106
- ,
107
- bottomRightText: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.RelativeTime, {
108
- timestamp: data.lastEventTimestamp
109
- })
110
- // Interaction
111
- ,
112
- isSelected: isSelected,
113
- onPress: onPress,
114
- testID: testID,
115
- accessibilityLabel: `${actionLabel} ${data.key}`
116
- });
117
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.StorageEventCard=void 0;exports.getValueType=getValueType;var _storageLabels=require("../utils/storageLabels");var _react=require("react");var _sharedUi=require("@buoy-gg/shared-ui");var _storageActionHelpers=require("../utils/storageActionHelpers");var _jsxRuntime=require("react/jsx-runtime");function getValueType(t){const e=(0,_sharedUi.parseValue)(t);if(e===null)return"null";if(e===void 0)return"undefined";if(Array.isArray(e))return"array";if(typeof e==="boolean")return"boolean";if(typeof e==="number")return"number";if(typeof e==="string")return"string";if(typeof e==="object")return"object";return"undefined"}function getActionColor(t){switch(t){case"setItem":case"multiSet":case"set.string":case"set.number":case"set.boolean":case"set.buffer":return _sharedUi.macOSColors.semantic.success;case"removeItem":case"multiRemove":case"clear":case"delete":case"clearAll":return _sharedUi.macOSColors.semantic.error;case"mergeItem":case"multiMerge":return _sharedUi.macOSColors.semantic.info;case"get.string":case"get.number":case"get.boolean":case"get.buffer":return _sharedUi.macOSColors.semantic.warning;default:return _sharedUi.macOSColors.text.muted}}function getStorageTypeSublabel(t,e){const r=Array.from(t).map(s=>s==="async"?_storageLabels.storageLabels.async:_storageLabels.storageLabels.mmkv).join("/");return`${r} \xB7 ${e} op${e!==1?"s":""}`}const StorageEventCard=exports.StorageEventCard=(0,_react.memo)(function t({data:e,onPress:r,isSelected:s=false,showChevron:n=true,testID:i}){const a=getActionColor(e.lastAction);const o=(0,_storageActionHelpers.translateStorageAction)(e.lastAction);const c=e.totalOperations??1;return(0,_jsxRuntime.jsx)(_sharedUi.CompactRow,{statusDotColor:a,statusLabel:"Storage",statusSublabel:getStorageTypeSublabel(e.storageTypes,c),primaryText:e.key,badgeText:o,badgeColor:a,showChevron:n,bottomRightText:(0,_jsxRuntime.jsx)(_sharedUi.RelativeTime,{timestamp:e.lastEventTimestamp}),isSelected:s,onPress:r,testID:i,accessibilityLabel:`${o} ${e.key}`})});
@@ -1,494 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.StorageEventDetailContent = StorageEventDetailContent;
7
- exports.StorageEventDetailFooter = StorageEventDetailFooter;
8
- var _reactNative = require("react-native");
9
- var _react = require("react");
10
- var _asyncStorage = _interopRequireDefault(require("@react-native-async-storage/async-storage"));
11
- var _sharedUi = require("@buoy-gg/shared-ui");
12
- var _license = require("@buoy-gg/license");
13
- var _lineDiff = require("../utils/lineDiff");
14
- var _ThemedSplitView = require("./DiffViewer/modes/ThemedSplitView");
15
- var _diffThemes = require("./DiffViewer/themes/diffThemes");
16
- var _TreeDiffViewer = require("./DiffViewer/TreeDiffViewer");
17
- var _storageActionHelpers = require("../utils/storageActionHelpers");
18
- var _StorageEventActionButton = require("./StorageEventActionButton");
19
- var _storageTimeTravelUtils = require("../utils/storageTimeTravelUtils");
20
- var _jsxRuntime = require("react/jsx-runtime");
21
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
- /**
23
- * StorageEventDetailContent
24
- *
25
- * Detail view for storage events using the shared EventHistoryViewer component.
26
- */
27
-
28
- /**
29
- * Compare-bar index for "the state before the oldest event".
30
- *
31
- * Not an event — it's reconstructed from that event's own `prevValue`, which
32
- * every write records. Without it a key's first event had nothing to diff
33
- * against and both panes showed the same value.
34
- */const ORIGIN_INDEX = -1;
35
-
36
- /** Compare-bar copy for each origin state. Kept in sync with the Flutter port. */
37
- const ORIGIN_LABELS = {
38
- prior: {
39
- label: "BEFORE #1",
40
- timestamp: "value before first event",
41
- relativeTime: "not captured",
42
- badge: "PRIOR"
43
- },
44
- absent: {
45
- label: "NO PRIOR VALUE",
46
- timestamp: "key did not exist",
47
- relativeTime: "created here",
48
- badge: "ABSENT"
49
- },
50
- scanned: {
51
- label: "ALREADY PRESENT",
52
- timestamp: "value found at startup",
53
- relativeTime: "not a write",
54
- badge: "SCANNED"
55
- }
56
- };
57
-
58
- // Unified storage event type (supports both AsyncStorage and MMKV)
59
-
60
- /**
61
- * Get color for storage action
62
- */
63
- function getActionColor(action) {
64
- switch (action) {
65
- case "setItem":
66
- case "multiSet":
67
- return _sharedUi.macOSColors.semantic.success;
68
- case "removeItem":
69
- case "multiRemove":
70
- case "clear":
71
- return _sharedUi.macOSColors.semantic.error;
72
- case "mergeItem":
73
- case "multiMerge":
74
- return _sharedUi.macOSColors.semantic.info;
75
- default:
76
- return _sharedUi.macOSColors.text.muted;
77
- }
78
- }
79
-
80
- /**
81
- * Get the type of a value
82
- */
83
- function getValueType(value) {
84
- if (value === null) return "null";
85
- if (value === undefined) return "undefined";
86
- if (Array.isArray(value)) return "array";
87
- return typeof value;
88
- }
89
-
90
- /**
91
- * Format timestamp with milliseconds
92
- */
93
- function formatTimeWithMs(date) {
94
- const h = String(date.getHours()).padStart(2, "0");
95
- const m = String(date.getMinutes()).padStart(2, "0");
96
- const s = String(date.getSeconds()).padStart(2, "0");
97
- const ms = String(date.getMilliseconds()).padStart(3, "0");
98
- return `${h}:${m}:${s}.${ms}`;
99
- }
100
- const SPLIT_VIEW_OPTIONS = {
101
- hideLineNumbers: false,
102
- disableWordDiff: false,
103
- showDiffOnly: false,
104
- compareMethod: "words",
105
- contextLines: 3,
106
- lineOffset: 0
107
- };
108
- const SPLIT_VIEW_DIFFERENCES = [];
109
- function StorageEventDetailContent({
110
- conversation,
111
- selectedEventIndex = 0,
112
- onEventIndexChange = () => {},
113
- disableInternalFooter = false
114
- }) {
115
- // Pro feature gating
116
- const isPro = (0, _license.useIsPro)();
117
- const [showProModal, setShowProModal] = (0, _react.useState)(false);
118
-
119
- // There is only the diff view now. The current stored value is what the Keys
120
- // table shows — repeating it behind a toggle here meant two places to look for
121
- // one fact, and the toggle was the first thing between you and the diff you
122
- // opened this screen for.
123
- const [diffMode, setDiffMode] = (0, _react.useState)("split");
124
-
125
- // Compare indices for diff view
126
- // Matches what the sync effect below computes, so the first frame doesn't
127
- // briefly pair the oldest event with itself.
128
- const [leftIndex, setLeftIndex] = (0, _react.useState)(Math.max(ORIGIN_INDEX, selectedEventIndex - 1));
129
- const [rightIndex, setRightIndex] = (0, _react.useState)(selectedEventIndex);
130
-
131
- // Track if preferences have been loaded
132
- const hasLoadedPreferences = (0, _react.useRef)(false);
133
-
134
- // Get sorted events
135
- const navigationItems = (0, _react.useMemo)(() => conversation.events.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime()), [conversation.events]);
136
- const totalEvents = navigationItems.length;
137
-
138
- // Load saved preferences on mount
139
- (0, _react.useEffect)(() => {
140
- if (hasLoadedPreferences.current) return;
141
- const loadPreferences = async () => {
142
- try {
143
- const savedDiffMode = await _asyncStorage.default.getItem(_sharedUi.devToolsStorageKeys.storage.diffViewerMode());
144
- if (savedDiffMode === "split" || savedDiffMode === "tree") {
145
- setDiffMode(savedDiffMode);
146
- }
147
- hasLoadedPreferences.current = true;
148
- } catch {
149
- // Failed to load preferences
150
- }
151
- };
152
- loadPreferences();
153
- }, []);
154
-
155
- // Keep compare indices synced to selection. Left may land on ORIGIN_INDEX,
156
- // which is not an event — it's the state the oldest event overwrote.
157
- (0, _react.useEffect)(() => {
158
- const newRight = Math.min(totalEvents - 1, Math.max(0, selectedEventIndex));
159
- const newLeft = Math.max(ORIGIN_INDEX, Math.min(newRight - 1, selectedEventIndex - 1));
160
- setLeftIndex(newLeft);
161
- setRightIndex(newRight);
162
- }, [selectedEventIndex, totalEvents]);
163
-
164
- // Save diff mode preference when changed
165
- const handleDiffModeChange = (0, _react.useCallback)(async mode => {
166
- setDiffMode(mode);
167
- try {
168
- await _asyncStorage.default.setItem(_sharedUi.devToolsStorageKeys.storage.diffViewerMode(), mode);
169
- } catch {
170
- // Failed to save preference
171
- }
172
- }, []);
173
-
174
- // Get current event
175
- const selectedEvent = navigationItems[selectedEventIndex];
176
- const action = selectedEvent?.action;
177
- // Compute type from the parsed value so it matches what we actually render
178
-
179
- // Get events for diff comparison. leftIndex === ORIGIN_INDEX means "the state
180
- // before the oldest event", which has no event object of its own.
181
- const isOriginLeft = leftIndex === ORIGIN_INDEX;
182
- const leftEvent = isOriginLeft ? undefined : navigationItems[Math.max(0, Math.min(totalEvents - 1, leftIndex))];
183
- const rightEvent = navigationItems[Math.max(0, Math.min(totalEvents - 1, rightIndex))];
184
-
185
- // Every write records the value it overwrote (for time travel), so even the
186
- // very first event can be diffed against what was actually there. Three
187
- // distinct origins, and conflating them would misinform:
188
- // PRIOR — the write replaced a real value (including `[]`, `""`, `null`)
189
- // ABSENT — the write created the key; there was nothing before it
190
- // SCANNED — not a write at all, just the startup snapshot of a key that
191
- // already existed, so nothing changed at this event
192
- const originKind = (0, _react.useMemo)(() => {
193
- const data = rightEvent?.data;
194
- if (data?.initialScan) return "scanned";
195
- return data?.prevValue === null || data?.prevValue === undefined ? "absent" : "prior";
196
- }, [rightEvent]);
197
- const originValue = (0, _react.useMemo)(() => {
198
- if (originKind === "absent") return _lineDiff.ABSENT_VALUE;
199
- // A scanned key was already holding the event's own value, so diffing
200
- // against it correctly reports no change.
201
- if (originKind === "scanned") return (0, _sharedUi.parseValue)(rightEvent?.data?.value);
202
- return (0, _sharedUi.parseValue)(rightEvent?.data?.prevValue);
203
- }, [originKind, rightEvent]);
204
-
205
- // Create event display info for compare bar
206
- const leftEventInfo = (0, _react.useMemo)(() => isOriginLeft ? {
207
- index: ORIGIN_INDEX,
208
- label: ORIGIN_LABELS[originKind].label,
209
- timestamp: ORIGIN_LABELS[originKind].timestamp,
210
- relativeTime: ORIGIN_LABELS[originKind].relativeTime,
211
- badge: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
212
- style: [styles.actionBadgeSmall, {
213
- backgroundColor: `${_sharedUi.night.color.textTertiary}20`
214
- }],
215
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
216
- style: [styles.actionTextSmall, {
217
- color: _sharedUi.night.color.textTertiary
218
- }],
219
- children: ORIGIN_LABELS[originKind].badge
220
- })
221
- })
222
- } : {
223
- index: leftIndex,
224
- label: `#${leftIndex + 1} / ${totalEvents}`,
225
- timestamp: leftEvent ? formatTimeWithMs(leftEvent.timestamp) : "",
226
- relativeTime: leftEvent ? (0, _sharedUi.formatRelativeTime)(leftEvent.timestamp) : "",
227
- badge: leftEvent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
228
- style: [styles.actionBadgeSmall, {
229
- backgroundColor: `${getActionColor(leftEvent.action)}20`
230
- }],
231
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
232
- style: [styles.actionTextSmall, {
233
- color: getActionColor(leftEvent.action)
234
- }],
235
- children: (0, _storageActionHelpers.translateStorageAction)(leftEvent.action)
236
- })
237
- }) : undefined
238
- }, [leftIndex, leftEvent, totalEvents, isOriginLeft, originKind]);
239
- const rightEventInfo = (0, _react.useMemo)(() => ({
240
- index: rightIndex,
241
- label: `#${rightIndex + 1} / ${totalEvents}`,
242
- timestamp: rightEvent ? formatTimeWithMs(rightEvent.timestamp) : "",
243
- relativeTime: rightEvent ? (0, _sharedUi.formatRelativeTime)(rightEvent.timestamp) : "",
244
- badge: rightEvent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
245
- style: [styles.actionBadgeSmall, {
246
- backgroundColor: `${getActionColor(rightEvent.action)}20`
247
- }],
248
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
249
- style: [styles.actionTextSmall, {
250
- color: getActionColor(rightEvent.action)
251
- }],
252
- children: (0, _storageActionHelpers.translateStorageAction)(rightEvent.action)
253
- })
254
- }) : undefined
255
- }), [rightIndex, rightEvent, totalEvents]);
256
-
257
- // Diff mode tabs
258
- const diffModeTabs = (0, _react.useMemo)(() => [{
259
- key: "tree",
260
- label: "TREE VIEW"
261
- }, {
262
- key: "split",
263
- label: "SPLIT VIEW"
264
- }], []);
265
-
266
- // Navigation handlers for compare bar
267
- const handleLeftPrevious = (0, _react.useCallback)(() => {
268
- // Stops at ORIGIN_INDEX — one step past event #1 is the state it overwrote.
269
- if (leftIndex > ORIGIN_INDEX) {
270
- setLeftIndex(leftIndex - 1);
271
- }
272
- }, [leftIndex]);
273
- const handleLeftNext = (0, _react.useCallback)(() => {
274
- if (leftIndex < rightIndex - 1) {
275
- setLeftIndex(leftIndex + 1);
276
- }
277
- }, [leftIndex, rightIndex]);
278
- const handleRightPrevious = (0, _react.useCallback)(() => {
279
- if (rightIndex > leftIndex + 1) {
280
- setRightIndex(rightIndex - 1);
281
- }
282
- }, [rightIndex, leftIndex]);
283
- const handleRightNext = (0, _react.useCallback)(() => {
284
- if (rightIndex < totalEvents - 1) {
285
- setRightIndex(rightIndex + 1);
286
- }
287
- }, [rightIndex, totalEvents]);
288
-
289
- // Memoized so the diff viewers don't see new oldValue/newValue refs on every
290
- // re-render. parseValue runs JSON.parse, which would otherwise produce fresh
291
- // object identities every time and force expensive recomputations downstream
292
- // (line diff, tree diff, expansion-state effects, etc.).
293
- const previousValue = (0, _react.useMemo)(() => isOriginLeft ? originValue : (0, _sharedUi.parseValue)(leftEvent?.data?.value ?? null), [isOriginLeft, originValue, leftEvent]);
294
- const currentValue = (0, _react.useMemo)(() => (0, _sharedUi.parseValue)(rightEvent?.data?.value), [rightEvent]);
295
-
296
- // Render diff content
297
- const renderDiffContent = (0, _react.useCallback)(() => {
298
- if (diffMode === "split") {
299
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ThemedSplitView.ThemedSplitView, {
300
- oldValue: previousValue,
301
- newValue: currentValue,
302
- differences: SPLIT_VIEW_DIFFERENCES,
303
- theme: _diffThemes.diffThemes.devToolsDefault,
304
- options: SPLIT_VIEW_OPTIONS,
305
- showThemeName: false,
306
- scrollEnabled: false
307
- });
308
- }
309
-
310
- // Inline: the whole diff section scrolls as one page (see
311
- // `scrollDiffSection` below), so the tree must not scroll itself.
312
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_TreeDiffViewer.TreeDiffViewer, {
313
- oldValue: previousValue,
314
- newValue: currentValue,
315
- scrollEnabled: false
316
- });
317
- }, [previousValue, currentValue, diffMode]);
318
-
319
- // Footer navigation handlers
320
- const handleFooterPrevious = (0, _react.useCallback)(() => {
321
- onEventIndexChange(Math.max(0, selectedEventIndex - 1));
322
- }, [selectedEventIndex, onEventIndexChange]);
323
- const handleFooterNext = (0, _react.useCallback)(() => {
324
- onEventIndexChange(Math.min(totalEvents - 1, selectedEventIndex + 1));
325
- }, [selectedEventIndex, totalEvents, onEventIndexChange]);
326
-
327
- // Time-travel action handlers
328
- const handleUndo = (0, _react.useCallback)(async () => {
329
- if (!isPro) {
330
- setShowProModal(true);
331
- return;
332
- }
333
- if (!selectedEvent || selectedEvent.storageType === "mmkv") return;
334
- try {
335
- await (0, _storageTimeTravelUtils.undoOperation)(selectedEvent);
336
- } catch {
337
- // Silent fail
338
- }
339
- }, [selectedEvent, isPro]);
340
- const handleJump = (0, _react.useCallback)(async () => {
341
- if (!isPro) {
342
- setShowProModal(true);
343
- return;
344
- }
345
- if (!selectedEvent || selectedEvent.storageType === "mmkv") return;
346
- const asyncEvents = navigationItems.filter(e => e.storageType !== "mmkv");
347
- const targetIndex = asyncEvents.findIndex(e => e.timestamp.getTime() === selectedEvent.timestamp.getTime());
348
- if (targetIndex === -1) return;
349
- try {
350
- await (0, _storageTimeTravelUtils.jumpToState)(asyncEvents, targetIndex);
351
- } catch {
352
- // Silent fail
353
- }
354
- }, [selectedEvent, navigationItems, isPro]);
355
- const handleCopy = (0, _react.useCallback)(async () => {
356
- if (!selectedEvent) return;
357
- const eventData = {
358
- action: selectedEvent.action,
359
- timestamp: selectedEvent.timestamp.toISOString(),
360
- data: selectedEvent.data
361
- };
362
- await (0, _sharedUi.copyToClipboard)(eventData);
363
- }, [selectedEvent]);
364
-
365
- // Check if current event supports actions
366
- const isAsyncStorageEvent = selectedEvent?.storageType !== "mmkv";
367
- const canUndoEvent = isAsyncStorageEvent && selectedEvent && (0, _storageTimeTravelUtils.canUndo)(selectedEvent);
368
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
369
- children: [isAsyncStorageEvent && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
370
- style: styles.actionButtonsContainer,
371
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventActionButton.StorageEventActionButton, {
372
- type: "undo",
373
- text: "UNDO",
374
- onPress: handleUndo,
375
- disabled: !canUndoEvent,
376
- locked: !isPro
377
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventActionButton.StorageEventActionButton, {
378
- type: "jump",
379
- text: "JUMP",
380
- onPress: handleJump,
381
- locked: !isPro
382
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StorageEventActionButton.StorageEventActionButton, {
383
- type: "copy",
384
- text: "COPY",
385
- onPress: handleCopy
386
- })]
387
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventHistoryViewer
388
- // Diff only: no `renderCurrentView`, so the viewer drops the toggle
389
- // cards entirely rather than showing a one-option switch.
390
- , {
391
- activeView: "diff",
392
- diffViewLabel: "DIFF VIEW",
393
- diffViewDescription: "Compare changes between versions",
394
- diffViewIcon: _sharedUi.GitBranch
395
- // Diff View
396
- ,
397
- diffModeTabs: diffModeTabs,
398
- activeDiffMode: diffMode,
399
- onDiffModeChange: handleDiffModeChange,
400
- renderDiffContent: renderDiffContent
401
- // Both diff modes render inline now, so the whole section scrolls as
402
- // one page rather than confining the rows to a nested pane.
403
- ,
404
- scrollDiffSection: true
405
- // Compare Bar
406
- ,
407
- leftEvent: leftEventInfo,
408
- rightEvent: rightEventInfo,
409
- showCompareNavigation: true,
410
- onLeftPrevious: handleLeftPrevious,
411
- onLeftNext: handleLeftNext,
412
- onRightPrevious: handleRightPrevious,
413
- onRightNext: handleRightNext,
414
- canLeftPrevious: leftIndex > ORIGIN_INDEX,
415
- canLeftNext: leftIndex < rightIndex - 1,
416
- canRightPrevious: rightIndex > leftIndex + 1,
417
- canRightNext: rightIndex < totalEvents - 1
418
- // Footer
419
- ,
420
- disableInternalFooter: disableInternalFooter,
421
- footerCurrentIndex: selectedEventIndex,
422
- footerTotalItems: totalEvents,
423
- footerItemLabel: "Event",
424
- footerSubtitle: (0, _sharedUi.formatRelativeTime)(selectedEvent?.timestamp),
425
- onFooterPrevious: handleFooterPrevious,
426
- onFooterNext: handleFooterNext
427
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProUpgradeModal, {
428
- visible: showProModal,
429
- onClose: () => setShowProModal(false),
430
- featureName: "Storage Time-Travel"
431
- })]
432
- });
433
- }
434
-
435
- /**
436
- * External footer component for modal use
437
- */
438
- function StorageEventDetailFooter({
439
- conversation,
440
- selectedEventIndex = 0,
441
- onEventIndexChange = () => {},
442
- applySafeAreaInset = true
443
- }) {
444
- const navigationItems = conversation.events.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
445
- const totalEvents = navigationItems.length;
446
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
447
- currentIndex: selectedEventIndex,
448
- totalItems: totalEvents,
449
- onPrevious: () => onEventIndexChange(Math.max(0, selectedEventIndex - 1)),
450
- onNext: () => onEventIndexChange(Math.min(totalEvents - 1, selectedEventIndex + 1)),
451
- itemLabel: "Event",
452
- subtitle: (0, _sharedUi.formatRelativeTime)(navigationItems[selectedEventIndex]?.timestamp),
453
- applySafeAreaInset: applySafeAreaInset
454
- });
455
- }
456
- const styles = _reactNative.StyleSheet.create({
457
- // Action Buttons
458
- actionButtonsContainer: {
459
- flexDirection: "row",
460
- justifyContent: "center",
461
- alignItems: "center",
462
- gap: 8,
463
- paddingHorizontal: 12,
464
- paddingVertical: 10,
465
- backgroundColor: _sharedUi.night.color.surface,
466
- borderBottomWidth: 1,
467
- borderBottomColor: _sharedUi.night.color.border
468
- },
469
- // Content Card
470
- valueBox: {
471
- backgroundColor: _sharedUi.night.color.bg,
472
- borderRadius: 6,
473
- borderWidth: 1,
474
- borderColor: _sharedUi.night.color.border,
475
- padding: 8
476
- },
477
- valueText: {
478
- fontSize: 12,
479
- color: _sharedUi.night.color.text,
480
- fontFamily: _sharedUi.monoFont,
481
- lineHeight: 18
482
- },
483
- // Action badges for compare bar
484
- actionBadgeSmall: {
485
- paddingHorizontal: 6,
486
- paddingVertical: 1,
487
- borderRadius: 3
488
- },
489
- actionTextSmall: {
490
- fontSize: 8,
491
- fontWeight: "700",
492
- fontFamily: _sharedUi.monoFont
493
- }
494
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.StorageEventDetailContent=StorageEventDetailContent;exports.StorageEventDetailFooter=StorageEventDetailFooter;var _reactNative=require("react-native");var _react=require("react");var _asyncStorage=_interopRequireDefault(require("@react-native-async-storage/async-storage"));var _sharedUi=require("@buoy-gg/shared-ui");var _license=require("@buoy-gg/license");var _lineDiff=require("../utils/lineDiff");var _ThemedSplitView=require("./DiffViewer/modes/ThemedSplitView");var _diffThemes=require("./DiffViewer/themes/diffThemes");var _TreeDiffViewer=require("./DiffViewer/TreeDiffViewer");var _storageActionHelpers=require("../utils/storageActionHelpers");var _StorageEventActionButton=require("./StorageEventActionButton");var _storageTimeTravelUtils=require("../utils/storageTimeTravelUtils");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const ORIGIN_INDEX=-1;const ORIGIN_LABELS={prior:{label:"BEFORE #1",timestamp:"value before first event",relativeTime:"not captured",badge:"PRIOR"},absent:{label:"NO PRIOR VALUE",timestamp:"key did not exist",relativeTime:"created here",badge:"ABSENT"},scanned:{label:"ALREADY PRESENT",timestamp:"value found at startup",relativeTime:"not a write",badge:"SCANNED"}};function getActionColor(e){switch(e){case"setItem":case"multiSet":return _sharedUi.macOSColors.semantic.success;case"removeItem":case"multiRemove":case"clear":return _sharedUi.macOSColors.semantic.error;case"mergeItem":case"multiMerge":return _sharedUi.macOSColors.semantic.info;default:return _sharedUi.macOSColors.text.muted}}function getValueType(e){if(e===null)return"null";if(e===void 0)return"undefined";if(Array.isArray(e))return"array";return typeof e}function formatTimeWithMs(e){const t=String(e.getHours()).padStart(2,"0");const f=String(e.getMinutes()).padStart(2,"0");const g=String(e.getSeconds()).padStart(2,"0");const l=String(e.getMilliseconds()).padStart(3,"0");return`${t}:${f}:${g}.${l}`}const SPLIT_VIEW_OPTIONS={hideLineNumbers:false,disableWordDiff:false,showDiffOnly:false,compareMethod:"words",contextLines:3,lineOffset:0};const SPLIT_VIEW_DIFFERENCES=[];function StorageEventDetailContent({conversation:e,selectedEventIndex:t=0,onEventIndexChange:f=()=>{},disableInternalFooter:g=false}){const l=(0,_license.useIsPro)();const[S,h]=(0,_react.useState)(false);const[p,M]=(0,_react.useState)("split");const[o,T]=(0,_react.useState)(Math.max(ORIGIN_INDEX,t-1));const[n,b]=(0,_react.useState)(t);const w=(0,_react.useRef)(false);const d=(0,_react.useMemo)(()=>e.events.sort((r,u)=>r.timestamp.getTime()-u.timestamp.getTime()),[e.events]);const s=d.length;(0,_react.useEffect)(()=>{if(w.current)return;const r=async()=>{try{const u=await _asyncStorage.default.getItem(_sharedUi.devToolsStorageKeys.storage.diffViewerMode());if(u==="split"||u==="tree"){M(u)}w.current=true}catch{}};r()},[]);(0,_react.useEffect)(()=>{const r=Math.min(s-1,Math.max(0,t));const u=Math.max(ORIGIN_INDEX,Math.min(r-1,t-1));T(u);b(r)},[t,s]);const D=(0,_react.useCallback)(async r=>{M(r);try{await _asyncStorage.default.setItem(_sharedUi.devToolsStorageKeys.storage.diffViewerMode(),r)}catch{}},[]);const a=d[t];const $=a?.action;const v=o===ORIGIN_INDEX;const c=v?void 0:d[Math.max(0,Math.min(s-1,o))];const i=d[Math.max(0,Math.min(s-1,n))];const m=(0,_react.useMemo)(()=>{const r=i?.data;if(r?.initialScan)return"scanned";return r?.prevValue===null||r?.prevValue===void 0?"absent":"prior"},[i]);const C=(0,_react.useMemo)(()=>{if(m==="absent")return _lineDiff.ABSENT_VALUE;if(m==="scanned")return(0,_sharedUi.parseValue)(i?.data?.value);return(0,_sharedUi.parseValue)(i?.data?.prevValue)},[m,i]);const P=(0,_react.useMemo)(()=>v?{index:ORIGIN_INDEX,label:ORIGIN_LABELS[m].label,timestamp:ORIGIN_LABELS[m].timestamp,relativeTime:ORIGIN_LABELS[m].relativeTime,badge:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.actionBadgeSmall,{backgroundColor:`${_sharedUi.night.color.textTertiary}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionTextSmall,{color:_sharedUi.night.color.textTertiary}],children:ORIGIN_LABELS[m].badge})})}:{index:o,label:`#${o+1} / ${s}`,timestamp:c?formatTimeWithMs(c.timestamp):"",relativeTime:c?(0,_sharedUi.formatRelativeTime)(c.timestamp):"",badge:c?(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.actionBadgeSmall,{backgroundColor:`${getActionColor(c.action)}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionTextSmall,{color:getActionColor(c.action)}],children:(0,_storageActionHelpers.translateStorageAction)(c.action)})}):void 0},[o,c,s,v,m]);const R=(0,_react.useMemo)(()=>({index:n,label:`#${n+1} / ${s}`,timestamp:i?formatTimeWithMs(i.timestamp):"",relativeTime:i?(0,_sharedUi.formatRelativeTime)(i.timestamp):"",badge:i?(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.actionBadgeSmall,{backgroundColor:`${getActionColor(i.action)}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionTextSmall,{color:getActionColor(i.action)}],children:(0,_storageActionHelpers.translateStorageAction)(i.action)})}):void 0}),[n,i,s]);const I=(0,_react.useMemo)(()=>[{key:"tree",label:"TREE VIEW"},{key:"split",label:"SPLIT VIEW"}],[]);const N=(0,_react.useCallback)(()=>{if(o>ORIGIN_INDEX){T(o-1)}},[o]);const k=(0,_react.useCallback)(()=>{if(o<n-1){T(o+1)}},[o,n]);const _=(0,_react.useCallback)(()=>{if(n>o+1){b(n-1)}},[n,o]);const L=(0,_react.useCallback)(()=>{if(n<s-1){b(n+1)}},[n,s]);const y=(0,_react.useMemo)(()=>v?C:(0,_sharedUi.parseValue)(c?.data?.value??null),[v,C,c]);const x=(0,_react.useMemo)(()=>(0,_sharedUi.parseValue)(i?.data?.value),[i]);const j=(0,_react.useCallback)(()=>{if(p==="split"){return(0,_jsxRuntime.jsx)(_ThemedSplitView.ThemedSplitView,{oldValue:y,newValue:x,differences:SPLIT_VIEW_DIFFERENCES,theme:_diffThemes.diffThemes.devToolsDefault,options:SPLIT_VIEW_OPTIONS,showThemeName:false,scrollEnabled:false})}return(0,_jsxRuntime.jsx)(_TreeDiffViewer.TreeDiffViewer,{oldValue:y,newValue:x,scrollEnabled:false})},[y,x,p]);const A=(0,_react.useCallback)(()=>{f(Math.max(0,t-1))},[t,f]);const O=(0,_react.useCallback)(()=>{f(Math.min(s-1,t+1))},[t,s,f]);const B=(0,_react.useCallback)(async()=>{if(!l){h(true);return}if(!a||a.storageType==="mmkv")return;try{await(0,_storageTimeTravelUtils.undoOperation)(a)}catch{}},[a,l]);const F=(0,_react.useCallback)(async()=>{if(!l){h(true);return}if(!a||a.storageType==="mmkv")return;const r=d.filter(V=>V.storageType!=="mmkv");const u=r.findIndex(V=>V.timestamp.getTime()===a.timestamp.getTime());if(u===-1)return;try{await(0,_storageTimeTravelUtils.jumpToState)(r,u)}catch{}},[a,d,l]);const q=(0,_react.useCallback)(async()=>{if(!a)return;const r={action:a.action,timestamp:a.timestamp.toISOString(),data:a.data};await(0,_sharedUi.copyToClipboard)(r)},[a]);const E=a?.storageType!=="mmkv";const U=E&&a&&(0,_storageTimeTravelUtils.canUndo)(a);return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[E&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionButtonsContainer,children:[(0,_jsxRuntime.jsx)(_StorageEventActionButton.StorageEventActionButton,{type:"undo",text:"UNDO",onPress:B,disabled:!U,locked:!l}),(0,_jsxRuntime.jsx)(_StorageEventActionButton.StorageEventActionButton,{type:"jump",text:"JUMP",onPress:F,locked:!l}),(0,_jsxRuntime.jsx)(_StorageEventActionButton.StorageEventActionButton,{type:"copy",text:"COPY",onPress:q})]}),(0,_jsxRuntime.jsx)(_sharedUi.EventHistoryViewer,{activeView:"diff",diffViewLabel:"DIFF VIEW",diffViewDescription:"Compare changes between versions",diffViewIcon:_sharedUi.GitBranch,diffModeTabs:I,activeDiffMode:p,onDiffModeChange:D,renderDiffContent:j,scrollDiffSection:true,leftEvent:P,rightEvent:R,showCompareNavigation:true,onLeftPrevious:N,onLeftNext:k,onRightPrevious:_,onRightNext:L,canLeftPrevious:o>ORIGIN_INDEX,canLeftNext:o<n-1,canRightPrevious:n>o+1,canRightNext:n<s-1,disableInternalFooter:g,footerCurrentIndex:t,footerTotalItems:s,footerItemLabel:"Event",footerSubtitle:(0,_sharedUi.formatRelativeTime)(a?.timestamp),onFooterPrevious:A,onFooterNext:O}),(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:S,onClose:()=>h(false),featureName:"Storage Time-Travel"})]})}function StorageEventDetailFooter({conversation:e,selectedEventIndex:t=0,onEventIndexChange:f=()=>{},applySafeAreaInset:g=true}){const l=e.events.sort((h,p)=>h.timestamp.getTime()-p.timestamp.getTime());const S=l.length;return(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:t,totalItems:S,onPrevious:()=>f(Math.max(0,t-1)),onNext:()=>f(Math.min(S-1,t+1)),itemLabel:"Event",subtitle:(0,_sharedUi.formatRelativeTime)(l[t]?.timestamp),applySafeAreaInset:g})}const styles=_reactNative.StyleSheet.create({actionButtonsContainer:{flexDirection:"row",justifyContent:"center",alignItems:"center",gap:8,paddingHorizontal:12,paddingVertical:10,backgroundColor:_sharedUi.night.color.surface,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.border},valueBox:{backgroundColor:_sharedUi.night.color.bg,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:8},valueText:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,lineHeight:18},actionBadgeSmall:{paddingHorizontal:6,paddingVertical:1,borderRadius:3},actionTextSmall:{fontSize:8,fontWeight:"700",fontFamily:_sharedUi.monoFont}});