UNPKG

@kovalenko/http-request-cache

Version:

TS decorator for caching logic of API calls.

71 lines 4.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpRequestCache = void 0; const rxjs_1 = require("rxjs"); const default_storage_1 = require("./default-storage"); const request_times_1 = require("./request-times"); const HttpRequestCache = (optionsHandler) => { return (target, methodName, descriptor) => { if (!((descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) instanceof Function)) { throw Error(`'@HttpRequestCache' can be applied only to the class method which returns an Observable`); } const cacheKeyPrefix = `${target.constructor.name}_${methodName}`; const originalMethod = descriptor.value; const working = {}; let subscribers = 0; descriptor.value = function (...args) { var _a, _b, _c, _d, _e; const options = optionsHandler === null || optionsHandler === void 0 ? void 0 : optionsHandler.call(this, this, ...args); if (!(options === null || options === void 0 ? void 0 : options.storage) && !target._____storage_____) { target._____storage_____ = new default_storage_1.DefaultStorage(); } if ((options === null || options === void 0 ? void 0 : options.ttl) && !target._____ttl_storage_____) { target._____ttl_storage_____ = new request_times_1.RequestTimes(); } const storage = (_a = options === null || options === void 0 ? void 0 : options.storage) !== null && _a !== void 0 ? _a : target._____storage_____; const key = `${cacheKeyPrefix}_${JSON.stringify(args)}`; let ttl = undefined; if (options === null || options === void 0 ? void 0 : options.ttl) { ttl = target._____ttl_storage_____.getItem(key); if (!ttl) { ttl = { requestTime: Date.now(), subject: new rxjs_1.Subject(), }; } else if (ttl.requestTime + options.ttl <= Date.now()) { working[key] = true; ttl.requestTime = Date.now(); ttl.subject.next(); } target._____ttl_storage_____.setItem(key, ttl); } const refreshOn = (0, rxjs_1.merge)((_b = options === null || options === void 0 ? void 0 : options.refreshOn) !== null && _b !== void 0 ? _b : rxjs_1.NEVER, (_c = ttl === null || ttl === void 0 ? void 0 : ttl.subject) !== null && _c !== void 0 ? _c : rxjs_1.NEVER); let observable = storage.getItem(key); if (!observable) { observable = refreshOn.pipe((0, rxjs_1.startWith)(true), (0, rxjs_1.switchMap)(() => originalMethod.apply(this, [...args])), (0, rxjs_1.tap)(() => { delete working[key]; }), (0, rxjs_1.shareReplay)({ bufferSize: 1, refCount: (_d = options === null || options === void 0 ? void 0 : options.refCount) !== null && _d !== void 0 ? _d : false, windowTime: (_e = options === null || options === void 0 ? void 0 : options.windowTime) !== null && _e !== void 0 ? _e : Infinity, }), (0, rxjs_1.filter)(() => { return !working[key]; }), (0, rxjs_1.finalize)(() => { var _a; subscribers--; if (subscribers === 0 && (options === null || options === void 0 ? void 0 : options.refCount)) { storage.deleteItem(key); (_a = target._____ttl_storage_____) === null || _a === void 0 ? void 0 : _a.deleteItem(key); } })); storage.setItem(key, observable); } subscribers++; return observable; }; return descriptor; }; }; exports.HttpRequestCache = HttpRequestCache; //# sourceMappingURL=http-request-cache.decorator.js.map