Created
May 24, 2023 19:14
-
-
Save 7iomka/8c3373578739dae72526b97c3a2a3928 to your computer and use it in GitHub Desktop.
http cache
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface HttpCacheEntry { | |
data: any; | |
expires: number; | |
} | |
export interface SerializeCacheKeyPayload { | |
headers?: Record<string, string>; | |
method?: string; | |
url: string; | |
body?: Record<string, any>; | |
} | |
export abstract class HttpCache { | |
/** | |
* Получить данные из кеша | |
* @param key - Уникальный ключ кеша | |
* @example | |
* ```ts | |
* cache.get('key'); | |
* ``` | |
*/ | |
public abstract get<T = any>(key: string): T | null; | |
/** | |
* Добавить данные в кеш | |
* @param key - Уникальный ключ кеша | |
* @param data - Данные для добавления | |
* @example | |
* ```ts | |
* cache.set('key', { ok: true }); | |
* ``` | |
*/ | |
public abstract set(key: string, data: any, ...rest: any): any; | |
/** | |
* Удалить закешированные данные по ключу | |
* @param key - Уникальный ключ кеша | |
* @xample | |
* ```ts | |
* cache.delete('key'); | |
* ``` | |
*/ | |
public abstract delete(key: string): any; | |
/** | |
* Полностью очистить кеш | |
*/ | |
public abstract reset(): any; | |
/** | |
* Сгенерировать уникальный ключ кеша из параметров http-запроса | |
* @example | |
* ```ts | |
* cache.serializeCacheKey({ | |
* url: 'https://example.com', | |
* body: { key: "value" }, | |
* method: "POST" | |
* }) | |
* ``` | |
*/ | |
// eslint-disable-next-line class-methods-use-this | |
public serializeCacheKey(payload: SerializeCacheKeyPayload): string { | |
try { | |
return JSON.stringify(payload); | |
} catch (_e) { | |
// на случай попытки сериализации объекта с циклическими зависимостями внутри | |
return payload.url + String(Math.random()); | |
} | |
} | |
} | |
const minute = 60000; | |
export class DefaultHttpCache extends HttpCache { | |
private static sharedInstance: DefaultHttpCache; | |
private _map = new Map<string, HttpCacheEntry>(); | |
private _ttl = 10 * minute; | |
/** | |
* Синглтон | |
* @example | |
* ```ts | |
* cache.shared.get('key'); | |
* ``` | |
*/ | |
public static get shared(): DefaultHttpCache { | |
if (!DefaultHttpCache.sharedInstance) { | |
DefaultHttpCache.sharedInstance = new DefaultHttpCache(); | |
} | |
return DefaultHttpCache.sharedInstance; | |
} | |
/** | |
* Время жизни кеша в миллисекундах | |
* @example | |
* ```ts | |
* cache.ttl = 60000; | |
* cache.ttl = Infinity; | |
* cache.tll = 0; | |
* | |
* // негативные значения игнорируются | |
* cache.ttl = -1; | |
* cache.ttl = Number.NEGATIVE_INFINITY; | |
* ``` | |
*/ | |
public get ttl(): number { | |
return this._ttl; | |
} | |
public set ttl(ttl: number) { | |
if (typeof ttl === 'number' && ttl >= 0) { | |
this._ttl = ttl; | |
} | |
} | |
/** | |
* Количество элементов в кеше | |
*/ | |
public get size(): number { | |
return this._map.size; | |
} | |
public get<T = any>(key: string) { | |
const data = this._map.get(key); | |
if (!data) return null; | |
if (data.expires <= Date.now()) { | |
this.delete(key); | |
return null; | |
} | |
return data.data as T; | |
} | |
public set(key: string, data: any): this { | |
this._map.set(key, { | |
data, | |
expires: Date.now() + this.ttl, | |
}); | |
return this; | |
} | |
public delete(key: string): this { | |
this._map.delete(key); | |
return this; | |
} | |
public reset(): this { | |
this._map.clear(); | |
return this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment