UNPKG

@imqueue/pg-cache

Version:

PostgreSQL managed cache on Redis for @imqueue-based service methods

98 lines 3.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeChannel = makeChannel; exports.cacheWith = cacheWith; /*! * I'm Queue Software Project * Copyright (C) 2025 imqueue.com <support@imqueue.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * If you want to use this code in a closed source (commercial) project, you can * purchase a proprietary commercial license. Please contact us at * <support@imqueue.com> to get commercial licensing options. */ const rpc_1 = require("@imqueue/rpc"); const env_1 = require("./env"); /** * Makes channel entry from a given channel name, class method name and options. * * @access private * @param {string} name * @param {string} method * @param {CacheWithOptions} options * @return {PgCacheChannel} */ function makeChannel(name, method, options) { return [method, !Array.isArray(options.channels) ? (options.channels)[name] : undefined, ]; } /** * Decorator factory @cacheWith(CacheWithOptions) * This decorator should be used on a service methods, to set the caching * rules for a method. * * @param {CacheWithOptions} options * @return {MethodDecorator} */ function cacheWith(options) { return (target, methodName, descriptor) => { const original = descriptor.value; const className = typeof target === 'function' ? target.name : target.constructor.name; const ttl = options.ttl || env_1.DEFAULT_CACHE_TTL; const isFiltered = !Array.isArray(options.channels); const channels = isFiltered ? Object.keys(options.channels) : options.channels; target.pgCacheChannels = target.pgCacheChannels || {}; for (const channel of channels) { const pgChannel = target.pgCacheChannels[channel] = target.pgCacheChannels[channel] || []; pgChannel.push(makeChannel(channel, String(methodName), options)); } descriptor.value = async function (...args) { const self = this || target; const cache = self.taggedCache; const logger = (self.logger || console); if (!cache) { (0, env_1.initError)(logger, className, String(methodName), cacheWith); return original.apply(self, args); } const key = (0, rpc_1.signature)(className, methodName, args); try { let result = await cache.get(key); if (result === null || result === undefined) { result = original.apply(self, args); if (result && result.then) { result = await result; } const tags = [(0, rpc_1.signature)(className, methodName, [])]; cache.set(key, result, tags, ttl) .then(res => (0, env_1.setInfo)(logger, res, key, cacheWith)) .catch(err => (0, env_1.setError)(logger, err, key, cacheWith)); } return result; } catch (err) { (0, env_1.fetchError)(logger, err, key, cacheWith); return original.apply(self, args); } }; }; } //# sourceMappingURL=cacheWith.js.map