react-native-nitro-storage 0.4.0 → 0.4.3
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 +90 -0
- package/android/build.gradle +0 -12
- package/android/consumer-rules.pro +26 -4
- package/android/src/main/cpp/AndroidStorageAdapterCpp.cpp +7 -10
- package/android/src/main/cpp/AndroidStorageAdapterCpp.hpp +0 -4
- package/android/src/main/cpp/cpp-adapter.cpp +3 -1
- package/android/src/main/java/com/nitrostorage/AndroidStorageAdapter.kt +172 -77
- package/cpp/bindings/HybridStorage.cpp +120 -69
- package/cpp/bindings/HybridStorage.hpp +4 -0
- package/ios/IOSStorageAdapterCpp.hpp +2 -1
- package/ios/IOSStorageAdapterCpp.mm +264 -49
- package/lib/commonjs/index.js +128 -20
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +169 -41
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/indexeddb-backend.js +130 -0
- package/lib/commonjs/indexeddb-backend.js.map +1 -0
- package/lib/commonjs/internal.js +51 -23
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/module/index.js +121 -20
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +162 -41
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/indexeddb-backend.js +126 -0
- package/lib/module/indexeddb-backend.js.map +1 -0
- package/lib/module/internal.js +51 -23
- package/lib/module/internal.js.map +1 -1
- package/lib/typescript/index.d.ts +6 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.web.d.ts +7 -1
- package/lib/typescript/index.web.d.ts.map +1 -1
- package/lib/typescript/indexeddb-backend.d.ts +29 -0
- package/lib/typescript/indexeddb-backend.d.ts.map +1 -0
- package/lib/typescript/internal.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroStorageOnLoad.cpp +22 -17
- package/nitrogen/generated/android/NitroStorageOnLoad.hpp +13 -4
- package/package.json +7 -3
- package/src/index.ts +137 -27
- package/src/index.web.ts +182 -49
- package/src/indexeddb-backend.ts +143 -0
- package/src/internal.ts +51 -23
|
@@ -84,13 +84,17 @@ export declare const storage: {
|
|
|
84
84
|
getByPrefix: (prefix: string, scope: StorageScope) => Record<string, string>;
|
|
85
85
|
getAll: (scope: StorageScope) => Record<string, string>;
|
|
86
86
|
size: (scope: StorageScope) => number;
|
|
87
|
-
setAccessControl: (
|
|
87
|
+
setAccessControl: (level: AccessControl) => void;
|
|
88
88
|
setSecureWritesAsync: (_enabled: boolean) => void;
|
|
89
89
|
flushSecureWrites: () => void;
|
|
90
90
|
setKeychainAccessGroup: (_group: string) => void;
|
|
91
91
|
setMetricsObserver: (observer?: StorageMetricsObserver) => void;
|
|
92
92
|
getMetricsSnapshot: () => Record<string, StorageMetricSummary>;
|
|
93
93
|
resetMetrics: () => void;
|
|
94
|
+
getString: (key: string, scope: StorageScope) => string | undefined;
|
|
95
|
+
setString: (key: string, value: string, scope: StorageScope) => void;
|
|
96
|
+
deleteString: (key: string, scope: StorageScope) => void;
|
|
97
|
+
import: (data: Record<string, string>, scope: StorageScope) => void;
|
|
94
98
|
};
|
|
95
99
|
export declare function setWebSecureStorageBackend(backend?: WebSecureStorageBackend): void;
|
|
96
100
|
export declare function getWebSecureStorageBackend(): WebSecureStorageBackend | undefined;
|
|
@@ -126,6 +130,7 @@ export interface StorageItem<T> {
|
|
|
126
130
|
}
|
|
127
131
|
export declare function createStorageItem<T = undefined>(config: StorageItemConfig<T>): StorageItem<T>;
|
|
128
132
|
export { useStorage, useStorageSelector, useSetStorage } from "./storage-hooks";
|
|
133
|
+
export { createIndexedDBBackend } from "./indexeddb-backend";
|
|
129
134
|
type BatchReadItem<T> = Pick<StorageItem<T>, "key" | "scope" | "get" | "deserialize"> & {
|
|
130
135
|
_hasValidation?: boolean;
|
|
131
136
|
_hasExpiration?: boolean;
|
|
@@ -154,4 +159,5 @@ export type SecureAuthStorageConfig<K extends string = string> = Record<K, {
|
|
|
154
159
|
export declare function createSecureAuthStorage<K extends string>(config: SecureAuthStorageConfig<K>, options?: {
|
|
155
160
|
namespace?: string;
|
|
156
161
|
}): Record<K, StorageItem<string>>;
|
|
162
|
+
export declare function isKeychainLockedError(_err: unknown): boolean;
|
|
157
163
|
//# sourceMappingURL=index.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../src/index.web.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../src/index.web.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WebSecureStorageBackend } from "./index.web";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a `WebSecureStorageBackend` backed by IndexedDB.
|
|
4
|
+
*
|
|
5
|
+
* IndexedDB is async, but `WebSecureStorageBackend` requires a synchronous
|
|
6
|
+
* interface. This implementation bridges the gap with a write-through in-memory
|
|
7
|
+
* cache:
|
|
8
|
+
*
|
|
9
|
+
* - **Reads** are always served from the in-memory cache (synchronous, O(1)).
|
|
10
|
+
* - **Writes** update the cache synchronously, then persist to IndexedDB
|
|
11
|
+
* asynchronously in the background.
|
|
12
|
+
* - **Initialisation**: the returned backend pre-loads all persisted entries
|
|
13
|
+
* from IndexedDB into memory before resolving, so the first synchronous read
|
|
14
|
+
* after `await createIndexedDBBackend()` already returns the correct value.
|
|
15
|
+
*
|
|
16
|
+
* @param dbName Name of the IndexedDB database. Defaults to `"nitro-storage-secure"`.
|
|
17
|
+
* @param storeName Name of the object store inside the database. Defaults to `"keyvalue"`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { setWebSecureStorageBackend } from "react-native-nitro-storage";
|
|
22
|
+
* import { createIndexedDBBackend } from "react-native-nitro-storage/indexeddb-backend";
|
|
23
|
+
*
|
|
24
|
+
* const backend = await createIndexedDBBackend();
|
|
25
|
+
* setWebSecureStorageBackend(backend);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function createIndexedDBBackend(dbName?: string, storeName?: string): Promise<WebSecureStorageBackend>;
|
|
29
|
+
//# sourceMappingURL=indexeddb-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexeddb-backend.d.ts","sourceRoot":"","sources":["../../src/indexeddb-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAgC3D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,SAAkB,EACxB,SAAS,SAAqB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,CAiFlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,eAAO,MAAM,qBAAqB,wCAAwC,CAAC;AAC3E,eAAO,MAAM,6BAA6B,wCACH,CAAC;
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,eAAO,MAAM,qBAAqB,wCAAwC,CAAC;AAC3E,eAAO,MAAM,6BAA6B,wCACH,CAAC;AAcxC,MAAM,MAAM,cAAc,GAAG;IAC3B,sBAAsB,EAAE,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAWxE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAQ1D;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,KAAK,EAAE,YAAY,GAClB,IAAI,CAaN;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEpE;AAED,wBAAgB,8BAA8B,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAqClE;AASD,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAqCpE;AAWD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAgBnD"}
|
|
@@ -20,25 +20,30 @@
|
|
|
20
20
|
namespace margelo::nitro::NitroStorage {
|
|
21
21
|
|
|
22
22
|
int initialize(JavaVM* vm) {
|
|
23
|
+
return facebook::jni::initialize(vm, []() {
|
|
24
|
+
::margelo::nitro::NitroStorage::registerAllNatives();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
void registerAllNatives() {
|
|
23
31
|
using namespace margelo::nitro;
|
|
24
32
|
using namespace margelo::nitro::NitroStorage;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
);
|
|
41
|
-
});
|
|
33
|
+
|
|
34
|
+
// Register native JNI methods
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// Register Nitro Hybrid Objects
|
|
38
|
+
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
39
|
+
"Storage",
|
|
40
|
+
[]() -> std::shared_ptr<HybridObject> {
|
|
41
|
+
static_assert(std::is_default_constructible_v<HybridStorage>,
|
|
42
|
+
"The HybridObject \"HybridStorage\" is not default-constructible! "
|
|
43
|
+
"Create a public constructor that takes zero arguments to be able to autolink this HybridObject.");
|
|
44
|
+
return std::make_shared<HybridStorage>();
|
|
45
|
+
}
|
|
46
|
+
);
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
} // namespace margelo::nitro::NitroStorage
|
|
@@ -6,20 +6,29 @@
|
|
|
6
6
|
///
|
|
7
7
|
|
|
8
8
|
#include <jni.h>
|
|
9
|
+
#include <functional>
|
|
9
10
|
#include <NitroModules/NitroDefines.hpp>
|
|
10
11
|
|
|
11
12
|
namespace margelo::nitro::NitroStorage {
|
|
12
13
|
|
|
14
|
+
[[deprecated("Use registerNatives() instead.")]]
|
|
15
|
+
int initialize(JavaVM* vm);
|
|
16
|
+
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
15
|
-
* Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`)
|
|
18
|
+
* Register the native (C++) part of NitroStorage, and autolinks all Hybrid Objects.
|
|
19
|
+
* Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`),
|
|
20
|
+
* inside a `facebook::jni::initialize(vm, ...)` call.
|
|
16
21
|
* Example:
|
|
17
22
|
* ```cpp (cpp-adapter.cpp)
|
|
18
23
|
* JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
|
|
19
|
-
* return
|
|
24
|
+
* return facebook::jni::initialize(vm, []() {
|
|
25
|
+
* // register all NitroStorage HybridObjects
|
|
26
|
+
* margelo::nitro::NitroStorage::registerNatives();
|
|
27
|
+
* // any other custom registrations go here.
|
|
28
|
+
* });
|
|
20
29
|
* }
|
|
21
30
|
* ```
|
|
22
31
|
*/
|
|
23
|
-
|
|
32
|
+
void registerAllNatives();
|
|
24
33
|
|
|
25
34
|
} // namespace margelo::nitro::NitroStorage
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-storage",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "The fastest, most complete storage solution for React Native. Synchronous Memory, Disk, and Secure storage in one unified API. Built with Nitro Modules.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"browser": "./src/index.web.ts",
|
|
17
17
|
"default": "./lib/commonjs/index.js"
|
|
18
18
|
},
|
|
19
|
+
"./indexeddb-backend": {
|
|
20
|
+
"types": "./lib/typescript/indexeddb-backend.d.ts",
|
|
21
|
+
"default": "./lib/commonjs/indexeddb-backend.js"
|
|
22
|
+
},
|
|
19
23
|
"./app.plugin": "./app.plugin.js",
|
|
20
24
|
"./app.plugin.js": "./app.plugin.js",
|
|
21
25
|
"./package.json": "./package.json"
|
|
@@ -91,11 +95,11 @@
|
|
|
91
95
|
"registry": "https://registry.npmjs.org/"
|
|
92
96
|
},
|
|
93
97
|
"devDependencies": {
|
|
94
|
-
"@expo/config-plugins": "^
|
|
98
|
+
"@expo/config-plugins": "^55.0.3",
|
|
95
99
|
"@react-native/babel-preset": "^0.83.2",
|
|
96
100
|
"@testing-library/react-hooks": "^8.0.1",
|
|
97
101
|
"@testing-library/react-native": "^13.3.3",
|
|
98
|
-
"@types/react": "~19.
|
|
102
|
+
"@types/react": "~19.2.0",
|
|
99
103
|
"typescript": "^5.9.3"
|
|
100
104
|
},
|
|
101
105
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -173,6 +173,9 @@ function measureOperation<T>(
|
|
|
173
173
|
fn: () => T,
|
|
174
174
|
keysCount = 1,
|
|
175
175
|
): T {
|
|
176
|
+
if (!metricsObserver) {
|
|
177
|
+
return fn();
|
|
178
|
+
}
|
|
176
179
|
const start = Date.now();
|
|
177
180
|
try {
|
|
178
181
|
return fn();
|
|
@@ -215,13 +218,20 @@ function clearScopeRawCache(scope: NonMemoryScope): void {
|
|
|
215
218
|
}
|
|
216
219
|
|
|
217
220
|
function notifyKeyListeners(registry: KeyListenerRegistry, key: string): void {
|
|
218
|
-
registry.get(key)
|
|
221
|
+
const listeners = registry.get(key);
|
|
222
|
+
if (listeners) {
|
|
223
|
+
for (const listener of listeners) {
|
|
224
|
+
listener();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
function notifyAllListeners(registry: KeyListenerRegistry): void {
|
|
222
|
-
registry.
|
|
223
|
-
|
|
224
|
-
|
|
230
|
+
for (const listeners of registry.values()) {
|
|
231
|
+
for (const listener of listeners) {
|
|
232
|
+
listener();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
225
235
|
}
|
|
226
236
|
|
|
227
237
|
function addKeyListener(
|
|
@@ -470,7 +480,12 @@ export const storage = {
|
|
|
470
480
|
flushSecureWrites();
|
|
471
481
|
}
|
|
472
482
|
|
|
473
|
-
|
|
483
|
+
const scopeCache = getScopeRawCache(scope);
|
|
484
|
+
for (const key of scopeCache.keys()) {
|
|
485
|
+
if (isNamespaced(key, namespace)) {
|
|
486
|
+
scopeCache.delete(key);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
474
489
|
getStorageModule().removeByPrefix(keyPrefix, scope);
|
|
475
490
|
});
|
|
476
491
|
},
|
|
@@ -616,6 +631,50 @@ export const storage = {
|
|
|
616
631
|
resetMetrics: () => {
|
|
617
632
|
metricsCounters.clear();
|
|
618
633
|
},
|
|
634
|
+
getString: (key: string, scope: StorageScope): string | undefined => {
|
|
635
|
+
return measureOperation("storage:getString", scope, () => {
|
|
636
|
+
return getRawValue(key, scope);
|
|
637
|
+
});
|
|
638
|
+
},
|
|
639
|
+
setString: (key: string, value: string, scope: StorageScope): void => {
|
|
640
|
+
measureOperation("storage:setString", scope, () => {
|
|
641
|
+
setRawValue(key, value, scope);
|
|
642
|
+
});
|
|
643
|
+
},
|
|
644
|
+
deleteString: (key: string, scope: StorageScope): void => {
|
|
645
|
+
measureOperation("storage:deleteString", scope, () => {
|
|
646
|
+
removeRawValue(key, scope);
|
|
647
|
+
});
|
|
648
|
+
},
|
|
649
|
+
import: (data: Record<string, string>, scope: StorageScope): void => {
|
|
650
|
+
const keys = Object.keys(data);
|
|
651
|
+
measureOperation(
|
|
652
|
+
"storage:import",
|
|
653
|
+
scope,
|
|
654
|
+
() => {
|
|
655
|
+
assertValidScope(scope);
|
|
656
|
+
if (keys.length === 0) return;
|
|
657
|
+
const values = keys.map((k) => data[k]!);
|
|
658
|
+
|
|
659
|
+
if (scope === StorageScope.Memory) {
|
|
660
|
+
keys.forEach((key, index) => {
|
|
661
|
+
memoryStore.set(key, values[index]);
|
|
662
|
+
});
|
|
663
|
+
keys.forEach((key) => notifyKeyListeners(memoryListeners, key));
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
if (scope === StorageScope.Secure) {
|
|
668
|
+
flushSecureWrites();
|
|
669
|
+
getStorageModule().setSecureAccessControl(secureDefaultAccessControl);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
getStorageModule().setBatch(keys, values, scope);
|
|
673
|
+
keys.forEach((key, index) => cacheRawValue(scope, key, values[index]));
|
|
674
|
+
},
|
|
675
|
+
keys.length,
|
|
676
|
+
);
|
|
677
|
+
},
|
|
619
678
|
};
|
|
620
679
|
|
|
621
680
|
export function setWebSecureStorageBackend(
|
|
@@ -667,6 +726,7 @@ export interface StorageItem<T> {
|
|
|
667
726
|
|
|
668
727
|
type StorageItemInternal<T> = StorageItem<T> & {
|
|
669
728
|
_triggerListeners: () => void;
|
|
729
|
+
_invalidateParsedCacheOnly: () => void;
|
|
670
730
|
_hasValidation: boolean;
|
|
671
731
|
_hasExpiration: boolean;
|
|
672
732
|
_readCacheEnabled: boolean;
|
|
@@ -792,17 +852,18 @@ export function createStorageItem<T = undefined>(
|
|
|
792
852
|
return memoryStore.get(storageKey);
|
|
793
853
|
}
|
|
794
854
|
|
|
795
|
-
if (
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
return readPendingSecureWrite(storageKey);
|
|
855
|
+
if (nonMemoryScope === StorageScope.Secure && !isBiometric) {
|
|
856
|
+
const pending = pendingSecureWrites.get(storageKey);
|
|
857
|
+
if (pending !== undefined) {
|
|
858
|
+
return pending.value;
|
|
859
|
+
}
|
|
801
860
|
}
|
|
802
861
|
|
|
803
862
|
if (readCache) {
|
|
804
|
-
|
|
805
|
-
|
|
863
|
+
const cache = getScopeRawCache(nonMemoryScope!);
|
|
864
|
+
const cached = cache.get(storageKey);
|
|
865
|
+
if (cached !== undefined || cache.has(storageKey)) {
|
|
866
|
+
return cached;
|
|
806
867
|
}
|
|
807
868
|
}
|
|
808
869
|
|
|
@@ -938,6 +999,7 @@ export function createStorageItem<T = undefined>(
|
|
|
938
999
|
onExpired?.(storageKey);
|
|
939
1000
|
lastValue = ensureValidatedValue(defaultValue, false);
|
|
940
1001
|
hasLastValue = true;
|
|
1002
|
+
listeners.forEach((cb) => cb());
|
|
941
1003
|
return lastValue;
|
|
942
1004
|
}
|
|
943
1005
|
}
|
|
@@ -979,6 +1041,7 @@ export function createStorageItem<T = undefined>(
|
|
|
979
1041
|
onExpired?.(storageKey);
|
|
980
1042
|
lastValue = ensureValidatedValue(defaultValue, false);
|
|
981
1043
|
hasLastValue = true;
|
|
1044
|
+
listeners.forEach((cb) => cb());
|
|
982
1045
|
return lastValue;
|
|
983
1046
|
}
|
|
984
1047
|
|
|
@@ -1017,14 +1080,13 @@ export function createStorageItem<T = undefined>(
|
|
|
1017
1080
|
? valueOrFn(getInternal())
|
|
1018
1081
|
: valueOrFn;
|
|
1019
1082
|
|
|
1020
|
-
invalidateParsedCache();
|
|
1021
|
-
|
|
1022
1083
|
if (validate && !validate(newValue)) {
|
|
1023
1084
|
throw new Error(
|
|
1024
1085
|
`Validation failed for key "${storageKey}" in scope "${StorageScope[config.scope]}".`,
|
|
1025
1086
|
);
|
|
1026
1087
|
}
|
|
1027
1088
|
|
|
1089
|
+
invalidateParsedCache();
|
|
1028
1090
|
writeValueWithoutValidation(newValue);
|
|
1029
1091
|
});
|
|
1030
1092
|
};
|
|
@@ -1095,6 +1157,9 @@ export function createStorageItem<T = undefined>(
|
|
|
1095
1157
|
invalidateParsedCache();
|
|
1096
1158
|
listeners.forEach((listener) => listener());
|
|
1097
1159
|
},
|
|
1160
|
+
_invalidateParsedCacheOnly: () => {
|
|
1161
|
+
invalidateParsedCache();
|
|
1162
|
+
},
|
|
1098
1163
|
_hasValidation: validate !== undefined,
|
|
1099
1164
|
_hasExpiration: expiration !== undefined,
|
|
1100
1165
|
_readCacheEnabled: readCache,
|
|
@@ -1111,6 +1176,7 @@ export function createStorageItem<T = undefined>(
|
|
|
1111
1176
|
}
|
|
1112
1177
|
|
|
1113
1178
|
export { useStorage, useStorageSelector, useSetStorage } from "./storage-hooks";
|
|
1179
|
+
export { createIndexedDBBackend } from "./indexeddb-backend";
|
|
1114
1180
|
|
|
1115
1181
|
type BatchReadItem<T> = Pick<
|
|
1116
1182
|
StorageItem<T>,
|
|
@@ -1159,15 +1225,18 @@ export function getBatch(
|
|
|
1159
1225
|
|
|
1160
1226
|
items.forEach((item, index) => {
|
|
1161
1227
|
if (scope === StorageScope.Secure) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1228
|
+
const pending = pendingSecureWrites.get(item.key);
|
|
1229
|
+
if (pending !== undefined) {
|
|
1230
|
+
rawValues[index] = pending.value;
|
|
1164
1231
|
return;
|
|
1165
1232
|
}
|
|
1166
1233
|
}
|
|
1167
1234
|
|
|
1168
1235
|
if (item._readCacheEnabled === true) {
|
|
1169
|
-
|
|
1170
|
-
|
|
1236
|
+
const cache = getScopeRawCache(scope);
|
|
1237
|
+
const cached = cache.get(item.key);
|
|
1238
|
+
if (cached !== undefined || cache.has(item.key)) {
|
|
1239
|
+
rawValues[index] = cached;
|
|
1171
1240
|
return;
|
|
1172
1241
|
}
|
|
1173
1242
|
}
|
|
@@ -1218,7 +1287,26 @@ export function setBatch<T>(
|
|
|
1218
1287
|
);
|
|
1219
1288
|
|
|
1220
1289
|
if (scope === StorageScope.Memory) {
|
|
1221
|
-
|
|
1290
|
+
// Determine if any item needs per-item handling (validation or TTL)
|
|
1291
|
+
const needsIndividualSets = items.some(({ item }) => {
|
|
1292
|
+
const internal = asInternal(item as StorageItem<unknown>);
|
|
1293
|
+
return internal._hasValidation || internal._hasExpiration;
|
|
1294
|
+
});
|
|
1295
|
+
|
|
1296
|
+
if (needsIndividualSets) {
|
|
1297
|
+
// Fall back to individual sets to preserve validation and TTL semantics
|
|
1298
|
+
items.forEach(({ item, value }) => item.set(value));
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// Atomic write: update all values in memoryStore, invalidate caches, then batch-notify
|
|
1303
|
+
items.forEach(({ item, value }) => {
|
|
1304
|
+
memoryStore.set(item.key, value);
|
|
1305
|
+
asInternal(item as StorageItem<unknown>)._invalidateParsedCacheOnly();
|
|
1306
|
+
});
|
|
1307
|
+
items.forEach(({ item }) =>
|
|
1308
|
+
notifyKeyListeners(memoryListeners, item.key),
|
|
1309
|
+
);
|
|
1222
1310
|
return;
|
|
1223
1311
|
}
|
|
1224
1312
|
|
|
@@ -1345,10 +1433,13 @@ export function migrateToLatest(
|
|
|
1345
1433
|
return;
|
|
1346
1434
|
}
|
|
1347
1435
|
migration(context);
|
|
1348
|
-
writeMigrationVersion(scope, version);
|
|
1349
1436
|
appliedVersion = version;
|
|
1350
1437
|
});
|
|
1351
1438
|
|
|
1439
|
+
if (appliedVersion !== currentVersion) {
|
|
1440
|
+
writeMigrationVersion(scope, appliedVersion);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1352
1443
|
return appliedVersion;
|
|
1353
1444
|
});
|
|
1354
1445
|
}
|
|
@@ -1363,13 +1454,18 @@ export function runTransaction<T>(
|
|
|
1363
1454
|
flushSecureWrites();
|
|
1364
1455
|
}
|
|
1365
1456
|
|
|
1366
|
-
const
|
|
1457
|
+
const NOT_SET = Symbol();
|
|
1458
|
+
const rollback = new Map<string, unknown>();
|
|
1367
1459
|
|
|
1368
1460
|
const rememberRollback = (key: string) => {
|
|
1369
1461
|
if (rollback.has(key)) {
|
|
1370
1462
|
return;
|
|
1371
1463
|
}
|
|
1372
|
-
|
|
1464
|
+
if (scope === StorageScope.Memory) {
|
|
1465
|
+
rollback.set(key, memoryStore.has(key) ? memoryStore.get(key) : NOT_SET);
|
|
1466
|
+
} else {
|
|
1467
|
+
rollback.set(key, getRawValue(key, scope));
|
|
1468
|
+
}
|
|
1373
1469
|
};
|
|
1374
1470
|
|
|
1375
1471
|
const tx: TransactionContext = {
|
|
@@ -1405,11 +1501,12 @@ export function runTransaction<T>(
|
|
|
1405
1501
|
const rollbackEntries = Array.from(rollback.entries()).reverse();
|
|
1406
1502
|
if (scope === StorageScope.Memory) {
|
|
1407
1503
|
rollbackEntries.forEach(([key, previousValue]) => {
|
|
1408
|
-
if (previousValue ===
|
|
1409
|
-
|
|
1504
|
+
if (previousValue === NOT_SET) {
|
|
1505
|
+
memoryStore.delete(key);
|
|
1410
1506
|
} else {
|
|
1411
|
-
|
|
1507
|
+
memoryStore.set(key, previousValue);
|
|
1412
1508
|
}
|
|
1509
|
+
notifyKeyListeners(memoryListeners, key);
|
|
1413
1510
|
});
|
|
1414
1511
|
} else {
|
|
1415
1512
|
const keysToSet: string[] = [];
|
|
@@ -1421,7 +1518,7 @@ export function runTransaction<T>(
|
|
|
1421
1518
|
keysToRemove.push(key);
|
|
1422
1519
|
} else {
|
|
1423
1520
|
keysToSet.push(key);
|
|
1424
|
-
valuesToSet.push(previousValue);
|
|
1521
|
+
valuesToSet.push(previousValue as string);
|
|
1425
1522
|
}
|
|
1426
1523
|
});
|
|
1427
1524
|
|
|
@@ -1454,6 +1551,19 @@ export type SecureAuthStorageConfig<K extends string = string> = Record<
|
|
|
1454
1551
|
}
|
|
1455
1552
|
>;
|
|
1456
1553
|
|
|
1554
|
+
export function isKeychainLockedError(err: unknown): boolean {
|
|
1555
|
+
if (!(err instanceof Error)) return false;
|
|
1556
|
+
const msg = err.message;
|
|
1557
|
+
return (
|
|
1558
|
+
msg.includes("errSecInteractionNotAllowed") ||
|
|
1559
|
+
msg.includes("UserNotAuthenticatedException") ||
|
|
1560
|
+
msg.includes("KeyStoreException") ||
|
|
1561
|
+
msg.includes("KeyPermanentlyInvalidatedException") ||
|
|
1562
|
+
msg.includes("InvalidKeyException") ||
|
|
1563
|
+
msg.includes("android.security.keystore")
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1457
1567
|
export function createSecureAuthStorage<K extends string>(
|
|
1458
1568
|
config: SecureAuthStorageConfig<K>,
|
|
1459
1569
|
options?: { namespace?: string },
|