@hyperttp/cache 1.1.1 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,3 @@
1
- ```markdown
2
1
  # hyperttp-cache
3
2
 
4
3
  > [Русский](https://github.com/IT-IF-OR/hyperttp-cache/tree/main/lang/ru) | English
@@ -136,7 +135,3 @@ from the map to ensure subsequent retries targeting the failed endpoint are neve
136
135
  ## 📄 License
137
136
 
138
137
  MIT
139
-
140
- ```
141
-
142
- ```
package/package.json CHANGED
@@ -1,10 +1,18 @@
1
1
  {
2
2
  "name": "@hyperttp/cache",
3
- "version": "1.1.1",
3
+ "version": "1.1.5",
4
4
  "description": "High-performance LRU caching plugin for Hyperttp client",
5
5
  "type": "module",
6
6
  "main": "./index.js",
7
7
  "types": "./index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./index.d.ts",
11
+ "import": "./index.js",
12
+ "require": "./index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
8
16
  "keywords": [
9
17
  "hyperttp"
10
18
  ],
@@ -14,12 +22,8 @@
14
22
  "type": "git",
15
23
  "url": "git+https://github.com/IT-IF-OR/hyperttp-cache.git"
16
24
  },
17
- "dependencies": {
18
- "@hyperttp/types": "^0.1.1",
19
- "lru-cache": "^11.5.1"
20
- },
21
25
  "peerDependencies": {
22
- "@hyperttp/core": "^1.2.0"
26
+ "@hyperttp/types": "^0.1.5"
23
27
  },
24
28
  "private": false
25
29
  }
package/plugin.d.ts CHANGED
@@ -1,24 +1,64 @@
1
1
  import type { HyperPlugin } from "@hyperttp/types";
2
- import type { CacheManagerOptions } from "./types/cache.js";
2
+ import type { CacheManagerOptions, LightweightResponse } from "./types/cache.js";
3
3
  import { CacheManager } from "./utils/CacheManager.js";
4
+ /**
5
+ * @en Extends the PluginContext to include the cache manager instance.
6
+ * @ru Расширяет PluginContext, добавляя экземпляр менеджера кэша.
7
+ */
4
8
  declare module "@hyperttp/types" {
5
9
  interface PluginContext {
6
- cache?: CacheManager;
10
+ /**
11
+ * @en The active cache manager instance.
12
+ * @ru Активный экземпляр менеджера кэша.
13
+ */
14
+ cache?: CacheManager<LightweightResponse>;
7
15
  }
16
+ /**
17
+ * @en Extends HyperttpPluginsExtension to include cache configuration options.
18
+ * @ru Расширяет HyperttpPluginsExtension, добавляя опции конфигурации кэша.
19
+ */
8
20
  interface HyperttpPluginsExtension {
21
+ /**
22
+ * @en Cache configuration and enablement flags.
23
+ * @ru Конфигурация кэша и флаги включения.
24
+ */
9
25
  cache?: CacheManagerOptions & {
26
+ /**
27
+ * @en Enables or disables the caching plugin.
28
+ * @ru Включает или отключает плагин кэширования.
29
+ */
10
30
  enabled: boolean;
31
+ /**
32
+ * @en List of HTTP methods allowed for caching (e.g., ["GET"]).
33
+ * @ru Список HTTP-методов, разрешенных для кэширования (например, ["GET"]).
34
+ */
35
+ methods?: string[];
11
36
  };
12
37
  }
38
+ /**
39
+ * @en Extends IHyperCore with cache management methods.
40
+ * @ru Расширяет IHyperCore методами управления кэшем.
41
+ */
13
42
  interface IHyperCore {
43
+ /**
44
+ * @en Clears the cache. If a key is provided, only that entry is removed.
45
+ * @ru Очищает кэш. Если указан ключ, удаляется только соответствующая запись.
46
+ * @param key - Optional cache key to delete.
47
+ */
14
48
  clearCache(key?: string): void;
49
+ /**
50
+ * @en Returns runtime statistics, including cache size.
51
+ * @ru Возвращает статистику выполнения, включая размер кэша.
52
+ */
15
53
  getStats?(): Record<string, any>;
16
54
  }
17
55
  }
18
56
  /**
19
- * @ru Фабрика плагина кэширования и дедупликации конкурентных запросов для HyperCore.
20
- * @en Cache management and concurrent request deduplication plugin factory for HyperCore.
21
- * @returns Модуль расширения ядра в рамках линейного жизненного цикла. / Configured extension plugin container.
57
+ * @en Creates a caching plugin for Hyperttp.
58
+ * Handles in-memory caching, conditional requests (ETag/Last-Modified), and request deduplication.
59
+ * @ru Создает плагин кэширования для Hyperttp.
60
+ * Обрабатывает кэширование в памяти, условные запросы (ETag/Last-Modified) и дедупликацию запросов.
61
+ * @returns The configured HyperPlugin instance.
22
62
  */
23
63
  export declare function withCache(): HyperPlugin;
24
64
  //# sourceMappingURL=plugin.d.ts.map
package/plugin.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,WAAW,EAKZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,aAAa;QACrB,KAAK,CAAC,EAAE,YAAY,CAAC;KACtB;IACD,UAAU,wBAAwB;QAChC,KAAK,CAAC,EAAE,mBAAmB,GAAG;YAC5B,OAAO,EAAE,OAAO,CAAC;SAClB,CAAC;KACH;IACD,UAAU,UAAU;QAClB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAClC;CACF;AAaD;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,WAAW,CA+LvC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,WAAW,EAIZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;GAGG;AACH,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,aAAa;QACrB;;;WAGG;QACH,KAAK,CAAC,EAAE,YAAY,CAAC,mBAAmB,CAAC,CAAC;KAC3C;IAED;;;OAGG;IACH,UAAU,wBAAwB;QAChC;;;WAGG;QACH,KAAK,CAAC,EAAE,mBAAmB,GAAG;YAC5B;;;eAGG;YACH,OAAO,EAAE,OAAO,CAAC;YACjB;;;eAGG;YACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;SACpB,CAAC;KACH;IAED;;;OAGG;IACH,UAAU,UAAU;QAClB;;;;WAIG;QACH,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAE/B;;;WAGG;QACH,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAClC;CACF;AA0BD;;;;;;GAMG;AACH,wBAAgB,SAAS,IAAI,WAAW,CAyKvC"}
package/plugin.js CHANGED
@@ -1,92 +1,76 @@
1
1
  import { CacheManager } from "./utils/CacheManager.js";
2
2
  /**
3
- * @ru Фабрика плагина кэширования и дедупликации конкурентных запросов для HyperCore.
4
- * @en Cache management and concurrent request deduplication plugin factory for HyperCore.
5
- * @returns Модуль расширения ядра в рамках линейного жизненного цикла. / Configured extension plugin container.
3
+ * @en Helper function to create a standardized HttpResponse object from lightweight data.
4
+ * @ru Вспомогательная функция для создания стандартизированного объекта HttpResponse из легких данных.
5
+ * @param data - The lightweight response data.
6
+ * @returns A full HttpResponse object.
7
+ */
8
+ const createHttpResponse = (data) => ({
9
+ status: data.status,
10
+ headers: data.headers,
11
+ body: data.body,
12
+ url: data.url,
13
+ clone: () => createHttpResponse(data),
14
+ });
15
+ /**
16
+ * @en Creates a caching plugin for Hyperttp.
17
+ * Handles in-memory caching, conditional requests (ETag/Last-Modified), and request deduplication.
18
+ * @ru Создает плагин кэширования для Hyperttp.
19
+ * Обрабатывает кэширование в памяти, условные запросы (ETag/Last-Modified) и дедупликацию запросов.
20
+ * @returns The configured HyperPlugin instance.
6
21
  */
7
22
  export function withCache() {
8
- /**
9
- * @private
10
- * @ru Изолированный инстанс менеджера кэша для текущего клиента.
11
- * @en Isolated cache manager orchestration instance allocated for the target client.
12
- */
13
23
  let cache;
14
- /**
15
- * @private
16
- * @ru Список HTTP-методов, для которых разрешено кэширование ответов.
17
- * @en Set of HTTP request methods authorized for downstream response caching.
18
- */
19
- let allowedMethods;
20
- /**
21
- * @private
22
- * @ru Карта активных сетевых запросов для предотвращения каскадного заваливания бэкенда (Cache Stampede).
23
- * @en Registry of concurrent requests in execution to prevent backend server breakdown (Cache Stampede).
24
- */
24
+ let allowedMethods = new Set();
25
25
  const inFlight = new Map();
26
26
  return {
27
27
  name: "hyperttp-cache",
28
- /**
29
- * @ru Динамическая проверка необходимости активации кэширования на основе переданных опций.
30
- * @en Dynamic check evaluating if the caching plugin layer should be appended based on client runtime options.
31
- * @param config - Глобальная конфигурация инстанса клиента. / Global active client lifecycle options.
32
- * @returns Индикатор необходимости сборки плагина. / Lifecycle activation indicator status.
33
- */
34
28
  enabled: (config) => {
35
29
  return !!config.cache?.enabled;
36
30
  },
37
- /**
38
- * @ru Однократный хук инициализации. Настраивает менеджер кэша и внедряет методы отладки/очистки в ядро.
39
- * @en One-time setup context hook. Orchestrates the cache manager and extends telemetry/purge interfaces inside the core.
40
- * @param ctx - Общий контекст окружения плагина. / Shared plugin execution context metadata.
41
- */
42
31
  setup(ctx) {
43
- const { core, config } = ctx;
32
+ const core = ctx.core;
33
+ const config = ctx.config;
44
34
  cache = new CacheManager(config?.cache);
45
35
  ctx.cache = cache;
46
36
  const methods = config?.cache?.methods ?? ["GET"];
47
37
  allowedMethods = new Set(methods.map((m) => m.toUpperCase()));
48
38
  if (core && typeof core.getStats === "function") {
49
- const originalGetStats = core.getStats;
39
+ const originalGetStats = core.getStats.bind(core);
50
40
  core.getStats = function () {
51
- const stats = originalGetStats.call(this);
52
- if (stats) {
53
- stats.cacheSize = cache.size;
54
- }
55
- return stats;
41
+ const stats = originalGetStats();
42
+ return {
43
+ ...stats,
44
+ cacheSize: cache.size,
45
+ };
56
46
  };
57
47
  }
58
48
  core.clearCache = (key) => {
59
- return key ? cache.delete(key) : cache.clear();
49
+ if (key) {
50
+ cache.delete(key);
51
+ }
52
+ else {
53
+ cache.clear();
54
+ }
60
55
  };
61
56
  },
62
- /**
63
- * @ru Перехватчик фазы отправки запроса. Проверяет локальные кэш-хиты и координирует пулинг конкурентных задач.
64
- * @en Request phase interceptor. Evaluates local cache hits, appends conditional headers, or hooks into active in-flight targets.
65
- * @param req - Сконфигурированный внутренний объект запроса. / Contextual internal request parameters.
66
- * @param ctx - Общий контекст окружения плагина. / Shared plugin execution context metadata.
67
- * @returns Мгновенный изолированный ответ из кэша, обертку гонки или void для продолжения сетевого цикла. / Short-circuit response clone, matching follower promise tracker, or void execution.
68
- */
69
- onRequest(req,
70
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
71
- _ctx) {
72
- const method = req.method.toUpperCase();
73
- if (!allowedMethods.has(method)) {
57
+ onRequest(req) {
58
+ if (!allowedMethods.has(req.method.toUpperCase())) {
74
59
  return;
75
60
  }
76
61
  const cacheKey = req.url;
77
62
  const cachedEntry = cache.getWithMetadata(cacheKey);
78
- if (cachedEntry !== undefined &&
79
- !cachedEntry.etag &&
80
- !cachedEntry.lastModified) {
81
- return cachedEntry.data.clone();
63
+ if (cachedEntry && !cachedEntry.etag && !cachedEntry.lastModified) {
64
+ return createHttpResponse(cachedEntry.data);
82
65
  }
83
- // Частичный кэш-хит, подмешиваем заголовки проверки свежести
84
- if (cachedEntry !== undefined) {
66
+ if (cachedEntry) {
85
67
  req.headers = { ...req.headers };
86
- if (cachedEntry.etag)
68
+ if (cachedEntry.etag) {
87
69
  req.headers["if-none-match"] = cachedEntry.etag;
88
- if (cachedEntry.lastModified)
70
+ }
71
+ if (cachedEntry.lastModified) {
89
72
  req.headers["if-modified-since"] = cachedEntry.lastModified;
73
+ }
90
74
  }
91
75
  const currentInFlight = inFlight.get(cacheKey);
92
76
  if (currentInFlight) {
@@ -94,62 +78,78 @@ export function withCache() {
94
78
  }
95
79
  let resolveFn;
96
80
  let rejectFn;
97
- const promise = new Promise((res, rej) => {
98
- resolveFn = res;
99
- rejectFn = rej;
81
+ const promise = new Promise((resolve, reject) => {
82
+ resolveFn = resolve;
83
+ rejectFn = reject;
100
84
  });
101
- promise.catch(() => { });
102
- inFlight.set(cacheKey, { promise, resolve: resolveFn, reject: rejectFn });
85
+ const trigger = {
86
+ promise,
87
+ resolve: resolveFn,
88
+ reject: (err) => {
89
+ inFlight.delete(cacheKey);
90
+ rejectFn(err);
91
+ },
92
+ };
93
+ inFlight.set(cacheKey, trigger);
94
+ setTimeout(() => {
95
+ if (inFlight.has(cacheKey)) {
96
+ console.warn(`[Cache] Warning: Request hung for ${cacheKey}, forcing cleanup`);
97
+ trigger.reject(new Error("Request timed out in cache plugin"));
98
+ }
99
+ }, 30_000);
100
+ return;
103
101
  },
104
- /**
105
- * @ru Перехватчик фазы получения ответа. Обновляет хранилище или трансформирует статус 304 в полные данные из кэша.
106
- * @en Response phase interceptor. Saves raw outputs to the storage layer or re-hydrates empty 304 responses with cached data bodies.
107
- */
108
- onResponse(res, req,
109
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
110
- _ctx) {
102
+ onResponse(res, req) {
103
+ if (!req)
104
+ return;
111
105
  const cacheKey = req.url;
112
106
  const trigger = inFlight.get(cacheKey);
113
- if (!trigger) {
107
+ if (!trigger)
114
108
  return;
115
- }
116
109
  inFlight.delete(cacheKey);
117
- const cachedEntry = cache.getWithMetadata(cacheKey);
118
- if (res.status === 304 && cachedEntry !== undefined) {
119
- const clonedCache = cachedEntry.data.clone();
120
- Object.assign(res, clonedCache);
121
- res.status = clonedCache.status ?? 200;
122
- trigger.resolve(clonedCache);
123
- return;
110
+ if (res.status === 304) {
111
+ const cachedEntry = cache.getWithMetadata(cacheKey);
112
+ if (cachedEntry) {
113
+ const cachedData = cachedEntry.data;
114
+ const restoredRes = {
115
+ status: cachedData.status,
116
+ headers: cachedData.headers,
117
+ body: cachedData.body,
118
+ url: cachedData.url,
119
+ clone: () => createHttpResponse(cachedData),
120
+ };
121
+ trigger.resolve(restoredRes);
122
+ return;
123
+ }
124
+ else {
125
+ console.warn(`[Cache] Received 304 for ${cacheKey} but no cache entry found.`);
126
+ }
124
127
  }
125
128
  if (res.status >= 200 && res.status < 300) {
126
- const valueToCache = res.clone();
127
- const headers = res.headers;
128
- const etag = headers?.["etag"] || headers?.["ETag"];
129
- const lastModified = headers?.["last-modified"] || headers?.["Last-Modified"];
130
- cache.setWithMetadata(cacheKey, valueToCache, {
131
- etag: typeof etag === "string" ? etag : undefined,
132
- lastModified: typeof lastModified === "string" ? lastModified : undefined,
129
+ const headers = res.headers || {};
130
+ const lightResponse = {
131
+ body: res.body,
132
+ status: res.status,
133
+ headers: res.headers,
134
+ url: res.url,
135
+ };
136
+ cache.setWithMetadata(cacheKey, lightResponse, {
137
+ etag: Array.isArray(headers["etag"])
138
+ ? headers["etag"][0]
139
+ : headers["etag"],
140
+ lastModified: Array.isArray(headers["last-modified"])
141
+ ? headers["last-modified"][0]
142
+ : headers["last-modified"],
133
143
  });
134
- trigger.resolve(res.clone());
135
- return;
136
144
  }
137
145
  trigger.resolve(res.clone());
138
146
  },
139
- /**
140
- * @ru Перехватчик фазы критических сбоев. Разрывает пул ожидания дедупликации, транслируя ошибку всем подписчикам.
141
- * @en Error phase interceptor. Purges matching metadata maps and forwards pipeline processing exceptions to all waiting threads.
142
- * @param err - Специфичный объект ошибки сетевого клиента. / Normalized client-level error framework tracking details.
143
- * @param req - Сконфигурированный внутренний объект запроса. / Contextual internal request parameters.
144
- * @param ctx - Общий контекст окружения плагина. / Shared plugin execution context metadata.
145
- */
146
- onError(err, req,
147
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
148
- _ctx) {
149
- const cacheKey = req.url;
150
- const trigger = inFlight.get(cacheKey);
147
+ onError(err, req) {
148
+ if (!req)
149
+ return;
150
+ const trigger = inFlight.get(req.url);
151
151
  if (trigger) {
152
- inFlight.delete(cacheKey);
152
+ inFlight.delete(req.url);
153
153
  trigger.reject(err);
154
154
  }
155
155
  },
package/plugin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/types/cache.d.ts CHANGED
@@ -1,29 +1,81 @@
1
1
  import { Method } from "@hyperttp/types";
2
+ /**
3
+ * @en Structure representing a cached item with optional HTTP validation metadata.
4
+ * @ru Структура, представляющая элемент кэша с опциональными метаданными для HTTP-валидации.
5
+ * @template T - Type of the cached data.
6
+ */
2
7
  export interface CacheEntry<T> {
8
+ /**
9
+ * @en The cached data payload.
10
+ * @ru Сохраненные данные.
11
+ */
3
12
  data: T;
13
+ /**
14
+ * @en HTTP ETag header value for conditional requests.
15
+ * @ru Значение заголовка HTTP ETag для условных запросов.
16
+ */
4
17
  etag?: string;
18
+ /**
19
+ * @en HTTP Last-Modified header value for conditional requests.
20
+ * @ru Значение заголовка HTTP Last-Modified для условных запросов.
21
+ */
5
22
  lastModified?: string;
6
23
  }
24
+ /**
25
+ * @en Configuration options for the CacheManager.
26
+ * @ru Конфигурационные опции для CacheManager.
27
+ */
7
28
  export interface CacheManagerOptions {
8
29
  /**
9
- * @ru Включить кэш
10
- * @en Enable cache
30
+ * @en Enable cache functionality.
31
+ * @ru Включить кэш.
11
32
  */
12
33
  enabled?: boolean;
13
34
  /**
14
- * @ru Время жизни кэша (мс)
15
- * @en Cache time-to-live in milliseconds
35
+ * @en Cache time-to-live in milliseconds.
36
+ * @ru Время жизни кэша (мс).
16
37
  */
17
38
  ttl?: number;
18
39
  /**
19
- * @ru Максимальный размер кэша
20
- * @en Maximum cache size
40
+ * @en Maximum number of entries in the cache.
41
+ * @ru Максимальный размер кэша.
21
42
  */
22
43
  maxSize?: number;
23
44
  /**
24
- * @ru HTTP методы, которые можно кэшировать
25
- * @en HTTP methods allowed to be cached
45
+ * @en HTTP methods allowed to be cached.
46
+ * @ru HTTP методы, которые можно кэшировать.
26
47
  */
27
48
  methods?: readonly Method[];
49
+ /**
50
+ * @en Update the expiration time when an entry is accessed.
51
+ * @ru Обновлять время истечения при доступе к записи.
52
+ */
53
+ updateAgeOnGet?: boolean;
54
+ }
55
+ /**
56
+ * @en A simplified response object used for efficient cache storage.
57
+ * @ru Упрощенный объект ответа, используемый для эффективного хранения в кэше.
58
+ */
59
+ export interface LightweightResponse<T = unknown> {
60
+ /**
61
+ * @en The response body content.
62
+ * @ru Содержимое тела ответа.
63
+ */
64
+ body: T;
65
+ /**
66
+ * @en The HTTP status code.
67
+ * @ru HTTP-код статуса.
68
+ */
69
+ status: number;
70
+ /**
71
+ * @en The response headers.
72
+ * @ru Заголовки ответа.
73
+ */
74
+ headers: Record<string, string | string[]>;
75
+ /**
76
+ * @en The final URL of the response.
77
+ * @ru Финальный URL ответа.
78
+ */
79
+ url: string;
28
80
  }
29
81
  //# sourceMappingURL=cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/types/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/types/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B;;;OAGG;IACH,IAAI,EAAE,CAAC,CAAC;IAER;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE5B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO;IAC9C;;;OAGG;IACH,IAAI,EAAE,CAAC,CAAC;IAER;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAE3C;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;CACb"}
@@ -1,78 +1,71 @@
1
1
  import type { CacheEntry, CacheManagerOptions } from "../types/cache.ts";
2
2
  /**
3
- * @class CacheManager
4
- * @en High-performance in-memory cache based on LRU strategy.
5
- * Provides TTL support, metadata storage (etag, lastModified) and fast key-value access.
3
+ * @en High-performance inline in-memory cache with no external dependencies.
4
+ * Uses native Map and lazy invalidation to ensure maximum RPS.
5
+ * @ru Высокопроизводительный инлайновый in-memory кэш без внешних зависимостей.
6
+ * Использует нативный Map и ленивую инвалидацию для обеспечения максимального RPS.
6
7
  *
7
- * @ru Высокопроизводительный in-memory кэш на основе LRU стратегии.
8
- * Поддерживает TTL, хранение метаданных (etag, lastModified) и быстрый доступ по ключу.
8
+ * @template T - Type of the data stored in the cache. Defaults to unknown.
9
9
  */
10
- export declare class CacheManager {
11
- private readonly cache;
10
+ export declare class CacheManager<T = unknown> {
11
+ private readonly storage;
12
+ private readonly maxSize;
13
+ private readonly ttl;
14
+ private readonly updateAgeOnGet;
12
15
  constructor(options?: CacheManagerOptions);
13
16
  /**
14
- * @en Retrieves cached value by key.
17
+ * @en Retrieves a value from the cache by key.
15
18
  * @ru Получает значение из кэша по ключу.
16
- *
17
- * @template T
18
- * @param key Cache key
19
- * @returns Cached value or undefined if not found
19
+ * @param key - The cache key.
20
+ * @returns The cached value or undefined if not found or expired.
20
21
  */
21
- get<T>(key: string): T | undefined;
22
+ get(key: string): T | undefined;
22
23
  /**
23
- * @en Stores value in cache.
24
+ * @en Stores a value in the cache.
24
25
  * @ru Сохраняет значение в кэш.
25
- *
26
- * @template T
27
- * @param key Cache key
28
- * @param value Value to store
26
+ * @param key - The cache key.
27
+ * @param value - The data to store.
29
28
  */
30
- set<T>(key: string, value: T): void;
29
+ set(key: string, value: T): void;
31
30
  /**
32
- * @en Retrieves cached entry with metadata (etag, lastModified).
31
+ * @en Retrieves a cache entry along with its metadata (etag, lastModified).
33
32
  * @ru Получает запись кэша вместе с метаданными (etag, lastModified).
34
- *
35
- * @template T
36
- * @param key Cache key
37
- * @returns Cached entry with metadata or undefined
33
+ * @param key - The cache key.
34
+ * @returns The cache entry with metadata or undefined if not found or expired.
38
35
  */
39
- getWithMetadata<T>(key: string): CacheEntry<T> | undefined;
36
+ getWithMetadata(key: string): CacheEntry<T> | undefined;
40
37
  /**
41
- * @en Stores value with optional HTTP metadata (etag, lastModified).
42
- * @ru Сохраняет значение с дополнительными HTTP метаданными (etag, lastModified).
43
- *
44
- * @template T
45
- * @param key Cache key
46
- * @param data Value to store
47
- * @param meta Optional HTTP metadata
38
+ * @en Stores a value with additional HTTP metadata.
39
+ * @ru Сохраняет значение с дополнительными HTTP метаданными.
40
+ * @param key - The cache key.
41
+ * @param data - The response data to store.
42
+ * @param meta - Optional HTTP metadata (etag, lastModified).
48
43
  */
49
- setWithMetadata<T>(key: string, data: T, meta?: {
44
+ setWithMetadata(key: string, data: T, meta?: {
50
45
  etag?: string;
51
46
  lastModified?: string;
52
47
  }): void;
53
48
  /**
54
- * @en Checks if key exists in cache.
55
- * @ru Проверяет наличие ключа в кэше.
56
- *
57
- * @param key Cache key
58
- * @returns true if exists, otherwise false
49
+ * @en Checks for the existence of a key in the cache without updating its TTL.
50
+ * @ru Проверяет наличие ключа в кэше без обновления его времени жизни.
51
+ * @param key - The cache key.
52
+ * @returns True if the key exists and is not expired.
59
53
  */
60
54
  has(key: string): boolean;
61
55
  /**
62
- * @en Deletes value from cache by key.
56
+ * @en Removes a value from the cache by key.
63
57
  * @ru Удаляет значение из кэша по ключу.
64
- *
65
- * @param key Cache key
66
- * @returns true if value was removed
58
+ * @param key - The cache key.
59
+ * @returns True if the element was removed, false otherwise.
67
60
  */
68
61
  delete(key: string): boolean;
69
62
  /**
70
- * @en Clears entire cache.
63
+ * @en Clears the entire cache.
71
64
  * @ru Очищает весь кэш.
72
65
  */
73
66
  clear(): void;
74
67
  /**
75
- * @en Returns current cache size.
68
+ * @en Returns the current number of items in the cache.
76
69
  * @ru Возвращает текущий размер кэша.
77
70
  */
78
71
  get size(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../../src/utils/CacheManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAE9C,OAAO,CAAC,EAAE,mBAAmB;IAQzC;;;;;;;OAOG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIlC;;;;;;;OAOG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAMnC;;;;;;;OAOG;IACH,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS;IAK1D;;;;;;;;OAQG;IACH,eAAe,CAAC,CAAC,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GACA,IAAI;IAQP;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../../src/utils/CacheManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAczE;;;;;;;GAOG;AACH,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAE7B,OAAO,CAAC,EAAE,mBAAmB;IAMzC;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAoB/B;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAgBhC;;;;;OAKG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS;IAuBvD;;;;;;OAMG;IACH,eAAe,CACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9C,IAAI;IAoBP;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAWzB;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -1,106 +1,154 @@
1
- import { LRUCache } from "lru-cache";
2
1
  /**
3
- * @class CacheManager
4
- * @en High-performance in-memory cache based on LRU strategy.
5
- * Provides TTL support, metadata storage (etag, lastModified) and fast key-value access.
2
+ * @en High-performance inline in-memory cache with no external dependencies.
3
+ * Uses native Map and lazy invalidation to ensure maximum RPS.
4
+ * @ru Высокопроизводительный инлайновый in-memory кэш без внешних зависимостей.
5
+ * Использует нативный Map и ленивую инвалидацию для обеспечения максимального RPS.
6
6
  *
7
- * @ru Высокопроизводительный in-memory кэш на основе LRU стратегии.
8
- * Поддерживает TTL, хранение метаданных (etag, lastModified) и быстрый доступ по ключу.
7
+ * @template T - Type of the data stored in the cache. Defaults to unknown.
9
8
  */
10
9
  export class CacheManager {
11
- cache;
10
+ storage = new Map();
11
+ maxSize;
12
+ ttl;
13
+ updateAgeOnGet;
12
14
  constructor(options) {
13
- this.cache = new LRUCache({
14
- max: options?.maxSize ?? 500,
15
- ttl: options?.ttl ?? 300_000,
16
- updateAgeOnGet: true,
17
- });
15
+ this.maxSize = options?.maxSize ?? 500;
16
+ this.ttl = options?.ttl ?? 300_000;
17
+ this.updateAgeOnGet = options?.updateAgeOnGet ?? true;
18
18
  }
19
19
  /**
20
- * @en Retrieves cached value by key.
20
+ * @en Retrieves a value from the cache by key.
21
21
  * @ru Получает значение из кэша по ключу.
22
- *
23
- * @template T
24
- * @param key Cache key
25
- * @returns Cached value or undefined if not found
22
+ * @param key - The cache key.
23
+ * @returns The cached value or undefined if not found or expired.
26
24
  */
27
25
  get(key) {
28
- return this.cache.get(key)?.data;
26
+ const entry = this.storage.get(key);
27
+ if (!entry)
28
+ return undefined;
29
+ const now = Date.now();
30
+ if (now > entry.expiresAt) {
31
+ this.storage.delete(key);
32
+ return undefined;
33
+ }
34
+ if (this.updateAgeOnGet) {
35
+ entry.expiresAt = now + this.ttl;
36
+ // Move to end for LRU
37
+ this.storage.delete(key);
38
+ this.storage.set(key, entry);
39
+ }
40
+ return entry.data;
29
41
  }
30
42
  /**
31
- * @en Stores value in cache.
43
+ * @en Stores a value in the cache.
32
44
  * @ru Сохраняет значение в кэш.
33
- *
34
- * @template T
35
- * @param key Cache key
36
- * @param value Value to store
45
+ * @param key - The cache key.
46
+ * @param value - The data to store.
37
47
  */
38
48
  set(key, value) {
39
- this.cache.set(key, {
49
+ const now = Date.now();
50
+ if (this.storage.has(key)) {
51
+ this.storage.delete(key);
52
+ }
53
+ else if (this.storage.size >= this.maxSize) {
54
+ const oldestKey = this.storage.keys().next().value;
55
+ if (oldestKey !== undefined)
56
+ this.storage.delete(oldestKey);
57
+ }
58
+ this.storage.set(key, {
40
59
  data: value,
60
+ expiresAt: now + this.ttl,
41
61
  });
42
62
  }
43
63
  /**
44
- * @en Retrieves cached entry with metadata (etag, lastModified).
64
+ * @en Retrieves a cache entry along with its metadata (etag, lastModified).
45
65
  * @ru Получает запись кэша вместе с метаданными (etag, lastModified).
46
- *
47
- * @template T
48
- * @param key Cache key
49
- * @returns Cached entry with metadata or undefined
66
+ * @param key - The cache key.
67
+ * @returns The cache entry with metadata or undefined if not found or expired.
50
68
  */
51
69
  getWithMetadata(key) {
52
- const entry = this.cache.get(key);
53
- return entry ? entry : undefined;
70
+ const entry = this.storage.get(key);
71
+ if (!entry)
72
+ return undefined;
73
+ const now = Date.now();
74
+ if (now > entry.expiresAt) {
75
+ this.storage.delete(key);
76
+ return undefined;
77
+ }
78
+ if (this.updateAgeOnGet) {
79
+ entry.expiresAt = now + this.ttl;
80
+ this.storage.delete(key);
81
+ this.storage.set(key, entry);
82
+ }
83
+ return {
84
+ data: entry.data,
85
+ etag: entry.etag,
86
+ lastModified: entry.lastModified,
87
+ };
54
88
  }
55
89
  /**
56
- * @en Stores value with optional HTTP metadata (etag, lastModified).
57
- * @ru Сохраняет значение с дополнительными HTTP метаданными (etag, lastModified).
58
- *
59
- * @template T
60
- * @param key Cache key
61
- * @param data Value to store
62
- * @param meta Optional HTTP metadata
90
+ * @en Stores a value with additional HTTP metadata.
91
+ * @ru Сохраняет значение с дополнительными HTTP метаданными.
92
+ * @param key - The cache key.
93
+ * @param data - The response data to store.
94
+ * @param meta - Optional HTTP metadata (etag, lastModified).
63
95
  */
64
96
  setWithMetadata(key, data, meta) {
65
- this.cache.set(key, {
97
+ const now = Date.now();
98
+ if (this.storage.has(key)) {
99
+ this.storage.delete(key);
100
+ }
101
+ else if (this.storage.size >= this.maxSize) {
102
+ const oldestKey = this.storage.keys().next().value;
103
+ if (oldestKey !== undefined) {
104
+ this.storage.delete(oldestKey);
105
+ }
106
+ }
107
+ this.storage.set(key, {
66
108
  data,
67
109
  etag: meta?.etag,
68
110
  lastModified: meta?.lastModified,
111
+ expiresAt: now + this.ttl,
69
112
  });
70
113
  }
71
114
  /**
72
- * @en Checks if key exists in cache.
73
- * @ru Проверяет наличие ключа в кэше.
74
- *
75
- * @param key Cache key
76
- * @returns true if exists, otherwise false
115
+ * @en Checks for the existence of a key in the cache without updating its TTL.
116
+ * @ru Проверяет наличие ключа в кэше без обновления его времени жизни.
117
+ * @param key - The cache key.
118
+ * @returns True if the key exists and is not expired.
77
119
  */
78
120
  has(key) {
79
- return this.cache.has(key);
121
+ const entry = this.storage.get(key);
122
+ if (!entry)
123
+ return false;
124
+ if (Date.now() > entry.expiresAt) {
125
+ this.storage.delete(key);
126
+ return false;
127
+ }
128
+ return true;
80
129
  }
81
130
  /**
82
- * @en Deletes value from cache by key.
131
+ * @en Removes a value from the cache by key.
83
132
  * @ru Удаляет значение из кэша по ключу.
84
- *
85
- * @param key Cache key
86
- * @returns true if value was removed
133
+ * @param key - The cache key.
134
+ * @returns True if the element was removed, false otherwise.
87
135
  */
88
136
  delete(key) {
89
- return this.cache.delete(key);
137
+ return this.storage.delete(key);
90
138
  }
91
139
  /**
92
- * @en Clears entire cache.
140
+ * @en Clears the entire cache.
93
141
  * @ru Очищает весь кэш.
94
142
  */
95
143
  clear() {
96
- this.cache.clear();
144
+ this.storage.clear();
97
145
  }
98
146
  /**
99
- * @en Returns current cache size.
147
+ * @en Returns the current number of items in the cache.
100
148
  * @ru Возвращает текущий размер кэша.
101
149
  */
102
150
  get size() {
103
- return this.cache.size;
151
+ return this.storage.size;
104
152
  }
105
153
  }
106
154
  //# sourceMappingURL=CacheManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CacheManager.js","sourceRoot":"","sources":["../../src/utils/CacheManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IACN,KAAK,CAAoC;IAE1D,YAAY,OAA6B;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC;YACxB,GAAG,EAAE,OAAO,EAAE,OAAO,IAAI,GAAG;YAC5B,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,OAAO;YAC5B,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAI,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAI,GAAW,EAAE,KAAQ;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAI,GAAW;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,CAAC,CAAE,KAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC;IAED;;;;;;;;OAQG;IACH,eAAe,CACb,GAAW,EACX,IAAO,EACP,IAGC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,IAAI;YACJ,IAAI,EAAE,IAAI,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI,EAAE,YAAY;SACjC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"CacheManager.js","sourceRoot":"","sources":["../../src/utils/CacheManager.ts"],"names":[],"mappings":"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"}