@hyperttp/cache 1.1.1 → 1.1.6

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.6",
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,52 @@
1
- import type { HyperPlugin } from "@hyperttp/types";
2
- import type { CacheManagerOptions } from "./types/cache.js";
1
+ import { CacheManagerOptions, LightweightResponse } from "./types/cache.js";
3
2
  import { CacheManager } from "./utils/CacheManager.js";
3
+ import type { HyperPlugin } from "@hyperttp/types";
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;
15
- getStats?(): Record<string, any>;
16
49
  }
17
50
  }
18
- /**
19
- * @ru Фабрика плагина кэширования и дедупликации конкурентных запросов для HyperCore.
20
- * @en Cache management and concurrent request deduplication plugin factory for HyperCore.
21
- * @returns Модуль расширения ядра в рамках линейного жизненного цикла. / Configured extension plugin container.
22
- */
23
- export declare function withCache(): HyperPlugin;
51
+ export declare function withCache(options?: CacheManagerOptions): HyperPlugin;
24
52
  //# 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,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,KAAK,EAGV,WAAW,EAEZ,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,aAAa;QACrB;;;WAGG;QACH,KAAK,CAAC,EAAE,YAAY,CAAC,mBAAmB,CAAC,CAAC;KAC3C;IACD;;;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;KAChC;CACF;AAUD,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,WAAW,CAiIpE"}
package/plugin.js CHANGED
@@ -1,156 +1,103 @@
1
1
  import { CacheManager } from "./utils/CacheManager.js";
