@buoy-gg/storage 7.0.41 → 7.0.43
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/README.md +11 -90
- package/lib/commonjs/index.js +1 -353
- package/lib/commonjs/preset.js +1 -85
- package/lib/commonjs/storage/components/DiffViewer/TreeDiffViewer.js +1 -36
- package/lib/commonjs/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -12
- package/lib/commonjs/storage/components/DiffViewer/themes/diffThemes.js +1 -24
- package/lib/commonjs/storage/components/GameUIStorageBrowser.js +3 -1259
- package/lib/commonjs/storage/components/MMKVInstanceInfoPanel.js +1 -257
- package/lib/commonjs/storage/components/MMKVInstanceSelector.js +1 -419
- package/lib/commonjs/storage/components/SelectionActionBar.js +1 -207
- package/lib/commonjs/storage/components/StorageActionButtons.js +1 -242
- package/lib/commonjs/storage/components/StorageBrowserMode.js +1 -61
- package/lib/commonjs/storage/components/StorageEventActionButton.js +1 -121
- package/lib/commonjs/storage/components/StorageEventCard.js +1 -118
- package/lib/commonjs/storage/components/StorageEventDetailContent.js +1 -494
- package/lib/commonjs/storage/components/StorageEventFilterView.js +1 -160
- package/lib/commonjs/storage/components/StorageEventsSection.js +1 -24
- package/lib/commonjs/storage/components/StorageFilterCards.js +1 -231
- package/lib/commonjs/storage/components/StorageKeyCard.js +1 -520
- package/lib/commonjs/storage/components/StorageKeyDetailScreen.js +1 -579
- package/lib/commonjs/storage/components/StorageKeyRow.js +1 -559
- package/lib/commonjs/storage/components/StorageKeySection.js +1 -160
- package/lib/commonjs/storage/components/StorageKeyStats.js +1 -345
- package/lib/commonjs/storage/components/StorageModalWithTabs.js +1 -954
- package/lib/commonjs/storage/components/StorageSaveNotice.js +1 -171
- package/lib/commonjs/storage/components/StorageSection.js +1 -43
- package/lib/commonjs/storage/components/StorageTypeFilterBar.js +1 -144
- package/lib/commonjs/storage/hooks/useAsyncStorageKeys.js +1 -141
- package/lib/commonjs/storage/hooks/useMMKVInstances.js +1 -210
- package/lib/commonjs/storage/hooks/useMMKVKeys.js +1 -376
- package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +1 -202
- package/lib/commonjs/storage/hooks/useStorageEvents.js +1 -61
- package/lib/commonjs/storage/stores/storageEventStore.js +1 -312
- package/lib/commonjs/storage/sync/storageSyncAdapter.js +1 -492
- package/lib/commonjs/storage/types.js +1 -5
- package/lib/commonjs/storage/utils/AsyncStorageListener.js +1 -691
- package/lib/commonjs/storage/utils/AsyncStorageListener.web.js +1 -89
- package/lib/commonjs/storage/utils/MMKVInstanceRegistry.js +1 -203
- package/lib/commonjs/storage/utils/MMKVListener.js +1 -416
- package/lib/commonjs/storage/utils/SecureStoreRegistry.js +1 -200
- package/lib/commonjs/storage/utils/asyncStorageCompat.js +1 -89
- package/lib/commonjs/storage/utils/browserStorageLifecycle.js +1 -10
- package/lib/commonjs/storage/utils/browserStorageLifecycle.web.js +1 -70
- package/lib/commonjs/storage/utils/clearAllStorage.js +1 -48
- package/lib/commonjs/storage/utils/deleteStorageKeys.js +1 -82
- package/lib/commonjs/storage/utils/lineDiff.js +1 -30
- package/lib/commonjs/storage/utils/mmkvAvailability.js +1 -62
- package/lib/commonjs/storage/utils/mmkvAvailability.web.js +1 -21
- package/lib/commonjs/storage/utils/mmkvTypeDetection.js +1 -154
- package/lib/commonjs/storage/utils/requiredStorageKeyScope.js +1 -17
- package/lib/commonjs/storage/utils/setStorageValue.js +1 -218
- package/lib/commonjs/storage/utils/snapshotProvider.js +1 -382
- package/lib/commonjs/storage/utils/storageActionHelpers.js +1 -46
- package/lib/commonjs/storage/utils/storageBrowserRefresh.js +1 -49
- package/lib/commonjs/storage/utils/storageLabels.js +1 -13
- package/lib/commonjs/storage/utils/storageLabels.web.js +1 -13
- package/lib/commonjs/storage/utils/storageOps.js +1 -53
- package/lib/commonjs/storage/utils/storageQueryUtils.js +1 -35
- package/lib/commonjs/storage/utils/storageTimeTravelUtils.js +1 -288
- package/lib/commonjs/storage/utils/valueType.js +1 -83
- package/lib/module/index.js +1 -114
- package/lib/module/preset.js +1 -82
- package/lib/module/storage/components/DiffViewer/TreeDiffViewer.js +1 -32
- package/lib/module/storage/components/DiffViewer/modes/ThemedSplitView.js +1 -9
- package/lib/module/storage/components/DiffViewer/themes/diffThemes.js +1 -10
- package/lib/module/storage/components/GameUIStorageBrowser.js +3 -1257
- package/lib/module/storage/components/MMKVInstanceInfoPanel.js +1 -253
- package/lib/module/storage/components/MMKVInstanceSelector.js +1 -415
- package/lib/module/storage/components/SelectionActionBar.js +1 -204
- package/lib/module/storage/components/StorageActionButtons.js +1 -238
- package/lib/module/storage/components/StorageBrowserMode.js +1 -57
- package/lib/module/storage/components/StorageEventActionButton.js +1 -118
- package/lib/module/storage/components/StorageEventCard.js +1 -113
- package/lib/module/storage/components/StorageEventDetailContent.js +1 -490
- package/lib/module/storage/components/StorageEventFilterView.js +1 -156
- package/lib/module/storage/components/StorageEventsSection.js +1 -20
- package/lib/module/storage/components/StorageFilterCards.js +1 -227
- package/lib/module/storage/components/StorageKeyCard.js +1 -517
- package/lib/module/storage/components/StorageKeyDetailScreen.js +1 -577
- package/lib/module/storage/components/StorageKeyRow.js +1 -554
- package/lib/module/storage/components/StorageKeySection.js +1 -155
- package/lib/module/storage/components/StorageKeyStats.js +1 -342
- package/lib/module/storage/components/StorageModalWithTabs.js +1 -949
- package/lib/module/storage/components/StorageSaveNotice.js +1 -168
- package/lib/module/storage/components/StorageSection.js +1 -40
- package/lib/module/storage/components/StorageTypeFilterBar.js +1 -139
- package/lib/module/storage/hooks/useAsyncStorageKeys.js +1 -136
- package/lib/module/storage/hooks/useMMKVInstances.js +1 -204
- package/lib/module/storage/hooks/useMMKVKeys.js +1 -371
- package/lib/module/storage/hooks/useSecureStoreKeys.js +1 -199
- package/lib/module/storage/hooks/useStorageEvents.js +1 -58
- package/lib/module/storage/stores/storageEventStore.js +1 -301
- package/lib/module/storage/sync/storageSyncAdapter.js +1 -486
- package/lib/module/storage/types.js +1 -3
- package/lib/module/storage/utils/AsyncStorageListener.js +1 -679
- package/lib/module/storage/utils/AsyncStorageListener.web.js +1 -76
- package/lib/module/storage/utils/MMKVInstanceRegistry.js +1 -197
- package/lib/module/storage/utils/MMKVListener.js +1 -403
- package/lib/module/storage/utils/SecureStoreRegistry.js +1 -194
- package/lib/module/storage/utils/asyncStorageCompat.js +1 -81
- package/lib/module/storage/utils/browserStorageLifecycle.js +1 -6
- package/lib/module/storage/utils/browserStorageLifecycle.web.js +1 -66
- package/lib/module/storage/utils/clearAllStorage.js +1 -43
- package/lib/module/storage/utils/deleteStorageKeys.js +1 -78
- package/lib/module/storage/utils/lineDiff.js +1 -12
- package/lib/module/storage/utils/mmkvAvailability.js +1 -56
- package/lib/module/storage/utils/mmkvAvailability.web.js +1 -15
- package/lib/module/storage/utils/mmkvTypeDetection.js +1 -148
- package/lib/module/storage/utils/requiredStorageKeyScope.js +1 -13
- package/lib/module/storage/utils/setStorageValue.js +1 -209
- package/lib/module/storage/utils/snapshotProvider.js +1 -380
- package/lib/module/storage/utils/storageActionHelpers.js +1 -42
- package/lib/module/storage/utils/storageBrowserRefresh.js +1 -44
- package/lib/module/storage/utils/storageLabels.js +1 -9
- package/lib/module/storage/utils/storageLabels.web.js +1 -9
- package/lib/module/storage/utils/storageOps.js +1 -46
- package/lib/module/storage/utils/storageQueryUtils.js +1 -30
- package/lib/module/storage/utils/storageTimeTravelUtils.js +1 -281
- package/lib/module/storage/utils/valueType.js +1 -76
- package/lib/web/index.mjs +2 -3
- package/package.json +6 -10
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/TreeDiffViewer.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/modes/ThemedSplitView.d.ts.map +0 -1
- package/lib/typescript/storage/components/DiffViewer/themes/diffThemes.d.ts.map +0 -1
- package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +0 -1
- package/lib/typescript/storage/components/MMKVInstanceInfoPanel.d.ts.map +0 -1
- package/lib/typescript/storage/components/MMKVInstanceSelector.d.ts.map +0 -1
- package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageActionButtons.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageBrowserMode.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventActionButton.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventCard.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventDetailContent.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventFilterView.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageEventsSection.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyCard.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyDetailScreen.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeySection.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageKeyStats.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageModalWithTabs.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageSaveNotice.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageSection.d.ts.map +0 -1
- package/lib/typescript/storage/components/StorageTypeFilterBar.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useAsyncStorageKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +0 -1
- package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +0 -1
- package/lib/typescript/storage/stores/storageEventStore.d.ts.map +0 -1
- package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/storage/types.d.ts.map +0 -1
- package/lib/typescript/storage/utils/AsyncStorageListener.d.ts.map +0 -1
- package/lib/typescript/storage/utils/AsyncStorageListener.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/MMKVInstanceRegistry.d.ts.map +0 -1
- package/lib/typescript/storage/utils/MMKVListener.d.ts.map +0 -1
- package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +0 -1
- package/lib/typescript/storage/utils/asyncStorageCompat.d.ts.map +0 -1
- package/lib/typescript/storage/utils/browserStorageLifecycle.d.ts.map +0 -1
- package/lib/typescript/storage/utils/browserStorageLifecycle.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/clearAllStorage.d.ts.map +0 -1
- package/lib/typescript/storage/utils/deleteStorageKeys.d.ts.map +0 -1
- package/lib/typescript/storage/utils/lineDiff.d.ts.map +0 -1
- package/lib/typescript/storage/utils/mmkvAvailability.d.ts.map +0 -1
- package/lib/typescript/storage/utils/mmkvAvailability.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/mmkvTypeDetection.d.ts.map +0 -1
- package/lib/typescript/storage/utils/requiredStorageKeyScope.d.ts.map +0 -1
- package/lib/typescript/storage/utils/setStorageValue.d.ts.map +0 -1
- package/lib/typescript/storage/utils/snapshotProvider.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageActionHelpers.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageBrowserRefresh.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageLabels.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageLabels.web.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageOps.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageQueryUtils.d.ts.map +0 -1
- package/lib/typescript/storage/utils/storageTimeTravelUtils.d.ts.map +0 -1
- package/lib/typescript/storage/utils/valueType.d.ts.map +0 -1
|
@@ -1,194 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Expo SecureStore Registry
|
|
5
|
-
*
|
|
6
|
-
* SecureStore (iOS Keychain / Android KeyStore) has NO key-enumeration API —
|
|
7
|
-
* unlike AsyncStorage (`getAllKeys`) and MMKV (`getAllKeys()`), there is no way
|
|
8
|
-
* to ask "what's stored?". Apps must therefore register the keys they want
|
|
9
|
-
* visible in the Storage tool.
|
|
10
|
-
*
|
|
11
|
-
* The SecureStore module itself is passed in at registration (never imported
|
|
12
|
-
* here) — the same Metro-safe pattern as `registerMMKVInstance`: this package
|
|
13
|
-
* has zero dependency on `expo-secure-store`, so bare RN apps without it
|
|
14
|
-
* bundle fine.
|
|
15
|
-
*
|
|
16
|
-
* @module SecureStoreRegistry
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Subset of expo-secure-store's SecureStoreOptions that the tool tracks.
|
|
21
|
-
* `keychainService` MUST match what the value was written with, or reads
|
|
22
|
-
* return null. `requireAuthentication` keys trigger a biometric prompt on
|
|
23
|
-
* read, so the tool never auto-reads them.
|
|
24
|
-
*
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Structural type for the expo-secure-store module. Matches
|
|
30
|
-
* `import * as SecureStore from "expo-secure-store"` without depending on it.
|
|
31
|
-
*
|
|
32
|
-
* @public
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* A key to expose in the Storage tool: either a bare key name, or a key with
|
|
37
|
-
* the SecureStore options it was written with (+ optional description shown
|
|
38
|
-
* in the expanded card).
|
|
39
|
-
*
|
|
40
|
-
* @public
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Normalized info for a registered SecureStore key.
|
|
45
|
-
*
|
|
46
|
-
* @public
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
class SecureStoreRegistry {
|
|
50
|
-
module = null;
|
|
51
|
-
keys = new Map();
|
|
52
|
-
listeners = new Set();
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Register the SecureStore module and the keys to expose. Callable multiple
|
|
56
|
-
* times — keys accumulate, the latest module wins.
|
|
57
|
-
*/
|
|
58
|
-
register(module, descriptors) {
|
|
59
|
-
const before = this.signature();
|
|
60
|
-
this.module = module;
|
|
61
|
-
for (const d of descriptors) {
|
|
62
|
-
const entry = typeof d === "string" ? {
|
|
63
|
-
key: d,
|
|
64
|
-
options: {}
|
|
65
|
-
} : {
|
|
66
|
-
key: d.key,
|
|
67
|
-
description: d.description,
|
|
68
|
-
options: {
|
|
69
|
-
keychainService: d.keychainService,
|
|
70
|
-
requireAuthentication: d.requireAuthentication,
|
|
71
|
-
authenticationPrompt: d.authenticationPrompt
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
this.keys.set(entry.key, entry);
|
|
75
|
-
}
|
|
76
|
-
// Only announce a real change. The desktop dashboard re-registers the same
|
|
77
|
-
// key set on every device snapshot, and subscribers re-read the keychain on
|
|
78
|
-
// notify — signature-comparing keeps that from turning into a read storm.
|
|
79
|
-
if (this.signature() !== before) this.notify();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Remove a key from the registry (does not delete the stored value). */
|
|
83
|
-
unregister(key) {
|
|
84
|
-
if (this.keys.delete(key)) this.notify();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Subscribe to registry changes (keys registered/unregistered). Lets the
|
|
89
|
-
* browser pick up keys that register after the tool is already open.
|
|
90
|
-
* Returns an unsubscribe function.
|
|
91
|
-
*/
|
|
92
|
-
subscribe(listener) {
|
|
93
|
-
this.listeners.add(listener);
|
|
94
|
-
return () => {
|
|
95
|
-
this.listeners.delete(listener);
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Content signature of the registered entries (module identity excluded). */
|
|
100
|
-
signature() {
|
|
101
|
-
return JSON.stringify(Array.from(this.keys.values()));
|
|
102
|
-
}
|
|
103
|
-
notify() {
|
|
104
|
-
this.listeners.forEach(listener => {
|
|
105
|
-
try {
|
|
106
|
-
listener();
|
|
107
|
-
} catch {
|
|
108
|
-
// Listener errors are not ours
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** The registered SecureStore module, or null if none registered yet. */
|
|
114
|
-
getModule() {
|
|
115
|
-
return this.module;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** All registered key entries. */
|
|
119
|
-
getAll() {
|
|
120
|
-
return Array.from(this.keys.values());
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/** Number of registered keys. */
|
|
124
|
-
count() {
|
|
125
|
-
return this.keys.size;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Delete a stored value via the registered module, using the options the
|
|
130
|
-
* key was registered with (required for keychainService-scoped keys).
|
|
131
|
-
*/
|
|
132
|
-
async deleteValue(key) {
|
|
133
|
-
const entry = this.keys.get(key);
|
|
134
|
-
if (!this.module || !entry) return;
|
|
135
|
-
await this.module.deleteItemAsync(key, entry.options);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Write a stored value via the registered module, using the options the key
|
|
140
|
-
* was registered with — writing with different `keychainService` options than
|
|
141
|
-
* the value was created with silently creates a SECOND entry the app can't
|
|
142
|
-
* read, so the registered options are the only safe ones to use.
|
|
143
|
-
*
|
|
144
|
-
* Throws rather than no-ops: unlike a delete, a write that quietly did
|
|
145
|
-
* nothing would leave the UI showing a value that was never stored.
|
|
146
|
-
*/
|
|
147
|
-
async setValue(key, value) {
|
|
148
|
-
const entry = this.keys.get(key);
|
|
149
|
-
if (!this.module) throw new Error("No SecureStore module is registered");
|
|
150
|
-
if (!entry) throw new Error(`SecureStore key "${key}" is not registered`);
|
|
151
|
-
if (entry.options.requireAuthentication) {
|
|
152
|
-
throw new Error(`SecureStore key "${key}" is biometric-protected — DevTools never writes it`);
|
|
153
|
-
}
|
|
154
|
-
await this.module.setItemAsync(key, value, entry.options);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Singleton registry instance (advanced usage — most apps only need
|
|
160
|
-
* {@link registerSecureStoreKeys}).
|
|
161
|
-
*/
|
|
162
|
-
export const secureStoreRegistry = new SecureStoreRegistry();
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Register Expo SecureStore keys with React Buoy DevTools.
|
|
166
|
-
*
|
|
167
|
-
* **⚠️ REQUIRED for SecureStore visibility**: SecureStore has no
|
|
168
|
-
* key-enumeration API, so the tool can only show keys you declare here.
|
|
169
|
-
* Pass the module itself so this package never has to import
|
|
170
|
-
* `expo-secure-store`.
|
|
171
|
-
*
|
|
172
|
-
* @example
|
|
173
|
-
* ```typescript
|
|
174
|
-
* import * as SecureStore from "expo-secure-store";
|
|
175
|
-
* import { registerSecureStoreKeys } from "@buoy-gg/storage";
|
|
176
|
-
*
|
|
177
|
-
* registerSecureStoreKeys(SecureStore, [
|
|
178
|
-
* "auth.token",
|
|
179
|
-
* { key: "session", keychainService: "com.myapp.auth" },
|
|
180
|
-
* // Never auto-read; shown as biometric-protected:
|
|
181
|
-
* { key: "pin", requireAuthentication: true },
|
|
182
|
-
* ]);
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
export function registerSecureStoreKeys(module, keys) {
|
|
186
|
-
secureStoreRegistry.register(module, keys);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Remove a key from the DevTools registry (the stored value is untouched).
|
|
191
|
-
*/
|
|
192
|
-
export function unregisterSecureStoreKey(key) {
|
|
193
|
-
secureStoreRegistry.unregister(key);
|
|
194
|
-
}
|
|
1
|
+
"use strict";class n{module=null;keys=new Map;listeners=new Set;register(e,r){const i=this.signature();this.module=e;for(const t of r){const o=typeof t==="string"?{key:t,options:{}}:{key:t.key,description:t.description,options:{keychainService:t.keychainService,requireAuthentication:t.requireAuthentication,authenticationPrompt:t.authenticationPrompt}};this.keys.set(o.key,o)}if(this.signature()!==i)this.notify()}unregister(e){if(this.keys.delete(e))this.notify()}subscribe(e){this.listeners.add(e);return()=>{this.listeners.delete(e)}}signature(){return JSON.stringify(Array.from(this.keys.values()))}notify(){this.listeners.forEach(e=>{try{e()}catch{}})}getModule(){return this.module}getAll(){return Array.from(this.keys.values())}count(){return this.keys.size}async deleteValue(e){const r=this.keys.get(e);if(!this.module||!r)return;await this.module.deleteItemAsync(e,r.options)}async setValue(e,r){const i=this.keys.get(e);if(!this.module)throw new Error("No SecureStore module is registered");if(!i)throw new Error(`SecureStore key "${e}" is not registered`);if(i.options.requireAuthentication){throw new Error(`SecureStore key "${e}" is biometric-protected \u2014 DevTools never writes it`)}await this.module.setItemAsync(e,r,i.options)}}export const secureStoreRegistry=new n;export function registerSecureStoreKeys(s,e){secureStoreRegistry.register(s,e)}export function unregisterSecureStoreKey(s){secureStoreRegistry.unregister(s)}
|
|
@@ -1,81 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* AsyncStorage compatibility adapter (v2 + v3)
|
|
5
|
-
*
|
|
6
|
-
* `@react-native-async-storage/async-storage` 3.x reshaped the default-export
|
|
7
|
-
* API. The single-item methods kept their v2 signatures, but the batch + merge
|
|
8
|
-
* methods changed:
|
|
9
|
-
*
|
|
10
|
-
* v2 (what this package was written against) v3
|
|
11
|
-
* ------------------------------------------ --------------------------------
|
|
12
|
-
* multiGet(keys): [key, value|null][] getMany(keys): Record<key, value|null>
|
|
13
|
-
* multiSet([[k, v]]): void setMany({ k: v }): void
|
|
14
|
-
* multiRemove(keys): void removeMany(keys): void
|
|
15
|
-
* mergeItem / multiMerge removed entirely
|
|
16
|
-
*
|
|
17
|
-
* This module is the single seam between the storage tool and whichever
|
|
18
|
-
* async-storage version the host app installed. The rest of the package always
|
|
19
|
-
* speaks the v2 tuple-shaped API; we translate to v3 here when needed.
|
|
20
|
-
*
|
|
21
|
-
* Reads (`readMany`) are routed through the *unswizzled* native methods, so the
|
|
22
|
-
* event listener can safely call them while capturing previous values without
|
|
23
|
-
* re-triggering itself.
|
|
24
|
-
*/
|
|
25
|
-
import RawAsyncStorage from "@react-native-async-storage/async-storage";
|
|
26
|
-
|
|
27
|
-
// Loosely typed because the surface differs across major versions; callers go
|
|
28
|
-
// through the helpers below rather than touching this directly.
|
|
29
|
-
|
|
30
|
-
/** The live default-export object (methods may be swizzled by the listener). */
|
|
31
|
-
export const asyncStorage = RawAsyncStorage;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Capability flags describing which API surface the installed version exposes.
|
|
35
|
-
* `multiGet` only exists on v2; `mergeItem` was removed in v3.
|
|
36
|
-
*/
|
|
37
|
-
export const asyncStorageCaps = {
|
|
38
|
-
/** v2 exposes multiGet/multiSet/multiRemove; v3 renamed these to *Many. */
|
|
39
|
-
hasLegacyMultiApi: typeof asyncStorage?.multiGet === "function",
|
|
40
|
-
/** v3 removed mergeItem/multiMerge with no replacement. */
|
|
41
|
-
hasMergeApi: typeof asyncStorage?.mergeItem === "function"
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Batch-read keys, normalized to the v2 `[key, value|null][]` tuple shape and
|
|
46
|
-
* preserving the requested key order regardless of installed version.
|
|
47
|
-
*/
|
|
48
|
-
export async function readMany(keys) {
|
|
49
|
-
if (typeof asyncStorage.multiGet === "function") {
|
|
50
|
-
return await asyncStorage.multiGet(keys);
|
|
51
|
-
}
|
|
52
|
-
// v3: getMany returns a Record; rebuild ordered tuples ("what you request is
|
|
53
|
-
// what you get" — missing keys come back as null).
|
|
54
|
-
const record = await asyncStorage.getMany(keys);
|
|
55
|
-
return keys.map(key => [key, record[key] ?? null]);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Batch-write key/value pairs. Calls the live method (which may be swizzled by
|
|
60
|
-
* the listener on v2's `multiSet` / v3's `setMany`) so writes still emit events.
|
|
61
|
-
*/
|
|
62
|
-
export async function writeMany(pairs) {
|
|
63
|
-
if (typeof asyncStorage.multiSet === "function") {
|
|
64
|
-
return asyncStorage.multiSet(pairs);
|
|
65
|
-
}
|
|
66
|
-
const record = {};
|
|
67
|
-
for (const [key, value] of pairs) record[key] = value;
|
|
68
|
-
return asyncStorage.setMany(record);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Batch-remove keys via the live method (swizzled on v2's `multiRemove` /
|
|
73
|
-
* v3's `removeMany`).
|
|
74
|
-
*/
|
|
75
|
-
export async function removeMany(keys) {
|
|
76
|
-
if (typeof asyncStorage.multiRemove === "function") {
|
|
77
|
-
return asyncStorage.multiRemove(keys);
|
|
78
|
-
}
|
|
79
|
-
return asyncStorage.removeMany(keys);
|
|
80
|
-
}
|
|
81
|
-
export default asyncStorage;
|
|
1
|
+
"use strict";import r from"@react-native-async-storage/async-storage";export const asyncStorage=r;export const asyncStorageCaps={hasLegacyMultiApi:typeof asyncStorage?.multiGet==="function",hasMergeApi:typeof asyncStorage?.mergeItem==="function"};export async function readMany(t){if(typeof asyncStorage.multiGet==="function"){return await asyncStorage.multiGet(t)}const e=await asyncStorage.getMany(t);return t.map(n=>[n,e[n]??null])}export async function writeMany(t){if(typeof asyncStorage.multiSet==="function"){return asyncStorage.multiSet(t)}const e={};for(const[n,o]of t)e[n]=o;return asyncStorage.setMany(e)}export async function removeMany(t){if(typeof asyncStorage.multiRemove==="function"){return asyncStorage.multiRemove(t)}return asyncStorage.removeMany(t)}export default asyncStorage;
|
|
@@ -1,66 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { getBrowserStorage, subscribeToBrowserStorage } from '@buoy-gg/shared-ui/utils';
|
|
4
|
-
import { registerMMKVInstance, unregisterMMKVInstance } from './MMKVInstanceRegistry';
|
|
5
|
-
let owners = 0;
|
|
6
|
-
const storage = () => getBrowserStorage('sessionStorage');
|
|
7
|
-
const keys = () => Array.from({
|
|
8
|
-
length: storage().length
|
|
9
|
-
}, (_, index) => storage().key(index)).filter(key => key !== null);
|
|
10
|
-
// Reuse the synchronous storage editor and snapshot provider with Web Storage strings.
|
|
11
|
-
const sessionBackend = {
|
|
12
|
-
set(key, value) {
|
|
13
|
-
storage().setItem(key, String(value));
|
|
14
|
-
},
|
|
15
|
-
getString(key) {
|
|
16
|
-
return storage().getItem(key) ?? undefined;
|
|
17
|
-
},
|
|
18
|
-
getNumber() {
|
|
19
|
-
return undefined;
|
|
20
|
-
},
|
|
21
|
-
getBoolean() {
|
|
22
|
-
return undefined;
|
|
23
|
-
},
|
|
24
|
-
getBuffer() {
|
|
25
|
-
return undefined;
|
|
26
|
-
},
|
|
27
|
-
contains(key) {
|
|
28
|
-
return storage().getItem(key) !== null;
|
|
29
|
-
},
|
|
30
|
-
delete(key) {
|
|
31
|
-
const found = this.contains(key);
|
|
32
|
-
storage().removeItem(key);
|
|
33
|
-
return found;
|
|
34
|
-
},
|
|
35
|
-
getAllKeys: keys,
|
|
36
|
-
clearAll() {
|
|
37
|
-
storage().clear();
|
|
38
|
-
},
|
|
39
|
-
get size() {
|
|
40
|
-
return keys().reduce((bytes, key) => bytes + 2 * (key.length + (storage().getItem(key)?.length ?? 0)), 0);
|
|
41
|
-
},
|
|
42
|
-
addOnValueChangedListener(listener) {
|
|
43
|
-
return {
|
|
44
|
-
remove: subscribeToBrowserStorage(change => {
|
|
45
|
-
if (change.area !== 'sessionStorage') return;
|
|
46
|
-
if (change.key !== undefined) listener(change.key);else change.prevPairs?.forEach(([key]) => listener(key));
|
|
47
|
-
})
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
export function startBrowserStorageCapture() {
|
|
52
|
-
if (typeof window === 'undefined') return () => {};
|
|
53
|
-
try {
|
|
54
|
-
storage();
|
|
55
|
-
} catch {
|
|
56
|
-
return () => {};
|
|
57
|
-
}
|
|
58
|
-
if (++owners === 1) registerMMKVInstance('sessionStorage', sessionBackend);
|
|
59
|
-
let active = true;
|
|
60
|
-
return () => {
|
|
61
|
-
if (active) {
|
|
62
|
-
active = false;
|
|
63
|
-
if (--owners === 0) unregisterMMKVInstance('sessionStorage');
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
}
|
|
1
|
+
"use strict";import{getBrowserStorage as i,subscribeToBrowserStorage as u}from"@buoy-gg/shared-ui/utils";import{registerMMKVInstance as a,unregisterMMKVInstance as g}from"./MMKVInstanceRegistry";let n=0;const r=()=>i("sessionStorage");const s=()=>Array.from({length:r().length},(e,t)=>r().key(t)).filter(e=>e!==null);const f={set(e,t){r().setItem(e,String(t))},getString(e){return r().getItem(e)??void 0},getNumber(){return void 0},getBoolean(){return void 0},getBuffer(){return void 0},contains(e){return r().getItem(e)!==null},delete(e){const t=this.contains(e);r().removeItem(e);return t},getAllKeys:s,clearAll(){r().clear()},get size(){return s().reduce((e,t)=>e+2*(t.length+(r().getItem(t)?.length??0)),0)},addOnValueChangedListener(e){return{remove:u(t=>{if(t.area!=="sessionStorage")return;if(t.key!==void 0)e(t.key);else t.prevPairs?.forEach(([o])=>e(o))})}}};export function startBrowserStorageCapture(){if(typeof window==="undefined")return()=>{};try{r()}catch{return()=>{}}if(++n===1)a("sessionStorage",f);let e=true;return()=>{if(e){e=false;if(--n===0)g("sessionStorage")}}}
|
|
@@ -1,43 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
4
|
-
import { removeMany } from "./asyncStorageCompat";
|
|
5
|
-
import { isDevToolsStorageKey } from "@buoy-gg/shared-ui";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Clear all storage data except dev tools keys
|
|
9
|
-
* This preserves dev tool settings while clearing app data
|
|
10
|
-
*/
|
|
11
|
-
export async function clearAllAppStorage() {
|
|
12
|
-
// Get all keys
|
|
13
|
-
const allKeys = await AsyncStorage.getAllKeys();
|
|
14
|
-
if (!allKeys || allKeys.length === 0) {
|
|
15
|
-
// No keys to clear
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Filter out dev tool keys - we don't want to clear those
|
|
20
|
-
const keysToRemove = allKeys.filter(key => !isDevToolsStorageKey(key));
|
|
21
|
-
if (keysToRemove.length === 0) {
|
|
22
|
-
// No app keys to clear (only dev tool keys found)
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Clearing ${keysToRemove.length} app storage keys
|
|
27
|
-
|
|
28
|
-
// Remove all non-dev-tool keys
|
|
29
|
-
await removeMany(keysToRemove);
|
|
30
|
-
|
|
31
|
-
// Successfully cleared app storage
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Clear absolutely all storage data including dev tools
|
|
36
|
-
* Use with caution - this will reset all dev tool settings
|
|
37
|
-
*/
|
|
38
|
-
export async function clearAllStorageIncludingDevTools() {
|
|
39
|
-
// Clear everything
|
|
40
|
-
await AsyncStorage.clear();
|
|
41
|
-
|
|
42
|
-
// Successfully cleared all storage including dev tools
|
|
43
|
-
}
|
|
1
|
+
"use strict";import o from"@react-native-async-storage/async-storage";import{removeMany as a}from"./asyncStorageCompat";import{isDevToolsStorageKey as l}from"@buoy-gg/shared-ui";export async function clearAllAppStorage(){const e=await o.getAllKeys();if(!e||e.length===0){return}const t=e.filter(r=>!l(r));if(t.length===0){return}await a(t)}export async function clearAllStorageIncludingDevTools(){await o.clear()}
|
|
@@ -1,78 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Deleting storage keys, in one place.
|
|
5
|
-
*
|
|
6
|
-
* Each backend removes keys differently — AsyncStorage takes a batch,
|
|
7
|
-
* SecureStore has to go through the registry (only it knows each key's
|
|
8
|
-
* `keychainService` options), and MMKV deletes per registered instance. A
|
|
9
|
-
* second copy of that fan-out is exactly how one backend quietly stops being
|
|
10
|
-
* cleaned up — which is not hypothetical: the MMKV branch called a method
|
|
11
|
-
* react-native-mmkv v4 had renamed, and deleting an MMKV key silently did
|
|
12
|
-
* nothing until an e2e test deleted from all three backends at once.
|
|
13
|
-
*
|
|
14
|
-
* One call site today: the selection action bar. Deleting is deliberately not
|
|
15
|
-
* an affordance on the row itself — see `StorageKeyRow`, whose expanded card
|
|
16
|
-
* carries three actions and only one of them changes anything.
|
|
17
|
-
*
|
|
18
|
-
* Pro gating and confirmation are deliberately NOT here: they belong to the UI
|
|
19
|
-
* that has the user's attention. This function assumes the caller already asked.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { removeMany } from "./asyncStorageCompat";
|
|
23
|
-
import { secureStoreRegistry } from "./SecureStoreRegistry";
|
|
24
|
-
/**
|
|
25
|
-
* Remove one key from an MMKV instance, whichever version it is.
|
|
26
|
-
*
|
|
27
|
-
* react-native-mmkv v4 renamed `delete(key)` to `remove(key)`. Calling the old
|
|
28
|
-
* name on a v4 instance throws, and because the callers wrap deletion in a
|
|
29
|
-
* try/catch that only surfaces an alert, the visible result was a key that
|
|
30
|
-
* refused to delete — the same shape as a permissions problem or a read-only
|
|
31
|
-
* instance, and nothing to point at the real cause.
|
|
32
|
-
*
|
|
33
|
-
* `storageSyncAdapter` and `snapshotProvider` already did this; this path was
|
|
34
|
-
* the one that missed it.
|
|
35
|
-
*/
|
|
36
|
-
function removeMMKVKey(instance, key) {
|
|
37
|
-
if (typeof instance.remove === "function") {
|
|
38
|
-
instance.remove(key);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (typeof instance.delete === "function") {
|
|
42
|
-
instance.delete(key);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
throw new Error("MMKV instance exposes neither remove() nor delete()");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Removes every key from whichever backend holds it. Rejects on the first
|
|
50
|
-
* failure — callers surface that, rather than reporting a partial delete as
|
|
51
|
-
* success.
|
|
52
|
-
*/
|
|
53
|
-
export async function deleteStorageKeys(keys, mmkvInstances) {
|
|
54
|
-
if (keys.length === 0) return;
|
|
55
|
-
const asyncKeys = keys.filter(k => k.storageType === "async");
|
|
56
|
-
const mmkvKeys = keys.filter(k => k.storageType === "mmkv");
|
|
57
|
-
const secureKeys = keys.filter(k => k.storageType === "secure");
|
|
58
|
-
if (asyncKeys.length > 0) {
|
|
59
|
-
await removeMany(asyncKeys.map(k => k.key));
|
|
60
|
-
}
|
|
61
|
-
for (const k of secureKeys) {
|
|
62
|
-
await secureStoreRegistry.deleteValue(k.key);
|
|
63
|
-
}
|
|
64
|
-
if (mmkvKeys.length > 0) {
|
|
65
|
-
const byInstance = {};
|
|
66
|
-
mmkvKeys.forEach(k => {
|
|
67
|
-
const instanceId = k.instanceId || "default";
|
|
68
|
-
if (!byInstance[instanceId]) byInstance[instanceId] = [];
|
|
69
|
-
byInstance[instanceId].push(k.key);
|
|
70
|
-
});
|
|
71
|
-
Object.entries(byInstance).forEach(([instanceId, instanceKeys]) => {
|
|
72
|
-
const inst = mmkvInstances.find(i => i.id === instanceId);
|
|
73
|
-
if (inst) {
|
|
74
|
-
instanceKeys.forEach(key => removeMMKVKey(inst.instance, key));
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
1
|
+
"use strict";import{removeMany as y}from"./asyncStorageCompat";import{secureStoreRegistry as m}from"./SecureStoreRegistry";function u(t,o){if(typeof t.remove==="function"){t.remove(o);return}if(typeof t.delete==="function"){t.delete(o);return}throw new Error("MMKV instance exposes neither remove() nor delete()")}export async function deleteStorageKeys(t,o){if(t.length===0)return;const i=t.filter(e=>e.storageType==="async");const f=t.filter(e=>e.storageType==="mmkv");const a=t.filter(e=>e.storageType==="secure");if(i.length>0){await y(i.map(e=>e.key))}for(const e of a){await m.deleteValue(e.key)}if(f.length>0){const e={};f.forEach(n=>{const r=n.instanceId||"default";if(!e[r])e[r]=[];e[r].push(n.key)});Object.entries(e).forEach(([n,r])=>{const c=o.find(s=>s.id===n);if(c){r.forEach(s=>u(c.instance,s))}})}}
|
|
@@ -1,12 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Line-by-line diff computation.
|
|
5
|
-
*
|
|
6
|
-
* This used to be a verbatim copy of the shared implementation, which meant a
|
|
7
|
-
* diff fix had to be made twice. It now re-exports the canonical one so the
|
|
8
|
-
* storage split view, the tree view, and every other tool's diff (redux, jotai,
|
|
9
|
-
* highlight-updates) share a single algorithm.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
export { computeLineDiff, DiffType, ABSENT_VALUE, isAbsent } from "@buoy-gg/shared-ui/dataViewer";
|
|
1
|
+
"use strict";export{computeLineDiff,DiffType,ABSENT_VALUE,isAbsent}from"@buoy-gg/shared-ui/dataViewer";
|
|
@@ -1,56 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MMKV Availability Detection
|
|
5
|
-
*
|
|
6
|
-
* Safely detects if react-native-mmkv is available in the current environment.
|
|
7
|
-
* This allows the app to work in Expo Go where native modules aren't available.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
let _isMMKVAvailable = null;
|
|
11
|
-
let _MMKVClass = null;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Check if MMKV is available in the current environment
|
|
15
|
-
*
|
|
16
|
-
* @returns True if react-native-mmkv is installed and available
|
|
17
|
-
*/
|
|
18
|
-
export function isMMKVAvailable() {
|
|
19
|
-
// Cache the result after first check
|
|
20
|
-
if (_isMMKVAvailable !== null) {
|
|
21
|
-
return _isMMKVAvailable;
|
|
22
|
-
}
|
|
23
|
-
try {
|
|
24
|
-
// Attempt to require MMKV
|
|
25
|
-
const MMKVModule = require('react-native-mmkv');
|
|
26
|
-
|
|
27
|
-
// v4 uses createMMKV factory function, v3 used MMKV class
|
|
28
|
-
// Try v4 API first (recommended), fall back to v3
|
|
29
|
-
_MMKVClass = MMKVModule.createMMKV || MMKVModule.MMKV;
|
|
30
|
-
_isMMKVAvailable = _MMKVClass !== undefined;
|
|
31
|
-
return _isMMKVAvailable;
|
|
32
|
-
} catch (error) {
|
|
33
|
-
// MMKV is not available (e.g., Expo Go, not installed)
|
|
34
|
-
_isMMKVAvailable = false;
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get the MMKV class if available
|
|
41
|
-
*
|
|
42
|
-
* @returns MMKV class or null if not available
|
|
43
|
-
*/
|
|
44
|
-
export function getMMKVClass() {
|
|
45
|
-
if (!isMMKVAvailable()) {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
return _MMKVClass;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Get a user-friendly error message when MMKV is not available
|
|
53
|
-
*/
|
|
54
|
-
export function getMMKVUnavailableMessage() {
|
|
55
|
-
return 'MMKV is not available in this environment. MMKV requires native modules and cannot run in Expo Go. Please use a development build or EAS Build.';
|
|
56
|
-
}
|
|
1
|
+
"use strict";let e=null;let t=null;export function isMMKVAvailable(){if(e!==null){return e}try{const n=require("react-native-mmkv");t=n.createMMKV||n.MMKV;e=t!==void 0;return e}catch(n){e=false;return false}}export function getMMKVClass(){if(!isMMKVAvailable()){return null}return t}export function getMMKVUnavailableMessage(){return"MMKV is not available in this environment. MMKV requires native modules and cannot run in Expo Go. Please use a development build or EAS Build."}
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
export function isMMKVAvailable() {
|
|
4
|
-
try {
|
|
5
|
-
return typeof window !== 'undefined' && !!window.sessionStorage;
|
|
6
|
-
} catch {
|
|
7
|
-
return false;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
export function getMMKVClass() {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
export function getMMKVUnavailableMessage() {
|
|
14
|
-
return 'Session storage is unavailable in this browser context.';
|
|
15
|
-
}
|
|
1
|
+
"use strict";export function isMMKVAvailable(){try{return typeof window!=="undefined"&&!!window.sessionStorage}catch{return false}}export function getMMKVClass(){return null}export function getMMKVUnavailableMessage(){return"Session storage is unavailable in this browser context."}
|