layered-loader
Version:
Data loader with support for caching and fallback data sources
127 lines • 5.72 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractCache = exports.DEFAULT_UNDEFINED_FROM_VALUE_RESOLVER = exports.DEFAULT_FROM_ID_RESOLVER = exports.DEFAULT_FROM_STRING_RESOLVER = exports.DEFAULT_CACHE_ERROR_HANDLER = exports.DEFAULT_LOAD_ERROR_HANDLER = void 0;
const InMemoryCache_1 = require("./memory/InMemoryCache");
const InMemoryGroupCache_1 = require("./memory/InMemoryGroupCache");
const NoopCache_1 = require("./memory/NoopCache");
const Logger_1 = require("./util/Logger");
const DEFAULT_LOAD_ERROR_HANDLER = (err, key, loader, logger) => {
logger.error(`Error while loading "${key}" with ${loader.name}: ${err.message}`);
};
exports.DEFAULT_LOAD_ERROR_HANDLER = DEFAULT_LOAD_ERROR_HANDLER;
const DEFAULT_CACHE_ERROR_HANDLER = (err, key, cache, logger) => {
logger.error(`Error while caching "${key}" with ${cache.name}: ${err.message}`);
};
exports.DEFAULT_CACHE_ERROR_HANDLER = DEFAULT_CACHE_ERROR_HANDLER;
const DEFAULT_FROM_STRING_RESOLVER = (source) => {
if (!(typeof source === 'string')) {
throw new Error('Please define cacheKeyFromLoadParamsResolver in your loader config if you are using composite loadParams and not just string keys');
}
return source;
};
exports.DEFAULT_FROM_STRING_RESOLVER = DEFAULT_FROM_STRING_RESOLVER;
const DEFAULT_FROM_ID_RESOLVER = (source) => source.id;
exports.DEFAULT_FROM_ID_RESOLVER = DEFAULT_FROM_ID_RESOLVER;
const DEFAULT_UNDEFINED_FROM_VALUE_RESOLVER = () => { throw new Error('Please define cacheKeyFromValueResolver in your loader config if you want to use getMany operations'); };
exports.DEFAULT_UNDEFINED_FROM_VALUE_RESOLVER = DEFAULT_UNDEFINED_FROM_VALUE_RESOLVER;
class AbstractCache {
inMemoryCache;
asyncCache;
cacheKeyFromLoadParamsResolver;
cacheKeyFromValueResolver;
logger;
cacheUpdateErrorHandler;
loadErrorHandler;
runningLoads;
notificationConsumer;
notificationPublisher;
initPromises;
constructor(config) {
this.initPromises = [];
// @ts-expect-error By default we assume simple string params
this.cacheKeyFromLoadParamsResolver = config.cacheKeyFromLoadParamsResolver ?? exports.DEFAULT_FROM_STRING_RESOLVER;
this.cacheKeyFromValueResolver = config.cacheKeyFromValueResolver ?? exports.DEFAULT_UNDEFINED_FROM_VALUE_RESOLVER;
if (config.inMemoryCache) {
if (this.isGroupCache()) {
// @ts-ignore
this.inMemoryCache = new InMemoryGroupCache_1.InMemoryGroupCache(config.inMemoryCache);
}
else {
// @ts-ignore
this.inMemoryCache = new InMemoryCache_1.InMemoryCache(config.inMemoryCache);
}
}
else {
// @ts-ignore
this.inMemoryCache = new NoopCache_1.NoopCache();
}
this.asyncCache = config.asyncCache;
this.logger = config.logger ?? Logger_1.defaultLogger;
this.cacheUpdateErrorHandler = config.cacheUpdateErrorHandler ?? exports.DEFAULT_CACHE_ERROR_HANDLER;
this.loadErrorHandler = config.loadErrorHandler ?? exports.DEFAULT_LOAD_ERROR_HANDLER;
if (config.notificationConsumer) {
if (!config.inMemoryCache) {
throw new Error('Cannot set notificationConsumer when InMemoryCache is disabled');
}
this.notificationConsumer = config.notificationConsumer;
this.notificationConsumer.setTargetCache(this.inMemoryCache);
this.initPromises.push(this.notificationConsumer.subscribe().catch((err) => {
/* c8 ignore next 1 */
this.notificationConsumer.errorHandler(err, this.notificationConsumer.serverUuid, this.logger);
}));
}
if (config.notificationPublisher) {
this.notificationPublisher = config.notificationPublisher;
this.initPromises.push(this.notificationPublisher.subscribe().catch((err) => {
/* c8 ignore next 1 */
this.notificationPublisher.errorHandler(err, this.notificationPublisher.channel, this.logger);
}));
}
this.runningLoads = new Map();
}
async init() {
await Promise.all(this.initPromises);
this.initPromises = [];
}
async invalidateCache() {
this.inMemoryCache.clear();
if (this.asyncCache) {
await this.asyncCache.clear().catch((err) => {
this.cacheUpdateErrorHandler(err, undefined, this.asyncCache, this.logger);
});
}
this.runningLoads.clear();
if (this.notificationPublisher) {
this.notificationPublisher.clear().catch((err) => {
this.notificationPublisher.errorHandler(err, this.notificationPublisher.channel, this.logger);
});
}
}
async close() {
if (this.asyncCache) {
await this.asyncCache.close();
}
/* c8 ignore start */
if (this.notificationConsumer) {
try {
await this.notificationConsumer.close();
}
catch (err) {
// @ts-ignore
this.logger.error(`Failed to close notification consumer: ${err.message}`);
}
}
if (this.notificationPublisher) {
try {
await this.notificationPublisher.close();
}
catch (err) {
// @ts-ignore
this.logger.error(`Failed to close notification publisher: ${err.message}`);
}
}
/* c8 ignore stop */
}
}
exports.AbstractCache = AbstractCache;
//# sourceMappingURL=AbstractCache.js.map