2
- /**
3
- * @ru Фабрика плагина кэширования и дедупликации конкурентных запросов для HyperCore.
4
- * @en Cache management and concurrent request deduplication plugin factory for HyperCore.
5
- * @returns Модуль расширения ядра в рамках линейного жизненного цикла. / Configured extension plugin container.
6
- */
7
- export function withCache() {
8
- /**
9
- * @private
10
- * @ru Изолированный инстанс менеджера кэша для текущего клиента.
11
- * @en Isolated cache manager orchestration instance allocated for the target client.
12
- */
2
+ import { createHttpResponse } from "./utils/createHttpResponse.js";
3
+ export function withCache(options) {
4
+ if (options?.enabled === false) {
5
+ return { name: "hyperttp-cache" };
6
+ }
13
7
  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
- */
8
+ const allowedMethods = new Set(options?.methods
9
+ ? options.methods.map((m) => m.toUpperCase())
10
+ : ["GET", "HEAD"]);
25
11
  const inFlight = new Map();
26
12
  return {
27
13
  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
- enabled: (config) => {
35
- return !!config.cache?.enabled;
36
- },
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
- setup(ctx) {
43
- const { core, config } = ctx;
44
- cache = new CacheManager(config?.cache);
45
- ctx.cache = cache;
46
- const methods = config?.cache?.methods ?? ["GET"];
47
- allowedMethods = new Set(methods.map((m) => m.toUpperCase()));
48
- if (core && typeof core.getStats === "function") {
49
- const originalGetStats = core.getStats;
50
- core.getStats = function () {
51
- const stats = originalGetStats.call(this);
52
- if (stats) {
53
- stats.cacheSize = cache.size;
54
- }
55
- return stats;
56
- };
57
- }
58
- core.clearCache = (key) => {
59
- return key ? cache.delete(key) : cache.clear();
60
- };
14
+ setup() {
15
+ cache = new CacheManager({
16
+ maxSize: options?.maxSize ?? 1000,
17
+ ttl: options?.ttl ?? 300_000,
18
+ updateAgeOnGet: options?.updateAgeOnGet ?? true,
19
+ });
61
20
  },
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)) {
21
+ onRequest(req) {
22
+ if (!allowedMethods.has(req.method.toUpperCase()))
74
23
  return;
75
- }
76
24
  const cacheKey = req.url;
77
25
  const cachedEntry = cache.getWithMetadata(cacheKey);
78
- if (cachedEntry !== undefined &&
79
- !cachedEntry.etag &&
80
- !cachedEntry.lastModified) {
81
- return cachedEntry.data.clone();
26
+ if (cachedEntry && !cachedEntry.etag && !cachedEntry.lastModified) {
27
+ return createHttpResponse(cachedEntry.data);
82
28
  }
83
- // Частичный кэш-хит, подмешиваем заголовки проверки свежести
84
- if (cachedEntry !== undefined) {
29
+ if (cachedEntry) {
85
30
  req.headers = { ...req.headers };
86
31
  if (cachedEntry.etag)
87
32
  req.headers["if-none-match"] = cachedEntry.etag;
88
- if (cachedEntry.lastModified)
33
+ if (cachedEntry.lastModified) {
89
34
  req.headers["if-modified-since"] = cachedEntry.lastModified;
35
+ }
90
36
  }
91
37
  const currentInFlight = inFlight.get(cacheKey);
92
38
  if (currentInFlight) {
93
- return currentInFlight.promise.then((res) => res.clone());
39
+ return new Promise((resolve, reject) => {
40
+ currentInFlight.listeners.push({ resolve, reject });
41
+ });
94
42
  }
95
- let resolveFn;
96
- let rejectFn;
97
- const promise = new Promise((res, rej) => {
98
- resolveFn = res;
99
- rejectFn = rej;
100
- });
101
- promise.catch(() => { });
102
- inFlight.set(cacheKey, { promise, resolve: resolveFn, reject: rejectFn });
43
+ inFlight.set(cacheKey, { listeners: [], timestamp: Date.now() });
103
44
  },
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) {
45
+ onResponse(res, req) {
46
+ if (!req)
47
+ return;
111
48
  const cacheKey = req.url;
112
49
  const trigger = inFlight.get(cacheKey);
113
- if (!trigger) {
114
- return;
115
- }
116
- 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;
50
+ if (res.status === 304) {
51
+ if (res.body &&
52
+ typeof res.body.cancel === "function") {
53
+ res.body.cancel().catch(() => { });
54
+ }
55
+ const cachedEntry = cache.getWithMetadata(cacheKey);
56
+ if (cachedEntry) {
57
+ const restoredRes = createHttpResponse(cachedEntry.data);
58
+ res.status = restoredRes.status;
59
+ res.headers = restoredRes.headers;
60
+ res.body = restoredRes.body;
61
+ if (trigger) {
62
+ inFlight.delete(cacheKey);
63
+ trigger.listeners.forEach((l) => l.resolve(restoredRes.clone()));
64
+ }
65
+ return;
66
+ }
67
+ const err = new Error("304 status received, but cache entry is missing");
68
+ if (trigger) {
69
+ inFlight.delete(cacheKey);
70
+ trigger.listeners.forEach((l) => l.reject(err));
71
+ }
72
+ throw err;
124
73
  }
125
74
  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,
75
+ const cleanHeaders = { ...res.headers };
76
+ cache.setWithMetadata(cacheKey, {
77
+ body: res.body,
78
+ status: res.status,
79
+ headers: cleanHeaders,
80
+ url: res.url ?? "",
81
+ }, {
82
+ etag: cleanHeaders["etag"] ?? cleanHeaders["ETag"],
83
+ lastModified: cleanHeaders["last-modified"] ?? cleanHeaders["Last-Modified"],
133
84
  });
134
- trigger.resolve(res.clone());
135
- return;
136
85
  }
137
- trigger.resolve(res.clone());
138
- },
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);
151
86
  if (trigger) {
152
87
  inFlight.delete(cacheKey);
153
- trigger.reject(err);
88
+ if (trigger.listeners.length > 0) {
89
+ const clonedForDependents = res.clone();
90
+ trigger.listeners.forEach((l) => l.resolve(clonedForDependents));
91
+ }
92
+ }
93
+ },
94
+ onError(err, req) {
95
+ if (!req)
96
+ return;
97
+ const trigger = inFlight.get(req.url);
98
+ if (trigger) {
99
+ inFlight.delete(req.url);
100
+ trigger.listeners.forEach((l) => l.reject(err));
154
101
  }
155
102
  },
156
103
  };
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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"}
@@ -0,0 +1,21 @@
1
+ import type { HttpResponse } from "@hyperttp/types";
2
+ import { LightweightResponse } from "../types/cache.js";
3
+ /**
4
+ * @en Reconstructs a full HttpResponse object from a lightweight cache response.
5
+ * @ru Реконструирует полный объект HttpResponse из легковесного ответа кэша.
6
+ *
7
+ * @param snapshot - Lightweight response object containing cached data.
8
+ * @returns A fully compatible HttpResponse object with methods like .text(), .json(), and .clone().
9
+ *
10
+ * @example
11
+ * const cached = {
12
+ * status: 200,
13
+ * headers: { 'content-type': 'application/json' },
14
+ * url: 'https://api.example.com/data',
15
+ * body: { id: 1, name: 'John' }
16
+ * };
17
+ * const response = createHttpResponse(cached);
18
+ * const data = await response.json(); // { id: 1, name: 'John' }
19
+ */
20
+ export declare function createHttpResponse(snapshot: LightweightResponse<unknown>): HttpResponse<unknown>;
21
+ //# sourceMappingURL=createHttpResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createHttpResponse.d.ts","sourceRoot":"","sources":["../../src/utils/createHttpResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,GACrC,YAAY,CAAC,OAAO,CAAC,CA6CvB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @en Reconstructs a full HttpResponse object from a lightweight cache response.
3
+ * @ru Реконструирует полный объект HttpResponse из легковесного ответа кэша.
4
+ *
5
+ * @param snapshot - Lightweight response object containing cached data.
6
+ * @returns A fully compatible HttpResponse object with methods like .text(), .json(), and .clone().
7
+ *
8
+ * @example
9
+ * const cached = {
10
+ * status: 200,
11
+ * headers: { 'content-type': 'application/json' },
12
+ * url: 'https://api.example.com/data',
13
+ * body: { id: 1, name: 'John' }
14
+ * };
15
+ * const response = createHttpResponse(cached);
16
+ * const data = await response.json(); // { id: 1, name: 'John' }
17
+ */
18
+ export function createHttpResponse(snapshot) {
19
+ return {
20
+ status: snapshot.status,
21
+ headers: { ...snapshot.headers },
22
+ url: snapshot.url,
23
+ body: snapshot.body,
24
+ text() {
25
+ if (typeof snapshot.body === "string") {
26
+ return Promise.resolve(snapshot.body);
27
+ }
28
+ try {
29
+ return Promise.resolve(JSON.stringify(snapshot.body));
30
+ }
31
+ catch {
32
+ return Promise.resolve("");
33
+ }
34
+ },
35
+ json() {
36
+ return Promise.resolve(snapshot.body);
37
+ },
38
+ dump() {
39
+ return Promise.resolve();
40
+ },
41
+ clone() {
42
+ let clonedBody = snapshot.body;
43
+ if (snapshot.body && typeof snapshot.body === "object") {
44
+ if (!(snapshot.body instanceof ReadableStream)) {
45
+ try {
46
+ clonedBody = structuredClone(snapshot.body);
47
+ }
48
+ catch {
49
+ clonedBody = JSON.parse(JSON.stringify(snapshot.body));
50
+ }
51
+ }
52
+ }
53
+ return createHttpResponse({
54
+ ...snapshot,
55
+ body: clonedBody,
56
+ });
57
+ },
58
+ };
59
+ }
60
+ //# sourceMappingURL=createHttpResponse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createHttpResponse.js","sourceRoot":"","sources":["../../src/utils/createHttpResponse.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAsC;IAEtC,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,OAAO,EAAE,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE;QAChC,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;QAEnB,IAAI;YACF,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI;YACF,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAS,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI;YACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK;YACH,IAAI,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;YAE/B,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,YAAY,cAAc,CAAC,EAAE,CAAC;oBAC/C,IAAI,CAAC;wBACH,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC9C,CAAC;oBAAC,MAAM,CAAC;wBACP,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,kBAAkB,CAAC;gBACxB,GAAG,QAAQ;gBACX,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}