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
package/lib/module/index.web.js
CHANGED
|
@@ -25,10 +25,12 @@ const webScopeKeyIndex = new Map([[StorageScope.Disk, new Set()], [StorageScope.
|
|
|
25
25
|
const hydratedWebScopeKeyIndex = new Set();
|
|
26
26
|
const pendingSecureWrites = new Map();
|
|
27
27
|
let secureFlushScheduled = false;
|
|
28
|
+
let secureDefaultAccessControl = AccessControl.WhenUnlocked;
|
|
28
29
|
const SECURE_WEB_PREFIX = "__secure_";
|
|
29
30
|
const BIOMETRIC_WEB_PREFIX = "__bio_";
|
|
30
31
|
let hasWarnedAboutWebBiometricFallback = false;
|
|
31
32
|
let hasWebStorageEventSubscription = false;
|
|
33
|
+
let webStorageSubscriberCount = 0;
|
|
32
34
|
let metricsObserver;
|
|
33
35
|
const metricsCounters = new Map();
|
|
34
36
|
function recordMetric(operation, scope, durationMs, keysCount = 1) {
|
|
@@ -52,6 +54,9 @@ function recordMetric(operation, scope, durationMs, keysCount = 1) {
|
|
|
52
54
|
});
|
|
53
55
|
}
|
|
54
56
|
function measureOperation(operation, scope, fn, keysCount = 1) {
|
|
57
|
+
if (!metricsObserver) {
|
|
58
|
+
return fn();
|
|
59
|
+
}
|
|
55
60
|
const start = Date.now();
|
|
56
61
|
try {
|
|
57
62
|
return fn();
|
|
@@ -80,6 +85,8 @@ function createLocalStorageWebSecureBackend() {
|
|
|
80
85
|
};
|
|
81
86
|
}
|
|
82
87
|
let webSecureStorageBackend = createLocalStorageWebSecureBackend();
|
|
88
|
+
let cachedSecureBrowserStorage;
|
|
89
|
+
let cachedSecureBackendRef;
|
|
83
90
|
function getBrowserStorage(scope) {
|
|
84
91
|
if (scope === StorageScope.Disk) {
|
|
85
92
|
return globalThis.localStorage;
|
|
@@ -88,16 +95,21 @@ function getBrowserStorage(scope) {
|
|
|
88
95
|
if (!webSecureStorageBackend) {
|
|
89
96
|
return undefined;
|
|
90
97
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
if (cachedSecureBackendRef === webSecureStorageBackend && cachedSecureBrowserStorage) {
|
|
99
|
+
return cachedSecureBrowserStorage;
|
|
100
|
+
}
|
|
101
|
+
cachedSecureBackendRef = webSecureStorageBackend;
|
|
102
|
+
cachedSecureBrowserStorage = {
|
|
103
|
+
setItem: (key, value) => webSecureStorageBackend.setItem(key, value),
|
|
104
|
+
getItem: key => webSecureStorageBackend.getItem(key) ?? null,
|
|
105
|
+
removeItem: key => webSecureStorageBackend.removeItem(key),
|
|
106
|
+
clear: () => webSecureStorageBackend.clear(),
|
|
107
|
+
key: index => webSecureStorageBackend.getAllKeys()[index] ?? null,
|
|
97
108
|
get length() {
|
|
98
|
-
return webSecureStorageBackend
|
|
109
|
+
return webSecureStorageBackend.getAllKeys().length;
|
|
99
110
|
}
|
|
100
111
|
};
|
|
112
|
+
return cachedSecureBrowserStorage;
|
|
101
113
|
}
|
|
102
114
|
return undefined;
|
|
103
115
|
}
|
|
@@ -197,14 +209,18 @@ function handleWebStorageEvent(event) {
|
|
|
197
209
|
notifyKeyListeners(getScopedListeners(StorageScope.Disk), key);
|
|
198
210
|
}
|
|
199
211
|
function ensureWebStorageEventSubscription() {
|
|
200
|
-
|
|
201
|
-
|
|
212
|
+
webStorageSubscriberCount += 1;
|
|
213
|
+
if (webStorageSubscriberCount === 1 && typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
214
|
+
window.addEventListener("storage", handleWebStorageEvent);
|
|
215
|
+
hasWebStorageEventSubscription = true;
|
|
202
216
|
}
|
|
203
|
-
|
|
204
|
-
|
|
217
|
+
}
|
|
218
|
+
function maybeCleanupWebStorageSubscription() {
|
|
219
|
+
webStorageSubscriberCount = Math.max(0, webStorageSubscriberCount - 1);
|
|
220
|
+
if (webStorageSubscriberCount === 0 && hasWebStorageEventSubscription && typeof window !== "undefined") {
|
|
221
|
+
window.removeEventListener("storage", handleWebStorageEvent);
|
|
222
|
+
hasWebStorageEventSubscription = false;
|
|
205
223
|
}
|
|
206
|
-
window.addEventListener("storage", handleWebStorageEvent);
|
|
207
|
-
hasWebStorageEventSubscription = true;
|
|
208
224
|
}
|
|
209
225
|
function getScopedListeners(scope) {
|
|
210
226
|
return webScopeListeners.get(scope);
|
|
@@ -225,12 +241,19 @@ function clearScopeRawCache(scope) {
|
|
|
225
241
|
getScopeRawCache(scope).clear();
|
|
226
242
|
}
|
|
227
243
|
function notifyKeyListeners(registry, key) {
|
|
228
|
-
registry.get(key)
|
|
244
|
+
const listeners = registry.get(key);
|
|
245
|
+
if (listeners) {
|
|
246
|
+
for (const listener of listeners) {
|
|
247
|
+
listener();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
229
250
|
}
|
|
230
251
|
function notifyAllListeners(registry) {
|
|
231
|
-
registry.
|
|
232
|
-
|
|
233
|
-
|
|
252
|
+
for (const listeners of registry.values()) {
|
|
253
|
+
for (const listener of listeners) {
|
|
254
|
+
listener();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
234
257
|
}
|
|
235
258
|
function addKeyListener(registry, key, listener) {
|
|
236
259
|
let listeners = registry.get(key);
|
|
@@ -276,7 +299,7 @@ function flushSecureWrites() {
|
|
|
276
299
|
if (value === undefined) {
|
|
277
300
|
keysToRemove.push(key);
|
|
278
301
|
} else {
|
|
279
|
-
const resolvedAccessControl = accessControl ??
|
|
302
|
+
const resolvedAccessControl = accessControl ?? secureDefaultAccessControl;
|
|
280
303
|
const existingGroup = groupedSetWrites.get(resolvedAccessControl);
|
|
281
304
|
const group = existingGroup ?? {
|
|
282
305
|
keys: [],
|
|
@@ -609,7 +632,12 @@ export const storage = {
|
|
|
609
632
|
if (scope === StorageScope.Secure) {
|
|
610
633
|
flushSecureWrites();
|
|
611
634
|
}
|
|
612
|
-
|
|
635
|
+
const scopeCache = getScopeRawCache(scope);
|
|
636
|
+
for (const key of scopeCache.keys()) {
|
|
637
|
+
if (isNamespaced(key, namespace)) {
|
|
638
|
+
scopeCache.delete(key);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
613
641
|
WebStorage.removeByPrefix(keyPrefix, scope);
|
|
614
642
|
});
|
|
615
643
|
},
|
|
@@ -678,9 +706,13 @@ export const storage = {
|
|
|
678
706
|
return result;
|
|
679
707
|
}
|
|
680
708
|
const keys = WebStorage.getAllKeys(scope);
|
|
681
|
-
keys.
|
|
682
|
-
|
|
683
|
-
|
|
709
|
+
if (keys.length === 0) return {};
|
|
710
|
+
const values = WebStorage.getBatch(keys, scope);
|
|
711
|
+
keys.forEach((key, index) => {
|
|
712
|
+
const val = values[index];
|
|
713
|
+
if (val !== undefined && val !== null) {
|
|
714
|
+
result[key] = val;
|
|
715
|
+
}
|
|
684
716
|
});
|
|
685
717
|
return result;
|
|
686
718
|
});
|
|
@@ -692,7 +724,8 @@ export const storage = {
|
|
|
692
724
|
return WebStorage.size(scope);
|
|
693
725
|
});
|
|
694
726
|
},
|
|
695
|
-
setAccessControl:
|
|
727
|
+
setAccessControl: level => {
|
|
728
|
+
secureDefaultAccessControl = level;
|
|
696
729
|
recordMetric("storage:setAccessControl", StorageScope.Secure, 0);
|
|
697
730
|
},
|
|
698
731
|
setSecureWritesAsync: _enabled => {
|
|
@@ -723,10 +756,48 @@ export const storage = {
|
|
|
723
756
|
},
|
|
724
757
|
resetMetrics: () => {
|
|
725
758
|
metricsCounters.clear();
|
|
759
|
+
},
|
|
760
|
+
getString: (key, scope) => {
|
|
761
|
+
return measureOperation("storage:getString", scope, () => {
|
|
762
|
+
return getRawValue(key, scope);
|
|
763
|
+
});
|
|
764
|
+
},
|
|
765
|
+
setString: (key, value, scope) => {
|
|
766
|
+
measureOperation("storage:setString", scope, () => {
|
|
767
|
+
setRawValue(key, value, scope);
|
|
768
|
+
});
|
|
769
|
+
},
|
|
770
|
+
deleteString: (key, scope) => {
|
|
771
|
+
measureOperation("storage:deleteString", scope, () => {
|
|
772
|
+
removeRawValue(key, scope);
|
|
773
|
+
});
|
|
774
|
+
},
|
|
775
|
+
import: (data, scope) => {
|
|
776
|
+
const keys = Object.keys(data);
|
|
777
|
+
measureOperation("storage:import", scope, () => {
|
|
778
|
+
assertValidScope(scope);
|
|
779
|
+
if (keys.length === 0) return;
|
|
780
|
+
const values = keys.map(k => data[k]);
|
|
781
|
+
if (scope === StorageScope.Memory) {
|
|
782
|
+
keys.forEach((key, index) => {
|
|
783
|
+
memoryStore.set(key, values[index]);
|
|
784
|
+
});
|
|
785
|
+
keys.forEach(key => notifyKeyListeners(memoryListeners, key));
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
if (scope === StorageScope.Secure) {
|
|
789
|
+
flushSecureWrites();
|
|
790
|
+
WebStorage.setSecureAccessControl(secureDefaultAccessControl);
|
|
791
|
+
}
|
|
792
|
+
WebStorage.setBatch(keys, values, scope);
|
|
793
|
+
keys.forEach((key, index) => cacheRawValue(scope, key, values[index]));
|
|
794
|
+
}, keys.length);
|
|
726
795
|
}
|
|
727
796
|
};
|
|
728
797
|
export function setWebSecureStorageBackend(backend) {
|
|
729
798
|
webSecureStorageBackend = backend ?? createLocalStorageWebSecureBackend();
|
|
799
|
+
cachedSecureBrowserStorage = undefined;
|
|
800
|
+
cachedSecureBackendRef = undefined;
|
|
730
801
|
hydratedWebScopeKeyIndex.delete(StorageScope.Secure);
|
|
731
802
|
clearScopeRawCache(StorageScope.Secure);
|
|
732
803
|
}
|
|
@@ -807,12 +878,17 @@ export function createStorageItem(config) {
|
|
|
807
878
|
}
|
|
808
879
|
return memoryStore.get(storageKey);
|
|
809
880
|
}
|
|
810
|
-
if (nonMemoryScope === StorageScope.Secure && !isBiometric
|
|
811
|
-
|
|
881
|
+
if (nonMemoryScope === StorageScope.Secure && !isBiometric) {
|
|
882
|
+
const pending = pendingSecureWrites.get(storageKey);
|
|
883
|
+
if (pending !== undefined) {
|
|
884
|
+
return pending.value;
|
|
885
|
+
}
|
|
812
886
|
}
|
|
813
887
|
if (readCache) {
|
|
814
|
-
|
|
815
|
-
|
|
888
|
+
const cache = getScopeRawCache(nonMemoryScope);
|
|
889
|
+
const cached = cache.get(storageKey);
|
|
890
|
+
if (cached !== undefined || cache.has(storageKey)) {
|
|
891
|
+
return cached;
|
|
816
892
|
}
|
|
817
893
|
}
|
|
818
894
|
if (isBiometric) {
|
|
@@ -829,7 +905,7 @@ export function createStorageItem(config) {
|
|
|
829
905
|
}
|
|
830
906
|
cacheRawValue(nonMemoryScope, storageKey, rawValue);
|
|
831
907
|
if (coalesceSecureWrites) {
|
|
832
|
-
scheduleSecureWrite(storageKey, rawValue, secureAccessControl ??
|
|
908
|
+
scheduleSecureWrite(storageKey, rawValue, secureAccessControl ?? secureDefaultAccessControl);
|
|
833
909
|
return;
|
|
834
910
|
}
|
|
835
911
|
if (nonMemoryScope === StorageScope.Secure) {
|
|
@@ -844,7 +920,7 @@ export function createStorageItem(config) {
|
|
|
844
920
|
}
|
|
845
921
|
cacheRawValue(nonMemoryScope, storageKey, undefined);
|
|
846
922
|
if (coalesceSecureWrites) {
|
|
847
|
-
scheduleSecureWrite(storageKey, undefined, secureAccessControl ??
|
|
923
|
+
scheduleSecureWrite(storageKey, undefined, secureAccessControl ?? secureDefaultAccessControl);
|
|
848
924
|
return;
|
|
849
925
|
}
|
|
850
926
|
if (nonMemoryScope === StorageScope.Secure) {
|
|
@@ -907,6 +983,7 @@ export function createStorageItem(config) {
|
|
|
907
983
|
onExpired?.(storageKey);
|
|
908
984
|
lastValue = ensureValidatedValue(defaultValue, false);
|
|
909
985
|
hasLastValue = true;
|
|
986
|
+
listeners.forEach(cb => cb());
|
|
910
987
|
return lastValue;
|
|
911
988
|
}
|
|
912
989
|
}
|
|
@@ -942,6 +1019,7 @@ export function createStorageItem(config) {
|
|
|
942
1019
|
onExpired?.(storageKey);
|
|
943
1020
|
lastValue = ensureValidatedValue(defaultValue, false);
|
|
944
1021
|
hasLastValue = true;
|
|
1022
|
+
listeners.forEach(cb => cb());
|
|
945
1023
|
return lastValue;
|
|
946
1024
|
}
|
|
947
1025
|
deserializableRaw = parsed.payload;
|
|
@@ -969,10 +1047,10 @@ export function createStorageItem(config) {
|
|
|
969
1047
|
const set = valueOrFn => {
|
|
970
1048
|
measureOperation("item:set", config.scope, () => {
|
|
971
1049
|
const newValue = isUpdater(valueOrFn) ? valueOrFn(getInternal()) : valueOrFn;
|
|
972
|
-
invalidateParsedCache();
|
|
973
1050
|
if (validate && !validate(newValue)) {
|
|
974
1051
|
throw new Error(`Validation failed for key "${storageKey}" in scope "${StorageScope[config.scope]}".`);
|
|
975
1052
|
}
|
|
1053
|
+
invalidateParsedCache();
|
|
976
1054
|
writeValueWithoutValidation(newValue);
|
|
977
1055
|
});
|
|
978
1056
|
};
|
|
@@ -1011,6 +1089,9 @@ export function createStorageItem(config) {
|
|
|
1011
1089
|
if (listeners.size === 0 && unsubscribe) {
|
|
1012
1090
|
unsubscribe();
|
|
1013
1091
|
unsubscribe = null;
|
|
1092
|
+
if (!isMemory) {
|
|
1093
|
+
maybeCleanupWebStorageSubscription();
|
|
1094
|
+
}
|
|
1014
1095
|
}
|
|
1015
1096
|
};
|
|
1016
1097
|
};
|
|
@@ -1028,6 +1109,9 @@ export function createStorageItem(config) {
|
|
|
1028
1109
|
invalidateParsedCache();
|
|
1029
1110
|
listeners.forEach(listener => listener());
|
|
1030
1111
|
},
|
|
1112
|
+
_invalidateParsedCacheOnly: () => {
|
|
1113
|
+
invalidateParsedCache();
|
|
1114
|
+
},
|
|
1031
1115
|
_hasValidation: validate !== undefined,
|
|
1032
1116
|
_hasExpiration: expiration !== undefined,
|
|
1033
1117
|
_readCacheEnabled: readCache,
|
|
@@ -1042,6 +1126,7 @@ export function createStorageItem(config) {
|
|
|
1042
1126
|
return storageItem;
|
|
1043
1127
|
}
|
|
1044
1128
|
export { useStorage, useStorageSelector, useSetStorage } from "./storage-hooks";
|
|
1129
|
+
export { createIndexedDBBackend } from "./indexeddb-backend";
|
|
1045
1130
|
export function getBatch(items, scope) {
|
|
1046
1131
|
return measureOperation("batch:get", scope, () => {
|
|
1047
1132
|
assertBatchScope(items, scope);
|
|
@@ -1057,14 +1142,17 @@ export function getBatch(items, scope) {
|
|
|
1057
1142
|
const keyIndexes = [];
|
|
1058
1143
|
items.forEach((item, index) => {
|
|
1059
1144
|
if (scope === StorageScope.Secure) {
|
|
1060
|
-
|
|
1061
|
-
|
|
1145
|
+
const pending = pendingSecureWrites.get(item.key);
|
|
1146
|
+
if (pending !== undefined) {
|
|
1147
|
+
rawValues[index] = pending.value;
|
|
1062
1148
|
return;
|
|
1063
1149
|
}
|
|
1064
1150
|
}
|
|
1065
1151
|
if (item._readCacheEnabled === true) {
|
|
1066
|
-
|
|
1067
|
-
|
|
1152
|
+
const cache = getScopeRawCache(scope);
|
|
1153
|
+
const cached = cache.get(item.key);
|
|
1154
|
+
if (cached !== undefined || cache.has(item.key)) {
|
|
1155
|
+
rawValues[index] = cached;
|
|
1068
1156
|
return;
|
|
1069
1157
|
}
|
|
1070
1158
|
}
|
|
@@ -1096,10 +1184,32 @@ export function setBatch(items, scope) {
|
|
|
1096
1184
|
measureOperation("batch:set", scope, () => {
|
|
1097
1185
|
assertBatchScope(items.map(batchEntry => batchEntry.item), scope);
|
|
1098
1186
|
if (scope === StorageScope.Memory) {
|
|
1187
|
+
// Determine if any item needs per-item handling (validation or TTL)
|
|
1188
|
+
const needsIndividualSets = items.some(({
|
|
1189
|
+
item
|
|
1190
|
+
}) => {
|
|
1191
|
+
const internal = asInternal(item);
|
|
1192
|
+
return internal._hasValidation || internal._hasExpiration;
|
|
1193
|
+
});
|
|
1194
|
+
if (needsIndividualSets) {
|
|
1195
|
+
items.forEach(({
|
|
1196
|
+
item,
|
|
1197
|
+
value
|
|
1198
|
+
}) => item.set(value));
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
// Atomic write: update all values in memoryStore, invalidate caches, then batch-notify
|
|
1099
1203
|
items.forEach(({
|
|
1100
1204
|
item,
|
|
1101
1205
|
value
|
|
1102
|
-
}) =>
|
|
1206
|
+
}) => {
|
|
1207
|
+
memoryStore.set(item.key, value);
|
|
1208
|
+
asInternal(item)._invalidateParsedCacheOnly();
|
|
1209
|
+
});
|
|
1210
|
+
items.forEach(({
|
|
1211
|
+
item
|
|
1212
|
+
}) => notifyKeyListeners(memoryListeners, item.key));
|
|
1103
1213
|
return;
|
|
1104
1214
|
}
|
|
1105
1215
|
if (scope === StorageScope.Secure) {
|
|
@@ -1128,7 +1238,7 @@ export function setBatch(items, scope) {
|
|
|
1128
1238
|
value,
|
|
1129
1239
|
internal
|
|
1130
1240
|
}) => {
|
|
1131
|
-
const accessControl = internal._secureAccessControl ??
|
|
1241
|
+
const accessControl = internal._secureAccessControl ?? secureDefaultAccessControl;
|
|
1132
1242
|
const existingGroup = groupedByAccessControl.get(accessControl);
|
|
1133
1243
|
const group = existingGroup ?? {
|
|
1134
1244
|
keys: [],
|
|
@@ -1205,9 +1315,11 @@ export function migrateToLatest(scope = StorageScope.Disk) {
|
|
|
1205
1315
|
return;
|
|
1206
1316
|
}
|
|
1207
1317
|
migration(context);
|
|
1208
|
-
writeMigrationVersion(scope, version);
|
|
1209
1318
|
appliedVersion = version;
|
|
1210
1319
|
});
|
|
1320
|
+
if (appliedVersion !== currentVersion) {
|
|
1321
|
+
writeMigrationVersion(scope, appliedVersion);
|
|
1322
|
+
}
|
|
1211
1323
|
return appliedVersion;
|
|
1212
1324
|
});
|
|
1213
1325
|
}
|
|
@@ -1217,12 +1329,17 @@ export function runTransaction(scope, transaction) {
|
|
|
1217
1329
|
if (scope === StorageScope.Secure) {
|
|
1218
1330
|
flushSecureWrites();
|
|
1219
1331
|
}
|
|
1332
|
+
const NOT_SET = Symbol();
|
|
1220
1333
|
const rollback = new Map();
|
|
1221
1334
|
const rememberRollback = key => {
|
|
1222
1335
|
if (rollback.has(key)) {
|
|
1223
1336
|
return;
|
|
1224
1337
|
}
|
|
1225
|
-
|
|
1338
|
+
if (scope === StorageScope.Memory) {
|
|
1339
|
+
rollback.set(key, memoryStore.has(key) ? memoryStore.get(key) : NOT_SET);
|
|
1340
|
+
} else {
|
|
1341
|
+
rollback.set(key, getRawValue(key, scope));
|
|
1342
|
+
}
|
|
1226
1343
|
};
|
|
1227
1344
|
const tx = {
|
|
1228
1345
|
scope,
|
|
@@ -1256,11 +1373,12 @@ export function runTransaction(scope, transaction) {
|
|
|
1256
1373
|
const rollbackEntries = Array.from(rollback.entries()).reverse();
|
|
1257
1374
|
if (scope === StorageScope.Memory) {
|
|
1258
1375
|
rollbackEntries.forEach(([key, previousValue]) => {
|
|
1259
|
-
if (previousValue ===
|
|
1260
|
-
|
|
1376
|
+
if (previousValue === NOT_SET) {
|
|
1377
|
+
memoryStore.delete(key);
|
|
1261
1378
|
} else {
|
|
1262
|
-
|
|
1379
|
+
memoryStore.set(key, previousValue);
|
|
1263
1380
|
}
|
|
1381
|
+
notifyKeyListeners(memoryListeners, key);
|
|
1264
1382
|
});
|
|
1265
1383
|
} else {
|
|
1266
1384
|
const keysToSet = [];
|
|
@@ -1319,4 +1437,7 @@ export function createSecureAuthStorage(config, options) {
|
|
|
1319
1437
|
}
|
|
1320
1438
|
return result;
|
|
1321
1439
|
}
|
|
1440
|
+
export function isKeychainLockedError(_err) {
|
|
1441
|
+
return false;
|
|
1442
|
+
}
|
|
1322
1443
|
//# sourceMappingURL=index.web.js.map
|