react-native-nitro-storage 0.10.3 → 0.11.0
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/CHANGELOG.md +85 -14
- package/README.md +148 -41
- package/SECURITY.md +16 -6
- package/android/build.gradle +0 -1
- package/android/consumer-rules.pro +0 -3
- package/android/src/main/cpp/AndroidStorageAdapterCpp.cpp +48 -33
- package/android/src/main/cpp/AndroidStorageAdapterCpp.hpp +3 -3
- package/android/src/main/java/com/nitrostorage/AndroidStorageAdapter.kt +73 -23
- package/android/src/main/java/com/nitrostorage/DiskSqliteStore.kt +22 -4
- package/app.plugin.js +51 -51
- package/cpp/bindings/HybridStorage.cpp +25 -6
- package/cpp/core/NativeStorageAdapter.hpp +14 -1
- package/cpp/core/SqliteDiskStore.cpp +94 -17
- package/cpp/core/SqliteDiskStore.hpp +10 -0
- package/docs/api-reference.md +73 -28
- package/docs/benchmarks.md +41 -12
- package/docs/mmkv-migration.md +3 -1
- package/docs/native-libraries.md +10 -4
- package/docs/secure-storage.md +26 -12
- package/docs/web-backends.md +6 -2
- package/indexeddb-backend/package.json +6 -0
- package/ios/IOSStorageAdapterCpp.hpp +4 -0
- package/ios/IOSStorageAdapterCpp.mm +149 -57
- package/lib/commonjs/capabilities.js +3 -8
- package/lib/commonjs/capabilities.js.map +1 -1
- package/lib/commonjs/index.js +23 -8
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +61 -19
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/indexeddb-backend.js +21 -37
- package/lib/commonjs/indexeddb-backend.js.map +1 -1
- package/lib/commonjs/internal.js +6 -0
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/storage-core.js +61 -22
- package/lib/commonjs/storage-core.js.map +1 -1
- package/lib/commonjs/storage-runtime.js +1 -1
- package/lib/commonjs/storage-runtime.js.map +1 -1
- package/lib/commonjs/testing.js +68 -23
- package/lib/commonjs/testing.js.map +1 -1
- package/lib/commonjs/web-backend-contract.js +6 -2
- package/lib/commonjs/web-backend-contract.js.map +1 -1
- package/lib/module/capabilities.js +3 -8
- package/lib/module/capabilities.js.map +1 -1
- package/lib/module/index.js +14 -5
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +61 -12
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/indexeddb-backend.js +21 -37
- package/lib/module/indexeddb-backend.js.map +1 -1
- package/lib/module/internal.js +5 -0
- package/lib/module/internal.js.map +1 -1
- package/lib/module/storage-core.js +62 -23
- package/lib/module/storage-core.js.map +1 -1
- package/lib/module/storage-runtime.js +1 -1
- package/lib/module/storage-runtime.js.map +1 -1
- package/lib/module/testing.js +59 -16
- package/lib/module/testing.js.map +1 -1
- package/lib/module/web-backend-contract.js +5 -2
- package/lib/module/web-backend-contract.js.map +1 -1
- package/lib/typescript/capabilities.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +8 -1
- 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.map +1 -1
- package/lib/typescript/internal.d.ts +1 -0
- package/lib/typescript/internal.d.ts.map +1 -1
- package/lib/typescript/storage-core.d.ts +1 -1
- package/lib/typescript/storage-core.d.ts.map +1 -1
- package/lib/typescript/storage-runtime.d.ts +1 -1
- package/lib/typescript/storage-runtime.d.ts.map +1 -1
- package/lib/typescript/testing.d.ts +15 -2
- package/lib/typescript/testing.d.ts.map +1 -1
- package/lib/typescript/web-backend-contract.d.ts +1 -0
- package/lib/typescript/web-backend-contract.d.ts.map +1 -1
- package/package.json +14 -5
- package/react-native-nitro-storage.podspec +4 -2
- package/src/capabilities.ts +4 -9
- package/src/index.ts +19 -5
- package/src/index.web.ts +86 -19
- package/src/indexeddb-backend.ts +20 -42
- package/src/internal.ts +8 -0
- package/src/storage-core.ts +84 -33
- package/src/storage-runtime.ts +3 -1
- package/src/testing.ts +91 -18
- package/src/web-backend-contract.ts +6 -2
- package/testing/package.json +8 -0
|
@@ -9,6 +9,7 @@ var _metrics = require("./core/metrics");
|
|
|
9
9
|
var _internal = require("./internal");
|
|
10
10
|
var _shared = require("./shared");
|
|
11
11
|
var _storageEvents = require("./storage-events");
|
|
12
|
+
var _storageRuntime = require("./storage-runtime");
|
|
12
13
|
var _Storage = require("./Storage.types");
|
|
13
14
|
const EMPTY_KEYS = Object.freeze([]);
|
|
14
15
|
function asInternal(item) {
|
|
@@ -39,6 +40,14 @@ function createStorageCore(buildAdapter) {
|
|
|
39
40
|
let eventObserverRedactSecureValues = true;
|
|
40
41
|
const storageEvents = new _storageEvents.StorageEventRegistry();
|
|
41
42
|
const metrics = (0, _metrics.createMetricsRegistry)();
|
|
43
|
+
function setOwnDataProperty(target, key, value) {
|
|
44
|
+
Object.defineProperty(target, key, {
|
|
45
|
+
configurable: true,
|
|
46
|
+
enumerable: true,
|
|
47
|
+
value,
|
|
48
|
+
writable: true
|
|
49
|
+
});
|
|
50
|
+
}
|
|
42
51
|
const durability = (0, _durability.createDurabilityCoordinator)({
|
|
43
52
|
backend: {
|
|
44
53
|
setBatch: (keys, values, scope) => {
|
|
@@ -147,6 +156,19 @@ function createStorageCore(buildAdapter) {
|
|
|
147
156
|
}
|
|
148
157
|
return scope !== _Storage.StorageScope.Secure || !eventObserverRedactSecureValues;
|
|
149
158
|
}
|
|
159
|
+
function readPreviousEventValue(scope, key, representation = "plain") {
|
|
160
|
+
if (!shouldReadPreviousEventValues(scope)) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
return getEventRawValueForRepresentation(scope, key, representation);
|
|
164
|
+
}
|
|
165
|
+
function toMemoryStoredValue(value) {
|
|
166
|
+
return typeof value === "string" ? (0, _internal.escapeCollidingRawValue)(value) : value;
|
|
167
|
+
}
|
|
168
|
+
function deleteMemoryKey(key) {
|
|
169
|
+
memoryStore.delete(key);
|
|
170
|
+
memoryExpirationDeadlines.delete(key);
|
|
171
|
+
}
|
|
150
172
|
function eventForGlobalObserver(event) {
|
|
151
173
|
if (!eventObserverRedactSecureValues || event.scope !== _Storage.StorageScope.Secure) {
|
|
152
174
|
return event;
|
|
@@ -261,6 +283,7 @@ function createStorageCore(buildAdapter) {
|
|
|
261
283
|
}
|
|
262
284
|
function setRawValue(key, value, scope) {
|
|
263
285
|
(0, _internal.assertValidScope)(scope);
|
|
286
|
+
(0, _internal.assertValidStorageKey)(key);
|
|
264
287
|
const storedValue = (0, _internal.escapeCollidingRawValue)(value);
|
|
265
288
|
const oldValue = scope === _Storage.StorageScope.Memory ? getEventRawValue(scope, key) : undefined;
|
|
266
289
|
if (scope === _Storage.StorageScope.Memory) {
|
|
@@ -293,9 +316,10 @@ function createStorageCore(buildAdapter) {
|
|
|
293
316
|
}
|
|
294
317
|
function removeRawValue(key, scope) {
|
|
295
318
|
(0, _internal.assertValidScope)(scope);
|
|
296
|
-
|
|
319
|
+
(0, _internal.assertValidStorageKey)(key);
|
|
320
|
+
const oldValue = readPreviousEventValue(scope, key);
|
|
297
321
|
if (scope === _Storage.StorageScope.Memory) {
|
|
298
|
-
|
|
322
|
+
deleteMemoryKey(key);
|
|
299
323
|
(0, _shared.notifyKeyListeners)(memoryListeners, key);
|
|
300
324
|
emitKeyChange(scope, key, oldValue, undefined, "remove", "memory");
|
|
301
325
|
return;
|
|
@@ -367,7 +391,7 @@ function createStorageCore(buildAdapter) {
|
|
|
367
391
|
return;
|
|
368
392
|
}
|
|
369
393
|
const previousValues = shouldReadPreviousEventValues(scope) ? removeKeys.map(key => getEventRawValue(scope, key)) : [];
|
|
370
|
-
removeKeys.forEach(
|
|
394
|
+
removeKeys.forEach(deleteMemoryKey);
|
|
371
395
|
removeKeys.forEach(key => {
|
|
372
396
|
(0, _shared.notifyKeyListeners)(memoryListeners, key);
|
|
373
397
|
});
|
|
@@ -643,7 +667,11 @@ function createStorageCore(buildAdapter) {
|
|
|
643
667
|
return measureOperation("storage:getKeysByPrefix", scope, () => {
|
|
644
668
|
(0, _internal.assertValidScope)(scope);
|
|
645
669
|
if (scope === _Storage.StorageScope.Memory) {
|
|
646
|
-
|
|
670
|
+
const keys = [];
|
|
671
|
+
for (const key of memoryStore.keys()) {
|
|
672
|
+
if (key.startsWith(prefix)) keys.push(key);
|
|
673
|
+
}
|
|
674
|
+
return keys;
|
|
647
675
|
}
|
|
648
676
|
if (scope === _Storage.StorageScope.Disk) {
|
|
649
677
|
flushDiskWrites();
|
|
@@ -665,7 +693,7 @@ function createStorageCore(buildAdapter) {
|
|
|
665
693
|
keys.forEach(key => {
|
|
666
694
|
const value = memoryStore.get(key);
|
|
667
695
|
if (typeof value === "string") {
|
|
668
|
-
result
|
|
696
|
+
setOwnDataProperty(result, key, (0, _internal.unescapeCollidingRawValue)(value));
|
|
669
697
|
}
|
|
670
698
|
});
|
|
671
699
|
return result;
|
|
@@ -680,7 +708,7 @@ function createStorageCore(buildAdapter) {
|
|
|
680
708
|
keys.forEach((key, idx) => {
|
|
681
709
|
const value = values[idx];
|
|
682
710
|
if (value !== undefined) {
|
|
683
|
-
result
|
|
711
|
+
setOwnDataProperty(result, key, (0, _internal.unescapeCollidingRawValue)(value));
|
|
684
712
|
}
|
|
685
713
|
});
|
|
686
714
|
return result;
|
|
@@ -691,10 +719,11 @@ function createStorageCore(buildAdapter) {
|
|
|
691
719
|
(0, _internal.assertValidScope)(scope);
|
|
692
720
|
const result = {};
|
|
693
721
|
if (scope === _Storage.StorageScope.Memory) {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
722
|
+
memoryStore.forEach((value, key) => {
|
|
723
|
+
if (typeof value === "string") {
|
|
724
|
+
setOwnDataProperty(result, key, (0, _internal.unescapeCollidingRawValue)(value));
|
|
725
|
+
}
|
|
726
|
+
});
|
|
698
727
|
return result;
|
|
699
728
|
}
|
|
700
729
|
if (scope === _Storage.StorageScope.Disk) {
|
|
@@ -708,7 +737,9 @@ function createStorageCore(buildAdapter) {
|
|
|
708
737
|
const values = adapter.backend.getBatch(keys, scope);
|
|
709
738
|
keys.forEach((key, idx) => {
|
|
710
739
|
const val = values[idx];
|
|
711
|
-
if (val !== undefined)
|
|
740
|
+
if (val !== undefined) {
|
|
741
|
+
setOwnDataProperty(result, key, (0, _internal.unescapeCollidingRawValue)(val));
|
|
742
|
+
}
|
|
712
743
|
});
|
|
713
744
|
return result;
|
|
714
745
|
});
|
|
@@ -819,10 +850,12 @@ function createStorageCore(buildAdapter) {
|
|
|
819
850
|
const keys = Object.keys(data);
|
|
820
851
|
measureOperation("storage:import", scope, () => {
|
|
821
852
|
(0, _internal.assertValidScope)(scope);
|
|
853
|
+
keys.forEach(_internal.assertValidStorageKey);
|
|
822
854
|
if (keys.length === 0) return;
|
|
823
855
|
const values = keys.map(k => data[k]);
|
|
824
856
|
const storedValues = values.map(_internal.escapeCollidingRawValue);
|
|
825
|
-
const
|
|
857
|
+
const readPrevious = scope === _Storage.StorageScope.Memory || shouldReadPreviousEventValues(scope);
|
|
858
|
+
const changes = keys.map((key, index) => (0, _shared.createKeyChange)(scope, key, readPrevious ? getEventRawValue(scope, key) : undefined, values[index], "import", scope === _Storage.StorageScope.Memory ? "memory" : adapter.changeSource));
|
|
826
859
|
if (scope === _Storage.StorageScope.Memory) {
|
|
827
860
|
keys.forEach((key, index) => {
|
|
828
861
|
memoryStore.set(key, storedValues[index]);
|
|
@@ -852,6 +885,7 @@ function createStorageCore(buildAdapter) {
|
|
|
852
885
|
}
|
|
853
886
|
};
|
|
854
887
|
function createStorageItem(config) {
|
|
888
|
+
(0, _internal.assertValidStorageKey)(config.key);
|
|
855
889
|
const storageKey = (0, _internal.prefixKey)(config.namespace, config.key);
|
|
856
890
|
const serialize = config.serialize ?? _shared.defaultSerialize;
|
|
857
891
|
const deserialize = config.deserialize ?? _shared.defaultDeserialize;
|
|
@@ -972,13 +1006,15 @@ function createStorageCore(buildAdapter) {
|
|
|
972
1006
|
}
|
|
973
1007
|
if (isBiometric) {
|
|
974
1008
|
const raw = readBackendRaw(() => adapter.backend.getSecureBiometric(storageKey));
|
|
975
|
-
if (readCache) {
|
|
1009
|
+
if (readCache || fallbackToCacheOnReadError) {
|
|
976
1010
|
cacheRawValue(resolveNonMemoryScope(), storageKey, raw, rawCacheRepresentation);
|
|
977
1011
|
}
|
|
978
1012
|
return raw;
|
|
979
1013
|
}
|
|
980
1014
|
const raw = readBackendRaw(() => adapter.backend.get(storageKey, config.scope));
|
|
981
|
-
|
|
1015
|
+
if (readCache || fallbackToCacheOnReadError) {
|
|
1016
|
+
cacheRawValue(resolveNonMemoryScope(), storageKey, raw);
|
|
1017
|
+
}
|
|
982
1018
|
return raw;
|
|
983
1019
|
};
|
|
984
1020
|
const readBackendRaw = read => {
|
|
@@ -986,7 +1022,7 @@ function createStorageCore(buildAdapter) {
|
|
|
986
1022
|
return read();
|
|
987
1023
|
} catch (error) {
|
|
988
1024
|
onReadError?.(error);
|
|
989
|
-
if (fallbackToCacheOnReadError) {
|
|
1025
|
+
if (fallbackToCacheOnReadError && (0, _storageRuntime.isStorageError)(error, "keychain_locked")) {
|
|
990
1026
|
const scope = resolveNonMemoryScope();
|
|
991
1027
|
const cached = readCachedRawValue(scope, storageKey, rawCacheRepresentation);
|
|
992
1028
|
if (cached !== undefined) {
|
|
@@ -1482,7 +1518,7 @@ function createStorageCore(buildAdapter) {
|
|
|
1482
1518
|
}
|
|
1483
1519
|
};
|
|
1484
1520
|
const removeStoredRaw = (operation = "remove") => {
|
|
1485
|
-
const oldValue =
|
|
1521
|
+
const oldValue = readPreviousEventValue(config.scope, storageKey, isBiometric ? "biometric" : "plain");
|
|
1486
1522
|
if (isBiometric) {
|
|
1487
1523
|
invalidateRawCache(_Storage.StorageScope.Secure, storageKey);
|
|
1488
1524
|
scheduleRenameSourceCleanup();
|
|
@@ -1524,8 +1560,7 @@ function createStorageCore(buildAdapter) {
|
|
|
1524
1560
|
} else {
|
|
1525
1561
|
memoryExpirationDeadlines.delete(storageKey);
|
|
1526
1562
|
}
|
|
1527
|
-
|
|
1528
|
-
memoryStore.set(storageKey, storedValue);
|
|
1563
|
+
memoryStore.set(storageKey, toMemoryStoredValue(value));
|
|
1529
1564
|
(0, _shared.notifyKeyListeners)(memoryListeners, storageKey);
|
|
1530
1565
|
emitKeyChange(config.scope, storageKey, oldValue, typeof value === "string" ? value : undefined, "set", "memory");
|
|
1531
1566
|
return;
|
|
@@ -1918,7 +1953,7 @@ function createStorageCore(buildAdapter) {
|
|
|
1918
1953
|
item,
|
|
1919
1954
|
value
|
|
1920
1955
|
}) => {
|
|
1921
|
-
memoryStore.set(item.key, value);
|
|
1956
|
+
memoryStore.set(item.key, toMemoryStoredValue(value));
|
|
1922
1957
|
asInternal(item)._invalidateParsedCacheOnly();
|
|
1923
1958
|
});
|
|
1924
1959
|
items.forEach(({
|
|
@@ -2211,7 +2246,11 @@ function createStorageCore(buildAdapter) {
|
|
|
2211
2246
|
const rollbackEntries = Array.from(rollback.values()).reverse();
|
|
2212
2247
|
const rollbackSource = scope === _Storage.StorageScope.Memory ? "memory" : adapter.changeSource;
|
|
2213
2248
|
const rollbackErrors = [];
|
|
2249
|
+
const readRollbackEvents = shouldReadPreviousEventValues(scope);
|
|
2214
2250
|
const readRollbackEventValue = entry => {
|
|
2251
|
+
if (!readRollbackEvents) {
|
|
2252
|
+
return undefined;
|
|
2253
|
+
}
|
|
2215
2254
|
try {
|
|
2216
2255
|
return getEventRawValueForRepresentation(scope, entry.key, entry.representation);
|
|
2217
2256
|
} catch (readError) {
|
|
@@ -2455,7 +2494,7 @@ function createStorageCore(buildAdapter) {
|
|
|
2455
2494
|
const initial = {};
|
|
2456
2495
|
if (defaultValue) {
|
|
2457
2496
|
for (const id of defaultValue) {
|
|
2458
|
-
initial
|
|
2497
|
+
setOwnDataProperty(initial, id, true);
|
|
2459
2498
|
}
|
|
2460
2499
|
}
|
|
2461
2500
|
const item = createStorageItem({
|
|
@@ -2471,7 +2510,7 @@ function createStorageCore(buildAdapter) {
|
|
|
2471
2510
|
const next = {
|
|
2472
2511
|
...current
|
|
2473
2512
|
};
|
|
2474
|
-
next
|
|
2513
|
+
setOwnDataProperty(next, id, true);
|
|
2475
2514
|
item.set(next);
|
|
2476
2515
|
};
|
|
2477
2516
|
const deleteId = id => {
|
|
@@ -2496,7 +2535,7 @@ function createStorageCore(buildAdapter) {
|
|
|
2496
2535
|
const getTyped = () => {
|
|
2497
2536
|
const typed = {};
|
|
2498
2537
|
for (const id of Object.keys(item.get())) {
|
|
2499
|
-
typed
|
|
2538
|
+
setOwnDataProperty(typed, id, true);
|
|
2500
2539
|
}
|
|
2501
2540
|
return typed;
|
|
2502
2541
|
};
|