UNPKG

@leyyo/cache

Version:
445 lines (444 loc) 18.3 kB
"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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CacheHashAbstract = void 0; const util_1 = require("../util"); const config_1 = require("../config"); // noinspection DuplicatedCode,JSUnusedGlobalSymbols class CacheHashAbstract { // endregion properties // region constructor constructor(channel) { this.channel = channel; util_1.cacheUtil.bindAll(this); } // endregion constructor // region private _formatRawValue(field, value, throwable = true) { switch (typeof value) { case "string": const str = value.trim(); if (str) { return str; } if (throwable) { throw new Error(`Empty value for field[${field}]`); } return null; case "number": case "bigint": return String(value); case "boolean": return value ? 'true' : 'false'; default: if (!value) { if (throwable) { throw new Error(`Empty value for field[${field}]`); } return null; } if (throwable) { throw new Error(`Invalid field[${field}] value, type of value: ${typeof value}`); } return null; } } _formatRawValues(record, throwable = true) { const errors = []; const result = {}; for (const [field, value] of Object.entries(record)) { switch (typeof value) { case "string": const str = value.trim(); if (str) { result[field] = str; } else if (throwable) { errors.push(`Empty value for field[${field}]`); } break; case "number": case "bigint": result[field] = String(value); break; case "boolean": result[field] = value ? 'true' : 'false'; break; default: if (!value) { if (throwable) { errors.push(`Empty value for field[${field}]`); } } else if (throwable) { errors.push(`Invalid field[${field}] value, type of value: ${typeof value}`); } break; } } if (Object.keys(result).length < 1 && throwable) { errors.push(`Empty value set`); } if (errors.length > 0) { throw new Error(errors.join(', ')); } return result; } // endregion private // region delete delete(key, fields) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNumber(config_1.CACHE_DISABLED); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Empty fields'); } return this.invalidator.success(yield this.$delete(full, items), [full]); }); } // endregion delete // region members exists(key, field) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNumber(config_1.CACHE_DISABLED); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty key'); } const item = this.format.field(field); if (!item) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Empty field'); } return this.invalidator.success((yield this.$exists(full, item)) ? 1 : 0, [full]); }); } existMore(key, fields) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledArray(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreArray('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreArray('Empty fields'); } return this.invalidator.success((yield Promise.all(items.map(item => this.$exists(full, item)))).map(i => i ? 1 : 0), [full]); }); } getLength(key) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNumber(config_1.CACHE_DISABLED); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty key'); } return this.invalidator.success(yield this.$length(full), [full]); }); } listFields(key) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledArray(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreArray('Empty key'); } return this.invalidator.success(yield this.$fields(full), [full]); }); } // endregion members // region get getAll(key) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNull(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNull('Empty key'); } return this.invalidator.success(yield this.$getAll(full), [full]); }); } getMore(key, fields) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNull(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNull('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreNull('Empty fields'); } const values = yield this.$get(full, items); return this.invalidator.success(util_1.cacheUtil.objectFromKeys(items, null, values), [full]); }); } getValue(key, field) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledText(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreText('Empty key'); } const checkedField = this.format.field(field); if (!checkedField) { return this.invalidator.ignoreText('Empty field'); } return this.invalidator.success(yield this.$getOne(full, checkedField), [full]); }); } // endregion get // region set setValue(key, field, value) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNumber(config_1.CACHE_DISABLED); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty key'); } const checkField = this.format.field(field); if (!checkField) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Empty field'); } const str = this._formatRawValue(checkField, value, true); return this.invalidator.success(yield this.$set(full, { [checkField]: str }), [full]); }); } setValuesMore(key, doc) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledNumber(config_1.CACHE_DISABLED); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty key'); } if (!doc) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Empty values'); } if (typeof doc !== 'object') { throw new Error('Invalid set data'); } const tempValue = {}; // Array<Partial<A>> | Array<[KeyId, Partial<A>]> if (Array.isArray(doc)) { if (doc.length < 1) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Empty array items'); } const first = doc[0]; // FieldTupleArray<A> if (Array.isArray(first) && first.length === 2) { const arr = doc; arr.forEach(item => { const [key, value] = item; tempValue[key] = value; }); } // normal array else { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Invalid array tuples'); } } // FieldMap<A> else if (doc instanceof Map) { if (doc.size < 1) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_VALUE, 'Empty map items'); } for (const [key, value] of doc.entries()) { tempValue[key] = value; } } // Partial<A> else { if (Object.keys(doc).length < 1) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty record value'); } for (const [key, value] of Object.entries(doc)) { tempValue[key] = value; } } const formatted = this._formatRawValues(tempValue, true); if (Object.keys(formatted).length < 1) { return this.invalidator.ignoreNumber(config_1.CACHE_EMPTY_KEY, 'Empty record value'); } return this.invalidator.success(yield this.$set(full, formatted), [full]); }); } // endregion set // region expiry getTimestamp(key, fields, opt) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledRecord(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreRecord('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreRecord('Empty fields'); } const times = yield this.$getTimestamp(full, items); if (times.length < 1) { return this.invalidator.success({}, [full]); } const unit = this.check.$expiryUnit(opt === null || opt === void 0 ? void 0 : opt.unit); switch (unit) { case "milliseconds": return this.invalidator.success(util_1.cacheUtil.objectFromKeys(items, 0, times), [full]); case 'seconds': return this.invalidator.success(util_1.cacheUtil.objectFromKeys(times.map(time => time / 1000), 0, times), [full]); case 'minutes': return this.invalidator.success(util_1.cacheUtil.objectFromKeys(times.map(time => time / 60000), 0, times), [full]); default: return this.invalidator.success(util_1.cacheUtil.objectFromKeys(items, 0, times), [full]); } }); } getTtl(key, fields, opt) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledRecord(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreRecord('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreRecord('Empty fields'); } const times = yield this.$getTtl(full, items); if (times.length < 1) { return this.invalidator.success({}, [full]); } const unit = this.check.$expiryUnit(opt === null || opt === void 0 ? void 0 : opt.unit); switch (unit) { case "milliseconds": return this.invalidator.success(util_1.cacheUtil.objectFromKeys(items, 0, times), [full]); case 'seconds': return this.invalidator.success(util_1.cacheUtil.objectFromKeys(times.map(time => time / 1000), 0, times), [full]); case 'minutes': return this.invalidator.success(util_1.cacheUtil.objectFromKeys(times.map(time => time / 60000), 0, times), [full]); default: return this.invalidator.success(util_1.cacheUtil.objectFromKeys(items, 0, times), [full]); } }); } setTimestamp(key, fields, opt) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledRecord(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreRecord('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreRecord('Empty fields'); } if (!opt) { opt = {}; } const milliseconds = this.check.$timestamp(opt.expiry); if (milliseconds < 1) { return this.invalidator.ignoreRecord('Invalid time value'); } const mode = this.check.$expiryMode(opt.mode); const result = yield this.$setTimestamp(full, items, milliseconds, mode); return this.invalidator.success(util_1.cacheUtil.objectFromKeys(result, -1, result), [full]); }); } setTtl(key, fields, opt) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledRecord(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreRecord('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreRecord('Empty fields'); } if (!opt) { opt = {}; } const milliseconds = this.check.$timestamp(opt.expiry); if (milliseconds < 1) { return this.invalidator.ignoreRecord('Invalid time value'); } const mode = this.check.$expiryMode(opt.mode); const result = yield this.$setTtl(full, items, milliseconds, mode); return this.invalidator.success(util_1.cacheUtil.objectFromKeys(result, -1, result), [full]); }); } persist(key, fields) { return __awaiter(this, void 0, void 0, function* () { if (!this.prop.enabled) { return this.invalidator.disabledRecord(); } const { full } = this.format.key(key); if (!full) { return this.invalidator.ignoreRecord('Empty key'); } const items = this.format.fields(fields); if (items.length < 1) { return this.invalidator.ignoreRecord('Empty fields'); } const result = yield this.$persist(full, items); return this.invalidator.success(util_1.cacheUtil.objectFromKeys(items, -2, result), [full]); }); } // endregion expiry // region secure get $flat() { return this; } get $secure() { return this; } get $back() { return this; } $init() { this.format = this.channel.format; this.invalidator = this.channel.invalidator; this.prop = this.channel.prop; this.check = this.channel.prop.$secure; } } exports.CacheHashAbstract = CacheHashAbstract;