/*! @azure/msal-browser v2.24.0 2022-05-02 */
'use strict';
import { __awaiter, __generator } from '../_virtual/_tslib.js';
import { BrowserAuthError, BrowserAuthErrorMessage } from '../error/BrowserAuthError.js';
import { DatabaseStorage } from './DatabaseStorage.js';
import { MemoryStorage } from './MemoryStorage.js';

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
/**
 * This class allows MSAL to store artifacts asynchronously using the DatabaseStorage IndexedDB wrapper,
 * backed up with the more volatile MemoryStorage object for cases in which IndexedDB may be unavailable.
 */
var AsyncMemoryStorage = /** @class */ (function () {
    function AsyncMemoryStorage(logger, storeName) {
        this.inMemoryCache = new MemoryStorage();
        this.indexedDBCache = new DatabaseStorage();
        this.logger = logger;
        this.storeName = storeName;
    }
    AsyncMemoryStorage.prototype.handleDatabaseAccessError = function (error) {
        if (error instanceof BrowserAuthError && error.errorCode === BrowserAuthErrorMessage.databaseUnavailable.code) {
            this.logger.error("Could not access persistent storage. This may be caused by browser privacy features which block persistent storage in third-party contexts.");
        }
        else {
            throw error;
        }
    };
    /**
     * Get the item matching the given key. Tries in-memory cache first, then in the asynchronous
     * storage object if item isn't found in-memory.
     * @param key
     */
    AsyncMemoryStorage.prototype.getItem = function (key) {
        return __awaiter(this, void 0, void 0, function () {
            var item, e_1;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        item = this.inMemoryCache.getItem(key);
                        if (!!item) return [3 /*break*/, 4];
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        this.logger.verbose("Queried item not found in in-memory cache, now querying persistent storage.");
                        return [4 /*yield*/, this.indexedDBCache.getItem(key)];
                    case 2: return [2 /*return*/, _a.sent()];
                    case 3:
                        e_1 = _a.sent();
                        this.handleDatabaseAccessError(e_1);
                        return [3 /*break*/, 4];
                    case 4: return [2 /*return*/, item];
                }
            });
        });
    };
    /**
     * Sets the item in the in-memory cache and then tries to set it in the asynchronous
     * storage object with the given key.
     * @param key
     * @param value
     */
    AsyncMemoryStorage.prototype.setItem = function (key, value) {
        return __awaiter(this, void 0, void 0, function () {
            var e_2;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.inMemoryCache.setItem(key, value);
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        return [4 /*yield*/, this.indexedDBCache.setItem(key, value)];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 4];
                    case 3:
                        e_2 = _a.sent();
                        this.handleDatabaseAccessError(e_2);
                        return [3 /*break*/, 4];
                    case 4: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Removes the item matching the key from the in-memory cache, then tries to remove it from the asynchronous storage object.
     * @param key
     */
    AsyncMemoryStorage.prototype.removeItem = function (key) {
        return __awaiter(this, void 0, void 0, function () {
            var e_3;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        this.inMemoryCache.removeItem(key);
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        return [4 /*yield*/, this.indexedDBCache.removeItem(key)];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 4];
                    case 3:
                        e_3 = _a.sent();
                        this.handleDatabaseAccessError(e_3);
                        return [3 /*break*/, 4];
                    case 4: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Get all the keys from the in-memory cache as an iterable array of strings. If no keys are found, query the keys in the
     * asynchronous storage object.
     */
    AsyncMemoryStorage.prototype.getKeys = function () {
        return __awaiter(this, void 0, void 0, function () {
            var cacheKeys, e_4;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        cacheKeys = this.inMemoryCache.getKeys();
                        if (!(cacheKeys.length === 0)) return [3 /*break*/, 4];
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        this.logger.verbose("In-memory cache is empty, now querying persistent storage.");
                        return [4 /*yield*/, this.indexedDBCache.getKeys()];
                    case 2: return [2 /*return*/, _a.sent()];
                    case 3:
                        e_4 = _a.sent();
                        this.handleDatabaseAccessError(e_4);
                        return [3 /*break*/, 4];
                    case 4: return [2 /*return*/, cacheKeys];
                }
            });
        });
    };
    /**
     * Returns true or false if the given key is present in the cache.
     * @param key
     */
    AsyncMemoryStorage.prototype.containsKey = function (key) {
        return __awaiter(this, void 0, void 0, function () {
            var containsKey, e_5;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        containsKey = this.inMemoryCache.containsKey(key);
                        if (!!containsKey) return [3 /*break*/, 4];
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        this.logger.verbose("Key not found in in-memory cache, now querying persistent storage.");
                        return [4 /*yield*/, this.indexedDBCache.containsKey(key)];
                    case 2: return [2 /*return*/, _a.sent()];
                    case 3:
                        e_5 = _a.sent();
                        this.handleDatabaseAccessError(e_5);
                        return [3 /*break*/, 4];
                    case 4: return [2 /*return*/, containsKey];
                }
            });
        });
    };
    /**
     * Clears in-memory Map and tries to delete the IndexedDB database.
     */
    AsyncMemoryStorage.prototype.clear = function () {
        return __awaiter(this, void 0, void 0, function () {
            var dbDeleted, e_6;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        // InMemory cache is a Map instance, clear is straightforward
                        this.logger.verbose("Deleting in-memory keystore " + this.storeName);
                        this.inMemoryCache.clear();
                        this.logger.verbose("In-memory keystore " + this.storeName + " deleted");
                        this.logger.verbose("Deleting persistent keystore " + this.storeName);
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        return [4 /*yield*/, this.indexedDBCache.deleteDatabase()];
                    case 2:
                        dbDeleted = _a.sent();
                        if (dbDeleted) {
                            this.logger.verbose("Persistent keystore " + this.storeName + " deleted");
                        }
                        return [2 /*return*/, dbDeleted];
                    case 3:
                        e_6 = _a.sent();
                        this.handleDatabaseAccessError(e_6);
                        return [2 /*return*/, false];
                    case 4: return [2 /*return*/];
                }
            });
        });
    };
    return AsyncMemoryStorage;
}());

export { AsyncMemoryStorage };
//# sourceMappingURL=AsyncMemoryStorage.js.map
