@kangfenmao/keyv-storage
Version:
Simple key-value storage with support for multiple backends
148 lines (147 loc) • 4.83 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const MemoryStorage_1 = __importDefault(require("./adapter/MemoryStorage"));
class KeyvStorage {
constructor(params = {}) {
this.env = '';
this.expiredSuffix = ':expired_time';
this.keepSuffix = '{[keep]}';
this.storage = params.driver || new MemoryStorage_1.default();
this.env = params.env || '';
}
init() {
return __awaiter(this, void 0, void 0, function* () {
yield this.storage.init();
this.removeExpiredKeys();
console.log('[Storage]', 'SyncStorage is ready!');
});
}
/**
* Remove expired keys
* @param {string} key
*/
removeExpiredKeys() {
this.storage.getAllKeys().forEach((k) => this.removeExpiredKey(k));
}
/**
* Remove expired key
* @param {string} key
*/
removeExpiredKey(key) {
if (key.indexOf(this.expiredSuffix) > -1) {
const cacheValue = this.storage.get(key);
if (!cacheValue) {
return;
}
const expiredAtTimestamp = new Date(cacheValue.expired_at).getTime();
const nowTimestamp = new Date().getTime();
const expired = expiredAtTimestamp < nowTimestamp;
const systemTimeChanged = !expired && expiredAtTimestamp - nowTimestamp > cacheValue.ttl;
if (expired || systemTimeChanged) {
this.storage.remove(key);
this.storage.remove(key.replace(this.expiredSuffix, ''));
}
}
}
/**
* Get storage key name
* @param {string} key
*/
getKey(key) {
return `${key}${this.env}`;
}
/**
* Get storage expired key name
* @param {string} key
*/
getExpiredKey(key) {
return `${key}${this.expiredSuffix}${this.env}`;
}
/**
* Get storage value
* @param {string} key
*/
get(key) {
const keyName = this.getKey(key);
const expiredKeyName = this.getExpiredKey(key);
this.removeExpiredKey(expiredKeyName);
return this.storage.get(keyName);
}
/**
* Set a storage key
* @param {string} key
* @param {any} data
* @param {object} expires
*/
set(key, data, { expires } = { expires: null }) {
if (data === null || data === undefined) {
return;
}
if (expires) {
if (!(expires instanceof Date)) {
throw new Error('[Storage] expires params is not a Date type');
}
const expiredKey = this.getExpiredKey(key);
const expiredAt = expires.getTime();
const nowTimestamp = new Date().getTime();
this.storage.set(expiredKey, {
expired_at: expiredAt,
ttl: expiredAt - nowTimestamp
});
}
return this.storage.set(this.getKey(key), data);
}
/**
* Is key exists
* @param {string} key
*/
exists(key) {
return !!this.get(key);
}
/**
* Remove a storage key
* @param {string} key
*/
remove(key) {
return this.storage.remove(this.getExpiredKey(key)) && this.storage.remove(this.getKey(key));
}
/**
* Get all keys
*/
keys() {
this.removeExpiredKeys();
return this.storage.getAllKeys().map((key) => key.replace(this.env, ''));
}
/**
* Clear storage
*/
clear() {
return __awaiter(this, void 0, void 0, function* () {
const keysWillRemove = this.storage
.getAllKeys()
.filter((e) => e.indexOf(this.keepSuffix) < 0);
keysWillRemove.forEach((key) => this.storage.remove(key));
});
}
/**
* Clear all
*/
clearAll() {
return __awaiter(this, void 0, void 0, function* () {
this.storage.clearAll();
});
}
}
exports.default = KeyvStorage;