@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,478 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.storageSyncAdapter = exports.VALUE_ON_DEVICE = exports.SNAPSHOT_VALUE_INLINE_LIMIT = exports.SNAPSHOT_EVENTS_BUDGET = void 0;
7
- var _asyncStorage = _interopRequireDefault(require("@react-native-async-storage/async-storage"));
8
- var _sharedUi = require("@buoy-gg/shared-ui");
9
- var _asyncStorageCompat = require("../utils/asyncStorageCompat");
10
- var _storageEventStore = require("../stores/storageEventStore");
11
- var _clearAllStorage = require("../utils/clearAllStorage");
12
- var _storageTimeTravelUtils = require("../utils/storageTimeTravelUtils");
13
- var _MMKVInstanceRegistry = require("../utils/MMKVInstanceRegistry");
14
- var _mmkvTypeDetection = require("../utils/mmkvTypeDetection");
15
- var _SecureStoreRegistry = require("../utils/SecureStoreRegistry");
16
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
- /**
18
- * Sentinel used in WIRE-FORM snapshots in place of oversized values.
19
- * Storage events, MMKV browse dumps, and SecureStore dumps all reuse this
20
- * marker. Dashboards fetch the real payload via `getEventDetail` / `mmkv.get`
21
- * / `secure.get`.
22
- */
23
- const VALUE_ON_DEVICE = exports.VALUE_ON_DEVICE = Object.freeze({
24
- __buoyValueOnDevice: true,
25
- note: "Value stays on the device — fetched on demand via getEventDetail / mmkv.get / secure.get."
26
- });
27
-
28
- /** Max serialized bytes of one storage value on the list snapshot. */
29
- const SNAPSHOT_VALUE_INLINE_LIMIT = exports.SNAPSHOT_VALUE_INLINE_LIMIT = 16 * 1024;
30
-
31
- /**
32
- * Total inline budget for one snapshot's event list, held under the emit
33
- * layer's 2MB so a snapshot is never DROPPED (a drop leaves the whole panel
34
- * stale). Per-value caps alone don't get there: the store keeps 500 events, so
35
- * 500 writes of an individually-legal 9KB value still total ~4.7MB. Newest
36
- * events keep their values inline; once the budget is spent, older ones
37
- * degrade to metadata + fetch-on-demand.
38
- */
39
- const SNAPSHOT_EVENTS_BUDGET = exports.SNAPSHOT_EVENTS_BUDGET = 1.25 * 1024 * 1024;
40
- const MAX_EVENT_DETAIL_BYTES = 8 * 1024 * 1024;
41
- function toWireValue(value) {
42
- if (value === undefined) return value;
43
- return (0, _sharedUi.isOverWireBudget)(value, SNAPSHOT_VALUE_INLINE_LIMIT) ? VALUE_ON_DEVICE : value;
44
- }
45
-
46
- /**
47
- * Apply `map` to every payload field an event carries, preserving object
48
- * identity when nothing changed (the desktop mirror feeds these into effect
49
- * dependencies, so a fresh object per snapshot would re-run them).
50
- *
51
- * The cast is deliberate and load-bearing: the wire form intentionally puts a
52
- * marker OBJECT where the domain type declares a string, because the real
53
- * value stayed on the device. `StorageEvent` describes on-device truth; this
54
- * is its wire projection.
55
- */
56
- function mapEventValues(event, map) {
57
- const data = event.data;
58
- if (!data) return event;
59
- const value = map(data.value);
60
- const prevValue = map(data.prevValue);
61
- const batch = (0, _storageEventStore.batchPairsOf)(event);
62
- const pairs = map(batch.pairs);
63
- const prevPairs = map(batch.prevPairs);
64
- if (value === data.value && prevValue === data.prevValue && pairs === batch.pairs && prevPairs === batch.prevPairs) {
65
- return event;
66
- }
67
- return {
68
- ...event,
69
- data: {
70
- ...data,
71
- value,
72
- prevValue,
73
- // Only AsyncStorage events have these; see batchPairsOf.
74
- ...(event.storageType === "async" ? {
75
- pairs,
76
- prevPairs
77
- } : {})
78
- }
79
- };
80
- }
81
- function capDetailValue(value) {
82
- if (value === undefined) return value;
83
- if (!(0, _sharedUi.isOverWireBudget)(value, MAX_EVENT_DETAIL_BYTES)) return value;
84
- return (0, _sharedUi.isJsonSerializable)(value) ? {
85
- __buoyTruncated: true,
86
- note: `Exceeds the ${MAX_EVENT_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
87
- } : VALUE_ON_DEVICE;
88
- }
89
-
90
- /** One event's wire form plus its measured cost, so the budget pass is free. */
91
-
92
- /**
93
- * Per-event wire cache. The store never mutates an event in place — `addEvent`
94
- * prepends and `hydrateEvent` replaces — so keying on identity is correct and
95
- * self-invalidating. Without it every value is re-measured on all ~5 snapshots
96
- * per second for as long as it stays in the list, which for storage means
97
- * re-walking megabytes of strings per tick.
98
- */
99
- const wireCache = new WeakMap();
100
- const strippedCache = new WeakMap();
101
- function wireFor(event) {
102
- const cached = wireCache.get(event);
103
- if (cached) return cached;
104
- let entry;
105
- try {
106
- const wire = mapEventValues(event, toWireValue);
107
- entry = {
108
- event: wire,
109
- bytes: (0, _sharedUi.approxJsonSize)(wire, SNAPSHOT_EVENTS_BUDGET).bytes
110
- };
111
- } catch {
112
- // A hostile getter can blow up the walk itself. Degrading this ONE event
113
- // beats letting getSnapshot throw and taking the whole panel with it.
114
- const wire = mapEventValues(event, () => VALUE_ON_DEVICE);
115
- entry = {
116
- event: wire,
117
- bytes: 1024
118
- };
119
- }
120
- wireCache.set(event, entry);
121
- return entry;
122
- }
123
-
124
- /** Metadata-only form for the tail of the list once the budget is spent. */
125
- function strippedFor(event) {
126
- const cached = strippedCache.get(event);
127
- if (cached) return cached;
128
- const wire = mapEventValues(event, v => v === undefined ? undefined : VALUE_ON_DEVICE);
129
- const entry = {
130
- event: wire,
131
- bytes: (0, _sharedUi.approxJsonSize)(wire, SNAPSHOT_EVENTS_BUDGET).bytes
132
- };
133
- strippedCache.set(event, entry);
134
- return entry;
135
- }
136
-
137
- /**
138
- * Spend the snapshot budget newest-first. The store keeps events newest-first,
139
- * so the developer keeps full detail on what they are actually looking at and
140
- * the tail degrades rather than the whole panel being dropped.
141
- */
142
- function fitEventsToBudget(events) {
143
- const out = new Array(events.length);
144
- let spent = 0;
145
- for (let i = 0; i < events.length; i++) {
146
- const full = wireFor(events[i]);
147
- if (spent + full.bytes <= SNAPSHOT_EVENTS_BUDGET) {
148
- out[i] = full.event;
149
- spent += full.bytes;
150
- } else {
151
- const lean = strippedFor(events[i]);
152
- out[i] = lean.event;
153
- spent += lean.bytes;
154
- }
155
- }
156
- return out;
157
- }
158
-
159
- /** One MMKV entry in a `mmkv.snapshot` result. */
160
-
161
- /** One MMKV instance in a `mmkv.snapshot` result. */
162
-
163
- /** One registered key in a `secure.snapshot` result. */
164
-
165
- /**
166
- * Resolve an MMKV instance for WRITING, refusing the ones the app registered
167
- * read-only.
168
- *
169
- * The registry has always tracked `readOnly`, but nothing enforced it: any sync
170
- * client — dashboard or MCP — could write to an instance the app explicitly
171
- * declared immutable. That was harmless while the tool could only read; it
172
- * stops being harmless the moment there's an edit UI pointed at it.
173
- */
174
- function assertMMKVWritable(instanceId) {
175
- const registered = _MMKVInstanceRegistry.mmkvInstanceRegistry.get(instanceId);
176
- if (!registered) {
177
- throw new Error(`No MMKV instance registered as "${instanceId}"`);
178
- }
179
- if (registered.instance?.isReadOnly) {
180
- throw new Error(`MMKV instance "${instanceId}" is registered read-only`);
181
- }
182
- return registered.instance;
183
- }
184
-
185
- /**
186
- * Sync adapter for the storage tool, consumed by @buoy-gg/external-sync's
187
- * `useExternalSync` (structurally matches its ToolSyncAdapter interface so
188
- * this package doesn't need a dependency on it).
189
- *
190
- * Subscribing starts the underlying capture lifecycle (including the initial
191
- * key scan), so storage events are only recorded while a dashboard is
192
- * watching.
193
- *
194
- * The `async.*` actions mirror the AsyncStorage API so the desktop dashboard
195
- * can proxy its browse/edit mode against the device's real storage.
196
- *
197
- * v2: oversized / unserializable event values are replaced with
198
- * VALUE_ON_DEVICE. Dashboards fetch them via `getEventDetail`.
199
- */
200
- const storageSyncAdapter = exports.storageSyncAdapter = {
201
- // v3: a total snapshot budget, so a burst of individually-legal values
202
- // degrades the oldest events instead of the emit layer dropping the panel.
203
- version: 3,
204
- // Strip Buoy's OWN devtool keys (@react_buoy*, @buoy*, buoy-*, legacy) at the
205
- // source so no sync client (desktop, MCP, raw socket) ever sees them as if
206
- // they were app data — matching the tools' default key filters, but
207
- // authoritative instead of UI-only.
208
- getSnapshot: () => fitEventsToBudget(_storageEventStore.storageEventStore.getEvents().filter(e => {
209
- const key = e.data?.key;
210
- return !(typeof key === "string" && (0, _sharedUi.isDevToolsStorageKey)(key));
211
- })),
212
- subscribe: onChange => _storageEventStore.storageEventStore.subscribeToEvents(onChange),
213
- actions: {
214
- clearEvents: () => {
215
- _storageEventStore.storageEventStore.clearEvents();
216
- },
217
- /**
218
- * On-demand detail: one event's real value/prevValue/pairs.
219
- * The per-snapshot stream stays payload-light; this is the explicit,
220
- * size-guarded channel for the detail pane (and for time-travel undo,
221
- * which needs `prevValue`).
222
- */
223
- getEventDetail: params => {
224
- const {
225
- id
226
- } = params ?? {};
227
- if (!id) return {
228
- found: false,
229
- reason: "missing id"
230
- };
231
- const event = _storageEventStore.storageEventStore.getEvents().find(e => e.id === id);
232
- if (!event) return {
233
- found: false,
234
- reason: "unknown id"
235
- };
236
- const detailed = mapEventValues(event, capDetailValue);
237
- return {
238
- found: true,
239
- id,
240
- event: detailed
241
- };
242
- },
243
- /** Clears all app storage keys, preserving dev tools settings. */
244
- clearAppStorage: () => (0, _clearAllStorage.clearAllAppStorage)(),
245
- // ── Time travel (same code path as the modal's UNDO / JUMP buttons) ──
246
- // The UI swallows failures silently; these THROW so a caller (desktop, MCP)
247
- // gets the actual reason back instead of a no-op.
248
-
249
- /** Undo one event, addressed by the `id` the store assigned it. */
250
- "timeTravel.undo": async params => {
251
- const id = params?.id;
252
- if (!id) throw new Error("timeTravel.undo requires an event `id`");
253
- const event = _storageEventStore.storageEventStore.getEvents().find(e => e.id === id);
254
- if (!event) throw new Error(`No storage event with id "${id}"`);
255
- if (event.storageType === "mmkv") {
256
- throw new Error("Time travel supports AsyncStorage events only");
257
- }
258
- const asyncEvent = event;
259
- if (!(0, _storageTimeTravelUtils.canUndo)(asyncEvent)) {
260
- throw new Error(`Event "${id}" (${asyncEvent.action}) has no previous value captured, so it cannot be undone`);
261
- }
262
- await (0, _storageTimeTravelUtils.undoOperation)(asyncEvent);
263
- return {
264
- undone: true,
265
- action: asyncEvent.action,
266
- key: asyncEvent.data?.key
267
- };
268
- },
269
- /**
270
- * Jump storage back to the state as of one event. `scope: "key"` (default)
271
- * replays only that key's history, matching the modal's JUMP button;
272
- * `scope: "all"` replays every captured AsyncStorage event.
273
- */
274
- "timeTravel.jump": async params => {
275
- const {
276
- id,
277
- scope = "key"
278
- } = params ?? {};
279
- if (!id) throw new Error("timeTravel.jump requires an event `id`");
280
-
281
- // Oldest-first, which is the order jumpToState replays in.
282
- const all = _storageEventStore.storageEventStore.getEvents().filter(e => e.storageType !== "mmkv").slice().reverse();
283
- const target = all.find(e => e.id === id);
284
- if (!target) throw new Error(`No AsyncStorage event with id "${id}"`);
285
- const timeline = scope === "all" ? all : all.filter(e => e.data?.key === target.data?.key);
286
- const index = timeline.findIndex(e => e.id === id);
287
- if (index === -1) throw new Error(`Event "${id}" is not in the timeline`);
288
- await (0, _storageTimeTravelUtils.jumpToState)(timeline, index);
289
- return {
290
- jumped: true,
291
- scope,
292
- replayed: index + 1,
293
- of: timeline.length,
294
- key: target.data?.key
295
- };
296
- },
297
- // ── Remote AsyncStorage proxy (desktop browse/edit mode) ──
298
- // Single-item methods share the same signature across async-storage v2/v3;
299
- // batch methods go through the compat helpers (which translate to v3's
300
- // getMany/setMany/removeMany) and keep the v2 tuple/pairs shape on the wire.
301
- // Read paths filter out Buoy's own devtool keys so they're never exposed.
302
- "async.getAllKeys": async () => (await _asyncStorage.default.getAllKeys()).filter(k => !(0, _sharedUi.isDevToolsStorageKey)(k)),
303
- "async.multiGet": async params => (await (0, _asyncStorageCompat.readMany)(params.keys)).filter(([k]) => !(0, _sharedUi.isDevToolsStorageKey)(k)),
304
- "async.getItem": params => {
305
- const {
306
- key
307
- } = params;
308
- return (0, _sharedUi.isDevToolsStorageKey)(key) ? Promise.resolve(null) : _asyncStorage.default.getItem(key);
309
- },
310
- "async.setItem": params => {
311
- const {
312
- key,
313
- value
314
- } = params;
315
- return _asyncStorage.default.setItem(key, value);
316
- },
317
- "async.removeItem": params => _asyncStorage.default.removeItem(params.key),
318
- "async.multiRemove": params => (0, _asyncStorageCompat.removeMany)(params.keys),
319
- "async.multiSet": params => (0, _asyncStorageCompat.writeMany)(params.pairs),
320
- "async.clear": () => _asyncStorage.default.clear(),
321
- // ── Remote MMKV proxy (desktop browse mode + MCP) ──
322
- // MMKV has no remote presence off-device; these read/write the registered
323
- // instances so sync clients can browse them like AsyncStorage.
324
- "mmkv.snapshot": () => _MMKVInstanceRegistry.mmkvInstanceRegistry.getAll().map(({
325
- id,
326
- instance,
327
- encrypted,
328
- readOnly
329
- }) => {
330
- let entries = [];
331
- try {
332
- entries = instance.getAllKeys().filter(key => !(0, _sharedUi.isDevToolsStorageKey)(key)).map(key => {
333
- const {
334
- value,
335
- type: valueType
336
- } = (0, _mmkvTypeDetection.detectMMKVType)(instance, key);
337
- return {
338
- key,
339
- value: toWireValue(value),
340
- valueType
341
- };
342
- });
343
- } catch {
344
- // Instance unreadable — return it with no entries rather than failing
345
- }
346
- return {
347
- id,
348
- encrypted,
349
- readOnly,
350
- entries
351
- };
352
- }),
353
- /**
354
- * On-demand MMKV value. `mmkv.snapshot` omits oversized strings so a
355
- * browse poll cannot blow the action-result budget; this is the
356
- * size-guarded channel for one key.
357
- */
358
- "mmkv.get": params => {
359
- const {
360
- instanceId,
361
- key
362
- } = params ?? {};
363
- if (!instanceId || !key) {
364
- return {
365
- found: false,
366
- reason: "missing instanceId/key"
367
- };
368
- }
369
- const registered = _MMKVInstanceRegistry.mmkvInstanceRegistry.get(instanceId);
370
- if (!registered) {
371
- return {
372
- found: false,
373
- reason: "unknown instance"
374
- };
375
- }
376
- const {
377
- value,
378
- type: valueType
379
- } = (0, _mmkvTypeDetection.detectMMKVType)(registered.instance, key);
380
- return {
381
- found: true,
382
- instanceId,
383
- key,
384
- value: capDetailValue(value),
385
- valueType
386
- };
387
- },
388
- "mmkv.set": params => {
389
- const {
390
- instanceId,
391
- key,
392
- value
393
- } = params;
394
- assertMMKVWritable(instanceId).set(key, value);
395
- },
396
- "mmkv.remove": params => {
397
- const {
398
- instanceId,
399
- key
400
- } = params;
401
- const instance = assertMMKVWritable(instanceId);
402
- // v4 renamed delete() to remove() — support both
403
- if (instance.remove) instance.remove(key);else instance.delete?.(key);
404
- },
405
- // ── Remote SecureStore proxy ──
406
- // Only registered keys are known (SecureStore has no enumeration API).
407
- // Biometric-protected keys are never read — reads would fire an auth prompt.
408
- "secure.keys": () => _SecureStoreRegistry.secureStoreRegistry.getAll().map(({
409
- key,
410
- options,
411
- description
412
- }) => ({
413
- key,
414
- description,
415
- keychainService: options.keychainService,
416
- requireAuthentication: options.requireAuthentication ?? false
417
- })),
418
- /**
419
- * Every registered key WITH its value, in one round trip — the SecureStore
420
- * counterpart to `mmkv.snapshot`. The dashboard polls this (the keychain
421
- * has no change feed) and serves the browser from the result, instead of
422
- * firing one `secure.get` per key per refresh.
423
- */
424
- "secure.snapshot": async () => {
425
- const module = _SecureStoreRegistry.secureStoreRegistry.getModule();
426
- const entries = _SecureStoreRegistry.secureStoreRegistry.getAll();
427
- const result = [];
428
- for (const {
429
- key,
430
- options,
431
- description
432
- } of entries) {
433
- let value = null;
434
- // Biometric-protected keys are never read — that would fire an auth prompt.
435
- if (module && !options.requireAuthentication) {
436
- try {
437
- value = await module.getItemAsync(key, options);
438
- } catch {
439
- // Unreadable (e.g. keychain state changed) — report as unset
440
- }
441
- }
442
- result.push({
443
- key,
444
- description,
445
- keychainService: options.keychainService,
446
- requireAuthentication: options.requireAuthentication ?? false,
447
- value: value == null ? value : toWireValue(value)
448
- });
449
- }
450
- return result;
451
- },
452
- "secure.get": params => {
453
- const {
454
- key
455
- } = params;
456
- const entry = _SecureStoreRegistry.secureStoreRegistry.getAll().find(e => e.key === key);
457
- const module = _SecureStoreRegistry.secureStoreRegistry.getModule();
458
- if (!entry || !module || entry.options.requireAuthentication) {
459
- return Promise.resolve(null);
460
- }
461
- return module.getItemAsync(key, entry.options);
462
- },
463
- /**
464
- * Write a registered SecureStore key. Goes through the registry so the
465
- * value is written with the SAME options it was registered with — writing
466
- * with different `keychainService` options creates a second entry the app
467
- * can't read. Biometric-protected keys throw rather than prompting.
468
- */
469
- "secure.set": params => {
470
- const {
471
- key,
472
- value
473
- } = params;
474
- return _SecureStoreRegistry.secureStoreRegistry.setValue(key, value);
475
- },
476
- "secure.delete": params => _SecureStoreRegistry.secureStoreRegistry.deleteValue(params.key)
477
- }
478
- };
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.VALUE_ON_DEVICE=exports.SNAPSHOT_VALUE_INLINE_LIMIT=exports.SNAPSHOT_EVENTS_BUDGET=void 0;exports.setToolRequiredStorageKeys=setToolRequiredStorageKeys;exports.storageSyncAdapter=void 0;var _asyncStorage=_interopRequireDefault(require("@react-native-async-storage/async-storage"));var _sharedUi=require("@buoy-gg/shared-ui");var _asyncStorageCompat=require("../utils/asyncStorageCompat");var _storageEventStore=require("../stores/storageEventStore");var _clearAllStorage=require("../utils/clearAllStorage");var _storageTimeTravelUtils=require("../utils/storageTimeTravelUtils");var _MMKVInstanceRegistry=require("../utils/MMKVInstanceRegistry");var _mmkvTypeDetection=require("../utils/mmkvTypeDetection");var _SecureStoreRegistry=require("../utils/SecureStoreRegistry");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const VALUE_ON_DEVICE=exports.VALUE_ON_DEVICE=Object.freeze({__buoyValueOnDevice:true,note:"Value stays on the device \u2014 fetched on demand via getEventDetail / mmkv.get / secure.get."});const SNAPSHOT_VALUE_INLINE_LIMIT=exports.SNAPSHOT_VALUE_INLINE_LIMIT=16*1024;const SNAPSHOT_EVENTS_BUDGET=exports.SNAPSHOT_EVENTS_BUDGET=1.25*1024*1024;const MAX_EVENT_DETAIL_BYTES=8*1024*1024;function toWireValue(e){if(e===void 0)return e;return(0,_sharedUi.isOverWireBudget)(e,SNAPSHOT_VALUE_INLINE_LIMIT)?VALUE_ON_DEVICE:e}function mapEventValues(e,t){const r=e.data;if(!r)return e;const n=t(r.value);const s=t(r.prevValue);const o=(0,_storageEventStore.batchPairsOf)(e);const i=t(o.pairs);const a=t(o.prevPairs);if(n===r.value&&s===r.prevValue&&i===o.pairs&&a===o.prevPairs){return e}return{...e,data:{...r,value:n,prevValue:s,...e.storageType==="async"?{pairs:i,prevPairs:a}:{}}}}function capDetailValue(e){if(e===void 0)return e;if(!(0,_sharedUi.isOverWireBudget)(e,MAX_EVENT_DETAIL_BYTES))return e;return(0,_sharedUi.isJsonSerializable)(e)?{__buoyTruncated:true,note:`Exceeds the ${MAX_EVENT_DETAIL_BYTES/(1024*1024)}MB detail limit \u2014 inspect it on-device.`}:VALUE_ON_DEVICE}const wireCache=new WeakMap;const strippedCache=new WeakMap;function wireFor(e){const t=wireCache.get(e);if(t)return t;let r;try{const n=mapEventValues(e,toWireValue);r={event:n,bytes:(0,_sharedUi.approxJsonSize)(n,SNAPSHOT_EVENTS_BUDGET).bytes}}catch{const n=mapEventValues(e,()=>VALUE_ON_DEVICE);r={event:n,bytes:1024}}wireCache.set(e,r);return r}function strippedFor(e){const t=strippedCache.get(e);if(t)return t;const r=mapEventValues(e,s=>s===void 0?void 0:VALUE_ON_DEVICE);const n={event:r,bytes:(0,_sharedUi.approxJsonSize)(r,SNAPSHOT_EVENTS_BUDGET).bytes};strippedCache.set(e,n);return n}function fitEventsToBudget(e){const t=new Array(e.length);let r=0;for(let n=0;n<e.length;n++){const s=wireFor(e[n]);if(r+s.bytes<=SNAPSHOT_EVENTS_BUDGET){t[n]=s.event;r+=s.bytes}else{const o=strippedFor(e[n]);t[n]=o.event;r+=o.bytes}}return t}function assertMMKVWritable(e){const t=_MMKVInstanceRegistry.mmkvInstanceRegistry.get(e);if(!t){throw new Error(`No MMKV instance registered as "${e}"`)}if(t.instance?.isReadOnly){throw new Error(`MMKV instance "${e}" is registered read-only`)}return t.instance}let toolRequiredStorageKeys=[];function setToolRequiredStorageKeys(e){toolRequiredStorageKeys=e}const storageSyncAdapter=exports.storageSyncAdapter={version:3,getSnapshot:()=>fitEventsToBudget(_storageEventStore.storageEventStore.getEvents().filter(e=>{const t=e.data?.key;return!(typeof t==="string"&&(0,_sharedUi.isDevToolsStorageKey)(t))})),subscribe:e=>_storageEventStore.storageEventStore.subscribeToEvents(e),actions:{clearEvents:()=>{_storageEventStore.storageEventStore.clearEvents()},getRequiredKeys:()=>toolRequiredStorageKeys,getEventDetail:e=>{const{id:t}=e??{};if(!t)return{found:false,reason:"missing id"};const r=_storageEventStore.storageEventStore.getEvents().find(s=>s.id===t);if(!r)return{found:false,reason:"unknown id"};const n=mapEventValues(r,capDetailValue);return{found:true,id:t,event:n}},clearAppStorage:()=>(0,_clearAllStorage.clearAllAppStorage)(),"timeTravel.undo":async e=>{const t=e?.id;if(!t)throw new Error("timeTravel.undo requires an event `id`");const r=_storageEventStore.storageEventStore.getEvents().find(s=>s.id===t);if(!r)throw new Error(`No storage event with id "${t}"`);if(r.storageType==="mmkv"){throw new Error("Time travel supports AsyncStorage events only")}const n=r;if(!(0,_storageTimeTravelUtils.canUndo)(n)){throw new Error(`Event "${t}" (${n.action}) has no previous value captured, so it cannot be undone`)}await(0,_storageTimeTravelUtils.undoOperation)(n);return{undone:true,action:n.action,key:n.data?.key}},"timeTravel.jump":async e=>{const{id:t,scope:r="key"}=e??{};if(!t)throw new Error("timeTravel.jump requires an event `id`");const n=_storageEventStore.storageEventStore.getEvents().filter(a=>a.storageType!=="mmkv").slice().reverse();const s=n.find(a=>a.id===t);if(!s)throw new Error(`No AsyncStorage event with id "${t}"`);const o=r==="all"?n:n.filter(a=>a.data?.key===s.data?.key);const i=o.findIndex(a=>a.id===t);if(i===-1)throw new Error(`Event "${t}" is not in the timeline`);await(0,_storageTimeTravelUtils.jumpToState)(o,i);return{jumped:true,scope:r,replayed:i+1,of:o.length,key:s.data?.key}},"async.getAllKeys":async()=>(await _asyncStorage.default.getAllKeys()).filter(e=>!(0,_sharedUi.isDevToolsStorageKey)(e)),"async.multiGet":async e=>(await(0,_asyncStorageCompat.readMany)(e.keys)).filter(([t])=>!(0,_sharedUi.isDevToolsStorageKey)(t)),"async.getItem":e=>{const{key:t}=e;return(0,_sharedUi.isDevToolsStorageKey)(t)?Promise.resolve(null):_asyncStorage.default.getItem(t)},"async.setItem":e=>{const{key:t,value:r}=e;return _asyncStorage.default.setItem(t,r)},"async.removeItem":e=>_asyncStorage.default.removeItem(e.key),"async.multiRemove":e=>(0,_asyncStorageCompat.removeMany)(e.keys),"async.multiSet":e=>(0,_asyncStorageCompat.writeMany)(e.pairs),"async.clear":()=>_asyncStorage.default.clear(),"mmkv.snapshot":()=>_MMKVInstanceRegistry.mmkvInstanceRegistry.getAll().map(({id:e,instance:t,encrypted:r,readOnly:n})=>{let s=[];try{s=t.getAllKeys().filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o)).map(o=>{const{value:i,type:a}=(0,_mmkvTypeDetection.detectMMKVType)(t,o);return{key:o,value:toWireValue(i),valueType:a}})}catch{}return{id:e,encrypted:r,readOnly:n,entries:s}}),"mmkv.get":e=>{const{instanceId:t,key:r}=e??{};if(!t||!r){return{found:false,reason:"missing instanceId/key"}}const n=_MMKVInstanceRegistry.mmkvInstanceRegistry.get(t);if(!n){return{found:false,reason:"unknown instance"}}const{value:s,type:o}=(0,_mmkvTypeDetection.detectMMKVType)(n.instance,r);return{found:true,instanceId:t,key:r,value:capDetailValue(s),valueType:o}},"mmkv.set":e=>{const{instanceId:t,key:r,value:n}=e;assertMMKVWritable(t).set(r,n)},"mmkv.remove":e=>{const{instanceId:t,key:r}=e;const n=assertMMKVWritable(t);if(n.remove)n.remove(r);else n.delete?.(r)},"secure.keys":()=>_SecureStoreRegistry.secureStoreRegistry.getAll().map(({key:e,options:t,description:r})=>({key:e,description:r,keychainService:t.keychainService,requireAuthentication:t.requireAuthentication??false})),"secure.snapshot":async()=>{const e=_SecureStoreRegistry.secureStoreRegistry.getModule();const t=_SecureStoreRegistry.secureStoreRegistry.getAll();const r=[];for(const{key:n,options:s,description:o}of t){let i=null;if(e&&!s.requireAuthentication){try{i=await e.getItemAsync(n,s)}catch{}}r.push({key:n,description:o,keychainService:s.keychainService,requireAuthentication:s.requireAuthentication??false,value:i==null?i:toWireValue(i)})}return r},"secure.get":e=>{const{key:t}=e;const r=_SecureStoreRegistry.secureStoreRegistry.getAll().find(s=>s.key===t);const n=_SecureStoreRegistry.secureStoreRegistry.getModule();if(!r||!n||r.options.requireAuthentication){return Promise.resolve(null)}return n.getItemAsync(t,r.options)},"secure.set":e=>{const{key:t,value:r}=e;return _SecureStoreRegistry.secureStoreRegistry.setValue(t,r)},"secure.delete":e=>_SecureStoreRegistry.secureStoreRegistry.deleteValue(e.key)}};
@@ -1,5 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});