@leyyo/cache
Version:
Common cache library
233 lines (232 loc) • 9.78 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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheHubImpl = void 0;
const builder_1 = require("@leyyo/builder");
const cache_hub_prop_impl_1 = require("./cache-hub-prop-impl");
const util_1 = require("../util");
const remote_1 = require("../remote");
class CacheHubImpl {
constructor() {
this._defaults = {
enabled: false,
property: null,
saveMode: 'always',
saveSpan: 'ttl',
expiryMode: 'always',
expirySpan: 'ttl',
milliseconds: 24 * 60 * 60 * 1000,
expiryUnit: 'seconds',
};
this._segmentCreators = new Map();
this._entityCreators = new Map();
this._channelCreators = new Map();
this._clientCreators = new Map();
this._segmentMap = new Map();
this._entityMap = new Map();
this._invalidatorConsumerMap = new Map();
this._segments = [];
this._providers = [];
this._clients = [];
this.prop = new cache_hub_prop_impl_1.CacheHubPropImpl(this._defaults, {});
}
get segments() {
return [...this._segments]; // return cloned
}
get clients() {
return [...this._clients]; // return cloned
}
get providers() {
return [...this._providers]; // return cloned
}
registerClient(provider, native, description) {
if (typeof description === 'string') {
description = description.trim();
if (!description) {
description = null;
}
}
else if (![null, undefined].includes(description)) {
console.log(`Invalid description!, info: ${util_1.cacheUtil.objectInfo(description)} in hub.registerClient`);
description = null;
}
else {
description = null;
}
util_1.cacheUtil.checkObject('hub.registerClient', 'provider', provider, 'leyyo.cache,CacheProvider');
if (!native || typeof native !== 'object' || Array.isArray(native)) {
util_1.cacheUtil.checkObject('hub.registerClient', 'native', native, 'leyyo.cache,Unknown');
}
const lambda = this.$getClientCreator(provider);
const client = lambda(native, description);
if (!this._clients.includes(client)) {
this._clients.push(client);
}
if (!this._providers.includes(provider)) {
this._providers.push(provider);
}
if (!provider.defaultClient) {
provider.$secure.$setDefaultClient(client);
}
return client;
}
newSegment(client, path, fn, id) {
id = util_1.cacheUtil.checkName('hub.newSegment', 'id', id, true);
path = util_1.cacheUtil.checkName('hub.newSegment', 'path', path, true);
util_1.cacheUtil.checkObject('hub.newSegment', 'client', client, 'leyyo.cache,CacheClient');
util_1.cacheUtil.checkLambda('hub.newSegment', 'lambda', fn, 1);
const prop = builder_1.Builder.retrieve(fn);
const lambda = this.$getSegmentCreator(client.provider);
const segment = lambda(client, path, prop, id);
this._segments.push(segment);
return segment;
}
newRemote(id) {
id = util_1.cacheUtil.checkName('hub.newSegment', 'id', id, false);
const ins = new remote_1.CacheRemoteImpl(id);
this.$checkInvalidatorConsumer(ins);
return ins;
}
info(check) {
return __awaiter(this, void 0, void 0, function* () {
const promises = this._segments.map(c => c.info(check));
return {
prop: this.prop.$secure.$pure,
defaults: this._defaults,
segments: yield Promise.all(promises),
};
});
}
changeProp(lambda) {
this.$setProp(util_1.cacheUtil.readProp(lambda(builder_1.Builder.build())));
}
getInvalidatorConsumer(id) {
if (!id || typeof id !== 'string') {
// todo
return null;
}
const consumer = this._invalidatorConsumerMap.get(id);
if (!consumer) {
// todo
return null;
}
return consumer;
}
getEntity(id) {
if (!id || typeof id !== 'string') {
return null;
}
return this._entityMap.get(id);
}
getSegment(id) {
if (!id || typeof id !== 'string') {
return null;
}
return this._segmentMap.get(id);
}
// region secure
get $secure() {
return this;
}
get $back() {
return this;
}
$getSegmentCreator(provider) {
util_1.cacheUtil.checkObject('hub.$getSegmentCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (!this._segmentCreators.has(provider)) {
throw new Error(`Not found segment for provider: ${provider.name} in hub.$getSegmentCreator`);
}
return this._segmentCreators.get(provider);
}
$setSegmentCreator(provider, lambda) {
util_1.cacheUtil.checkObject('hub.$setSegmentCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (this._segmentCreators.has(provider)) {
throw new Error(`Duplicated segment for provider: ${provider.name} in hub.$setSegmentCreator`);
}
util_1.cacheUtil.checkLambda('hub.$setSegmentCreator', 'lambda', lambda, 4);
this._segmentCreators.set(provider, lambda);
}
$getEntityCreator(provider) {
util_1.cacheUtil.checkObject('hub.$getEntityCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (!this._entityCreators.has(provider)) {
throw new Error(`Not found entity for provider: ${provider.name} in hub.$getEntityCreator`);
}
return this._entityCreators.get(provider);
}
$setEntityCreator(provider, lambda) {
util_1.cacheUtil.checkObject('hub.$setEntityCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (this._entityCreators.has(provider)) {
throw new Error(`Duplicated entity for provider: ${provider.name} in hub.$setEntityCreator`);
}
util_1.cacheUtil.checkLambda('hub.$setEntityCreator', 'lambda', lambda, 4);
this._entityCreators.set(provider, lambda);
}
$getChannelCreator(provider) {
util_1.cacheUtil.checkObject('hub.$getChannelCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (!this._channelCreators.has(provider)) {
throw new Error(`Not found channel for provider: ${provider.name} in hub.$getChannelCreator`);
}
return this._channelCreators.get(provider);
}
$setChannelCreator(provider, lambda) {
util_1.cacheUtil.checkObject('hub.$setChannelCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (this._channelCreators.has(provider)) {
throw new Error(`Duplicated channel for provider: ${provider.name} in hub.$setChannelCreator`);
}
util_1.cacheUtil.checkLambda('hub.$setChannelCreator', 'lambda', lambda, 4);
this._channelCreators.set(provider, lambda);
}
$getClientCreator(provider) {
util_1.cacheUtil.checkObject('hub.$getClientCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (!this._clientCreators.has(provider)) {
throw new Error(`Not found client for provider: ${provider.name} in hub.$getClientCreator`);
}
return this._clientCreators.get(provider);
}
$setClientCreator(provider, lambda) {
util_1.cacheUtil.checkObject('hub.$setClientCreator', 'provider', provider, 'leyyo.cache,CacheProvider');
if (this._clientCreators.has(provider)) {
throw new Error(`Duplicated client for provider: ${provider.name} in hub.$setClientCreator`);
}
util_1.cacheUtil.checkLambda('hub.$setClientCreator', 'lambda', lambda, 4);
this._clientCreators.set(provider, lambda);
}
$setProp(prop) {
this.prop.$secure.$setPure(prop);
this._segments.forEach(segment => segment.$secure.$setProp(prop));
}
$checkInvalidatorConsumer(consumer) {
util_1.cacheUtil.checkName('hub.$checkInvalidatorConsumer', 'id', consumer.id, false);
if (this._invalidatorConsumerMap.has(consumer.id)) {
throw new Error(`Id of remote was already used by another invalidator consumer: ${consumer.id}`);
}
this._invalidatorConsumerMap.set(consumer.id, consumer);
}
$checkEntity(entity) {
if (!entity.id) {
return;
}
if (this._entityMap.has(entity.id)) {
throw new Error(`Entity is duplicated! id: ${entity.id}`);
}
this._entityMap.set(entity.id, entity);
}
$checkSegment(segment) {
if (!segment.id) {
return;
}
if (this._segmentMap.has(segment.id)) {
throw new Error(`Segment is duplicated! id: ${segment.id}`);
}
this._segmentMap.set(segment.id, segment);
}
}
exports.CacheHubImpl = CacheHubImpl;