@buoy-gg/storage 7.0.16 → 7.0.18
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 +13 -0
- package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +5 -602
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +17 -1
- package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +13 -10
- package/lib/commonjs/storage/hooks/useMMKVKeys.js +28 -23
- package/lib/commonjs/storage/stores/storageEventStore.js +85 -1
- package/lib/commonjs/storage/sync/storageSyncAdapter.js +214 -6
- package/lib/commonjs/storage/utils/requiredStorageKeyScope.js +17 -0
- package/lib/commonjs/storage/utils/snapshotProvider.js +447 -0
- package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +17 -3
- package/lib/module/index.js +9 -1
- package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +7 -603
- package/lib/module/storage/components/StorageModalWithTabs.js +17 -1
- package/lib/module/storage/hooks/useAsyncStorageKeys.js +13 -10
- package/lib/module/storage/hooks/useMMKVKeys.js +28 -23
- package/lib/module/storage/stores/storageEventStore.js +81 -0
- package/lib/module/storage/sync/storageSyncAdapter.js +215 -7
- package/lib/module/storage/utils/requiredStorageKeyScope.js +13 -0
- package/lib/module/storage/utils/snapshotProvider.js +445 -0
- package/lib/module/storage/utils/storageTimeTravelUtils.js +17 -3
- package/lib/typescript/index.d.ts +3 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts +7 -18
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts +8 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +1 -1
- package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +1 -1
- package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +1 -1
- package/lib/typescript/storage/stores/storageEventStore.d.ts +26 -0
- package/lib/typescript/storage/stores/storageEventStore.d.ts.map +1 -1
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +71 -5
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/storage/types.d.ts +9 -9
- package/lib/typescript/storage/types.d.ts.map +1 -1
- package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts +10 -0
- package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts.map +1 -0
- package/lib/typescript/storage/utils/snapshotProvider.d.ts +2 -0
- package/lib/typescript/storage/utils/snapshotProvider.d.ts.map +1 -0
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +1 -1
- package/package.json +9 -6
|
@@ -1,6 +1,29 @@
|
|
|
1
|
+
import { type StorageEvent } from "../stores/storageEventStore";
|
|
2
|
+
/**
|
|
3
|
+
* Sentinel used in WIRE-FORM snapshots in place of oversized values.
|
|
4
|
+
* Storage events, MMKV browse dumps, and SecureStore dumps all reuse this
|
|
5
|
+
* marker. Dashboards fetch the real payload via `getEventDetail` / `mmkv.get`
|
|
6
|
+
* / `secure.get`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const VALUE_ON_DEVICE: Readonly<{
|
|
9
|
+
__buoyValueOnDevice: true;
|
|
10
|
+
note: "Value stays on the device — fetched on demand via getEventDetail / mmkv.get / secure.get.";
|
|
11
|
+
}>;
|
|
12
|
+
/** Max serialized bytes of one storage value on the list snapshot. */
|
|
13
|
+
export declare const SNAPSHOT_VALUE_INLINE_LIMIT: number;
|
|
14
|
+
/**
|
|
15
|
+
* Total inline budget for one snapshot's event list, held under the emit
|
|
16
|
+
* layer's 2MB so a snapshot is never DROPPED (a drop leaves the whole panel
|
|
17
|
+
* stale). Per-value caps alone don't get there: the store keeps 500 events, so
|
|
18
|
+
* 500 writes of an individually-legal 9KB value still total ~4.7MB. Newest
|
|
19
|
+
* events keep their values inline; once the budget is spent, older ones
|
|
20
|
+
* degrade to metadata + fetch-on-demand.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SNAPSHOT_EVENTS_BUDGET: number;
|
|
1
23
|
/** One MMKV entry in a `mmkv.snapshot` result. */
|
|
2
24
|
export interface MMKVSnapshotEntry {
|
|
3
25
|
key: string;
|
|
26
|
+
/** Oversized values are replaced with VALUE_ON_DEVICE on the wire. */
|
|
4
27
|
value: unknown;
|
|
5
28
|
valueType: string;
|
|
6
29
|
}
|
|
@@ -17,8 +40,11 @@ export interface SecureSnapshotEntry {
|
|
|
17
40
|
description?: string;
|
|
18
41
|
keychainService?: string;
|
|
19
42
|
requireAuthentication: boolean;
|
|
20
|
-
/**
|
|
21
|
-
|
|
43
|
+
/**
|
|
44
|
+
* `null` when unset, or when the key is biometric-protected (never read).
|
|
45
|
+
* Oversized values are replaced with VALUE_ON_DEVICE on the wire.
|
|
46
|
+
*/
|
|
47
|
+
value: unknown;
|
|
22
48
|
}
|
|
23
49
|
/**
|
|
24
50
|
* Sync adapter for the storage tool, consumed by @buoy-gg/external-sync's
|
|
@@ -31,19 +57,39 @@ export interface SecureSnapshotEntry {
|
|
|
31
57
|
*
|
|
32
58
|
* The `async.*` actions mirror the AsyncStorage API so the desktop dashboard
|
|
33
59
|
* can proxy its browse/edit mode against the device's real storage.
|
|
60
|
+
*
|
|
61
|
+
* v2: oversized / unserializable event values are replaced with
|
|
62
|
+
* VALUE_ON_DEVICE. Dashboards fetch them via `getEventDetail`.
|
|
34
63
|
*/
|
|
35
64
|
export declare const storageSyncAdapter: {
|
|
36
65
|
version: number;
|
|
37
|
-
getSnapshot: () =>
|
|
66
|
+
getSnapshot: () => StorageEvent[];
|
|
38
67
|
subscribe: (onChange: () => void) => () => void;
|
|
39
68
|
actions: {
|
|
40
69
|
clearEvents: () => void;
|
|
70
|
+
/**
|
|
71
|
+
* On-demand detail: one event's real value/prevValue/pairs.
|
|
72
|
+
* The per-snapshot stream stays payload-light; this is the explicit,
|
|
73
|
+
* size-guarded channel for the detail pane (and for time-travel undo,
|
|
74
|
+
* which needs `prevValue`).
|
|
75
|
+
*/
|
|
76
|
+
getEventDetail: (params: unknown) => {
|
|
77
|
+
found: false;
|
|
78
|
+
reason: string;
|
|
79
|
+
id?: undefined;
|
|
80
|
+
event?: undefined;
|
|
81
|
+
} | {
|
|
82
|
+
found: true;
|
|
83
|
+
id: string;
|
|
84
|
+
event: StorageEvent;
|
|
85
|
+
reason?: undefined;
|
|
86
|
+
};
|
|
41
87
|
/** Clears all app storage keys, preserving dev tools settings. */
|
|
42
88
|
clearAppStorage: () => Promise<void>;
|
|
43
89
|
/** Undo one event, addressed by the `id` the store assigned it. */
|
|
44
90
|
"timeTravel.undo": (params: unknown) => Promise<{
|
|
45
91
|
undone: boolean;
|
|
46
|
-
action: "
|
|
92
|
+
action: "mergeItem" | "multiSet" | "multiRemove" | "clear" | "setItem" | "removeItem" | "multiMerge";
|
|
47
93
|
key: string | undefined;
|
|
48
94
|
}>;
|
|
49
95
|
/**
|
|
@@ -53,7 +99,7 @@ export declare const storageSyncAdapter: {
|
|
|
53
99
|
*/
|
|
54
100
|
"timeTravel.jump": (params: unknown) => Promise<{
|
|
55
101
|
jumped: boolean;
|
|
56
|
-
scope: "
|
|
102
|
+
scope: "key" | "all";
|
|
57
103
|
replayed: number;
|
|
58
104
|
of: number;
|
|
59
105
|
key: string | undefined;
|
|
@@ -67,6 +113,26 @@ export declare const storageSyncAdapter: {
|
|
|
67
113
|
"async.multiSet": (params: unknown) => Promise<void>;
|
|
68
114
|
"async.clear": () => Promise<void>;
|
|
69
115
|
"mmkv.snapshot": () => MMKVSnapshotInstance[];
|
|
116
|
+
/**
|
|
117
|
+
* On-demand MMKV value. `mmkv.snapshot` omits oversized strings so a
|
|
118
|
+
* browse poll cannot blow the action-result budget; this is the
|
|
119
|
+
* size-guarded channel for one key.
|
|
120
|
+
*/
|
|
121
|
+
"mmkv.get": (params: unknown) => {
|
|
122
|
+
found: false;
|
|
123
|
+
reason: string;
|
|
124
|
+
instanceId?: undefined;
|
|
125
|
+
key?: undefined;
|
|
126
|
+
value?: undefined;
|
|
127
|
+
valueType?: undefined;
|
|
128
|
+
} | {
|
|
129
|
+
found: true;
|
|
130
|
+
instanceId: string;
|
|
131
|
+
key: string;
|
|
132
|
+
value: unknown;
|
|
133
|
+
valueType: import("../..").MMKVValueType;
|
|
134
|
+
reason?: undefined;
|
|
135
|
+
};
|
|
70
136
|
"mmkv.set": (params: unknown) => void;
|
|
71
137
|
"mmkv.remove": (params: unknown) => void;
|
|
72
138
|
"secure.keys": () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageSyncAdapter.d.ts","sourceRoot":"","sources":["../../../../src/storage/sync/storageSyncAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storageSyncAdapter.d.ts","sourceRoot":"","sources":["../../../../src/storage/sync/storageSyncAdapter.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAC;AAYrC;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;EAG1B,CAAC;AAEH,sEAAsE;AACtE,eAAO,MAAM,2BAA2B,QAAY,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,QAAqB,CAAC;AA4JzD,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB;AAsBD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB;;;0BAeP,MAAM,IAAI;;;QAM9B;;;;;WAKG;iCACsB,OAAO;;;;;;;;;;;QAUhC,kEAAkE;;QAOlE,mEAAmE;oCACjC,OAAO;;;;;QAkBzC;;;;WAIG;oCAC+B,OAAO;;;;;;;;mCAyCR,OAAO;kCAId,OAAO;kCAMP,OAAO;qCAIJ,OAAO;sCAEN,OAAO;mCAEV,OAAO;;+BAOb,oBAAoB,EAAE;QAgB3C;;;;WAIG;6BACkB,OAAO;;;;;;;;;;;;;;;6BAkBP,OAAO;gCAIJ,OAAO;;;;;;;QAkB/B;;;;;WAKG;iCAC0B,OAAO,CAAC,mBAAmB,EAAE,CAAC;+BAwBpC,OAAO;QAW9B;;;;;WAKG;+BACoB,OAAO;kCAIJ,OAAO;;CAGpC,CAAC"}
|
|
@@ -12,17 +12,17 @@ export interface StorageKeyInfo {
|
|
|
12
12
|
category: "required" | "optional";
|
|
13
13
|
lastUpdated?: Date;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* A required key the browser validates. `storageType` scopes the check to one
|
|
17
|
+
* backend — without it, every backend's hook historically synthesized its own
|
|
18
|
+
* Missing row for the same key (Async + MMKV both counting it). Prefer always
|
|
19
|
+
* setting `storageType` when more than one backend is registered.
|
|
20
|
+
*/
|
|
15
21
|
export type RequiredStorageKey = string | {
|
|
16
22
|
key: string;
|
|
17
|
-
expectedValue
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
key: string;
|
|
21
|
-
expectedType: string;
|
|
22
|
-
description?: string;
|
|
23
|
-
} | {
|
|
24
|
-
key: string;
|
|
25
|
-
storageType: StorageType;
|
|
23
|
+
expectedValue?: string;
|
|
24
|
+
expectedType?: string;
|
|
25
|
+
storageType?: StorageType;
|
|
26
26
|
description?: string;
|
|
27
27
|
};
|
|
28
28
|
export interface StorageKeyStats {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/storage/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EACF,kBAAkB,GAClB,kBAAkB,GAClB,sBAAsB,GACtB,qBAAqB,GACrB,kBAAkB,CAAC;IACvB,QAAQ,EAAE,UAAU,GAAG,UAAU,CAAC;IAClC,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/storage/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EACF,kBAAkB,GAClB,kBAAkB,GAClB,sBAAsB,GACtB,qBAAqB,GACrB,kBAAkB,CAAC;IACvB,QAAQ,EAAE,UAAU,GAAG,UAAU,CAAC;IAClC,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IAEtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IAEpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RequiredStorageKey } from "../types";
|
|
2
|
+
import type { StorageType } from "./storageQueryUtils";
|
|
3
|
+
/**
|
|
4
|
+
* Whether a required-key declaration should be enforced by a given backend
|
|
5
|
+
* hook. Explicit `storageType` wins; bare string keys default to AsyncStorage
|
|
6
|
+
* (the historical zero-config backend). Objects without `storageType` still
|
|
7
|
+
* apply to every backend — matching prior behavior for apps that never set it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function requiredKeyAppliesTo(req: RequiredStorageKey, backend: StorageType): boolean;
|
|
10
|
+
//# sourceMappingURL=requiredStorageKeyScope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requiredStorageKeyScope.d.ts","sourceRoot":"","sources":["../../../../src/storage/utils/requiredStorageKeyScope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,kBAAkB,EACvB,OAAO,EAAE,WAAW,GACnB,OAAO,CAIT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshotProvider.d.ts","sourceRoot":"","sources":["../../../../src/storage/utils/snapshotProvider.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storageTimeTravelUtils.d.ts","sourceRoot":"","sources":["../../../../src/storage/utils/storageTimeTravelUtils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"storageTimeTravelUtils.d.ts","sourceRoot":"","sources":["../../../../src/storage/utils/storageTimeTravelUtils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAUhE;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0E3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,iBAAiB,EAAE,EAC3B,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAqDf;AAoGD;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAyBzD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/storage",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.18",
|
|
4
4
|
"description": "Browse & edit AsyncStorage, MMKV & SecureStore inside your React Native app, with change history. Part of Buoy devtools.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -24,13 +24,16 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"lib"
|
|
26
26
|
],
|
|
27
|
-
"sideEffects":
|
|
27
|
+
"sideEffects": [
|
|
28
|
+
"**/snapshotProvider.js",
|
|
29
|
+
"**/snapshotProvider.ts"
|
|
30
|
+
],
|
|
28
31
|
"dependencies": {
|
|
29
|
-
"@buoy-gg/floating-tools-core": "^7.0.
|
|
30
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
32
|
+
"@buoy-gg/floating-tools-core": "^7.0.18",
|
|
33
|
+
"@buoy-gg/shared-ui": "^7.0.18"
|
|
31
34
|
},
|
|
32
35
|
"peerDependencies": {
|
|
33
|
-
"@buoy-gg/license": "7.0.
|
|
36
|
+
"@buoy-gg/license": "7.0.18",
|
|
34
37
|
"@react-native-async-storage/async-storage": "^2.0.0 || ^3.1.0",
|
|
35
38
|
"react": "*",
|
|
36
39
|
"react-native": "*"
|
|
@@ -40,7 +43,7 @@
|
|
|
40
43
|
"@types/react": "^19.1.0",
|
|
41
44
|
"@types/react-native": "^0.73.0",
|
|
42
45
|
"typescript": "~5.8.3",
|
|
43
|
-
"@buoy-gg/license": "^7.0.
|
|
46
|
+
"@buoy-gg/license": "^7.0.18"
|
|
44
47
|
},
|
|
45
48
|
"react-native-builder-bob": {
|
|
46
49
|
"source": "src",
|