@aws-amplify/core
Version:
Core category of aws-amplify
1 lines • 30.2 kB
Source Map (JSON)
{"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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"}