@buoy-gg/storage 7.0.4 → 7.0.5
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.
- package/lib/commonjs/index.js +77 -1
- package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +10 -3
- package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +26 -8
- package/lib/commonjs/storage/components/GameUIStorageBrowser.js +263 -115
- package/lib/commonjs/storage/components/GameUIStorageStats.js +7 -7
- package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -1
- package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -1
- package/lib/commonjs/storage/components/SelectionActionBar.js +2 -36
- package/lib/commonjs/storage/components/StorageActions.js +6 -6
- package/lib/commonjs/storage/components/StorageBrowserMode.js +16 -2
- package/lib/commonjs/storage/components/StorageEventDetailContent.js +106 -149
- package/lib/commonjs/storage/components/StorageEventListener.js +13 -13
- package/lib/commonjs/storage/components/StorageFilterCards.js +13 -135
- package/lib/commonjs/storage/components/StorageKeyCard.js +1 -1
- package/lib/commonjs/storage/components/StorageKeyEditorScreen.js +392 -0
- package/lib/commonjs/storage/components/StorageKeyRow.js +53 -15
- package/lib/commonjs/storage/components/StorageKeySection.js +10 -4
- package/lib/commonjs/storage/components/StorageKeyStats.js +10 -10
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +272 -129
- package/lib/commonjs/storage/components/StorageScalarKeyEditor.js +46 -0
- package/lib/commonjs/storage/components/StorageTypeFilterBar.js +141 -0
- package/lib/commonjs/storage/components/StorageValueEditModal.js +361 -0
- package/lib/commonjs/storage/hooks/useKeyEditor.js +104 -0
- package/lib/commonjs/storage/hooks/useMeasuredWidth.js +74 -0
- package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +70 -15
- package/lib/commonjs/storage/hooks/useTreeDraft.js +107 -0
- package/lib/commonjs/storage/index.js +29 -0
- package/lib/commonjs/storage/stores/storageEventStore.js +4 -2
- package/lib/commonjs/storage/sync/storageSyncAdapter.js +125 -3
- package/lib/commonjs/storage/utils/AsyncStorageListener.js +76 -12
- package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +10 -9
- package/lib/commonjs/storage/utils/MMKVListener.js +40 -4
- package/lib/commonjs/storage/utils/SecureStoreRegistry.js +52 -1
- package/lib/commonjs/storage/utils/deleteStorageKeys.js +53 -0
- package/lib/commonjs/storage/utils/index.js +13 -0
- package/lib/commonjs/storage/utils/lineDiff.js +21 -354
- package/lib/commonjs/storage/utils/setStorageValue.js +218 -0
- package/lib/commonjs/storage/utils/storageBrowserRefresh.js +49 -0
- package/lib/commonjs/storage/utils/storageOps.js +53 -0
- package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +60 -38
- package/lib/commonjs/storage/utils/valueType.js +24 -0
- package/lib/module/index.js +18 -1
- package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +10 -3
- package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +26 -8
- package/lib/module/storage/components/GameUIStorageBrowser.js +266 -118
- package/lib/module/storage/components/GameUIStorageStats.js +7 -7
- package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -1
- package/lib/module/storage/components/MMKVInstanceSelector.js +1 -1
- package/lib/module/storage/components/SelectionActionBar.js +2 -36
- package/lib/module/storage/components/StorageActions.js +7 -7
- package/lib/module/storage/components/StorageBrowserMode.js +16 -2
- package/lib/module/storage/components/StorageEventDetailContent.js +110 -151
- package/lib/module/storage/components/StorageEventListener.js +14 -14
- package/lib/module/storage/components/StorageFilterCards.js +13 -135
- package/lib/module/storage/components/StorageKeyCard.js +1 -1
- package/lib/module/storage/components/StorageKeyEditorScreen.js +388 -0
- package/lib/module/storage/components/StorageKeyRow.js +55 -17
- package/lib/module/storage/components/StorageKeySection.js +11 -5
- package/lib/module/storage/components/StorageKeyStats.js +11 -10
- package/lib/module/storage/components/StorageModalWithTabs.js +272 -130
- package/lib/module/storage/components/StorageScalarKeyEditor.js +42 -0
- package/lib/module/storage/components/StorageTypeFilterBar.js +136 -0
- package/lib/module/storage/components/StorageValueEditModal.js +357 -0
- package/lib/module/storage/hooks/useKeyEditor.js +100 -0
- package/lib/module/storage/hooks/useMeasuredWidth.js +71 -0
- package/lib/module/storage/hooks/useSecureStoreKeys.js +71 -16
- package/lib/module/storage/hooks/useTreeDraft.js +103 -0
- package/lib/module/storage/index.js +3 -0
- package/lib/module/storage/stores/storageEventStore.js +4 -2
- package/lib/module/storage/sync/storageSyncAdapter.js +125 -3
- package/lib/module/storage/utils/AsyncStorageListener.js +76 -12
- package/lib/module/storage/utils/MMKVInstanceRegistry.js +8 -7
- package/lib/module/storage/utils/MMKVListener.js +40 -4
- package/lib/module/storage/utils/SecureStoreRegistry.js +52 -1
- package/lib/module/storage/utils/deleteStorageKeys.js +49 -0
- package/lib/module/storage/utils/index.js +3 -0
- package/lib/module/storage/utils/lineDiff.js +7 -354
- package/lib/module/storage/utils/setStorageValue.js +209 -0
- package/lib/module/storage/utils/storageBrowserRefresh.js +44 -0
- package/lib/module/storage/utils/storageOps.js +46 -0
- package/lib/module/storage/utils/storageTimeTravelUtils.js +61 -40
- package/lib/module/storage/utils/valueType.js +23 -0
- package/lib/typescript/index.d.ts +12 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts +4 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +1 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts +7 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts +27 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -1
- package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts +17 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts +4 -1
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageFilterCards.d.ts +9 -3
- package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts +42 -0
- package/lib/typescript/storage/components/StorageKeyEditorScreen.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts +17 -0
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts +7 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts +28 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts +24 -0
- package/lib/typescript/storage/components/StorageScalarKeyEditor.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts +29 -0
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +1 -0
- package/lib/typescript/storage/components/StorageValueEditModal.d.ts +36 -0
- package/lib/typescript/storage/components/StorageValueEditModal.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useKeyEditor.d.ts +51 -0
- package/lib/typescript/storage/hooks/useKeyEditor.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts +37 -0
- package/lib/typescript/storage/hooks/useMeasuredWidth.d.ts.map +1 -0
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts +8 -1
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +1 -1
- package/lib/typescript/storage/hooks/useTreeDraft.d.ts +67 -0
- package/lib/typescript/storage/hooks/useTreeDraft.d.ts.map +1 -0
- package/lib/typescript/storage/index.d.ts +2 -0
- package/lib/typescript/storage/index.d.ts.map +1 -1
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +41 -0
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts +15 -0
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +1 -1
- package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +1 -1
- package/lib/typescript/storage/utils/MMKVListener.d.ts +7 -0
- package/lib/typescript/storage/utils/MMKVListener.d.ts.map +1 -1
- package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts +20 -0
- package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +1 -1
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts +27 -0
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +1 -0
- package/lib/typescript/storage/utils/index.d.ts +1 -0
- package/lib/typescript/storage/utils/index.d.ts.map +1 -1
- package/lib/typescript/storage/utils/lineDiff.d.ts +7 -31
- package/lib/typescript/storage/utils/lineDiff.d.ts.map +1 -1
- package/lib/typescript/storage/utils/setStorageValue.d.ts +64 -0
- package/lib/typescript/storage/utils/setStorageValue.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts +28 -0
- package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageOps.d.ts +25 -0
- package/lib/typescript/storage/utils/storageOps.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts +15 -5
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +1 -1
- package/lib/typescript/storage/utils/valueType.d.ts +13 -0
- package/lib/typescript/storage/utils/valueType.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -129,6 +129,20 @@ class MMKVListener {
|
|
|
129
129
|
// The native listener (addOnValueChangedListener) is sufficient for monitoring writes
|
|
130
130
|
|
|
131
131
|
let nativeListenerUnsubscribe;
|
|
132
|
+
|
|
133
|
+
// Seed the shadow copy so the FIRST observed write already knows what it
|
|
134
|
+
// replaced. Without this, every key's first event would claim the key never
|
|
135
|
+
// existed even when it was carried over from a previous launch.
|
|
136
|
+
const lastKnownValues = new Map();
|
|
137
|
+
try {
|
|
138
|
+
for (const key of instance.getAllKeys() ?? []) {
|
|
139
|
+
if (this.shouldIgnoreKey(key)) continue;
|
|
140
|
+
lastKnownValues.set(key, (0, _mmkvTypeDetection.detectMMKVType)(instance, key).value);
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
// Key scan unavailable — prevValue is simply absent until each key is
|
|
144
|
+
// written once, which is strictly better than reporting a wrong value.
|
|
145
|
+
}
|
|
132
146
|
if (typeof instance.addOnValueChangedListener === "function") {
|
|
133
147
|
try {
|
|
134
148
|
nativeListenerUnsubscribe = instance.addOnValueChangedListener(key => {
|
|
@@ -141,9 +155,15 @@ class MMKVListener {
|
|
|
141
155
|
type
|
|
142
156
|
} = (0, _mmkvTypeDetection.detectMMKVType)(instance, key);
|
|
143
157
|
|
|
158
|
+
// Read the shadow copy BEFORE overwriting it — this is the value the
|
|
159
|
+
// write replaced. `undefined` means the key did not exist.
|
|
160
|
+
const prevValue = lastKnownValues.get(key);
|
|
161
|
+
|
|
144
162
|
// Determine action: if value is undefined/unknown, it was deleted
|
|
145
163
|
const isDelete = type === "unknown" || value === undefined;
|
|
146
164
|
if (isDelete) {
|
|
165
|
+
lastKnownValues.delete(key);
|
|
166
|
+
|
|
147
167
|
// Key was deleted
|
|
148
168
|
const event = {
|
|
149
169
|
action: "delete",
|
|
@@ -151,11 +171,14 @@ class MMKVListener {
|
|
|
151
171
|
instanceId,
|
|
152
172
|
data: {
|
|
153
173
|
key,
|
|
174
|
+
prevValue,
|
|
154
175
|
success: true
|
|
155
176
|
}
|
|
156
177
|
};
|
|
157
178
|
this.emit(event);
|
|
158
179
|
} else {
|
|
180
|
+
lastKnownValues.set(key, value);
|
|
181
|
+
|
|
159
182
|
// Key was set/updated
|
|
160
183
|
const action = type === "string" ? "set.string" : type === "number" ? "set.number" : type === "boolean" ? "set.boolean" : type === "buffer" ? "set.buffer" : "set.string"; // fallback
|
|
161
184
|
|
|
@@ -166,6 +189,7 @@ class MMKVListener {
|
|
|
166
189
|
data: {
|
|
167
190
|
key,
|
|
168
191
|
value,
|
|
192
|
+
prevValue,
|
|
169
193
|
valueType: type,
|
|
170
194
|
success: true
|
|
171
195
|
}
|
|
@@ -184,7 +208,8 @@ class MMKVListener {
|
|
|
184
208
|
instanceId,
|
|
185
209
|
originalMethods: {},
|
|
186
210
|
// Not used in v4
|
|
187
|
-
nativeListenerUnsubscribe
|
|
211
|
+
nativeListenerUnsubscribe,
|
|
212
|
+
lastKnownValues
|
|
188
213
|
});
|
|
189
214
|
}
|
|
190
215
|
|
|
@@ -204,9 +229,20 @@ class MMKVListener {
|
|
|
204
229
|
nativeListenerUnsubscribe
|
|
205
230
|
} = tracked;
|
|
206
231
|
|
|
207
|
-
// Remove native listener
|
|
208
|
-
|
|
209
|
-
|
|
232
|
+
// Remove native listener. The return of addOnValueChangedListener varies by
|
|
233
|
+
// implementation: a bare unsubscribe function, or a Listener object with a
|
|
234
|
+
// `.remove()` method (react-native-mmkv v4 and the desktop RemoteMMKV
|
|
235
|
+
// back-end). Handle both, and never let teardown throw — this runs during
|
|
236
|
+
// React unmount, where an exception escapes every error boundary and blanks
|
|
237
|
+
// the whole app.
|
|
238
|
+
try {
|
|
239
|
+
if (typeof nativeListenerUnsubscribe === "function") {
|
|
240
|
+
nativeListenerUnsubscribe();
|
|
241
|
+
} else if (typeof nativeListenerUnsubscribe?.remove === "function") {
|
|
242
|
+
nativeListenerUnsubscribe.remove();
|
|
243
|
+
}
|
|
244
|
+
} catch {
|
|
245
|
+
/* listener already gone / back-end offline — nothing to clean up */
|
|
210
246
|
}
|
|
211
247
|
|
|
212
248
|
// Remove from tracking
|
|
@@ -55,12 +55,14 @@ exports.unregisterSecureStoreKey = unregisterSecureStoreKey;
|
|
|
55
55
|
class SecureStoreRegistry {
|
|
56
56
|
module = null;
|
|
57
57
|
keys = new Map();
|
|
58
|
+
listeners = new Set();
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* Register the SecureStore module and the keys to expose. Callable multiple
|
|
61
62
|
* times — keys accumulate, the latest module wins.
|
|
62
63
|
*/
|
|
63
64
|
register(module, descriptors) {
|
|
65
|
+
const before = this.signature();
|
|
64
66
|
this.module = module;
|
|
65
67
|
for (const d of descriptors) {
|
|
66
68
|
const entry = typeof d === "string" ? {
|
|
@@ -77,11 +79,41 @@ class SecureStoreRegistry {
|
|
|
77
79
|
};
|
|
78
80
|
this.keys.set(entry.key, entry);
|
|
79
81
|
}
|
|
82
|
+
// Only announce a real change. The desktop dashboard re-registers the same
|
|
83
|
+
// key set on every device snapshot, and subscribers re-read the keychain on
|
|
84
|
+
// notify — signature-comparing keeps that from turning into a read storm.
|
|
85
|
+
if (this.signature() !== before) this.notify();
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
/** Remove a key from the registry (does not delete the stored value). */
|
|
83
89
|
unregister(key) {
|
|
84
|
-
this.keys.delete(key);
|
|
90
|
+
if (this.keys.delete(key)) this.notify();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Subscribe to registry changes (keys registered/unregistered). Lets the
|
|
95
|
+
* browser pick up keys that register after the tool is already open.
|
|
96
|
+
* Returns an unsubscribe function.
|
|
97
|
+
*/
|
|
98
|
+
subscribe(listener) {
|
|
99
|
+
this.listeners.add(listener);
|
|
100
|
+
return () => {
|
|
101
|
+
this.listeners.delete(listener);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Content signature of the registered entries (module identity excluded). */
|
|
106
|
+
signature() {
|
|
107
|
+
return JSON.stringify(Array.from(this.keys.values()));
|
|
108
|
+
}
|
|
109
|
+
notify() {
|
|
110
|
+
this.listeners.forEach(listener => {
|
|
111
|
+
try {
|
|
112
|
+
listener();
|
|
113
|
+
} catch {
|
|
114
|
+
// Listener errors are not ours
|
|
115
|
+
}
|
|
116
|
+
});
|
|
85
117
|
}
|
|
86
118
|
|
|
87
119
|
/** The registered SecureStore module, or null if none registered yet. */
|
|
@@ -108,6 +140,25 @@ class SecureStoreRegistry {
|
|
|
108
140
|
if (!this.module || !entry) return;
|
|
109
141
|
await this.module.deleteItemAsync(key, entry.options);
|
|
110
142
|
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Write a stored value via the registered module, using the options the key
|
|
146
|
+
* was registered with — writing with different `keychainService` options than
|
|
147
|
+
* the value was created with silently creates a SECOND entry the app can't
|
|
148
|
+
* read, so the registered options are the only safe ones to use.
|
|
149
|
+
*
|
|
150
|
+
* Throws rather than no-ops: unlike a delete, a write that quietly did
|
|
151
|
+
* nothing would leave the UI showing a value that was never stored.
|
|
152
|
+
*/
|
|
153
|
+
async setValue(key, value) {
|
|
154
|
+
const entry = this.keys.get(key);
|
|
155
|
+
if (!this.module) throw new Error("No SecureStore module is registered");
|
|
156
|
+
if (!entry) throw new Error(`SecureStore key "${key}" is not registered`);
|
|
157
|
+
if (entry.options.requireAuthentication) {
|
|
158
|
+
throw new Error(`SecureStore key "${key}" is biometric-protected — DevTools never writes it`);
|
|
159
|
+
}
|
|
160
|
+
await this.module.setItemAsync(key, value, entry.options);
|
|
161
|
+
}
|
|
111
162
|
}
|
|
112
163
|
|
|
113
164
|
/**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.deleteStorageKeys = deleteStorageKeys;
|
|
7
|
+
var _asyncStorageCompat = require("./asyncStorageCompat");
|
|
8
|
+
var _SecureStoreRegistry = require("./SecureStoreRegistry");
|
|
9
|
+
/**
|
|
10
|
+
* Deleting storage keys, in one place.
|
|
11
|
+
*
|
|
12
|
+
* Each backend removes keys differently — AsyncStorage takes a batch,
|
|
13
|
+
* SecureStore has to go through the registry (only it knows each key's
|
|
14
|
+
* `keychainService` options), and MMKV deletes per registered instance. Two call
|
|
15
|
+
* sites need this (the selection action bar and a single row's "Delete key"),
|
|
16
|
+
* and a second copy of that fan-out is exactly how one backend quietly stops
|
|
17
|
+
* being cleaned up.
|
|
18
|
+
*
|
|
19
|
+
* Pro gating and confirmation are deliberately NOT here: they belong to the UI
|
|
20
|
+
* that has the user's attention. This function assumes the caller already asked.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Removes every key from whichever backend holds it. Rejects on the first
|
|
25
|
+
* failure — callers surface that, rather than reporting a partial delete as
|
|
26
|
+
* success.
|
|
27
|
+
*/
|
|
28
|
+
async function deleteStorageKeys(keys, mmkvInstances) {
|
|
29
|
+
if (keys.length === 0) return;
|
|
30
|
+
const asyncKeys = keys.filter(k => k.storageType === "async");
|
|
31
|
+
const mmkvKeys = keys.filter(k => k.storageType === "mmkv");
|
|
32
|
+
const secureKeys = keys.filter(k => k.storageType === "secure");
|
|
33
|
+
if (asyncKeys.length > 0) {
|
|
34
|
+
await (0, _asyncStorageCompat.removeMany)(asyncKeys.map(k => k.key));
|
|
35
|
+
}
|
|
36
|
+
for (const k of secureKeys) {
|
|
37
|
+
await _SecureStoreRegistry.secureStoreRegistry.deleteValue(k.key);
|
|
38
|
+
}
|
|
39
|
+
if (mmkvKeys.length > 0) {
|
|
40
|
+
const byInstance = {};
|
|
41
|
+
mmkvKeys.forEach(k => {
|
|
42
|
+
const instanceId = k.instanceId || "default";
|
|
43
|
+
if (!byInstance[instanceId]) byInstance[instanceId] = [];
|
|
44
|
+
byInstance[instanceId].push(k.key);
|
|
45
|
+
});
|
|
46
|
+
Object.entries(byInstance).forEach(([instanceId, instanceKeys]) => {
|
|
47
|
+
const inst = mmkvInstances.find(i => i.id === instanceId);
|
|
48
|
+
if (inst) {
|
|
49
|
+
instanceKeys.forEach(key => inst.instance.delete(key));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -141,6 +141,12 @@ Object.defineProperty(exports, "mmkvListener", {
|
|
|
141
141
|
return _MMKVListener.mmkvListener;
|
|
142
142
|
}
|
|
143
143
|
});
|
|
144
|
+
Object.defineProperty(exports, "onStorageBrowserRefresh", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
get: function () {
|
|
147
|
+
return _storageBrowserRefresh.onStorageBrowserRefresh;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
144
150
|
Object.defineProperty(exports, "pauseCapture", {
|
|
145
151
|
enumerable: true,
|
|
146
152
|
get: function () {
|
|
@@ -177,6 +183,12 @@ Object.defineProperty(exports, "removeMMKVInstance", {
|
|
|
177
183
|
return _MMKVListener.removeMMKVInstance;
|
|
178
184
|
}
|
|
179
185
|
});
|
|
186
|
+
Object.defineProperty(exports, "requestStorageBrowserRefresh", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
get: function () {
|
|
189
|
+
return _storageBrowserRefresh.requestStorageBrowserRefresh;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
180
192
|
Object.defineProperty(exports, "resumeCapture", {
|
|
181
193
|
enumerable: true,
|
|
182
194
|
get: function () {
|
|
@@ -213,5 +225,6 @@ var _AsyncStorageListener = _interopRequireWildcard(require("./AsyncStorageListe
|
|
|
213
225
|
var _storageTimeTravelUtils = require("./storageTimeTravelUtils");
|
|
214
226
|
var _MMKVInstanceRegistry = require("./MMKVInstanceRegistry");
|
|
215
227
|
var _MMKVListener = require("./MMKVListener");
|
|
228
|
+
var _storageBrowserRefresh = require("./storageBrowserRefresh");
|
|
216
229
|
var _mmkvTypeDetection = require("./mmkvTypeDetection");
|
|
217
230
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
@@ -3,361 +3,28 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* Adapted from react-diff-viewer for object comparison
|
|
11
|
-
*/
|
|
12
|
-
let DiffType = exports.DiffType = /*#__PURE__*/function (DiffType) {
|
|
13
|
-
DiffType["DEFAULT"] = "unchanged";
|
|
14
|
-
DiffType["ADDED"] = "added";
|
|
15
|
-
DiffType["REMOVED"] = "removed";
|
|
16
|
-
DiffType["MODIFIED"] = "modified";
|
|
17
|
-
return DiffType;
|
|
18
|
-
}({});
|
|
19
|
-
/**
|
|
20
|
-
* Compute diff based on method - for word-level diff within lines
|
|
21
|
-
*/
|
|
22
|
-
function computeDiffByMethod(oldStr, newStr, method) {
|
|
23
|
-
let oldParts;
|
|
24
|
-
let newParts;
|
|
25
|
-
switch (method) {
|
|
26
|
-
case "chars":
|
|
27
|
-
// Split into individual characters
|
|
28
|
-
oldParts = oldStr.split("");
|
|
29
|
-
newParts = newStr.split("");
|
|
30
|
-
break;
|
|
31
|
-
case "words":
|
|
32
|
-
// Split by word boundaries, keeping whitespace
|
|
33
|
-
oldParts = oldStr.match(/\S+|\s+/g) || [];
|
|
34
|
-
newParts = newStr.match(/\S+|\s+/g) || [];
|
|
35
|
-
break;
|
|
36
|
-
case "trimmedLines":
|
|
37
|
-
{
|
|
38
|
-
// For trimmedLines, compare without leading/trailing whitespace
|
|
39
|
-
const oldTrimmed = oldStr.trim();
|
|
40
|
-
const newTrimmed = newStr.trim();
|
|
41
|
-
// But still do word-level diff on the trimmed content
|
|
42
|
-
oldParts = oldTrimmed.match(/\S+|\s+/g) || [];
|
|
43
|
-
newParts = newTrimmed.match(/\S+|\s+/g) || [];
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
case "lines":
|
|
47
|
-
default:
|
|
48
|
-
// For lines mode, don't do word diff - just show the whole line
|
|
49
|
-
return {
|
|
50
|
-
left: [{
|
|
51
|
-
value: oldStr,
|
|
52
|
-
type: DiffType.REMOVED
|
|
53
|
-
}],
|
|
54
|
-
right: [{
|
|
55
|
-
value: newStr,
|
|
56
|
-
type: DiffType.ADDED
|
|
57
|
-
}]
|
|
58
|
-
};
|
|
6
|
+
Object.defineProperty(exports, "ABSENT_VALUE", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _dataViewer.ABSENT_VALUE;
|
|
59
10
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
j = 0;
|
|
66
|
-
|
|
67
|
-
// Find matching parts
|
|
68
|
-
while (i < oldParts.length && j < newParts.length) {
|
|
69
|
-
if (oldParts[i] === newParts[j]) {
|
|
70
|
-
// Parts match
|
|
71
|
-
left.push({
|
|
72
|
-
value: oldParts[i],
|
|
73
|
-
type: DiffType.DEFAULT
|
|
74
|
-
});
|
|
75
|
-
right.push({
|
|
76
|
-
value: newParts[j],
|
|
77
|
-
type: DiffType.DEFAULT
|
|
78
|
-
});
|
|
79
|
-
i++;
|
|
80
|
-
j++;
|
|
81
|
-
} else {
|
|
82
|
-
// Look ahead for matches
|
|
83
|
-
let foundMatch = false;
|
|
84
|
-
|
|
85
|
-
// Check if we can find newParts[j] in upcoming oldParts
|
|
86
|
-
for (let k = i + 1; k < Math.min(i + 5, oldParts.length); k++) {
|
|
87
|
-
if (oldParts[k] === newParts[j]) {
|
|
88
|
-
// Mark everything from i to k-1 as removed
|
|
89
|
-
for (let m = i; m < k; m++) {
|
|
90
|
-
left.push({
|
|
91
|
-
value: oldParts[m],
|
|
92
|
-
type: DiffType.REMOVED
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
i = k;
|
|
96
|
-
foundMatch = true;
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (!foundMatch) {
|
|
101
|
-
// Check if we can find oldParts[i] in upcoming newParts
|
|
102
|
-
for (let k = j + 1; k < Math.min(j + 5, newParts.length); k++) {
|
|
103
|
-
if (newParts[k] === oldParts[i]) {
|
|
104
|
-
// Mark everything from j to k-1 as added
|
|
105
|
-
for (let m = j; m < k; m++) {
|
|
106
|
-
right.push({
|
|
107
|
-
value: newParts[m],
|
|
108
|
-
type: DiffType.ADDED
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
j = k;
|
|
112
|
-
foundMatch = true;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (!foundMatch) {
|
|
118
|
-
// No match found nearby, mark as changed
|
|
119
|
-
left.push({
|
|
120
|
-
value: oldParts[i],
|
|
121
|
-
type: DiffType.REMOVED
|
|
122
|
-
});
|
|
123
|
-
right.push({
|
|
124
|
-
value: newParts[j],
|
|
125
|
-
type: DiffType.ADDED
|
|
126
|
-
});
|
|
127
|
-
i++;
|
|
128
|
-
j++;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Handle remaining parts
|
|
134
|
-
while (i < oldParts.length) {
|
|
135
|
-
left.push({
|
|
136
|
-
value: oldParts[i],
|
|
137
|
-
type: DiffType.REMOVED
|
|
138
|
-
});
|
|
139
|
-
i++;
|
|
140
|
-
}
|
|
141
|
-
while (j < newParts.length) {
|
|
142
|
-
right.push({
|
|
143
|
-
value: newParts[j],
|
|
144
|
-
type: DiffType.ADDED
|
|
145
|
-
});
|
|
146
|
-
j++;
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
left,
|
|
150
|
-
right
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Convert object to formatted JSON lines
|
|
156
|
-
*/
|
|
157
|
-
function objectToLines(obj) {
|
|
158
|
-
if (obj === null || obj === undefined) {
|
|
159
|
-
return [String(obj)];
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
// Pretty print JSON with 2 space indentation
|
|
163
|
-
const jsonStr = JSON.stringify(obj, null, 2);
|
|
164
|
-
// Split into lines and filter out empty lines that appear between array elements
|
|
165
|
-
const lines = jsonStr.split("\n");
|
|
166
|
-
|
|
167
|
-
// Remove empty lines but keep structure
|
|
168
|
-
const filteredLines = [];
|
|
169
|
-
for (let i = 0; i < lines.length; i++) {
|
|
170
|
-
const line = lines[i];
|
|
171
|
-
const trimmed = line.trim();
|
|
172
|
-
|
|
173
|
-
// Keep the line if it's not empty or if it's meaningful whitespace
|
|
174
|
-
if (trimmed !== "") {
|
|
175
|
-
filteredLines.push(line);
|
|
176
|
-
} else if (i === 0 || i === lines.length - 1) {
|
|
177
|
-
// Keep first and last empty lines if they exist (though they shouldn't)
|
|
178
|
-
filteredLines.push(line);
|
|
179
|
-
}
|
|
180
|
-
// Skip other empty lines
|
|
181
|
-
}
|
|
182
|
-
return filteredLines;
|
|
183
|
-
} catch {
|
|
184
|
-
return [String(obj)];
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Apply showDiffOnly filter with context lines
|
|
189
|
-
*/
|
|
190
|
-
function filterDiffWithContext(diffs, contextLines) {
|
|
191
|
-
if (contextLines < 0) return diffs;
|
|
192
|
-
const result = [];
|
|
193
|
-
const changedIndices = [];
|
|
194
|
-
|
|
195
|
-
// Find all changed lines
|
|
196
|
-
diffs.forEach((diff, idx) => {
|
|
197
|
-
if (diff.type !== DiffType.DEFAULT) {
|
|
198
|
-
changedIndices.push(idx);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// If no changes, return empty
|
|
203
|
-
if (changedIndices.length === 0) {
|
|
204
|
-
return [];
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Build ranges to include
|
|
208
|
-
const ranges = [];
|
|
209
|
-
let currentStart = Math.max(0, changedIndices[0] - contextLines);
|
|
210
|
-
let currentEnd = Math.min(diffs.length - 1, changedIndices[0] + contextLines);
|
|
211
|
-
for (let i = 1; i < changedIndices.length; i++) {
|
|
212
|
-
const idx = changedIndices[i];
|
|
213
|
-
const rangeStart = Math.max(0, idx - contextLines);
|
|
214
|
-
const rangeEnd = Math.min(diffs.length - 1, idx + contextLines);
|
|
215
|
-
|
|
216
|
-
// If ranges overlap or are adjacent, merge them
|
|
217
|
-
if (rangeStart <= currentEnd + 1) {
|
|
218
|
-
currentEnd = Math.max(currentEnd, rangeEnd);
|
|
219
|
-
} else {
|
|
220
|
-
// Save current range and start a new one
|
|
221
|
-
ranges.push([currentStart, currentEnd]);
|
|
222
|
-
currentStart = rangeStart;
|
|
223
|
-
currentEnd = rangeEnd;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Don't forget the last range
|
|
228
|
-
ranges.push([currentStart, currentEnd]);
|
|
229
|
-
|
|
230
|
-
// Build result from ranges
|
|
231
|
-
ranges.forEach(([start, end]) => {
|
|
232
|
-
for (let i = start; i <= end; i++) {
|
|
233
|
-
result.push(diffs[i]);
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
return result;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Compare lines based on method
|
|
241
|
-
*/
|
|
242
|
-
function compareLinesWithMethod(line1, line2, method) {
|
|
243
|
-
switch (method) {
|
|
244
|
-
case "trimmedLines":
|
|
245
|
-
return line1.trim() === line2.trim();
|
|
246
|
-
case "chars":
|
|
247
|
-
case "words":
|
|
248
|
-
case "lines":
|
|
249
|
-
default:
|
|
250
|
-
return line1 === line2;
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "DiffType", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _dataViewer.DiffType;
|
|
251
16
|
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
function computeLineDiff(oldValue, newValue, options = {}) {
|
|
258
|
-
const {
|
|
259
|
-
compareMethod = "words",
|
|
260
|
-
disableWordDiff = false,
|
|
261
|
-
showDiffOnly = false,
|
|
262
|
-
contextLines = 3
|
|
263
|
-
} = options;
|
|
264
|
-
const oldLines = objectToLines(oldValue);
|
|
265
|
-
const newLines = objectToLines(newValue);
|
|
266
|
-
const result = [];
|
|
267
|
-
let leftLineNum = 1;
|
|
268
|
-
let rightLineNum = 1;
|
|
269
|
-
|
|
270
|
-
// Simple line diff algorithm (can be improved with LCS)
|
|
271
|
-
let i = 0,
|
|
272
|
-
j = 0;
|
|
273
|
-
while (i < oldLines.length || j < newLines.length) {
|
|
274
|
-
if (i >= oldLines.length) {
|
|
275
|
-
// Rest are additions
|
|
276
|
-
result.push({
|
|
277
|
-
rightLineNumber: rightLineNum++,
|
|
278
|
-
type: DiffType.ADDED,
|
|
279
|
-
rightContent: newLines[j],
|
|
280
|
-
rightRaw: newLines[j]
|
|
281
|
-
});
|
|
282
|
-
j++;
|
|
283
|
-
} else if (j >= newLines.length) {
|
|
284
|
-
// Rest are removals
|
|
285
|
-
result.push({
|
|
286
|
-
leftLineNumber: leftLineNum++,
|
|
287
|
-
type: DiffType.REMOVED,
|
|
288
|
-
leftContent: oldLines[i],
|
|
289
|
-
leftRaw: oldLines[i]
|
|
290
|
-
});
|
|
291
|
-
i++;
|
|
292
|
-
} else if (compareLinesWithMethod(oldLines[i], newLines[j], compareMethod === "trimmedLines" ? "trimmedLines" : "lines")) {
|
|
293
|
-
// Lines match (possibly after trimming if trimmedLines)
|
|
294
|
-
result.push({
|
|
295
|
-
leftLineNumber: leftLineNum++,
|
|
296
|
-
rightLineNumber: rightLineNum++,
|
|
297
|
-
type: DiffType.DEFAULT,
|
|
298
|
-
leftContent: oldLines[i],
|
|
299
|
-
rightContent: newLines[j],
|
|
300
|
-
leftRaw: oldLines[i],
|
|
301
|
-
rightRaw: newLines[j]
|
|
302
|
-
});
|
|
303
|
-
i++;
|
|
304
|
-
j++;
|
|
305
|
-
} else {
|
|
306
|
-
// Lines differ - check if it's a modification or separate add/remove
|
|
307
|
-
const oldTrimmed = oldLines[i].trim();
|
|
308
|
-
const newTrimmed = newLines[j].trim();
|
|
309
|
-
|
|
310
|
-
// Simple heuristic: if lines start similarly, treat as modification
|
|
311
|
-
if (oldTrimmed && newTrimmed && (oldTrimmed.startsWith(newTrimmed.substring(0, 3)) || newTrimmed.startsWith(oldTrimmed.substring(0, 3)))) {
|
|
312
|
-
// Treat as modification - compute word diff if enabled
|
|
313
|
-
if (!disableWordDiff && compareMethod !== "lines") {
|
|
314
|
-
const wordDiff = computeDiffByMethod(oldLines[i], newLines[j], compareMethod);
|
|
315
|
-
result.push({
|
|
316
|
-
leftLineNumber: leftLineNum++,
|
|
317
|
-
rightLineNumber: rightLineNum++,
|
|
318
|
-
type: DiffType.MODIFIED,
|
|
319
|
-
leftContent: wordDiff.left,
|
|
320
|
-
rightContent: wordDiff.right,
|
|
321
|
-
leftRaw: oldLines[i],
|
|
322
|
-
rightRaw: newLines[j]
|
|
323
|
-
});
|
|
324
|
-
} else {
|
|
325
|
-
// No word diff - just mark lines as different
|
|
326
|
-
result.push({
|
|
327
|
-
leftLineNumber: leftLineNum++,
|
|
328
|
-
rightLineNumber: rightLineNum++,
|
|
329
|
-
type: DiffType.MODIFIED,
|
|
330
|
-
leftContent: oldLines[i],
|
|
331
|
-
rightContent: newLines[j],
|
|
332
|
-
leftRaw: oldLines[i],
|
|
333
|
-
rightRaw: newLines[j]
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
i++;
|
|
337
|
-
j++;
|
|
338
|
-
} else {
|
|
339
|
-
// Treat as separate remove and add
|
|
340
|
-
result.push({
|
|
341
|
-
leftLineNumber: leftLineNum++,
|
|
342
|
-
type: DiffType.REMOVED,
|
|
343
|
-
leftContent: oldLines[i],
|
|
344
|
-
leftRaw: oldLines[i]
|
|
345
|
-
});
|
|
346
|
-
result.push({
|
|
347
|
-
rightLineNumber: rightLineNum++,
|
|
348
|
-
type: DiffType.ADDED,
|
|
349
|
-
rightContent: newLines[j],
|
|
350
|
-
rightRaw: newLines[j]
|
|
351
|
-
});
|
|
352
|
-
i++;
|
|
353
|
-
j++;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "computeLineDiff", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _dataViewer.computeLineDiff;
|
|
356
22
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "isAbsent", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _dataViewer.isAbsent;
|
|
361
28
|
}
|
|
362
|
-
|
|
363
|
-
|
|
29
|
+
});
|
|
30
|
+
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|