{"version":3,"file":"StorageCacheCommon.mjs","sources":["../../../src/Cache/StorageCacheCommon.ts"],"sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { ConsoleLogger } from '../Logger';\nimport { currentSizeKey, defaultConfig } from './constants';\nimport { getByteLength, getCurrentSizeKey, getCurrentTime } from './utils';\nimport { CacheErrorCode, assert } from './utils/errorHelpers';\nconst logger = new ConsoleLogger('StorageCache');\n/**\n * Initialization of the cache\n *\n */\nexport class StorageCacheCommon {\n    /**\n     * Initialize the cache\n     *\n     * @param config - Custom configuration for this instance.\n     */\n    constructor({ config, keyValueStorage, }) {\n        this.config = {\n            ...defaultConfig,\n            ...config,\n        };\n        this.keyValueStorage = keyValueStorage;\n        this.sanitizeConfig();\n    }\n    getModuleName() {\n        return 'Cache';\n    }\n    /**\n     * Set custom configuration for the cache instance.\n     *\n     * @param config - customized configuration (without keyPrefix, which can't be changed)\n     *\n     * @return - the current configuration\n     */\n    configure(config) {\n        if (config) {\n            if (config.keyPrefix) {\n                logger.warn('keyPrefix can not be re-configured on an existing Cache instance.');\n            }\n            this.config = {\n                ...this.config,\n                ...config,\n            };\n        }\n        this.sanitizeConfig();\n        return this.config;\n    }\n    /**\n     * return the current size of the cache\n     * @return {Promise}\n     */\n    async getCurrentCacheSize() {\n        let size = await this.getStorage().getItem(getCurrentSizeKey(this.config.keyPrefix));\n        if (!size) {\n            await this.getStorage().setItem(getCurrentSizeKey(this.config.keyPrefix), '0');\n            size = '0';\n        }\n        return Number(size);\n    }\n    /**\n     * Set item into cache. You can put number, string, boolean or object.\n     * The cache will first check whether has the same key.\n     * If it has, it will delete the old item and then put the new item in\n     * The cache will pop out items if it is full\n     * You can specify the cache item options. The cache will abort and output a warning:\n     * If the key is invalid\n     * If the size of the item exceeds itemMaxSize.\n     * If the value is undefined\n     * If incorrect cache item configuration\n     * If error happened with browser storage\n     *\n     * @param {String} key - the key of the item\n     * @param {Object} value - the value of the item\n     * @param {Object} [options] - optional, the specified meta-data\n     *\n     * @return {Promise}\n     */\n    async setItem(key, value, options) {\n        logger.debug(`Set item: key is ${key}, value is ${value} with options: ${options}`);\n        if (!key || key === currentSizeKey) {\n            logger.warn(`Invalid key: should not be empty or reserved key: '${currentSizeKey}'`);\n            return;\n        }\n        if (typeof value === 'undefined') {\n            logger.warn(`The value of item should not be undefined!`);\n            return;\n        }\n        const cacheItemOptions = {\n            priority: options?.priority !== undefined\n                ? options.priority\n                : this.config.defaultPriority,\n            expires: options?.expires !== undefined\n                ? options.expires\n                : this.config.defaultTTL + getCurrentTime(),\n        };\n        if (cacheItemOptions.priority < 1 || cacheItemOptions.priority > 5) {\n            logger.warn(`Invalid parameter: priority due to out or range. It should be within 1 and 5.`);\n            return;\n        }\n        const prefixedKey = `${this.config.keyPrefix}${key}`;\n        const item = this.fillCacheItem(prefixedKey, value, cacheItemOptions);\n        // check whether this item is too big;\n        if (item.byteSize > this.config.itemMaxSize) {\n            logger.warn(`Item with key: ${key} you are trying to put into is too big!`);\n            return;\n        }\n        try {\n            // first look into the storage, if it exists, delete it.\n            const val = await this.getStorage().getItem(prefixedKey);\n            if (val) {\n                await this.removeCacheItem(prefixedKey, JSON.parse(val).byteSize);\n            }\n            // check whether the cache is full\n            if (await this.isCacheFull(item.byteSize)) {\n                const validKeys = await this.clearInvalidAndGetRemainingKeys();\n                if (await this.isCacheFull(item.byteSize)) {\n                    const sizeToPop = await this.sizeToPop(item.byteSize);\n                    await this.popOutItems(validKeys, sizeToPop);\n                }\n            }\n            // put item in the cache\n            return this.setCacheItem(prefixedKey, item);\n        }\n        catch (e) {\n            logger.warn(`setItem failed! ${e}`);\n        }\n    }\n    /**\n     * Get item from cache. It will return null if item doesn’t exist or it has been expired.\n     * If you specified callback function in the options,\n     * then the function will be executed if no such item in the cache\n     * and finally put the return value into cache.\n     * Please make sure the callback function will return the value you want to put into the cache.\n     * The cache will abort output a warning:\n     * If the key is invalid\n     * If error happened with AsyncStorage\n     *\n     * @param {String} key - the key of the item\n     * @param {Object} [options] - the options of callback function\n     *\n     * @return {Promise} - return a promise resolves to be the value of the item\n     */\n    async getItem(key, options) {\n        logger.debug(`Get item: key is ${key} with options ${options}`);\n        let cached;\n        if (!key || key === currentSizeKey) {\n            logger.warn(`Invalid key: should not be empty or reserved key: '${currentSizeKey}'`);\n            return null;\n        }\n        const prefixedKey = `${this.config.keyPrefix}${key}`;\n        try {\n            cached = await this.getStorage().getItem(prefixedKey);\n            if (cached != null) {\n                if (await this.isExpired(prefixedKey)) {\n                    // if expired, remove that item and return null\n                    await this.removeCacheItem(prefixedKey, JSON.parse(cached).byteSize);\n                }\n                else {\n                    // if not expired, update its visitedTime and return the value\n                    const item = await this.updateVisitedTime(JSON.parse(cached), prefixedKey);\n                    return item.data;\n                }\n            }\n            if (options?.callback) {\n                const val = options.callback();\n                if (val !== null) {\n                    await this.setItem(key, val, options);\n                }\n                return val;\n            }\n            return null;\n        }\n        catch (e) {\n            logger.warn(`getItem failed! ${e}`);\n            return null;\n        }\n    }\n    /**\n     * remove item from the cache\n     * The cache will abort output a warning:\n     * If error happened with AsyncStorage\n     * @param {String} key - the key of the item\n     * @return {Promise}\n     */\n    async removeItem(key) {\n        logger.debug(`Remove item: key is ${key}`);\n        if (!key || key === currentSizeKey) {\n            logger.warn(`Invalid key: should not be empty or reserved key: '${currentSizeKey}'`);\n            return;\n        }\n        const prefixedKey = `${this.config.keyPrefix}${key}`;\n        try {\n            const val = await this.getStorage().getItem(prefixedKey);\n            if (val) {\n                await this.removeCacheItem(prefixedKey, JSON.parse(val).byteSize);\n            }\n        }\n        catch (e) {\n            logger.warn(`removeItem failed! ${e}`);\n        }\n    }\n    /**\n     * Return all the keys owned by this cache.\n     * Will return an empty array if error occurred.\n     *\n     * @return {Promise}\n     */\n    async getAllKeys() {\n        try {\n            return await this.getAllCacheKeys();\n        }\n        catch (e) {\n            logger.warn(`getAllkeys failed! ${e}`);\n            return [];\n        }\n    }\n    getStorage() {\n        return this.keyValueStorage;\n    }\n    /**\n     * check whether item is expired\n     *\n     * @param key - the key of the item\n     *\n     * @return true if the item is expired.\n     */\n    async isExpired(key) {\n        const text = await this.getStorage().getItem(key);\n        assert(text !== null, CacheErrorCode.NoCacheItem, `Key: ${key}`);\n        const item = JSON.parse(text);\n        if (getCurrentTime() >= item.expires) {\n            return true;\n        }\n        return false;\n    }\n    /**\n     * delete item from cache\n     *\n     * @param prefixedKey - the key of the item\n     * @param size - optional, the byte size of the item\n     */\n    async removeCacheItem(prefixedKey, size) {\n        const item = await this.getStorage().getItem(prefixedKey);\n        assert(item !== null, CacheErrorCode.NoCacheItem, `Key: ${prefixedKey}`);\n        const itemSize = size ?? JSON.parse(item).byteSize;\n        // first try to update the current size of the cache\n        await this.decreaseCurrentSizeInBytes(itemSize);\n        // try to remove the item from cache\n        try {\n            await this.getStorage().removeItem(prefixedKey);\n        }\n        catch (removeItemError) {\n            // if some error happened, we need to rollback the current size\n            await this.increaseCurrentSizeInBytes(itemSize);\n            logger.error(`Failed to remove item: ${removeItemError}`);\n        }\n    }\n    /**\n     * produce a JSON object with meta-data and data value\n     * @param value - the value of the item\n     * @param options - optional, the specified meta-data\n     *\n     * @return - the item which has the meta-data and the value\n     */\n    fillCacheItem(key, value, options) {\n        const item = {\n            key,\n            data: value,\n            timestamp: getCurrentTime(),\n            visitedTime: getCurrentTime(),\n            priority: options.priority ?? 0,\n            expires: options.expires ?? 0,\n            type: typeof value,\n            byteSize: 0,\n        };\n        // calculate byte size\n        item.byteSize = getByteLength(JSON.stringify(item));\n        // re-calculate using cache item with updated byteSize property\n        item.byteSize = getByteLength(JSON.stringify(item));\n        return item;\n    }\n    sanitizeConfig() {\n        if (this.config.itemMaxSize > this.config.capacityInBytes) {\n            logger.error('Invalid parameter: itemMaxSize. It should be smaller than capacityInBytes. Setting back to default.');\n            this.config.itemMaxSize = defaultConfig.itemMaxSize;\n        }\n        if (this.config.defaultPriority > 5 || this.config.defaultPriority < 1) {\n            logger.error('Invalid parameter: defaultPriority. It should be between 1 and 5. Setting back to default.');\n            this.config.defaultPriority = defaultConfig.defaultPriority;\n        }\n        if (Number(this.config.warningThreshold) > 1 ||\n            Number(this.config.warningThreshold) < 0) {\n            logger.error('Invalid parameter: warningThreshold. It should be between 0 and 1. Setting back to default.');\n            this.config.warningThreshold = defaultConfig.warningThreshold;\n        }\n        // Set 5MB limit\n        const cacheLimit = 5 * 1024 * 1024;\n        if (this.config.capacityInBytes > cacheLimit) {\n            logger.error('Cache Capacity should be less than 5MB. Setting back to default. Setting back to default.');\n            this.config.capacityInBytes = defaultConfig.capacityInBytes;\n        }\n    }\n    /**\n     * increase current size of the cache\n     *\n     * @param amount - the amount of the cache szie which need to be increased\n     */\n    async increaseCurrentSizeInBytes(amount) {\n        const size = await this.getCurrentCacheSize();\n        await this.getStorage().setItem(getCurrentSizeKey(this.config.keyPrefix), (size + amount).toString());\n    }\n    /**\n     * decrease current size of the cache\n     *\n     * @param amount - the amount of the cache size which needs to be decreased\n     */\n    async decreaseCurrentSizeInBytes(amount) {\n        const size = await this.getCurrentCacheSize();\n        await this.getStorage().setItem(getCurrentSizeKey(this.config.keyPrefix), (size - amount).toString());\n    }\n    /**\n     * update the visited time if item has been visited\n     *\n     * @param item - the item which need to be updated\n     * @param prefixedKey - the key of the item\n     *\n     * @return the updated item\n     */\n    async updateVisitedTime(item, prefixedKey) {\n        item.visitedTime = getCurrentTime();\n        await this.getStorage().setItem(prefixedKey, JSON.stringify(item));\n        return item;\n    }\n    /**\n     * put item into cache\n     *\n     * @param prefixedKey - the key of the item\n     * @param itemData - the value of the item\n     * @param itemSizeInBytes - the byte size of the item\n     */\n    async setCacheItem(prefixedKey, item) {\n        // first try to update the current size of the cache.\n        await this.increaseCurrentSizeInBytes(item.byteSize);\n        // try to add the item into cache\n        try {\n            await this.getStorage().setItem(prefixedKey, JSON.stringify(item));\n        }\n        catch (setItemErr) {\n            // if some error happened, we need to rollback the current size\n            await this.decreaseCurrentSizeInBytes(item.byteSize);\n            logger.error(`Failed to set item ${setItemErr}`);\n        }\n    }\n    /**\n     * total space needed when poping out items\n     *\n     * @param itemSize\n     *\n     * @return total space needed\n     */\n    async sizeToPop(itemSize) {\n        const cur = await this.getCurrentCacheSize();\n        const spaceItemNeed = cur + itemSize - this.config.capacityInBytes;\n        const cacheThresholdSpace = (1 - this.config.warningThreshold) * this.config.capacityInBytes;\n        return spaceItemNeed > cacheThresholdSpace\n            ? spaceItemNeed\n            : cacheThresholdSpace;\n    }\n    /**\n     * see whether cache is full\n     *\n     * @param itemSize\n     *\n     * @return true if cache is full\n     */\n    async isCacheFull(itemSize) {\n        const cur = await this.getCurrentCacheSize();\n        return itemSize + cur > this.config.capacityInBytes;\n    }\n    /**\n     * get all the items we have, sort them by their priority,\n     * if priority is same, sort them by their last visited time\n     * pop out items from the low priority (5 is the lowest)\n     * @private\n     * @param keys - all the keys in this cache\n     * @param sizeToPop - the total size of the items which needed to be poped out\n     */\n    async popOutItems(keys, sizeToPop) {\n        const items = [];\n        let remainedSize = sizeToPop;\n        for (const key of keys) {\n            const val = await this.getStorage().getItem(key);\n            if (val != null) {\n                const item = JSON.parse(val);\n                items.push(item);\n            }\n        }\n        // first compare priority\n        // then compare visited time\n        items.sort((a, b) => {\n            if (a.priority > b.priority) {\n                return -1;\n            }\n            else if (a.priority < b.priority) {\n                return 1;\n            }\n            else {\n                if (a.visitedTime < b.visitedTime) {\n                    return -1;\n                }\n                else\n                    return 1;\n            }\n        });\n        for (const item of items) {\n            // pop out items until we have enough room for new item\n            await this.removeCacheItem(item.key, item.byteSize);\n            remainedSize -= item.byteSize;\n            if (remainedSize <= 0) {\n                return;\n            }\n        }\n    }\n    /**\n     * Scan the storage and combine the following operations for efficiency\n     *   1. Clear out all expired keys owned by this cache, not including the size key.\n     *   2. Return the remaining keys.\n     *\n     * @return The remaining valid keys\n     */\n    async clearInvalidAndGetRemainingKeys() {\n        const remainingKeys = [];\n        const keys = await this.getAllCacheKeys({\n            omitSizeKey: true,\n        });\n        for (const key of keys) {\n            if (await this.isExpired(key)) {\n                await this.removeCacheItem(key);\n            }\n            else {\n                remainingKeys.push(key);\n            }\n        }\n        return remainingKeys;\n    }\n    /**\n     * clear the entire cache\n     * The cache will abort and output a warning if error occurs\n     * @return {Promise}\n     */\n    async clear() {\n        logger.debug(`Clear Cache`);\n        try {\n            const keys = await this.getAllKeys();\n            for (const key of keys) {\n                const prefixedKey = `${this.config.keyPrefix}${key}`;\n                await this.getStorage().removeItem(prefixedKey);\n            }\n        }\n        catch (e) {\n            logger.warn(`clear failed! ${e}`);\n        }\n    }\n}\n"],"names":[],"mappings":"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"}