@hyperttp/cache 1.0.3 → 1.0.4

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/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { withCache } from "./plugin.js";
2
+ export type * from "./types/cache.js";
3
+ export * from "./utils/CacheManager.js";
4
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,mBAAmB,kBAAkB,CAAC;AACtC,cAAc,yBAAyB,CAAC"}
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { withCache } from "./plugin.js";
2
+ export * from "./utils/CacheManager.js";
3
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,cAAc,yBAAyB,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "@hyperttp/cache",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "High-performance LRU caching plugin for Hyperttp client",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "files": [
9
- "dist"
10
- ],
6
+ "main": "./index.js",
7
+ "types": "./index.d.ts",
11
8
  "keywords": [
12
9
  "hyperttp"
13
10
  ],
@@ -17,10 +14,8 @@
17
14
  "type": "git",
18
15
  "url": "git+https://github.com/IT-IF-OR/hyperttp-cache.git"
19
16
  },
20
- "peerDependencies": {
21
- "@hyperttp/core": "^1.0.5"
22
- },
23
17
  "dependencies": {
18
+ "@hyperttp/core": "^1.1.2",
24
19
  "lru-cache": "^11.5.0"
25
20
  }
26
- }
21
+ }
@@ -1,9 +1,8 @@
1
1
  import type { HyperCore, HyperPlugin } from "@hyperttp/core";
2
2
  import type { CacheManagerOptions } from "./types/cache.js";
