react-native-nitro-storage 0.4.4 → 0.4.5
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 +107 -7
- package/android/src/main/java/com/nitrostorage/AndroidStorageAdapter.kt +61 -10
- package/ios/IOSStorageAdapterCpp.mm +44 -14
- package/lib/commonjs/index.js +221 -5
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +444 -202
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/indexeddb-backend.js +129 -7
- package/lib/commonjs/indexeddb-backend.js.map +1 -1
- package/lib/commonjs/storage-runtime.js +41 -0
- package/lib/commonjs/storage-runtime.js.map +1 -0
- package/lib/commonjs/web-storage-backend.js +90 -0
- package/lib/commonjs/web-storage-backend.js.map +1 -0
- package/lib/module/index.js +213 -5
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +436 -202
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/indexeddb-backend.js +129 -7
- package/lib/module/indexeddb-backend.js.map +1 -1
- package/lib/module/storage-runtime.js +36 -0
- package/lib/module/storage-runtime.js.map +1 -0
- package/lib/module/web-storage-backend.js +86 -0
- package/lib/module/web-storage-backend.js.map +1 -0
- package/lib/typescript/index.d.ts +11 -7
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.web.d.ts +12 -8
- package/lib/typescript/index.web.d.ts.map +1 -1
- package/lib/typescript/indexeddb-backend.d.ts +6 -2
- package/lib/typescript/indexeddb-backend.d.ts.map +1 -1
- package/lib/typescript/storage-runtime.d.ts +16 -0
- package/lib/typescript/storage-runtime.d.ts.map +1 -0
- package/lib/typescript/web-storage-backend.d.ts +30 -0
- package/lib/typescript/web-storage-backend.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +264 -20
- package/src/index.web.ts +597 -245
- package/src/indexeddb-backend.ts +147 -6
- package/src/storage-runtime.ts +94 -0
- package/src/web-storage-backend.ts +129 -0
package/lib/commonjs/index.js
CHANGED
|
@@ -29,7 +29,15 @@ Object.defineProperty(exports, "createIndexedDBBackend", {
|
|
|
29
29
|
});
|
|
30
30
|
exports.createSecureAuthStorage = createSecureAuthStorage;
|
|
31
31
|
exports.createStorageItem = createStorageItem;
|
|
32
|
+
exports.flushWebStorageBackends = flushWebStorageBackends;
|
|
32
33
|
exports.getBatch = getBatch;
|
|
34
|
+
Object.defineProperty(exports, "getStorageErrorCode", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function () {
|
|
37
|
+
return _storageRuntime.getStorageErrorCode;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
exports.getWebDiskStorageBackend = getWebDiskStorageBackend;
|
|
33
41
|
exports.getWebSecureStorageBackend = getWebSecureStorageBackend;
|
|
34
42
|
exports.isKeychainLockedError = isKeychainLockedError;
|
|
35
43
|
Object.defineProperty(exports, "migrateFromMMKV", {
|
|
@@ -43,6 +51,7 @@ exports.registerMigration = registerMigration;
|
|
|
43
51
|
exports.removeBatch = removeBatch;
|
|
44
52
|
exports.runTransaction = runTransaction;
|
|
45
53
|
exports.setBatch = setBatch;
|
|
54
|
+
exports.setWebDiskStorageBackend = setWebDiskStorageBackend;
|
|
46
55
|
exports.setWebSecureStorageBackend = setWebSecureStorageBackend;
|
|
47
56
|
exports.storage = void 0;
|
|
48
57
|
Object.defineProperty(exports, "useSetStorage", {
|
|
@@ -66,6 +75,7 @@ Object.defineProperty(exports, "useStorageSelector", {
|
|
|
66
75
|
var _reactNativeNitroModules = require("react-native-nitro-modules");
|
|
67
76
|
var _Storage = require("./Storage.types");
|
|
68
77
|
var _internal = require("./internal");
|
|
78
|
+
var _storageRuntime = require("./storage-runtime");
|
|
69
79
|
var _migration = require("./migration");
|
|
70
80
|
var _storageHooks = require("./storage-hooks");
|
|
71
81
|
var _indexeddbBackend = require("./indexeddb-backend");
|
|
@@ -82,6 +92,7 @@ const registeredMigrations = new Map();
|
|
|
82
92
|
const runMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : task => {
|
|
83
93
|
Promise.resolve().then(task);
|
|
84
94
|
};
|
|
95
|
+
const now = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
|
|
85
96
|
let _storageModule = null;
|
|
86
97
|
function getStorageModule() {
|
|
87
98
|
if (!_storageModule) {
|
|
@@ -94,6 +105,9 @@ const memoryListeners = new Map();
|
|
|
94
105
|
const scopedListeners = new Map([[_Storage.StorageScope.Disk, new Map()], [_Storage.StorageScope.Secure, new Map()]]);
|
|
95
106
|
const scopedUnsubscribers = new Map();
|
|
96
107
|
const scopedRawCache = new Map([[_Storage.StorageScope.Disk, new Map()], [_Storage.StorageScope.Secure, new Map()]]);
|
|
108
|
+
const pendingDiskWrites = new Map();
|
|
109
|
+
let diskFlushScheduled = false;
|
|
110
|
+
let diskWritesAsync = false;
|
|
97
111
|
const pendingSecureWrites = new Map();
|
|
98
112
|
let secureFlushScheduled = false;
|
|
99
113
|
let secureDefaultAccessControl = _Storage.AccessControl.WhenUnlocked;
|
|
@@ -123,11 +137,11 @@ function measureOperation(operation, scope, fn, keysCount = 1) {
|
|
|
123
137
|
if (!metricsObserver) {
|
|
124
138
|
return fn();
|
|
125
139
|
}
|
|
126
|
-
const start =
|
|
140
|
+
const start = now();
|
|
127
141
|
try {
|
|
128
142
|
return fn();
|
|
129
143
|
} finally {
|
|
130
|
-
recordMetric(operation, scope,
|
|
144
|
+
recordMetric(operation, scope, now() - start, keysCount);
|
|
131
145
|
}
|
|
132
146
|
}
|
|
133
147
|
function getScopedListeners(scope) {
|
|
@@ -184,12 +198,50 @@ function addKeyListener(registry, key, listener) {
|
|
|
184
198
|
function readPendingSecureWrite(key) {
|
|
185
199
|
return pendingSecureWrites.get(key)?.value;
|
|
186
200
|
}
|
|
201
|
+
function readPendingDiskWrite(key) {
|
|
202
|
+
return pendingDiskWrites.get(key)?.value;
|
|
203
|
+
}
|
|
204
|
+
function hasPendingDiskWrite(key) {
|
|
205
|
+
return pendingDiskWrites.has(key);
|
|
206
|
+
}
|
|
187
207
|
function hasPendingSecureWrite(key) {
|
|
188
208
|
return pendingSecureWrites.has(key);
|
|
189
209
|
}
|
|
210
|
+
function clearPendingDiskWrite(key) {
|
|
211
|
+
pendingDiskWrites.delete(key);
|
|
212
|
+
}
|
|
190
213
|
function clearPendingSecureWrite(key) {
|
|
191
214
|
pendingSecureWrites.delete(key);
|
|
192
215
|
}
|
|
216
|
+
function flushDiskWrites() {
|
|
217
|
+
diskFlushScheduled = false;
|
|
218
|
+
if (pendingDiskWrites.size === 0) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const writes = Array.from(pendingDiskWrites.values());
|
|
222
|
+
pendingDiskWrites.clear();
|
|
223
|
+
const keysToSet = [];
|
|
224
|
+
const valuesToSet = [];
|
|
225
|
+
const keysToRemove = [];
|
|
226
|
+
writes.forEach(({
|
|
227
|
+
key,
|
|
228
|
+
value
|
|
229
|
+
}) => {
|
|
230
|
+
if (value === undefined) {
|
|
231
|
+
keysToRemove.push(key);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
keysToSet.push(key);
|
|
235
|
+
valuesToSet.push(value);
|
|
236
|
+
});
|
|
237
|
+
const storageModule = getStorageModule();
|
|
238
|
+
if (keysToSet.length > 0) {
|
|
239
|
+
storageModule.setBatch(keysToSet, valuesToSet, _Storage.StorageScope.Disk);
|
|
240
|
+
}
|
|
241
|
+
if (keysToRemove.length > 0) {
|
|
242
|
+
storageModule.removeBatch(keysToRemove, _Storage.StorageScope.Disk);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
193
245
|
function flushSecureWrites() {
|
|
194
246
|
secureFlushScheduled = false;
|
|
195
247
|
if (pendingSecureWrites.size === 0) {
|
|
@@ -229,6 +281,17 @@ function flushSecureWrites() {
|
|
|
229
281
|
storageModule.removeBatch(keysToRemove, _Storage.StorageScope.Secure);
|
|
230
282
|
}
|
|
231
283
|
}
|
|
284
|
+
function scheduleDiskWrite(key, value) {
|
|
285
|
+
pendingDiskWrites.set(key, {
|
|
286
|
+
key,
|
|
287
|
+
value
|
|
288
|
+
});
|
|
289
|
+
if (diskFlushScheduled) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
diskFlushScheduled = true;
|
|
293
|
+
runMicrotask(flushDiskWrites);
|
|
294
|
+
}
|
|
232
295
|
function scheduleSecureWrite(key, value, accessControl) {
|
|
233
296
|
const pendingWrite = {
|
|
234
297
|
key,
|
|
@@ -249,6 +312,13 @@ function ensureNativeScopeSubscription(scope) {
|
|
|
249
312
|
return;
|
|
250
313
|
}
|
|
251
314
|
const unsubscribe = getStorageModule().addOnChange(scope, (key, value) => {
|
|
315
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
316
|
+
if (key === "") {
|
|
317
|
+
pendingDiskWrites.clear();
|
|
318
|
+
} else {
|
|
319
|
+
clearPendingDiskWrite(key);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
252
322
|
if (scope === _Storage.StorageScope.Secure) {
|
|
253
323
|
if (key === "") {
|
|
254
324
|
pendingSecureWrites.clear();
|
|
@@ -284,6 +354,9 @@ function getRawValue(key, scope) {
|
|
|
284
354
|
const value = memoryStore.get(key);
|
|
285
355
|
return typeof value === "string" ? value : undefined;
|
|
286
356
|
}
|
|
357
|
+
if (scope === _Storage.StorageScope.Disk && hasPendingDiskWrite(key)) {
|
|
358
|
+
return readPendingDiskWrite(key);
|
|
359
|
+
}
|
|
287
360
|
if (scope === _Storage.StorageScope.Secure && hasPendingSecureWrite(key)) {
|
|
288
361
|
return readPendingSecureWrite(key);
|
|
289
362
|
}
|
|
@@ -296,6 +369,15 @@ function setRawValue(key, value, scope) {
|
|
|
296
369
|
notifyKeyListeners(memoryListeners, key);
|
|
297
370
|
return;
|
|
298
371
|
}
|
|
372
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
373
|
+
cacheRawValue(scope, key, value);
|
|
374
|
+
if (diskWritesAsync) {
|
|
375
|
+
scheduleDiskWrite(key, value);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
flushDiskWrites();
|
|
379
|
+
clearPendingDiskWrite(key);
|
|
380
|
+
}
|
|
299
381
|
if (scope === _Storage.StorageScope.Secure) {
|
|
300
382
|
flushSecureWrites();
|
|
301
383
|
clearPendingSecureWrite(key);
|
|
@@ -311,6 +393,15 @@ function removeRawValue(key, scope) {
|
|
|
311
393
|
notifyKeyListeners(memoryListeners, key);
|
|
312
394
|
return;
|
|
313
395
|
}
|
|
396
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
397
|
+
cacheRawValue(scope, key, undefined);
|
|
398
|
+
if (diskWritesAsync) {
|
|
399
|
+
scheduleDiskWrite(key, undefined);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
flushDiskWrites();
|
|
403
|
+
clearPendingDiskWrite(key);
|
|
404
|
+
}
|
|
314
405
|
if (scope === _Storage.StorageScope.Secure) {
|
|
315
406
|
flushSecureWrites();
|
|
316
407
|
clearPendingSecureWrite(key);
|
|
@@ -337,6 +428,10 @@ const storage = exports.storage = {
|
|
|
337
428
|
notifyAllListeners(memoryListeners);
|
|
338
429
|
return;
|
|
339
430
|
}
|
|
431
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
432
|
+
flushDiskWrites();
|
|
433
|
+
pendingDiskWrites.clear();
|
|
434
|
+
}
|
|
340
435
|
if (scope === _Storage.StorageScope.Secure) {
|
|
341
436
|
flushSecureWrites();
|
|
342
437
|
pendingSecureWrites.clear();
|
|
@@ -365,6 +460,9 @@ const storage = exports.storage = {
|
|
|
365
460
|
return;
|
|
366
461
|
}
|
|
367
462
|
const keyPrefix = (0, _internal.prefixKey)(namespace, "");
|
|
463
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
464
|
+
flushDiskWrites();
|
|
465
|
+
}
|
|
368
466
|
if (scope === _Storage.StorageScope.Secure) {
|
|
369
467
|
flushSecureWrites();
|
|
370
468
|
}
|
|
@@ -388,6 +486,12 @@ const storage = exports.storage = {
|
|
|
388
486
|
if (scope === _Storage.StorageScope.Memory) {
|
|
389
487
|
return memoryStore.has(key);
|
|
390
488
|
}
|
|
489
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
490
|
+
flushDiskWrites();
|
|
491
|
+
}
|
|
492
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
493
|
+
flushSecureWrites();
|
|
494
|
+
}
|
|
391
495
|
return getStorageModule().has(key, scope);
|
|
392
496
|
});
|
|
393
497
|
},
|
|
@@ -397,6 +501,12 @@ const storage = exports.storage = {
|
|
|
397
501
|
if (scope === _Storage.StorageScope.Memory) {
|
|
398
502
|
return Array.from(memoryStore.keys());
|
|
399
503
|
}
|
|
504
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
505
|
+
flushDiskWrites();
|
|
506
|
+
}
|
|
507
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
508
|
+
flushSecureWrites();
|
|
509
|
+
}
|
|
400
510
|
return getStorageModule().getAllKeys(scope);
|
|
401
511
|
});
|
|
402
512
|
},
|
|
@@ -406,6 +516,12 @@ const storage = exports.storage = {
|
|
|
406
516
|
if (scope === _Storage.StorageScope.Memory) {
|
|
407
517
|
return Array.from(memoryStore.keys()).filter(key => key.startsWith(prefix));
|
|
408
518
|
}
|
|
519
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
520
|
+
flushDiskWrites();
|
|
521
|
+
}
|
|
522
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
523
|
+
flushSecureWrites();
|
|
524
|
+
}
|
|
409
525
|
return getStorageModule().getKeysByPrefix(prefix, scope);
|
|
410
526
|
});
|
|
411
527
|
},
|
|
@@ -425,6 +541,12 @@ const storage = exports.storage = {
|
|
|
425
541
|
});
|
|
426
542
|
return result;
|
|
427
543
|
}
|
|
544
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
545
|
+
flushDiskWrites();
|
|
546
|
+
}
|
|
547
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
548
|
+
flushSecureWrites();
|
|
549
|
+
}
|
|
428
550
|
const values = getStorageModule().getBatch(keys, scope);
|
|
429
551
|
keys.forEach((key, idx) => {
|
|
430
552
|
const value = (0, _internal.decodeNativeBatchValue)(values[idx]);
|
|
@@ -445,6 +567,12 @@ const storage = exports.storage = {
|
|
|
445
567
|
});
|
|
446
568
|
return result;
|
|
447
569
|
}
|
|
570
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
571
|
+
flushDiskWrites();
|
|
572
|
+
}
|
|
573
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
574
|
+
flushSecureWrites();
|
|
575
|
+
}
|
|
448
576
|
const keys = getStorageModule().getAllKeys(scope);
|
|
449
577
|
if (keys.length === 0) return result;
|
|
450
578
|
const values = getStorageModule().getBatch(keys, scope);
|
|
@@ -461,6 +589,12 @@ const storage = exports.storage = {
|
|
|
461
589
|
if (scope === _Storage.StorageScope.Memory) {
|
|
462
590
|
return memoryStore.size;
|
|
463
591
|
}
|
|
592
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
593
|
+
flushDiskWrites();
|
|
594
|
+
}
|
|
595
|
+
if (scope === _Storage.StorageScope.Secure) {
|
|
596
|
+
flushSecureWrites();
|
|
597
|
+
}
|
|
464
598
|
return getStorageModule().size(scope);
|
|
465
599
|
});
|
|
466
600
|
},
|
|
@@ -475,6 +609,19 @@ const storage = exports.storage = {
|
|
|
475
609
|
getStorageModule().setSecureWritesAsync(enabled);
|
|
476
610
|
});
|
|
477
611
|
},
|
|
612
|
+
setDiskWritesAsync: enabled => {
|
|
613
|
+
measureOperation("storage:setDiskWritesAsync", _Storage.StorageScope.Disk, () => {
|
|
614
|
+
diskWritesAsync = enabled;
|
|
615
|
+
if (!enabled) {
|
|
616
|
+
flushDiskWrites();
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
},
|
|
620
|
+
flushDiskWrites: () => {
|
|
621
|
+
measureOperation("storage:flushDiskWrites", _Storage.StorageScope.Disk, () => {
|
|
622
|
+
flushDiskWrites();
|
|
623
|
+
});
|
|
624
|
+
},
|
|
478
625
|
flushSecureWrites: () => {
|
|
479
626
|
measureOperation("storage:flushSecureWrites", _Storage.StorageScope.Secure, () => {
|
|
480
627
|
flushSecureWrites();
|
|
@@ -503,6 +650,18 @@ const storage = exports.storage = {
|
|
|
503
650
|
resetMetrics: () => {
|
|
504
651
|
metricsCounters.clear();
|
|
505
652
|
},
|
|
653
|
+
getCapabilities: () => ({
|
|
654
|
+
platform: "native",
|
|
655
|
+
backend: {
|
|
656
|
+
disk: "platform-preferences",
|
|
657
|
+
secure: "platform-secure-storage"
|
|
658
|
+
},
|
|
659
|
+
writeBuffering: {
|
|
660
|
+
disk: true,
|
|
661
|
+
secure: true
|
|
662
|
+
},
|
|
663
|
+
errorClassification: true
|
|
664
|
+
}),
|
|
506
665
|
getString: (key, scope) => {
|
|
507
666
|
return measureOperation("storage:getString", scope, () => {
|
|
508
667
|
return getRawValue(key, scope);
|
|
@@ -546,6 +705,15 @@ function setWebSecureStorageBackend(_backend) {
|
|
|
546
705
|
function getWebSecureStorageBackend() {
|
|
547
706
|
return undefined;
|
|
548
707
|
}
|
|
708
|
+
function setWebDiskStorageBackend(_backend) {
|
|
709
|
+
// Native platforms do not use web disk backends.
|
|
710
|
+
}
|
|
711
|
+
function getWebDiskStorageBackend() {
|
|
712
|
+
return undefined;
|
|
713
|
+
}
|
|
714
|
+
async function flushWebStorageBackends() {
|
|
715
|
+
// Native platforms do not use web storage backends.
|
|
716
|
+
}
|
|
549
717
|
function canUseRawBatchPath(item) {
|
|
550
718
|
return item._hasExpiration === false && item._hasValidation === false && item._isBiometric !== true && item._secureAccessControl === undefined;
|
|
551
719
|
}
|
|
@@ -573,6 +741,7 @@ function createStorageItem(config) {
|
|
|
573
741
|
const expirationTtlMs = expiration?.ttlMs;
|
|
574
742
|
const memoryExpiration = expiration && isMemory ? new Map() : null;
|
|
575
743
|
const readCache = !isMemory && config.readCache === true;
|
|
744
|
+
const coalesceDiskWrites = config.scope === _Storage.StorageScope.Disk && config.coalesceDiskWrites === true;
|
|
576
745
|
const coalesceSecureWrites = config.scope === _Storage.StorageScope.Secure && config.coalesceSecureWrites === true && !isBiometric;
|
|
577
746
|
const defaultValue = config.defaultValue;
|
|
578
747
|
const nonMemoryScope = config.scope === _Storage.StorageScope.Disk ? _Storage.StorageScope.Disk : config.scope === _Storage.StorageScope.Secure ? _Storage.StorageScope.Secure : null;
|
|
@@ -620,6 +789,12 @@ function createStorageItem(config) {
|
|
|
620
789
|
}
|
|
621
790
|
return memoryStore.get(storageKey);
|
|
622
791
|
}
|
|
792
|
+
if (nonMemoryScope === _Storage.StorageScope.Disk) {
|
|
793
|
+
const pending = pendingDiskWrites.get(storageKey);
|
|
794
|
+
if (pending !== undefined) {
|
|
795
|
+
return pending.value;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
623
798
|
if (nonMemoryScope === _Storage.StorageScope.Secure && !isBiometric) {
|
|
624
799
|
const pending = pendingSecureWrites.get(storageKey);
|
|
625
800
|
if (pending !== undefined) {
|
|
@@ -646,6 +821,13 @@ function createStorageItem(config) {
|
|
|
646
821
|
return;
|
|
647
822
|
}
|
|
648
823
|
cacheRawValue(nonMemoryScope, storageKey, rawValue);
|
|
824
|
+
if (nonMemoryScope === _Storage.StorageScope.Disk) {
|
|
825
|
+
if (coalesceDiskWrites || diskWritesAsync) {
|
|
826
|
+
scheduleDiskWrite(storageKey, rawValue);
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
clearPendingDiskWrite(storageKey);
|
|
830
|
+
}
|
|
649
831
|
if (coalesceSecureWrites) {
|
|
650
832
|
scheduleSecureWrite(storageKey, rawValue, secureAccessControl ?? secureDefaultAccessControl);
|
|
651
833
|
return;
|
|
@@ -662,6 +844,13 @@ function createStorageItem(config) {
|
|
|
662
844
|
return;
|
|
663
845
|
}
|
|
664
846
|
cacheRawValue(nonMemoryScope, storageKey, undefined);
|
|
847
|
+
if (nonMemoryScope === _Storage.StorageScope.Disk) {
|
|
848
|
+
if (coalesceDiskWrites || diskWritesAsync) {
|
|
849
|
+
scheduleDiskWrite(storageKey, undefined);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
clearPendingDiskWrite(storageKey);
|
|
853
|
+
}
|
|
665
854
|
if (coalesceSecureWrites) {
|
|
666
855
|
scheduleSecureWrite(storageKey, undefined, secureAccessControl ?? secureDefaultAccessControl);
|
|
667
856
|
return;
|
|
@@ -822,6 +1011,18 @@ function createStorageItem(config) {
|
|
|
822
1011
|
const hasItem = () => measureOperation("item:has", config.scope, () => {
|
|
823
1012
|
if (isMemory) return memoryStore.has(storageKey);
|
|
824
1013
|
if (isBiometric) return getStorageModule().hasSecureBiometric(storageKey);
|
|
1014
|
+
if (nonMemoryScope === _Storage.StorageScope.Disk) {
|
|
1015
|
+
const pending = pendingDiskWrites.get(storageKey);
|
|
1016
|
+
if (pending !== undefined) {
|
|
1017
|
+
return pending.value !== undefined;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
if (nonMemoryScope === _Storage.StorageScope.Secure) {
|
|
1021
|
+
const pending = pendingSecureWrites.get(storageKey);
|
|
1022
|
+
if (pending !== undefined) {
|
|
1023
|
+
return pending.value !== undefined;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
825
1026
|
return getStorageModule().has(storageKey, config.scope);
|
|
826
1027
|
});
|
|
827
1028
|
const subscribe = callback => {
|
|
@@ -882,6 +1083,13 @@ function getBatch(items, scope) {
|
|
|
882
1083
|
const keysToFetch = [];
|
|
883
1084
|
const keyIndexes = [];
|
|
884
1085
|
items.forEach((item, index) => {
|
|
1086
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
1087
|
+
const pending = pendingDiskWrites.get(item.key);
|
|
1088
|
+
if (pending !== undefined) {
|
|
1089
|
+
rawValues[index] = pending.value;
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
885
1093
|
if (scope === _Storage.StorageScope.Secure) {
|
|
886
1094
|
const pending = pendingSecureWrites.get(item.key);
|
|
887
1095
|
if (pending !== undefined) {
|
|
@@ -1000,6 +1208,7 @@ function setBatch(items, scope) {
|
|
|
1000
1208
|
});
|
|
1001
1209
|
return;
|
|
1002
1210
|
}
|
|
1211
|
+
flushDiskWrites();
|
|
1003
1212
|
const useRawBatchPath = items.every(({
|
|
1004
1213
|
item
|
|
1005
1214
|
}) => canUseRawBatchPath(asInternal(item)));
|
|
@@ -1024,6 +1233,9 @@ function removeBatch(items, scope) {
|
|
|
1024
1233
|
return;
|
|
1025
1234
|
}
|
|
1026
1235
|
const keys = items.map(item => item.key);
|
|
1236
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
1237
|
+
flushDiskWrites();
|
|
1238
|
+
}
|
|
1027
1239
|
if (scope === _Storage.StorageScope.Secure) {
|
|
1028
1240
|
flushSecureWrites();
|
|
1029
1241
|
}
|
|
@@ -1069,6 +1281,9 @@ function migrateToLatest(scope = _Storage.StorageScope.Disk) {
|
|
|
1069
1281
|
function runTransaction(scope, transaction) {
|
|
1070
1282
|
return measureOperation("transaction:run", scope, () => {
|
|
1071
1283
|
(0, _internal.assertValidScope)(scope);
|
|
1284
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
1285
|
+
flushDiskWrites();
|
|
1286
|
+
}
|
|
1072
1287
|
if (scope === _Storage.StorageScope.Secure) {
|
|
1073
1288
|
flushSecureWrites();
|
|
1074
1289
|
}
|
|
@@ -1135,6 +1350,9 @@ function runTransaction(scope, transaction) {
|
|
|
1135
1350
|
valuesToSet.push(previousValue);
|
|
1136
1351
|
}
|
|
1137
1352
|
});
|
|
1353
|
+
if (scope === _Storage.StorageScope.Disk) {
|
|
1354
|
+
flushDiskWrites();
|
|
1355
|
+
}
|
|
1138
1356
|
if (scope === _Storage.StorageScope.Secure) {
|
|
1139
1357
|
flushSecureWrites();
|
|
1140
1358
|
}
|
|
@@ -1152,9 +1370,7 @@ function runTransaction(scope, transaction) {
|
|
|
1152
1370
|
});
|
|
1153
1371
|
}
|
|
1154
1372
|
function isKeychainLockedError(err) {
|
|
1155
|
-
|
|
1156
|
-
const msg = err.message;
|
|
1157
|
-
return msg.includes("errSecInteractionNotAllowed") || msg.includes("UserNotAuthenticatedException") || msg.includes("KeyStoreException") || msg.includes("KeyPermanentlyInvalidatedException") || msg.includes("InvalidKeyException") || msg.includes("android.security.keystore");
|
|
1373
|
+
return (0, _storageRuntime.isLockedStorageErrorCode)((0, _storageRuntime.getStorageErrorCode)(err));
|
|
1158
1374
|
}
|
|
1159
1375
|
function createSecureAuthStorage(config, options) {
|
|
1160
1376
|
const ns = options?.namespace ?? "auth";
|