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
|
@@ -21,10 +21,17 @@ Object.defineProperty(exports, "StorageScope", {
|
|
|
21
21
|
return _Storage.StorageScope;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "createIndexedDBBackend", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _indexeddbBackend.createIndexedDBBackend;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
24
30
|
exports.createSecureAuthStorage = createSecureAuthStorage;
|
|
25
31
|
exports.createStorageItem = createStorageItem;
|
|
26
32
|
exports.getBatch = getBatch;
|
|
27
33
|
exports.getWebSecureStorageBackend = getWebSecureStorageBackend;
|
|
34
|
+
exports.isKeychainLockedError = isKeychainLockedError;
|
|
28
35
|
Object.defineProperty(exports, "migrateFromMMKV", {
|
|
29
36
|
enumerable: true,
|
|
30
37
|
get: function () {
|
|
@@ -60,6 +67,7 @@ var _Storage = require("./Storage.types");
|
|
|
60
67
|
var _internal = require("./internal");
|
|
61
68
|
var _migration = require("./migration");
|
|
62
69
|
var _storageHooks = require("./storage-hooks");
|
|
70
|
+
var _indexeddbBackend = require("./indexeddb-backend");
|
|
63
71
|
function asInternal(item) {
|
|
64
72
|
return item;
|
|
65
73
|
}
|
|
@@ -81,10 +89,12 @@ const webScopeKeyIndex = new Map([[_Storage.StorageScope.Disk, new Set()], [_Sto
|
|
|
81
89
|
const hydratedWebScopeKeyIndex = new Set();
|
|
82
90
|
const pendingSecureWrites = new Map();
|
|
83
91
|
let secureFlushScheduled = false;
|
|
92
|
+
let secureDefaultAccessControl = _Storage.AccessControl.WhenUnlocked;
|
|
84
93
|
const SECURE_WEB_PREFIX = "__secure_";
|
|
85
94
|
const BIOMETRIC_WEB_PREFIX = "__bio_";
|
|
86
95
|
let hasWarnedAboutWebBiometricFallback = false;
|
|
87
96
|
let hasWebStorageEventSubscription = false;
|
|
97
|
+
let webStorageSubscriberCount = 0;
|
|
88
98
|
let metricsObserver;
|
|
89
99
|
const metricsCounters = new Map();
|
|
90
100
|
function recordMetric(operation, scope, durationMs, keysCount = 1) {
|
|
@@ -108,6 +118,9 @@ function recordMetric(operation, scope, durationMs, keysCount = 1) {
|
|
|
108
118
|
});
|
|
109
119
|
}
|
|
110
120
|
function measureOperation(operation, scope, fn, keysCount = 1) {
|
|
121
|
+
if (!metricsObserver) {
|
|
122
|
+
return fn();
|
|
123
|
+
}
|
|
111
124
|
const start = Date.now();
|
|
112
125
|
try {
|
|
113
126
|
return fn();
|
|
@@ -136,6 +149,8 @@ function createLocalStorageWebSecureBackend() {
|
|
|
136
149
|
};
|
|
137
150
|
}
|
|
138
151
|
let webSecureStorageBackend = createLocalStorageWebSecureBackend();
|
|
152
|
+
let cachedSecureBrowserStorage;
|
|
153
|
+
let cachedSecureBackendRef;
|
|
139
154
|
function getBrowserStorage(scope) {
|
|
140
155
|
if (scope === _Storage.StorageScope.Disk) {
|
|
141
156
|
return globalThis.localStorage;
|
|
@@ -144,16 +159,21 @@ function getBrowserStorage(scope) {
|
|
|
144
159
|
if (!webSecureStorageBackend) {
|
|
145
160
|
return undefined;
|
|
146
161
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
162
|
+
if (cachedSecureBackendRef === webSecureStorageBackend && cachedSecureBrowserStorage) {
|
|
163
|
+
return cachedSecureBrowserStorage;
|
|
164
|
+
}
|
|
165
|
+
cachedSecureBackendRef = webSecureStorageBackend;
|
|
166
|
+
cachedSecureBrowserStorage = {
|
|
167
|
+
setItem: (key, value) => webSecureStorageBackend.setItem(key, value),
|
|
168
|
+
getItem: key => webSecureStorageBackend.getItem(key) ?? null,
|
|
169
|
+
removeItem: key => webSecureStorageBackend.removeItem(key),
|
|
170
|
+
clear: () => webSecureStorageBackend.clear(),
|
|
171
|
+
key: index => webSecureStorageBackend.getAllKeys()[index] ?? null,
|
|
153
172
|
get length() {
|
|
154
|
-
return webSecureStorageBackend
|
|
173
|
+
return webSecureStorageBackend.getAllKeys().length;
|
|
155
174
|
}
|
|
156
175
|
};
|
|
176
|
+
return cachedSecureBrowserStorage;
|
|
157
177
|
}
|
|
158
178
|
return undefined;
|
|
159
179
|
}
|
|
@@ -253,14 +273,18 @@ function handleWebStorageEvent(event) {
|
|
|
253
273
|
notifyKeyListeners(getScopedListeners(_Storage.StorageScope.Disk), key);
|
|
254
274
|
}
|
|
255
275
|
function ensureWebStorageEventSubscription() {
|
|
256
|
-
|
|
257
|
-
|
|
276
|
+
webStorageSubscriberCount += 1;
|
|
277
|
+
if (webStorageSubscriberCount === 1 && typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
278
|
+
window.addEventListener("storage", handleWebStorageEvent);
|
|
279
|
+
hasWebStorageEventSubscription = true;
|
|
258
280
|
}
|
|
259
|
-
|
|
260
|
-
|
|
281
|
+
}
|
|
282
|
+
function maybeCleanupWebStorageSubscription() {
|
|
283
|
+
webStorageSubscriberCount = Math.max(0, webStorageSubscriberCount - 1);
|
|
284
|
+
if (webStorageSubscriberCount === 0 && hasWebStorageEventSubscription && typeof window !== "undefined") {
|
|
285
|
+
window.removeEventListener("storage", handleWebStorageEvent);
|
|
286
|
+
hasWebStorageEventSubscription = false;
|
|
261
287
|
}
|
|
262
|
-
window.addEventListener("storage", handleWebStorageEvent);
|
|
263
|
-
hasWebStorageEventSubscription = true;
|
|
264
288
|
}
|
|
265
289
|
function getScopedListeners(scope) {
|
|
266
290
|
return webScopeListeners.get(scope);
|
|
@@ -281,12 +305,19 @@ function clearScopeRawCache(scope) {
|
|
|
281
305
|
getScopeRawCache(scope).clear();
|
|
282
306
|
}
|
|
283
307
|
function notifyKeyListeners(registry, key) {
|
|
284
|
-
registry.get(key)
|
|
308
|
+
const listeners = registry.get(key);
|
|
309
|
+
if (listeners) {
|
|
310
|
+
for (const listener of listeners) {
|
|
311
|
+
listener();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
285
314
|
}
|
|
286
315
|
function notifyAllListeners(registry) {
|
|
287
|
-
registry.
|
|
288
|
-
|
|
289
|
-
|
|
316
|
+
for (const listeners of registry.values()) {
|
|
317
|
+
for (const listener of listeners) {
|
|
318
|
+
listener();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
290
321
|
}
|
|
291
322
|
function addKeyListener(registry, key, listener) {
|
|
292
323
|
let listeners = registry.get(key);
|
|
@@ -332,7 +363,7 @@ function flushSecureWrites() {
|
|
|
332
363
|
if (value === undefined) {
|
|
333
364
|
keysToRemove.push(key);
|
|
334
365
|
} else {
|
|
335
|
-
const resolvedAccessControl = accessControl ??
|
|
366
|
+
const resolvedAccessControl = accessControl ?? secureDefaultAccessControl;
|
|
336
367
|
const existingGroup = groupedSetWrites.get(resolvedAccessControl);
|
|
337
368
|
const group = existingGroup ?? {
|
|
338
369
|
keys: [],
|
|
@@ -665,7 +696,12 @@ const storage = exports.storage = {
|
|
|
665
696
|
if (scope === _Storage.StorageScope.Secure) {
|
|
666
697
|
flushSecureWrites();
|
|
667
698
|
}
|
|
668
|
-
|
|
699
|
+
const scopeCache = getScopeRawCache(scope);
|
|
700
|
+
for (const key of scopeCache.keys()) {
|
|
701
|
+
if ((0, _internal.isNamespaced)(key, namespace)) {
|
|
702
|
+
scopeCache.delete(key);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
669
705
|
WebStorage.removeByPrefix(keyPrefix, scope);
|
|
670
706
|
});
|
|
671
707
|
},
|
|
@@ -734,9 +770,13 @@ const storage = exports.storage = {
|
|
|
734
770
|
return result;
|
|
735
771
|
}
|
|
736
772
|
const keys = WebStorage.getAllKeys(scope);
|
|
737
|
-
keys.
|
|
738
|
-
|
|
739
|
-
|
|
773
|
+
if (keys.length === 0) return {};
|
|
774
|
+
const values = WebStorage.getBatch(keys, scope);
|
|
775
|
+
keys.forEach((key, index) => {
|
|
776
|
+
const val = values[index];
|
|
777
|
+
if (val !== undefined && val !== null) {
|
|
778
|
+
result[key] = val;
|
|
779
|
+
}
|
|
740
780
|
});
|
|
741
781
|
return result;
|
|
742
782
|
});
|
|
@@ -748,7 +788,8 @@ const storage = exports.storage = {
|
|
|
748
788
|
return WebStorage.size(scope);
|
|
749
789
|
});
|
|
750
790
|
},
|
|
751
|
-
setAccessControl:
|
|
791
|
+
setAccessControl: level => {
|
|
792
|
+
secureDefaultAccessControl = level;
|
|
752
793
|
recordMetric("storage:setAccessControl", _Storage.StorageScope.Secure, 0);
|
|
753
794
|
},
|
|
754
795
|
setSecureWritesAsync: _enabled => {
|
|
@@ -779,10 +820,48 @@ const storage = exports.storage = {
|
|
|
779
820
|
},
|
|
780
821
|
resetMetrics: () => {
|
|
781
822
|
metricsCounters.clear();
|
|
823
|
+
},
|
|
824
|
+
getString: (key, scope) => {
|
|
825
|
+
return measureOperation("storage:getString", scope, () => {
|
|
826
|
+
return getRawValue(key, scope);
|
|
827
|
+
});
|
|
828
|
+
},
|
|
829
|
+
setString: (key, value, scope) => {
|
|
830
|
+
measureOperation("storage:setString", scope, () => {
|
|
831
|
+
setRawValue(key, value, scope);
|
|
832
|
+
});
|
|
833
|
+
},
|
|
834
|
+
deleteString: (key, scope) => {
|
|
835
|
+
measureOperation("storage:deleteString", scope, () => {
|
|
836
|
+
removeRawValue(key, scope);
|
|
837
|
+
});
|
|
838
|
+
},
|
|
839
|
+
import: (data, scope) => {
|
|
840
|
+
const keys = Object.keys(data);
|
|
841
|
+
measureOperation("storage:import", scope, () => {
|
|
842
|
+
(0, _internal.assertValidScope)(scope);
|
|
843
|
+
if (keys.length === 0) return;
|
|
844
|
+
const values = keys.map(k => data[k]);
|
|
845
|
+
if (scope === _Storage.StorageScope.Memory) {
|
|
846
|
+
keys.forEach((key, index) => {
|
|
847
|
+
memoryStore.set(key, values[index]);
|
|
848
|
+
});
|
|
849
|
+
keys.forEach(key => notifyKeyListeners(memoryListeners, key));
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
853
|
+
flushSecureWrites();
|
|
854
|
+
WebStorage.setSecureAccessControl(secureDefaultAccessControl);
|
|
855
|
+
}
|
|
856
|
+
WebStorage.setBatch(keys, values, scope);
|
|
857
|
+
keys.forEach((key, index) => cacheRawValue(scope, key, values[index]));
|
|
858
|
+
}, keys.length);
|
|
782
859
|
}
|
|
783
860
|
};
|
|
784
861
|
function setWebSecureStorageBackend(backend) {
|
|
785
862
|
webSecureStorageBackend = backend ?? createLocalStorageWebSecureBackend();
|
|
863
|
+
cachedSecureBrowserStorage = undefined;
|
|
864
|
+
cachedSecureBackendRef = undefined;
|
|
786
865
|
hydratedWebScopeKeyIndex.delete(_Storage.StorageScope.Secure);
|
|
787
866
|
clearScopeRawCache(_Storage.StorageScope.Secure);
|
|
788
867
|
}
|
|
@@ -863,12 +942,17 @@ function createStorageItem(config) {
|
|
|
863
942
|
}
|
|
864
943
|
return memoryStore.get(storageKey);
|
|
865
944
|
}
|
|
866
|
-
if (nonMemoryScope === _Storage.StorageScope.Secure && !isBiometric
|
|
867
|
-
|
|
945
|
+
if (nonMemoryScope === _Storage.StorageScope.Secure && !isBiometric) {
|
|
946
|
+
const pending = pendingSecureWrites.get(storageKey);
|
|
947
|
+
if (pending !== undefined) {
|
|
948
|
+
return pending.value;
|
|
949
|
+
}
|
|
868
950
|
}
|
|
869
951
|
if (readCache) {
|
|
870
|
-
|
|
871
|
-
|
|
952
|
+
const cache = getScopeRawCache(nonMemoryScope);
|
|
953
|
+
const cached = cache.get(storageKey);
|
|
954
|
+
if (cached !== undefined || cache.has(storageKey)) {
|
|
955
|
+
return cached;
|
|
872
956
|
}
|
|
873
957
|
}
|
|
874
958
|
if (isBiometric) {
|
|
@@ -885,7 +969,7 @@ function createStorageItem(config) {
|
|
|
885
969
|
}
|
|
886
970
|
cacheRawValue(nonMemoryScope, storageKey, rawValue);
|
|
887
971
|
if (coalesceSecureWrites) {
|
|
888
|
-
scheduleSecureWrite(storageKey, rawValue, secureAccessControl ??
|
|
972
|
+
scheduleSecureWrite(storageKey, rawValue, secureAccessControl ?? secureDefaultAccessControl);
|
|
889
973
|
return;
|
|
890
974
|
}
|
|
891
975
|
if (nonMemoryScope === _Storage.StorageScope.Secure) {
|
|
@@ -900,7 +984,7 @@ function createStorageItem(config) {
|
|
|
900
984
|
}
|
|
901
985
|
cacheRawValue(nonMemoryScope, storageKey, undefined);
|
|
902
986
|
if (coalesceSecureWrites) {
|
|
903
|
-
scheduleSecureWrite(storageKey, undefined, secureAccessControl ??
|
|
987
|
+
scheduleSecureWrite(storageKey, undefined, secureAccessControl ?? secureDefaultAccessControl);
|
|
904
988
|
return;
|
|
905
989
|
}
|
|
906
990
|
if (nonMemoryScope === _Storage.StorageScope.Secure) {
|
|
@@ -963,6 +1047,7 @@ function createStorageItem(config) {
|
|
|
963
1047
|
onExpired?.(storageKey);
|
|
964
1048
|
lastValue = ensureValidatedValue(defaultValue, false);
|
|
965
1049
|
hasLastValue = true;
|
|
1050
|
+
listeners.forEach(cb => cb());
|
|
966
1051
|
return lastValue;
|
|
967
1052
|
}
|
|
968
1053
|
}
|
|
@@ -998,6 +1083,7 @@ function createStorageItem(config) {
|
|
|
998
1083
|
onExpired?.(storageKey);
|
|
999
1084
|
lastValue = ensureValidatedValue(defaultValue, false);
|
|
1000
1085
|
hasLastValue = true;
|
|
1086
|
+
listeners.forEach(cb => cb());
|
|
1001
1087
|
return lastValue;
|
|
1002
1088
|
}
|
|
1003
1089
|
deserializableRaw = parsed.payload;
|
|
@@ -1025,10 +1111,10 @@ function createStorageItem(config) {
|
|
|
1025
1111
|
const set = valueOrFn => {
|
|
1026
1112
|
measureOperation("item:set", config.scope, () => {
|
|
1027
1113
|
const newValue = isUpdater(valueOrFn) ? valueOrFn(getInternal()) : valueOrFn;
|
|
1028
|
-
invalidateParsedCache();
|
|
1029
1114
|
if (validate && !validate(newValue)) {
|
|
1030
1115
|
throw new Error(`Validation failed for key "${storageKey}" in scope "${_Storage.StorageScope[config.scope]}".`);
|
|
1031
1116
|
}
|
|
1117
|
+
invalidateParsedCache();
|
|
1032
1118
|
writeValueWithoutValidation(newValue);
|
|
1033
1119
|
});
|
|
1034
1120
|
};
|
|
@@ -1067,6 +1153,9 @@ function createStorageItem(config) {
|
|
|
1067
1153
|
if (listeners.size === 0 && unsubscribe) {
|
|
1068
1154
|
unsubscribe();
|
|
1069
1155
|
unsubscribe = null;
|
|
1156
|
+
if (!isMemory) {
|
|
1157
|
+
maybeCleanupWebStorageSubscription();
|
|
1158
|
+
}
|
|
1070
1159
|
}
|
|
1071
1160
|
};
|
|
1072
1161
|
};
|
|
@@ -1084,6 +1173,9 @@ function createStorageItem(config) {
|
|
|
1084
1173
|
invalidateParsedCache();
|
|
1085
1174
|
listeners.forEach(listener => listener());
|
|
1086
1175
|
},
|
|
1176
|
+
_invalidateParsedCacheOnly: () => {
|
|
1177
|
+
invalidateParsedCache();
|
|
1178
|
+
},
|
|
1087
1179
|
_hasValidation: validate !== undefined,
|
|
1088
1180
|
_hasExpiration: expiration !== undefined,
|
|
1089
1181
|
_readCacheEnabled: readCache,
|
|
@@ -1112,14 +1204,17 @@ function getBatch(items, scope) {
|
|
|
1112
1204
|
const keyIndexes = [];
|
|
1113
1205
|
items.forEach((item, index) => {
|
|
1114
1206
|
if (scope === _Storage.StorageScope.Secure) {
|
|
1115
|
-
|
|
1116
|
-
|
|
1207
|
+
const pending = pendingSecureWrites.get(item.key);
|
|
1208
|
+
if (pending !== undefined) {
|
|
1209
|
+
rawValues[index] = pending.value;
|
|
1117
1210
|
return;
|
|
1118
1211
|
}
|
|
1119
1212
|
}
|
|
1120
1213
|
if (item._readCacheEnabled === true) {
|
|
1121
|
-
|
|
1122
|
-
|
|
1214
|
+
const cache = getScopeRawCache(scope);
|
|
1215
|
+
const cached = cache.get(item.key);
|
|
1216
|
+
if (cached !== undefined || cache.has(item.key)) {
|
|
1217
|
+
rawValues[index] = cached;
|
|
1123
1218
|
return;
|
|
1124
1219
|
}
|
|
1125
1220
|
}
|
|
@@ -1151,10 +1246,32 @@ function setBatch(items, scope) {
|
|
|
1151
1246
|
measureOperation("batch:set", scope, () => {
|
|
1152
1247
|
(0, _internal.assertBatchScope)(items.map(batchEntry => batchEntry.item), scope);
|
|
1153
1248
|
if (scope === _Storage.StorageScope.Memory) {
|
|
1249
|
+
// Determine if any item needs per-item handling (validation or TTL)
|
|
1250
|
+
const needsIndividualSets = items.some(({
|
|
1251
|
+
item
|
|
1252
|
+
}) => {
|
|
1253
|
+
const internal = asInternal(item);
|
|
1254
|
+
return internal._hasValidation || internal._hasExpiration;
|
|
1255
|
+
});
|
|
1256
|
+
if (needsIndividualSets) {
|
|
1257
|
+
items.forEach(({
|
|
1258
|
+
item,
|
|
1259
|
+
value
|
|
1260
|
+
}) => item.set(value));
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
// Atomic write: update all values in memoryStore, invalidate caches, then batch-notify
|
|
1154
1265
|
items.forEach(({
|
|
1155
1266
|
item,
|
|
1156
1267
|
value
|
|
1157
|
-
}) =>
|
|
1268
|
+
}) => {
|
|
1269
|
+
memoryStore.set(item.key, value);
|
|
1270
|
+
asInternal(item)._invalidateParsedCacheOnly();
|
|
1271
|
+
});
|
|
1272
|
+
items.forEach(({
|
|
1273
|
+
item
|
|
1274
|
+
}) => notifyKeyListeners(memoryListeners, item.key));
|
|
1158
1275
|
return;
|
|
1159
1276
|
}
|
|
1160
1277
|
if (scope === _Storage.StorageScope.Secure) {
|
|
@@ -1183,7 +1300,7 @@ function setBatch(items, scope) {
|
|
|
1183
1300
|
value,
|
|
1184
1301
|
internal
|
|
1185
1302
|
}) => {
|
|
1186
|
-
const accessControl = internal._secureAccessControl ??
|
|
1303
|
+
const accessControl = internal._secureAccessControl ?? secureDefaultAccessControl;
|
|
1187
1304
|
const existingGroup = groupedByAccessControl.get(accessControl);
|
|
1188
1305
|
const group = existingGroup ?? {
|
|
1189
1306
|
keys: [],
|
|
@@ -1260,9 +1377,11 @@ function migrateToLatest(scope = _Storage.StorageScope.Disk) {
|
|
|
1260
1377
|
return;
|
|
1261
1378
|
}
|
|
1262
1379
|
migration(context);
|
|
1263
|
-
writeMigrationVersion(scope, version);
|
|
1264
1380
|
appliedVersion = version;
|
|
1265
1381
|
});
|
|
1382
|
+
if (appliedVersion !== currentVersion) {
|
|
1383
|
+
writeMigrationVersion(scope, appliedVersion);
|
|
1384
|
+
}
|
|
1266
1385
|
return appliedVersion;
|
|
1267
1386
|
});
|
|
1268
1387
|
}
|
|
@@ -1272,12 +1391,17 @@ function runTransaction(scope, transaction) {
|
|
|
1272
1391
|
if (scope === _Storage.StorageScope.Secure) {
|
|
1273
1392
|
flushSecureWrites();
|
|
1274
1393
|
}
|
|
1394
|
+
const NOT_SET = Symbol();
|
|
1275
1395
|
const rollback = new Map();
|
|
1276
1396
|
const rememberRollback = key => {
|
|
1277
1397
|
if (rollback.has(key)) {
|
|
1278
1398
|
return;
|
|
1279
1399
|
}
|
|
1280
|
-
|
|
1400
|
+
if (scope === _Storage.StorageScope.Memory) {
|
|
1401
|
+
rollback.set(key, memoryStore.has(key) ? memoryStore.get(key) : NOT_SET);
|
|
1402
|
+
} else {
|
|
1403
|
+
rollback.set(key, getRawValue(key, scope));
|
|
1404
|
+
}
|
|
1281
1405
|
};
|
|
1282
1406
|
const tx = {
|
|
1283
1407
|
scope,
|
|
@@ -1311,11 +1435,12 @@ function runTransaction(scope, transaction) {
|
|
|
1311
1435
|
const rollbackEntries = Array.from(rollback.entries()).reverse();
|
|
1312
1436
|
if (scope === _Storage.StorageScope.Memory) {
|
|
1313
1437
|
rollbackEntries.forEach(([key, previousValue]) => {
|
|
1314
|
-
if (previousValue ===
|
|
1315
|
-
|
|
1438
|
+
if (previousValue === NOT_SET) {
|
|
1439
|
+
memoryStore.delete(key);
|
|
1316
1440
|
} else {
|
|
1317
|
-
|
|
1441
|
+
memoryStore.set(key, previousValue);
|
|
1318
1442
|
}
|
|
1443
|
+
notifyKeyListeners(memoryListeners, key);
|
|
1319
1444
|
});
|
|
1320
1445
|
} else {
|
|
1321
1446
|
const keysToSet = [];
|
|
@@ -1374,4 +1499,7 @@ function createSecureAuthStorage(config, options) {
|
|
|
1374
1499
|
}
|
|
1375
1500
|
return result;
|
|
1376
1501
|
}
|
|
1502
|
+
function isKeychainLockedError(_err) {
|
|
1503
|
+
return false;
|
|
1504
|
+
}
|
|
1377
1505
|
//# sourceMappingURL=index.web.js.map
|