3
- interface CacheableHyperCore extends HyperCore {
3
+ export interface CacheableHyperCore extends HyperCore {
4
4
  clearCache?: () => void;
5
5
  }
6
- export declare function withCache(client: HyperCore, options: CacheManagerOptions): CacheableHyperCore;
7
6
  declare module "@hyperttp/core" {
8
7
  interface HyperttpPluginsExtension {
9
8
  cache?: CacheManagerOptions & {
@@ -11,6 +10,5 @@ declare module "@hyperttp/core" {
11
10
  };
12
11
  }
13
12
  }
14
- export declare const CachePlugin: HyperPlugin;
15
- export {};
13
+ export declare function withCache(): HyperPlugin;
16
14
  //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAmB,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,OAAO,QAAQ,gBAAgB,CAAC;IAC9B,UAAU,wBAAwB;QAChC,KAAK,CAAC,EAAE,mBAAmB,GAAG;YAC5B,OAAO,EAAE,OAAO,CAAC;SAClB,CAAC;KACH;CACF;AAED,wBAAgB,SAAS,IAAI,WAAW,CA+DvC"}
package/plugin.js ADDED
@@ -0,0 +1,52 @@
1
+ import { CacheManager } from "./utils/CacheManager.js";
2
+ export function withCache() {
3
+ let cache;
4
+ return {
5
+ name: "hyperttp-cache",
6
+ phase: "PREPARE",
7
+ enabled: (config) => !!config.cache?.enabled,
8
+ setup(core, config) {
9
+ cache = new CacheManager(config.cache);
10
+ core.clearCache = () => cache.clear();
11
+ if (core && typeof core.getStats === "function") {
12
+ const originalGetStats = core.getStats.bind(core);
13
+ core.getStats = () => ({
14
+ ...originalGetStats(),
15
+ cacheSize: cache?.size ?? 0,
16
+ });
17
+ }
18
+ },
19
+ wrapDispatch: (next) => {
20
+ return async (req) => {
21
+ if (req.method !== "GET")
22
+ return next(req);
23
+ const cached = await cache.get(req.url);
24
+ if (cached !== undefined) {
25
+ return (typeof cached.clone === "function"
26
+ ? cached.clone()
27
+ : cached);
28
+ }
29
+ const result = await next(req);
30
+ if (result !== undefined) {
31
+ const valueToCache = typeof result.clone === "function"
32
+ ? result.clone()
33
+ : result;
34
+ const headers = result.headers;
35
+ if (headers) {
36
+ const etag = headers["etag"] || headers["ETag"];
37
+ const lastModified = headers["last-modified"] || headers["Last-Modified"];
38
+ cache.setWithMetadata(req.url, valueToCache, {
39
+ etag: typeof etag === "string" ? etag : undefined,
40
+ lastModified: typeof lastModified === "string" ? lastModified : undefined,
41
+ });
42
+ }
43
+ else {
44
+ cache.set(req.url, valueToCache);
45
+ }
46
+ }
47
+ return result;
48
+ };
49
+ },
50
+ };
51
+ }
52
+ //# sourceMappingURL=plugin.js.map
package/plugin.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAcvD,MAAM,UAAU,SAAS;IACvB,IAAI,KAAoB,CAAC;IAEzB,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO;QAE5C,KAAK,CAAC,IAAwB,EAAE,MAAM;YACpC,KAAK,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,KAAM,CAAC,CAAC;YAExC,IAAI,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAEtC,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;gBAChD,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClD,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC;oBACrB,GAAG,gBAAgB,EAAE;oBACrB,SAAS,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC;iBAC5B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,OAAO,KAAK,EAAW,GAAoB,EAAc,EAAE;gBACzD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK;oBAAE,OAAO,IAAI,CAAC,GAAG,CAAe,CAAC;gBAEzD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,OAAO,CACL,OAAQ,MAAc,CAAC,KAAK,KAAK,UAAU;wBACzC,CAAC,CAAE,MAAc,CAAC,KAAK,EAAE;wBACzB,CAAC,CAAC,MAAM,CACN,CAAC;gBACT,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;gBAE/B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM,YAAY,GAChB,OAAQ,MAAc,CAAC,KAAK,KAAK,UAAU;wBACzC,CAAC,CAAE,MAAc,CAAC,KAAK,EAAE;wBACzB,CAAC,CAAC,MAAM,CAAC;oBAEb,MAAM,OAAO,GAAI,MAAc,CAAC,OAAO,CAAC;oBACxC,IAAI,OAAO,EAAE,CAAC;wBACZ,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;wBAChD,MAAM,YAAY,GAChB,OAAO,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;wBAEvD,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,EAAE;4BAC3C,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;4BACjD,YAAY,EACV,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;yBAC9D,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;gBAED,OAAO,MAAW,CAAC;YACrB,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 IT IF OR
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/README.md DELETED
@@ -1,96 +0,0 @@
1
- # @hyperttp/cache
2
-
3
- Высокопроизводительный плагин кэширования для HTTP-клиента **Hyperttp**,
4
- работающий на базе `lru-cache`.
5
- Перехватывает идемпотентные запросы на фазе управления (`CONTROL`),
6
- сводя к нулю нагрузку на сеть при повторных вызовах.
7
-
8
- ## Особенности
9
-
10
- - ⚡ **Нулевая задержка**: Проверяет кэш на фазе `CONTROL`,
11
- полностью минуя сетевой стек.
12
- - 📦 **LRU Стратегия**:
13
- Автоматически вытесняет старые данные при достижении лимитов (благодаря `lru-cache`).
14
- - 📊 **Прозрачная статистика**: Интегрируется в системный вызов `client.getStats()`,
15
- добавляя метрику `cacheSize`.
16
- - 🧹 **Ручное управление**:
17
- Добавляет метод `client.clearCache()` для принудительного сброса данных.
18
- - 🔒 **Строгая типизация**:
19
- Полная поддержка TypeScript «из коробки» через Module Augmentation.
20
-
21
- ## Установка
22
-
23
- ```bash
24
- # Использованием bun (рекомендуется)
25
- bun add @hyperttp/cache
26
-
27
- # Или через npm/pnpm
28
- npm install @hyperttp/cache
29
-
30
- ```
31
-
32
- ## Использование
33
-
34
- Плагин автоматически обнаруживается менеджером плагинов `Hyperttp`
35
- (если настроен автоскан `package.json`), либо его можно передать явно.
36
-
37
- ### Настройка при инициализации клиента
38
-
39
- ```typescript
40
- import { HyperClient } from "@hyperttp/core";
41
- // Импорт нужен для того, чтобы TypeScript подтянул расширение типов для HttpClientOptions
42
- import "@hyperttp/cache";
43
-
44
- const client = new HyperClient({
45
- verbose: true,
46
- cache: {
47
- enabled: true,
48
- max: 500, // Максимальное количество объектов в кэше
49
- ttl: 1000 * 60 * 5, // Время жизни кэша (5 минут)
50
- }
51
- });
52
-
53
- // Первый запрос пойдет в сеть
54
- const data1 = await client.get("https://api.example.com/data");
55
-
56
- // Второй запрос вернется мгновенно из кэша
57
- const data2 = await client.get("https://api.example.com/data");
58
-
59
- ```
60
-
61
- ### Метрики и управление кэшем
62
-
63
- Плагин динамически расширяет инстанс ядра, добавляя методы управления:
64
-
65
- ```typescript
66
- // Получить текущий размер кэша вместе с общими метриками ядра
67
- console.log(client.getStats());
68
- // Выведет: { requests: 2, ..., cacheSize: 1 }
69
-
70
- // Полная очистка кэша вручную
71
- (client as any).clearCache();
72
-
73
- ```
74
-
75
- ## Как это работает (Архитектура)
76
-
77
- Плагин встраивается в «луковичную» (onion) архитектуру запроса на фазе **`CONTROL`**:
78
-
79
- ```mermaid
80
- graph LR
81
- Req([Запрос]) --> MONITOR --> LOGIC --> CONTROL{Проверка кэша}
82
-
83
- CONTROL -- Кэш-хит --> Return([Возврат данных])
84
- CONTROL -- Кэш-мисс --> FORMAT --> NETWORK --> Save[Запись в Кэш] --> Return
85
-
86
- style CONTROL fill:#f9f,stroke:#333,stroke-width:2px
87
- style Return fill:#bbf,stroke:#333,stroke-width:2px
88
- ```
89
-
90
- Он перехватывает исключительно `GET` запросы (проверка через флаг `req.isGet`).
91
- Если URL уже есть в памяти, выполнение сетевой цепочки прерывается,
92
- и клиент моментально возвращает сохраненный результат.
93
-
94
- ## Лицензия
95
-
96
- MIT © dirold2
package/dist/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export { withCache, CachePlugin } from "./plugin.js";
2
- export type * from "./types/cache.js";
3
- export * from "./utils/CacheManager.js";
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACrD,mBAAmB,kBAAkB,CAAC;AACtC,cAAc,yBAAyB,CAAC"}
package/dist/index.js DELETED
@@ -1,3 +0,0 @@
1
- export { withCache, CachePlugin } from "./plugin.js";
2
- export * from "./utils/CacheManager.js";
3
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErD,cAAc,yBAAyB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5D,UAAU,kBAAmB,SAAQ,SAAS;IAC5C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,mBAAmB,GAC3B,kBAAkB,CA0BpB;AAED,OAAO,QAAQ,gBAAgB,CAAC;IAC9B,UAAU,wBAAwB;QAChC,KAAK,CAAC,EAAE,mBAAmB,GAAG;YAC5B,OAAO,EAAE,OAAO,CAAC;SAClB,CAAC;KACH;CACF;AAED,eAAO,MAAM,WAAW,EAAE,WAQzB,CAAC"}
package/dist/plugin.js DELETED
@@ -1,34 +0,0 @@
1
- import { CacheManager } from "./utils/CacheManager.js";
2
- export function withCache(client, options) {
3
- const cache = new CacheManager(options);
4
- const next = client.dispatch;
5
- const originalGetStats = client.getStats.bind(client);
6
- client.getStats = () => ({
7
- ...originalGetStats(),
8
- cacheSize: cache.size ?? 0,
9
- });
10
- client.dispatch = async (req) => {
11
- if (!req.isGet)
12
- return next(req);
13
- const urlString = typeof req.url === "string" ? req.url : req.url.getURL();
14
- const cached = await cache.get(urlString);
15
- if (cached !== undefined)
16
- return cached;
17
- const result = await next(req);
18
- if (result !== undefined)
19
- cache.set(urlString, result);
20
- return result;
21
- };
22
- const extendedClient = client;
23
- extendedClient.clearCache = () => cache.clear();
24
- return extendedClient;
25
- }
26
- export const CachePlugin = {
27
- name: "hyperttp-cache",
28
- phase: "CONTROL",
29
- enabled: (config) => !!config.cache?.enabled,
30
- apply: (client, config) => {
31
- return withCache(client, config.cache);
32
- },
33
- };
34
- //# sourceMappingURL=plugin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAMvD,MAAM,UAAU,SAAS,CACvB,MAAiB,EACjB,OAA4B;IAE5B,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC7B,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEtD,MAAM,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC;QACvB,GAAG,gBAAgB,EAAE;QACrB,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,MAAM,CAAC,QAAQ,GAAG,KAAK,EAAW,GAAoB,EAAc,EAAE;QACpE,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,GAAG,CAAM,CAAC;QAEtC,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAW,CAAC;QAE7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO,MAAW,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,MAA4B,CAAC;IACpD,cAAc,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAEhD,OAAO,cAAc,CAAC;AACxB,CAAC;AAUD,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,IAAI,EAAE,gBAAgB;IACtB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,CAAC,MAAyB,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO;IAE/D,KAAK,EAAE,CAAC,MAAiB,EAAE,MAAyB,EAAE,EAAE;QACtD,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,KAAM,CAAC,CAAC;IAC1C,CAAC;CACF,CAAC"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes