Comparing version 2.0.0 to 3.0.0
@@ -0,1 +1,23 @@ | ||
# [3.0.0](https://github.com/TinkoffCreditSystems/cachalot/compare/v2.0.0...v3.0.0) (2020-05-08) | ||
### Performance Improvements | ||
* Base storage only touches and get tags if tag list is not empty ([22b8d3a](https://github.com/TinkoffCreditSystems/cachalot/commit/22b8d3a)) | ||
### BREAKING CHANGES | ||
* fixed typings for get/set and managers. Throw errors if executor returns undefined. Executor should always return value or null - for emptiness | ||
fix: Remove undefined as get return type. | ||
Also removed `E extends Executor<R>` type parameter. | ||
`Record.value` is always defined. | ||
WriteOptions now has type parameter used in getTags signature. | ||
Throw an error if executor returns undefined. | ||
# [2.0.0](https://github.com/TinkoffCreditSystems/cachalot/compare/v1.6.0...v2.0.0) (2020-03-17) | ||
@@ -2,0 +24,0 @@ |
@@ -41,3 +41,3 @@ import IORedis, { Redis } from "ioredis"; | ||
*/ | ||
onConnect(callback: (...args: any[]) => void): void; | ||
onConnect(callback: (...args: unknown[]) => void): void; | ||
/** | ||
@@ -44,0 +44,0 @@ * The set method provided by the adapter. |
import { ConnectionStatus } from "../ConnectionStatus"; | ||
import { StorageAdapterOptions, StorageAdapter } from "../StorageAdapter"; | ||
import { StorageAdapter, StorageAdapterOptions } from "../StorageAdapter"; | ||
declare class TestStorageAdapter implements StorageAdapter { | ||
@@ -4,0 +4,0 @@ options: StorageAdapterOptions; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
const ConnectionStatus_1 = require("../ConnectionStatus"); | ||
@@ -44,4 +45,3 @@ class TestStorageAdapter { | ||
this.checkConnection(); | ||
const isDeleted = await this.del(`${key}_lock`); | ||
return isDeleted; | ||
return this.del(`${key}_lock`); | ||
} | ||
@@ -48,0 +48,0 @@ async isLockExists(key) { |
@@ -1,7 +0,8 @@ | ||
import { Executor, ValueOfExecutor } from "./Executor"; | ||
import { Executor } from "./Executor"; | ||
import { Logger } from "./Logger"; | ||
import { Manager } from "./Manager"; | ||
import { ManagerOptions } from "./managers/BaseManager"; | ||
import { Record } from "./storage/Record"; | ||
import { ReadWriteOptions, Storage, WriteOptions } from "./storage/Storage"; | ||
import { StorageAdapter } from "./StorageAdapter"; | ||
import { Logger } from "./Logger"; | ||
import { BaseManager, ManagerOptions } from "./managers/BaseManager"; | ||
import { RecordValue } from "./storage/Record"; | ||
export interface CacheWithCustomStorageOptions { | ||
@@ -14,3 +15,3 @@ storage: Storage; | ||
} | ||
export interface ManagerConstructor<T extends BaseManager = any> { | ||
export interface ManagerConstructor<T extends Manager> { | ||
new (options: ManagerOptions): T; | ||
@@ -25,4 +26,4 @@ getName(): string; | ||
}; | ||
export declare const isCustomStorageOptions: (options: any) => options is CacheWithCustomStorageOptions; | ||
export declare const isBaseStorageOptions: (options: any) => options is CacheWithBaseStorageOptions; | ||
export declare const isCustomStorageOptions: (options: object) => options is CacheWithCustomStorageOptions; | ||
export declare const isBaseStorageOptions: (options: object) => options is CacheWithBaseStorageOptions; | ||
export interface ManagerSelectorOptions { | ||
@@ -63,7 +64,7 @@ manager?: string; | ||
*/ | ||
get<E extends Executor>(key: string, executor: E, options?: ReadWriteOptions & ManagerSelectorOptions): Promise<ValueOfExecutor<E>>; | ||
get<R>(key: string, executor: Executor<R>, options?: ReadWriteOptions<R> & ManagerSelectorOptions): Promise<R>; | ||
/** | ||
* Just like "get" this method delegates call to default or provided manager | ||
*/ | ||
set(key: string, value: RecordValue, options?: WriteOptions & ManagerSelectorOptions): Promise<any>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R> & ManagerSelectorOptions): Promise<Record<R>>; | ||
/** | ||
@@ -80,7 +81,7 @@ * The touch method is intended for all cases when you need to inform the cache manager that the data for | ||
*/ | ||
touch(tags: string[]): Promise<any>; | ||
touch(tags: string[]): Promise<void>; | ||
/** | ||
* Register a new cache manager | ||
*/ | ||
registerManager(managerClass: ManagerConstructor, name?: string | null, options?: Partial<ManagerOptions>): void; | ||
registerManager<T extends Manager>(managerClass: ManagerConstructor<T>, name?: string | null, options?: Partial<ManagerOptions>): void; | ||
/** | ||
@@ -87,0 +88,0 @@ * Returns cache manager by its name |
@@ -8,6 +8,7 @@ "use strict"; | ||
const ConnectionStatus_1 = require("./ConnectionStatus"); | ||
const Executor_1 = require("./Executor"); | ||
const RefreshAheadManager_1 = __importDefault(require("./managers/RefreshAheadManager")); | ||
const BaseStorage_1 = require("./storage/BaseStorage"); | ||
const RefreshAheadManager_1 = __importDefault(require("./managers/RefreshAheadManager")); | ||
exports.isCustomStorageOptions = (options) => Boolean(options.storage); | ||
exports.isBaseStorageOptions = (options) => Boolean(options.adapter) && !Boolean(options.storage); | ||
exports.isCustomStorageOptions = (options) => Object.prototype.hasOwnProperty.call(options, "storage"); | ||
exports.isBaseStorageOptions = (options) => Object.prototype.hasOwnProperty.call(options, "adapter"); | ||
exports.EXPIRES_IN = { | ||
@@ -67,3 +68,3 @@ minute: 60000, | ||
this.logger.error(`Storage connection status is "${connectionStatus}", cache is unavailable!. Running executor.`); | ||
return executor(); | ||
return Executor_1.runExecutor(executor); | ||
} | ||
@@ -70,0 +71,0 @@ const { manager: managerName = RefreshAheadManager_1.default.getName() } = options; |
@@ -1,1 +0,1 @@ | ||
export default function (value: any): any; | ||
export default function <R>(value: string): R; |
@@ -12,5 +12,2 @@ "use strict"; | ||
function default_1(value) { | ||
if (value === undefined) { | ||
return value; | ||
} | ||
try { | ||
@@ -17,0 +14,0 @@ return JSON.parse(value); |
@@ -6,2 +6,3 @@ export declare const ERRORS: { | ||
OperationTimeoutError: string; | ||
ExecutorReturnsUndefinedError: string; | ||
}; |
@@ -8,3 +8,4 @@ "use strict"; | ||
OperationTimeoutError: "OperationTimeoutError", | ||
ExecutorReturnsUndefinedError: "ExecutorReturnsUndefinedError", | ||
}; | ||
//# sourceMappingURL=constants.js.map |
@@ -6,1 +6,2 @@ export declare function parseError(error: Error): Error; | ||
export declare function isOperationTimeoutError(error: unknown): boolean; | ||
export declare function executorReturnsUndefinedError(): Error; |
@@ -31,2 +31,7 @@ "use strict"; | ||
exports.isOperationTimeoutError = isOperationTimeoutError; | ||
function executorReturnsUndefinedError() { | ||
const text = "Executor should not return undefined. Correct value for emptiness is null."; | ||
return custom_error_1.default(constants_1.ERRORS.ExecutorReturnsUndefinedError, text); | ||
} | ||
exports.executorReturnsUndefinedError = executorReturnsUndefinedError; | ||
//# sourceMappingURL=errors.js.map |
import { ReadWriteOptions } from "./storage/Storage"; | ||
import { Record } from "./storage/Record"; | ||
export interface ExecutorContext { | ||
export interface ExecutorContext<R> { | ||
key: string; | ||
executor: Executor; | ||
options: ReadWriteOptions; | ||
record?: Record; | ||
executor: Executor<R>; | ||
options: ReadWriteOptions<R>; | ||
record?: Record<R>; | ||
} | ||
export declare type ValueOfExecutor<V extends Executor> = ReturnType<V> extends Promise<infer RT> ? RT : V; | ||
export declare type Executor = (...args: any[]) => Promise<any> | any; | ||
export declare function runExecutor<R>(executor: Executor<R>): Promise<R>; | ||
export declare type Executor<R> = (...args: unknown[]) => Promise<R> | R; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const errors_1 = require("./errors/errors"); | ||
async function runExecutor(executor) { | ||
const result = await executor(); | ||
if (result === undefined) { | ||
throw errors_1.executorReturnsUndefinedError(); | ||
} | ||
return result; | ||
} | ||
exports.runExecutor = runExecutor; | ||
//# sourceMappingURL=Executor.js.map |
import { StorageAdapter, StorageAdapterOptions } from "./StorageAdapter"; | ||
import { Tag, Tags } from "./storage/Storage"; | ||
import { Record, RecordValue } from "./storage/Record"; | ||
import { Record } from "./storage/Record"; | ||
import Cache, { CacheOptions } from "./Cache"; | ||
@@ -10,5 +10,5 @@ import RedisStorageAdapter from "./adapters/RedisStorageAdapter"; | ||
import RefreshAheadManager from "./managers/RefreshAheadManager"; | ||
export { CacheOptions, StorageAdapter, StorageAdapterOptions, Record, Tag, RecordValue, Tags, RedisStorageAdapter, MemcachedStorageAdapter, ReadThroughManager, RefreshAheadManager, WriteThroughManager, }; | ||
export { CacheOptions, StorageAdapter, StorageAdapterOptions, Record, Tag, Tags, RedisStorageAdapter, MemcachedStorageAdapter, ReadThroughManager, RefreshAheadManager, WriteThroughManager, }; | ||
export * from "./errors/constants"; | ||
export { LockedKeyRetrieveStrategy } from "./LockedKeyRetrieveStrategy"; | ||
export default Cache; |
@@ -9,3 +9,3 @@ import { LockedKeyRetrieveStrategy } from "../LockedKeyRetrieveStrategy"; | ||
getName(): string; | ||
get(context: ExecutorContext): Promise<any>; | ||
get<R>(context: ExecutorContext<R>): Promise<R>; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const Executor_1 = require("../Executor"); | ||
/** | ||
@@ -12,3 +13,3 @@ * This locked key retrieve strategy is default and suitable for most cases. It just | ||
async get(context) { | ||
return context.executor(); | ||
return Executor_1.runExecutor(context.executor); | ||
} | ||
@@ -15,0 +16,0 @@ } |
import { LockedKeyRetrieveStrategy } from "../LockedKeyRetrieveStrategy"; | ||
import { ExecutorContext } from "../Executor"; | ||
import { Logger } from "../Logger"; | ||
import { Record } from "../storage/Record"; | ||
export declare const DEFAULT_MAXIMUM_TIMEOUT = 3000; | ||
export declare const DEFAULT_REQUEST_TIMEOUT = 250; | ||
export declare type KeyLockCheckFn = (key: string) => boolean | Promise<boolean>; | ||
export declare type GetRecordFn = (key: string) => Promise<any>; | ||
export declare type GetRecordFn = <R>(key: string) => Promise<Record<R> | null>; | ||
export declare type WaitForResultLockedKeyRetrieveStrategyOptions = { | ||
@@ -29,3 +30,3 @@ maximumTimeout?: number; | ||
getName(): string; | ||
get(context: ExecutorContext): Promise<any>; | ||
get<R>(context: ExecutorContext<R>): Promise<R>; | ||
} |
@@ -9,3 +9,3 @@ import { ExecutorContext } from "./Executor"; | ||
getName(): string; | ||
get<R = unknown>(context: ExecutorContext): Promise<R>; | ||
get<R>(context: ExecutorContext<R>): Promise<R>; | ||
} | ||
@@ -12,0 +12,0 @@ export declare enum LockedKeyRetrieveStrategyTypes { |
@@ -6,6 +6,6 @@ /** | ||
export interface Logger { | ||
info(...args: any[]): void; | ||
trace(...args: any[]): void; | ||
warn(...args: any[]): void; | ||
error(...args: any[]): void; | ||
info(...args: unknown[]): void; | ||
trace(...args: unknown[]): void; | ||
warn(...args: unknown[]): void; | ||
error(...args: unknown[]): void; | ||
} |
@@ -1,4 +0,4 @@ | ||
import { Executor, ValueOfExecutor } from "./Executor"; | ||
import { Executor } from "./Executor"; | ||
import { WriteOptions, ReadWriteOptions } from "./storage/Storage"; | ||
import { RecordValue } from "./storage/Record"; | ||
import { Record } from "./storage/Record"; | ||
/** | ||
@@ -10,4 +10,4 @@ * Manager is the basic interface for all caching classes. Manager must implement | ||
export interface Manager { | ||
get<E extends Executor>(key: string, executor: E, options: ReadWriteOptions): Promise<ValueOfExecutor<E>>; | ||
set(key: string, value: RecordValue, options?: WriteOptions): Promise<any>; | ||
get<R>(key: string, executor: Executor<R>, options: ReadWriteOptions<R>): Promise<R>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
} |
@@ -1,7 +0,6 @@ | ||
import { Manager } from "../Manager"; | ||
import { ExpireOptions, WriteOptions, Storage, ReadWriteOptions } from "../storage/Storage"; | ||
import { LockedKeyRetrieveStrategy } from "../LockedKeyRetrieveStrategy"; | ||
import { Logger } from "../Logger"; | ||
import { Executor, ExecutorContext, ValueOfExecutor } from "../Executor"; | ||
import { Record, RecordValue } from "../storage/Record"; | ||
import { Executor, ExecutorContext } from "../Executor"; | ||
import { Record } from "../storage/Record"; | ||
export interface ManagerOptions extends ExpireOptions { | ||
@@ -15,3 +14,3 @@ prefix?: string; | ||
} | ||
export declare abstract class BaseManager implements Manager { | ||
export declare abstract class BaseManager { | ||
protected constructor(options: ManagerOptions); | ||
@@ -21,7 +20,7 @@ protected storage: Storage; | ||
protected logger: Logger; | ||
abstract get<E extends Executor>(key: string, executor: E, options: ReadWriteOptions): Promise<ValueOfExecutor<E>>; | ||
abstract set(key: string, value: RecordValue, options?: WriteOptions): Promise<Record>; | ||
abstract get<R>(key: string, executor: Executor<R>, options: ReadWriteOptions<R>): Promise<R>; | ||
abstract set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
del(key: string): Promise<boolean>; | ||
protected updateCacheAndGetResult<E extends Executor>(context: ExecutorContext, options: ReadWriteOptions): Promise<ValueOfExecutor<E>>; | ||
protected updateCacheAndGetResult<R>(context: ExecutorContext<R>, options: ReadWriteOptions<R>): Promise<R>; | ||
protected getLockedKeyRetrieveStrategy(strategyName?: string): LockedKeyRetrieveStrategy; | ||
} |
@@ -6,2 +6,3 @@ "use strict"; | ||
const RunExecutorLockedKeyRetrieveStrategy_1 = require("../locked-key-retrieve-strategies/RunExecutorLockedKeyRetrieveStrategy"); | ||
const Executor_1 = require("../Executor"); | ||
class BaseManager { | ||
@@ -39,3 +40,3 @@ constructor(options) { | ||
this.logger.error(`Error occurred while trying to lock key "${context.key}". Reason: ${keyLockError.message}. Running executor`); | ||
return context.executor(); | ||
return Executor_1.runExecutor(context.executor); | ||
} | ||
@@ -47,3 +48,3 @@ if (!isKeySuccessfullyLocked) { | ||
this.logger.trace(`Running executor for key "${context.key}"`); | ||
const executorResult = await context.executor(); | ||
const executorResult = await Executor_1.runExecutor(context.executor); | ||
await this.set(context.key, executorResult, options); | ||
@@ -50,0 +51,0 @@ return executorResult; |
import { BaseManager, ManagerOptions } from "./BaseManager"; | ||
import { Executor, ValueOfExecutor } from "../Executor"; | ||
import { Executor } from "../Executor"; | ||
import { WriteOptions, ReadWriteOptions } from "../storage/Storage"; | ||
import { Record, RecordValue } from "../storage/Record"; | ||
import { Record } from "../storage/Record"; | ||
declare class ReadThroughManager extends BaseManager { | ||
static getName(): string; | ||
constructor(options: ManagerOptions); | ||
get<E extends Executor>(key: string, executor: E, options?: ReadWriteOptions): Promise<ValueOfExecutor<E>>; | ||
set(key: string, value: RecordValue, options?: WriteOptions): Promise<Record>; | ||
get<R>(key: string, executor: Executor<R>, options?: ReadWriteOptions<R>): Promise<R>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
private isRecordValid; | ||
} | ||
export default ReadThroughManager; |
@@ -7,2 +7,3 @@ "use strict"; | ||
const BaseManager_1 = require("./BaseManager"); | ||
const Executor_1 = require("../Executor"); | ||
const deserialize_1 = __importDefault(require("../deserialize")); | ||
@@ -17,3 +18,2 @@ class ReadThroughManager extends BaseManager_1.BaseManager { | ||
async get(key, executor, options = {}) { | ||
const executorContext = { key, executor, options }; | ||
let record = null; | ||
@@ -25,3 +25,3 @@ try { | ||
this.logger.error("Failed to get value from storage, falling back to executor", e); | ||
return executor(); | ||
return Executor_1.runExecutor(executor); | ||
} | ||
@@ -31,2 +31,3 @@ if (this.isRecordValid(record) && !(await this.storage.isOutdated(record))) { | ||
} | ||
const executorContext = { key, executor, options }; | ||
return this.updateCacheAndGetResult(executorContext, options); | ||
@@ -33,0 +34,0 @@ } |
import { BaseManager, ManagerOptions } from "./BaseManager"; | ||
import { Executor, ValueOfExecutor } from "../Executor"; | ||
import { Executor } from "../Executor"; | ||
import { WriteOptions, ReadWriteOptions } from "../storage/Storage"; | ||
import { Record, RecordValue } from "../storage/Record"; | ||
import { Record } from "../storage/Record"; | ||
export declare const DEFAULT_REFRESH_AHEAD_FACTOR = 0.8; | ||
@@ -12,5 +12,5 @@ export interface RefreshAheadManagerOptions extends ManagerOptions { | ||
constructor(options: RefreshAheadManagerOptions); | ||
private refreshAheadFactor; | ||
get<E extends Executor>(key: string, executor: E, options?: ReadWriteOptions): Promise<ValueOfExecutor<E>>; | ||
set(key: string, value: RecordValue, options?: WriteOptions): Promise<Record>; | ||
private readonly refreshAheadFactor; | ||
get<R>(key: string, executor: Executor<R>, options?: ReadWriteOptions<R>): Promise<R>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
private isRecordValid; | ||
@@ -17,0 +17,0 @@ private isRecordExpireSoon; |
@@ -7,2 +7,3 @@ "use strict"; | ||
const BaseManager_1 = require("./BaseManager"); | ||
const Executor_1 = require("../Executor"); | ||
const deserialize_1 = __importDefault(require("../deserialize")); | ||
@@ -27,3 +28,2 @@ exports.DEFAULT_REFRESH_AHEAD_FACTOR = 0.8; | ||
async get(key, executor, options = {}) { | ||
const executorContext = { key, executor, options }; | ||
let record = null; | ||
@@ -35,4 +35,5 @@ try { | ||
this.logger.error("Failed to get value from storage, falling back to executor", e); | ||
return executor(); | ||
return Executor_1.runExecutor(executor); | ||
} | ||
const executorContext = { key, executor, options }; | ||
if (this.isRecordValid(record) && !(await this.storage.isOutdated(record))) { | ||
@@ -76,3 +77,3 @@ const result = deserialize_1.default(record.value); | ||
this.logger.trace(`refresh "${key}"`); | ||
const executorResult = await context.executor(); | ||
const executorResult = await Executor_1.runExecutor(context.executor); | ||
await this.storage.set(key, executorResult, options); | ||
@@ -79,0 +80,0 @@ } |
import { BaseManager, ManagerOptions } from "./BaseManager"; | ||
import { Executor, ValueOfExecutor } from "../Executor"; | ||
import { Executor } from "../Executor"; | ||
import { ReadWriteOptions, WriteOptions } from "../storage/Storage"; | ||
import { Record, RecordValue } from "../storage/Record"; | ||
import { Record } from "../storage/Record"; | ||
declare class WriteThroughManager extends BaseManager { | ||
static getName(): string; | ||
constructor(options: ManagerOptions); | ||
get<E extends Executor>(key: string, executor: E, options?: ReadWriteOptions): Promise<ValueOfExecutor<E>>; | ||
set(key: string, value: RecordValue, options?: WriteOptions): Promise<Record>; | ||
get<R>(key: string, executor: Executor<R>, options?: ReadWriteOptions<R>): Promise<R>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
private isRecordValid; | ||
} | ||
export default WriteThroughManager; |
@@ -7,2 +7,3 @@ "use strict"; | ||
const BaseManager_1 = require("./BaseManager"); | ||
const Executor_1 = require("../Executor"); | ||
const deserialize_1 = __importDefault(require("../deserialize")); | ||
@@ -23,5 +24,4 @@ class WriteThroughManager extends BaseManager_1.BaseManager { | ||
this.logger.error("Failed to get value from storage, falling back to executor", e); | ||
return executor(); | ||
return Executor_1.runExecutor(executor); | ||
} | ||
const executorContext = { key, executor, options }; | ||
if (this.isRecordValid(record)) { | ||
@@ -32,2 +32,3 @@ this.logger.trace("hit", key); | ||
this.logger.trace("miss", key); | ||
const executorContext = { key, executor, options }; | ||
return this.updateCacheAndGetResult(executorContext, options); | ||
@@ -34,0 +35,0 @@ } |
import { ConnectionStatus } from "../ConnectionStatus"; | ||
import { Storage, Tag, WriteOptions } from "./Storage"; | ||
import { StorageAdapter } from "../StorageAdapter"; | ||
import { Record, RecordValue } from "./Record"; | ||
import { Record } from "./Record"; | ||
export declare const TAGS_VERSIONS_ALIAS = "cache-tags-versions"; | ||
@@ -62,3 +62,3 @@ export declare type BaseStorageOptions = { | ||
*/ | ||
get(key: string): Promise<Record | null>; | ||
get<R>(key: string): Promise<Record<R> | null>; | ||
/** | ||
@@ -96,3 +96,3 @@ * Creates new set of tag records and updates them. | ||
*/ | ||
set(key: string, value: RecordValue, options?: WriteOptions): Promise<Record>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
/** | ||
@@ -103,3 +103,3 @@ * Checks if record is outdated by tags | ||
*/ | ||
isOutdated(record: Record): Promise<boolean>; | ||
isOutdated<R>(record: Record<R>): Promise<boolean>; | ||
/** | ||
@@ -106,0 +106,0 @@ * Returns current connection status of storage. |
@@ -41,3 +41,7 @@ "use strict"; | ||
async get(key) { | ||
const record = deserialize_1.default(await this.adapter.get(this.createKey(key))); | ||
const value = await this.adapter.get(this.createKey(key)); | ||
if (value == null) { | ||
return null; | ||
} | ||
const record = deserialize_1.default(value); | ||
if (!Record_1.Record.isRecord(record)) { | ||
@@ -59,3 +63,5 @@ return null; | ||
async touch(tags) { | ||
return this.cachedCommand(this.setTagVersions.bind(this), tags.map(this.createTag)); | ||
if (tags.length > 0) { | ||
await this.cachedCommand(this.setTagVersions.bind(this), tags.map(this.createTag)); | ||
} | ||
} | ||
@@ -91,2 +97,5 @@ /** | ||
async getTags(tagNames) { | ||
if (tagNames.length === 0) { | ||
return []; | ||
} | ||
const existingTags = await this.tagsAdapter.mget(tagNames.map(tagName => this.createTagKey(tagName))); | ||
@@ -93,0 +102,0 @@ return tagNames.map((tagName, index) => ({ |
import { Tag, WriteOptions } from "./Storage"; | ||
export declare type RecordValue = object | string | number | null; | ||
export declare class Record { | ||
export declare class Record<R> { | ||
/** | ||
* Checks if provided value is valid Record. | ||
*/ | ||
static isRecord(value: any): value is Record; | ||
static isRecord(value: unknown): value is Record<unknown>; | ||
/** | ||
@@ -27,3 +26,3 @@ * Record key | ||
*/ | ||
value?: RecordValue; | ||
value: R; | ||
/** | ||
@@ -33,3 +32,3 @@ * Cache tags Array with pairs of tag name and version. The version is stored as unixtime. | ||
tags: Tag[]; | ||
constructor(key: string, value: RecordValue, tags: Tag[], options?: WriteOptions); | ||
constructor(key: string, value: R, tags: Tag[], options?: WriteOptions<R>); | ||
} |
@@ -20,3 +20,3 @@ "use strict"; | ||
static isRecord(value) { | ||
return value === null || (typeof value === "object" && value.key); | ||
return typeof value === "object" && Object.prototype.hasOwnProperty.call(value, "key"); | ||
} | ||
@@ -23,0 +23,0 @@ } |
import { LockedKeyRetrieveStrategyType } from "../LockedKeyRetrieveStrategy"; | ||
import { ConnectionStatus } from "../ConnectionStatus"; | ||
import { Record, RecordValue } from "./Record"; | ||
import { Record } from "./Record"; | ||
/** | ||
@@ -10,3 +10,3 @@ * Storage is an abstraction over different operations with records | ||
export interface Storage { | ||
get(key: string): Promise<Record | null>; | ||
get<R>(key: string): Promise<Record<R> | null>; | ||
touch(tags: string[]): Promise<void>; | ||
@@ -18,4 +18,4 @@ lockKey(key: string): Promise<boolean>; | ||
getTags(tagNames: string[]): Promise<Tag[]>; | ||
isOutdated(record: Record): Promise<boolean>; | ||
set(key: string, value: RecordValue, options?: WriteOptions): Promise<Record>; | ||
isOutdated<R>(record: Record<R>): Promise<boolean>; | ||
set<R>(key: string, value: R, options?: WriteOptions<R>): Promise<Record<R>>; | ||
getConnectionStatus(): ConnectionStatus; | ||
@@ -59,3 +59,3 @@ } | ||
} | ||
export interface WriteOptions extends ExpireOptions { | ||
export interface WriteOptions<R> extends ExpireOptions { | ||
/** | ||
@@ -70,4 +70,4 @@ * Tags - are keys for which the manager checks the validity of a particular entry. | ||
*/ | ||
getTags?: (executorResult: any) => string[]; | ||
getTags?: (executorResult: R) => string[]; | ||
} | ||
export declare type ReadWriteOptions = ReadOptions & WriteOptions; | ||
export declare type ReadWriteOptions<R> = ReadOptions & WriteOptions<R>; |
{ | ||
"name": "cachalot", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "Cache manager for nodejs with support different cache strategies", | ||
@@ -30,4 +30,4 @@ "keywords": [ | ||
"watch": "tsc -w", | ||
"format": "prettier --write tests/**/*.ts src/**/*.ts", | ||
"lint": "prettier -c tests/**/*.ts src/**/*.ts && eslint src/**/*.ts tests/**/*.ts", | ||
"format": "prettier --write tests/**/*.ts src/*.ts src/**/*.ts", | ||
"lint": "prettier -c tests/**/*.ts src/*.ts src/**/*.ts && eslint src tests --ext .ts --max-warnings 0", | ||
"check": "npm run lint && npm run test:unit", | ||
@@ -34,0 +34,0 @@ "test": "npm run test:unit", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
134768
1923
0