rust-node-cache 0.2.0 → 0.2.1

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
@@ -44,6 +44,25 @@ Works with both **ESM** and **CommonJS**, and requires **Node.js 18+**.
44
44
 
45
45
  ---
46
46
 
47
+ ## Supported platforms
48
+
49
+ Prebuilt binaries are published for:
50
+
51
+ | OS | Architecture | Triple |
52
+ | ------- | --------------------- | ---------------------------- |
53
+ | macOS | arm64 | `aarch64-apple-darwin` |
54
+ | macOS | x64 | `x86_64-apple-darwin` |
55
+ | Linux | x64 (glibc) | `x86_64-unknown-linux-gnu` |
56
+ | Linux | arm64 (glibc) | `aarch64-unknown-linux-gnu` |
57
+ | Linux | x64 (musl, Alpine) | `x86_64-unknown-linux-musl` |
58
+ | Linux | arm64 (musl, Alpine) | `aarch64-unknown-linux-musl` |
59
+ | Windows | x64 | `x86_64-pc-windows-msvc` |
60
+
61
+ Every release is installed from the packed tarball and exercised on each of these platforms
62
+ in CI before it is published.
63
+
64
+ ---
65
+
47
66
  ## Quick Start
48
67
 
49
68
  ```ts
package/binding.d.ts CHANGED
@@ -4,32 +4,32 @@
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
6
  /**
7
- * Opções do construtor:
7
+ * Constructor options:
8
8
  * `new Cache({ maxSize, evictionPolicy, cleanupIntervalSeconds })`.
9
9
  */
10
10
  export interface CacheOptions {
11
11
  /**
12
- * Limite opcional de chaves. Comportamento ao atingir depende de
13
- * `evictionPolicy`.
12
+ * Optional limit on the number of keys. What happens when it is reached
13
+ * depends on `evictionPolicy`.
14
14
  */
15
15
  maxSize?: number
16
16
  /**
17
- * `"reject"` (padrão) — `set` de chave nova retorna `false` quando cheio;
18
- * `"lru"` — remove a entrada menos recentemente usada e prossegue.
17
+ * `"reject"` (default) — `set` of a new key returns `false` when full;
18
+ * `"lru"` — removes the least recently used entry and goes on.
19
19
  */
20
20
  evictionPolicy?: string
21
21
  /**
22
- * Se definido (> 0), liga uma thread que varre entradas expiradas a cada
23
- * N segundos (expiração em background, além da lazy).
22
+ * When set (> 0), starts a thread that sweeps expired entries every N
23
+ * seconds (background expiration, on top of the lazy one).
24
24
  */
25
25
  cleanupIntervalSeconds?: number
26
26
  }
27
- /** Opções por escrita: `cache.set(key, value, { ttlSeconds })`. */
27
+ /** Per-write options: `cache.set(key, value, { ttlSeconds })`. */
28
28
  export interface SetOptions {
29
- /** Tempo de vida em segundos. Ausente => a entrada não expira por tempo. */
29
+ /** Time to live in seconds. Absent => the entry does not expire by time. */
30
30
  ttlSeconds?: number
31
31
  }
32
- /** Objeto devolvido por `cache.stats()`. Campos `i64` viram `number` no JS. */
32
+ /** Object returned by `cache.stats()`. `i64` fields become `number` in JS. */
33
33
  export interface CacheStatsObject {
34
34
  hits: number
35
35
  misses: number
@@ -40,34 +40,34 @@ export interface CacheStatsObject {
40
40
  size: number
41
41
  }
42
42
  /**
43
- * Cache em memória exposto ao Node como a classe `Cache`.
43
+ * In-memory cache exposed to Node as the `Cache` class.
44
44
  *
45
- * Internamente delega tudo para o `RustCache` (que carrega o `DashMap` e os
46
- * contadores atômicos). Todos os métodos recebem `&self`: como o estado é
47
- * concorrente por dentro, várias chamadas podem rodar em paralelo.
45
+ * It delegates everything to `RustCache` (which holds the `DashMap` and the
46
+ * atomic counters). Every method takes `&self`: the state is concurrent
47
+ * inside, so it is safe to use from several threads (such as the sweeper).
48
48
  */
49
49
  export declare class Cache {
50
- /** `new Cache()` ou `new Cache({ maxSize, evictionPolicy, cleanupIntervalSeconds })`. */
50
+ /** `new Cache()` or `new Cache({ maxSize, evictionPolicy, cleanupIntervalSeconds })`. */
51
51
  constructor(options?: CacheOptions | undefined | null)
52
- /** A política de evicção ativa: `"reject"` ou `"lru"`. */
52
+ /** The active eviction policy: `"reject"` or `"lru"`. */
53
53
  get evictionPolicy(): string
54
54
  /**
55
- * Insere/atualiza uma chave. Retorna `true` em sucesso, `false` se o cache
56
- * estiver cheio (`maxSize`) e a chave for nova.
55
+ * Inserts or updates a key. Returns `true` on success, `false` if the cache
56
+ * is full (`maxSize`) and the key is new.
57
57
  */
58
58
  set(key: string, value: any, options?: SetOptions | undefined | null): boolean
59
- /** Lê uma chave. Retorna o valor ou `null` se ausente/expirada. */
59
+ /** Reads a key. Returns the value, or `null` if missing or expired. */
60
60
  get(key: string): any | null
61
- /** Remove uma chave. Retorna `true` se existia, `false` caso contrário. */
61
+ /** Removes a key. Returns `true` if it existed, `false` otherwise. */
62
62
  delete(key: string): boolean
63
- /** Indica se a chave existe e está válida (não expirada). */
63
+ /** Whether the key exists and is still valid (not expired). */
64
64
  exists(key: string): boolean
65
- /** Esvazia todas as entradas do cache. */
65
+ /** Removes every entry from the cache. */
66
66
  clear(): void
67
- /** Quantidade de chaves armazenadas no momento. */
67
+ /** Number of keys currently stored. */
68
68
  size(): number
69
- /** Varre e remove todas as entradas expiradas. Retorna quantas removeu. */
69
+ /** Sweeps and removes every expired entry. Returns how many it removed. */
70
70
  cleanupExpired(): number
71
- /** Estatísticas acumuladas + tamanho atual. */
71
+ /** Accumulated statistics + the current size. */
72
72
  stats(): CacheStatsObject
73
73
  }
@@ -2,32 +2,32 @@ import { Request, Response, NextFunction } from 'express';
2
2
  import { Cache } from './index.mjs';
3
3
 
4
4
  /**
5
- * Integração com Express: cache de respostas JSON.
5
+ * Express integration: caching of JSON responses.
6
6
  *
7
- * Uso:
7
+ * Usage:
8
8
  * import { Cache } from "rust-node-cache";
9
9
  * import { cacheMiddleware } from "rust-node-cache/express";
10
10
  *
11
11
  * const cache = new Cache();
12
12
  * app.get("/users/:id", cacheMiddleware({ cache, ttlSeconds: 60 }), handler);
13
13
  *
14
- * O middleware intercepta `res.json`: num HIT responde direto do cache; num
15
- * MISS deixa o handler rodar e guarda o corpo da resposta (apenas em 2xx).
14
+ * The middleware intercepts `res.json`: on a HIT it responds straight from the
15
+ * cache; on a MISS it lets the handler run and stores the response body (2xx only).
16
16
  */
17
17
 
18
18
  interface CacheMiddlewareOptions {
19
- /** Instância de cache a usar. */
19
+ /** Cache instance to use. */
20
20
  cache: Cache;
21
- /** TTL aplicado às respostas guardadas (em segundos). */
21
+ /** TTL applied to stored responses (in seconds). */
22
22
  ttlSeconds?: number;
23
- /** Métodos HTTP elegíveis para cache. Padrão: `["GET"]`. */
23
+ /** HTTP methods eligible for caching. Default: `["GET"]`. */
24
24
  methods?: string[];
25
- /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */
25
+ /** Builds the cache key from the request. Default: `METHOD:url`. */
26
26
  keyGenerator?: (req: Request) => string;
27
27
  }
28
28
  /**
29
- * Cria um middleware Express que cacheia respostas JSON. Adiciona o cabeçalho
30
- * `X-Cache: HIT|MISS` para facilitar a observabilidade.
29
+ * Creates an Express middleware that caches JSON responses. Adds an
30
+ * `X-Cache: HIT|MISS` header for observability.
31
31
  */
32
32
  declare function cacheMiddleware(options: CacheMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => void;
33
33
 
package/dist/express.d.ts CHANGED
@@ -2,32 +2,32 @@ import { Request, Response, NextFunction } from 'express';
2
2
  import { Cache } from './index.js';
3
3
 
4
4
  /**
5
- * Integração com Express: cache de respostas JSON.
5
+ * Express integration: caching of JSON responses.
6
6
  *
7
- * Uso:
7
+ * Usage:
8
8
  * import { Cache } from "rust-node-cache";
9
9
  * import { cacheMiddleware } from "rust-node-cache/express";
10
10
  *
11
11
  * const cache = new Cache();
12
12
  * app.get("/users/:id", cacheMiddleware({ cache, ttlSeconds: 60 }), handler);
13
13
  *
14
- * O middleware intercepta `res.json`: num HIT responde direto do cache; num
15
- * MISS deixa o handler rodar e guarda o corpo da resposta (apenas em 2xx).
14
+ * The middleware intercepts `res.json`: on a HIT it responds straight from the
15
+ * cache; on a MISS it lets the handler run and stores the response body (2xx only).
16
16
  */
17
17
 
18
18
  interface CacheMiddlewareOptions {
19
- /** Instância de cache a usar. */
19
+ /** Cache instance to use. */
20
20
  cache: Cache;
21
- /** TTL aplicado às respostas guardadas (em segundos). */
21
+ /** TTL applied to stored responses (in seconds). */
22
22
  ttlSeconds?: number;
23
- /** Métodos HTTP elegíveis para cache. Padrão: `["GET"]`. */
23
+ /** HTTP methods eligible for caching. Default: `["GET"]`. */
24
24
  methods?: string[];
25
- /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */
25
+ /** Builds the cache key from the request. Default: `METHOD:url`. */
26
26
  keyGenerator?: (req: Request) => string;
27
27
  }
28
28
  /**
29
- * Cria um middleware Express que cacheia respostas JSON. Adiciona o cabeçalho
30
- * `X-Cache: HIT|MISS` para facilitar a observabilidade.
29
+ * Creates an Express middleware that caches JSON responses. Adds an
30
+ * `X-Cache: HIT|MISS` header for observability.
31
31
  */
32
32
  declare function cacheMiddleware(options: CacheMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => void;
33
33
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/express.ts"],"sourcesContent":["/**\n * Integração com Express: cache de respostas JSON.\n *\n * Uso:\n * import { Cache } from \"rust-node-cache\";\n * import { cacheMiddleware } from \"rust-node-cache/express\";\n *\n * const cache = new Cache();\n * app.get(\"/users/:id\", cacheMiddleware({ cache, ttlSeconds: 60 }), handler);\n *\n * O middleware intercepta `res.json`: num HIT responde direto do cache; num\n * MISS deixa o handler rodar e guarda o corpo da resposta (apenas em 2xx).\n */\n\nimport type { Request, Response, NextFunction } from \"express\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheMiddlewareOptions {\n /** Instância de cache a usar. */\n cache: Cache;\n /** TTL aplicado às respostas guardadas (em segundos). */\n ttlSeconds?: number;\n /** Métodos HTTP elegíveis para cache. Padrão: `[\"GET\"]`. */\n methods?: string[];\n /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */\n keyGenerator?: (req: Request) => string;\n}\n\n/**\n * Cria um middleware Express que cacheia respostas JSON. Adiciona o cabeçalho\n * `X-Cache: HIT|MISS` para facilitar a observabilidade.\n */\nexport function cacheMiddleware(options: CacheMiddlewareOptions) {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: Request) => `${req.method}:${req.originalUrl}`);\n\n return function rustNodeCache(\n req: Request,\n res: Response,\n next: NextFunction,\n ): void {\n if (!methods.includes(req.method)) {\n next();\n return;\n }\n\n const key = keyGenerator(req);\n const cached = cache.get(key);\n if (cached !== null) {\n res.setHeader(\"X-Cache\", \"HIT\");\n res.json(cached);\n return;\n }\n\n res.setHeader(\"X-Cache\", \"MISS\");\n const originalJson = res.json.bind(res);\n res.json = (body: unknown): Response => {\n // Só guardamos respostas bem-sucedidas (2xx).\n if (res.statusCode >= 200 && res.statusCode < 300) {\n cache.set(key, body, ttlSeconds ? { ttlSeconds } : undefined);\n }\n return originalJson(body);\n };\n\n next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCO,SAAS,gBAAgB,SAAiC;AAC/D,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAiB,GAAG,IAAI,MAAM,IAAI,IAAI,WAAW;AAE7E,SAAO,SAAS,cACd,KACA,KACA,MACM;AACN,QAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,GAAG;AACjC,WAAK;AACL;AAAA,IACF;AAEA,UAAM,MAAM,aAAa,GAAG;AAC5B,UAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,QAAI,WAAW,MAAM;AACnB,UAAI,UAAU,WAAW,KAAK;AAC9B,UAAI,KAAK,MAAM;AACf;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,MAAM;AAC/B,UAAM,eAAe,IAAI,KAAK,KAAK,GAAG;AACtC,QAAI,OAAO,CAAC,SAA4B;AAEtC,UAAI,IAAI,cAAc,OAAO,IAAI,aAAa,KAAK;AACjD,cAAM,IAAI,KAAK,MAAM,aAAa,EAAE,WAAW,IAAI,MAAS;AAAA,MAC9D;AACA,aAAO,aAAa,IAAI;AAAA,IAC1B;AAEA,SAAK;AAAA,EACP;AACF;","names":[]}
1
+ {"version":3,"sources":["../js/express.ts"],"sourcesContent":["/**\n * Express integration: caching of JSON responses.\n *\n * Usage:\n * import { Cache } from \"rust-node-cache\";\n * import { cacheMiddleware } from \"rust-node-cache/express\";\n *\n * const cache = new Cache();\n * app.get(\"/users/:id\", cacheMiddleware({ cache, ttlSeconds: 60 }), handler);\n *\n * The middleware intercepts `res.json`: on a HIT it responds straight from the\n * cache; on a MISS it lets the handler run and stores the response body (2xx only).\n */\n\nimport type { Request, Response, NextFunction } from \"express\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheMiddlewareOptions {\n /** Cache instance to use. */\n cache: Cache;\n /** TTL applied to stored responses (in seconds). */\n ttlSeconds?: number;\n /** HTTP methods eligible for caching. Default: `[\"GET\"]`. */\n methods?: string[];\n /** Builds the cache key from the request. Default: `METHOD:url`. */\n keyGenerator?: (req: Request) => string;\n}\n\n/**\n * Creates an Express middleware that caches JSON responses. Adds an\n * `X-Cache: HIT|MISS` header for observability.\n */\nexport function cacheMiddleware(options: CacheMiddlewareOptions) {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: Request) => `${req.method}:${req.originalUrl}`);\n\n return function rustNodeCache(\n req: Request,\n res: Response,\n next: NextFunction,\n ): void {\n if (!methods.includes(req.method)) {\n next();\n return;\n }\n\n const key = keyGenerator(req);\n const cached = cache.get(key);\n if (cached !== null) {\n res.setHeader(\"X-Cache\", \"HIT\");\n res.json(cached);\n return;\n }\n\n res.setHeader(\"X-Cache\", \"MISS\");\n const originalJson = res.json.bind(res);\n res.json = (body: unknown): Response => {\n // Only successful responses (2xx) are stored.\n if (res.statusCode >= 200 && res.statusCode < 300) {\n cache.set(key, body, ttlSeconds ? { ttlSeconds } : undefined);\n }\n return originalJson(body);\n };\n\n next();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCO,SAAS,gBAAgB,SAAiC;AAC/D,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAiB,GAAG,IAAI,MAAM,IAAI,IAAI,WAAW;AAE7E,SAAO,SAAS,cACd,KACA,KACA,MACM;AACN,QAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,GAAG;AACjC,WAAK;AACL;AAAA,IACF;AAEA,UAAM,MAAM,aAAa,GAAG;AAC5B,UAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,QAAI,WAAW,MAAM;AACnB,UAAI,UAAU,WAAW,KAAK;AAC9B,UAAI,KAAK,MAAM;AACf;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,MAAM;AAC/B,UAAM,eAAe,IAAI,KAAK,KAAK,GAAG;AACtC,QAAI,OAAO,CAAC,SAA4B;AAEtC,UAAI,IAAI,cAAc,OAAO,IAAI,aAAa,KAAK;AACjD,cAAM,IAAI,KAAK,MAAM,aAAa,EAAE,WAAW,IAAI,MAAS;AAAA,MAC9D;AACA,aAAO,aAAa,IAAI;AAAA,IAC1B;AAEA,SAAK;AAAA,EACP;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/express.ts"],"sourcesContent":["/**\n * Integração com Express: cache de respostas JSON.\n *\n * Uso:\n * import { Cache } from \"rust-node-cache\";\n * import { cacheMiddleware } from \"rust-node-cache/express\";\n *\n * const cache = new Cache();\n * app.get(\"/users/:id\", cacheMiddleware({ cache, ttlSeconds: 60 }), handler);\n *\n * O middleware intercepta `res.json`: num HIT responde direto do cache; num\n * MISS deixa o handler rodar e guarda o corpo da resposta (apenas em 2xx).\n */\n\nimport type { Request, Response, NextFunction } from \"express\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheMiddlewareOptions {\n /** Instância de cache a usar. */\n cache: Cache;\n /** TTL aplicado às respostas guardadas (em segundos). */\n ttlSeconds?: number;\n /** Métodos HTTP elegíveis para cache. Padrão: `[\"GET\"]`. */\n methods?: string[];\n /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */\n keyGenerator?: (req: Request) => string;\n}\n\n/**\n * Cria um middleware Express que cacheia respostas JSON. Adiciona o cabeçalho\n * `X-Cache: HIT|MISS` para facilitar a observabilidade.\n */\nexport function cacheMiddleware(options: CacheMiddlewareOptions) {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: Request) => `${req.method}:${req.originalUrl}`);\n\n return function rustNodeCache(\n req: Request,\n res: Response,\n next: NextFunction,\n ): void {\n if (!methods.includes(req.method)) {\n next();\n return;\n }\n\n const key = keyGenerator(req);\n const cached = cache.get(key);\n if (cached !== null) {\n res.setHeader(\"X-Cache\", \"HIT\");\n res.json(cached);\n return;\n }\n\n res.setHeader(\"X-Cache\", \"MISS\");\n const originalJson = res.json.bind(res);\n res.json = (body: unknown): Response => {\n // Só guardamos respostas bem-sucedidas (2xx).\n if (res.statusCode >= 200 && res.statusCode < 300) {\n cache.set(key, body, ttlSeconds ? { ttlSeconds } : undefined);\n }\n return originalJson(body);\n };\n\n next();\n };\n}\n"],"mappings":";AAgCO,SAAS,gBAAgB,SAAiC;AAC/D,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAiB,GAAG,IAAI,MAAM,IAAI,IAAI,WAAW;AAE7E,SAAO,SAAS,cACd,KACA,KACA,MACM;AACN,QAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,GAAG;AACjC,WAAK;AACL;AAAA,IACF;AAEA,UAAM,MAAM,aAAa,GAAG;AAC5B,UAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,QAAI,WAAW,MAAM;AACnB,UAAI,UAAU,WAAW,KAAK;AAC9B,UAAI,KAAK,MAAM;AACf;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,MAAM;AAC/B,UAAM,eAAe,IAAI,KAAK,KAAK,GAAG;AACtC,QAAI,OAAO,CAAC,SAA4B;AAEtC,UAAI,IAAI,cAAc,OAAO,IAAI,aAAa,KAAK;AACjD,cAAM,IAAI,KAAK,MAAM,aAAa,EAAE,WAAW,IAAI,MAAS;AAAA,MAC9D;AACA,aAAO,aAAa,IAAI;AAAA,IAC1B;AAEA,SAAK;AAAA,EACP;AACF;","names":[]}
1
+ {"version":3,"sources":["../js/express.ts"],"sourcesContent":["/**\n * Express integration: caching of JSON responses.\n *\n * Usage:\n * import { Cache } from \"rust-node-cache\";\n * import { cacheMiddleware } from \"rust-node-cache/express\";\n *\n * const cache = new Cache();\n * app.get(\"/users/:id\", cacheMiddleware({ cache, ttlSeconds: 60 }), handler);\n *\n * The middleware intercepts `res.json`: on a HIT it responds straight from the\n * cache; on a MISS it lets the handler run and stores the response body (2xx only).\n */\n\nimport type { Request, Response, NextFunction } from \"express\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheMiddlewareOptions {\n /** Cache instance to use. */\n cache: Cache;\n /** TTL applied to stored responses (in seconds). */\n ttlSeconds?: number;\n /** HTTP methods eligible for caching. Default: `[\"GET\"]`. */\n methods?: string[];\n /** Builds the cache key from the request. Default: `METHOD:url`. */\n keyGenerator?: (req: Request) => string;\n}\n\n/**\n * Creates an Express middleware that caches JSON responses. Adds an\n * `X-Cache: HIT|MISS` header for observability.\n */\nexport function cacheMiddleware(options: CacheMiddlewareOptions) {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: Request) => `${req.method}:${req.originalUrl}`);\n\n return function rustNodeCache(\n req: Request,\n res: Response,\n next: NextFunction,\n ): void {\n if (!methods.includes(req.method)) {\n next();\n return;\n }\n\n const key = keyGenerator(req);\n const cached = cache.get(key);\n if (cached !== null) {\n res.setHeader(\"X-Cache\", \"HIT\");\n res.json(cached);\n return;\n }\n\n res.setHeader(\"X-Cache\", \"MISS\");\n const originalJson = res.json.bind(res);\n res.json = (body: unknown): Response => {\n // Only successful responses (2xx) are stored.\n if (res.statusCode >= 200 && res.statusCode < 300) {\n cache.set(key, body, ttlSeconds ? { ttlSeconds } : undefined);\n }\n return originalJson(body);\n };\n\n next();\n };\n}\n"],"mappings":";AAgCO,SAAS,gBAAgB,SAAiC;AAC/D,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAiB,GAAG,IAAI,MAAM,IAAI,IAAI,WAAW;AAE7E,SAAO,SAAS,cACd,KACA,KACA,MACM;AACN,QAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,GAAG;AACjC,WAAK;AACL;AAAA,IACF;AAEA,UAAM,MAAM,aAAa,GAAG;AAC5B,UAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,QAAI,WAAW,MAAM;AACnB,UAAI,UAAU,WAAW,KAAK;AAC9B,UAAI,KAAK,MAAM;AACf;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,MAAM;AAC/B,UAAM,eAAe,IAAI,KAAK,KAAK,GAAG;AACtC,QAAI,OAAO,CAAC,SAA4B;AAEtC,UAAI,IAAI,cAAc,OAAO,IAAI,aAAa,KAAK;AACjD,cAAM,IAAI,KAAK,MAAM,aAAa,EAAE,WAAW,IAAI,MAAS;AAAA,MAC9D;AACA,aAAO,aAAa,IAAI;AAAA,IAC1B;AAEA,SAAK;AAAA,EACP;AACF;","names":[]}
@@ -2,31 +2,31 @@ import { FastifyRequest, FastifyInstance } from 'fastify';
2
2
  import { Cache } from './index.mjs';
3
3
 
4
4
  /**
5
- * Integração com Fastify: cache de respostas JSON via plugin.
5
+ * Fastify integration: caching of JSON responses through a plugin.
6
6
  *
7
- * Uso:
7
+ * Usage:
8
8
  * import { Cache } from "rust-node-cache";
9
9
  * import { cachePlugin } from "rust-node-cache/fastify";
10
10
  *
11
11
  * const cache = new Cache();
12
12
  * fastify.register(cachePlugin, { cache, ttlSeconds: 60 });
13
13
  *
14
- * Fluxo: o hook `onRequest` checa o cache e, num HIT, responde imediatamente
15
- * (curto-circuito). Num MISS, o hook `onSend` guarda o payload serializado.
14
+ * Flow: the `onRequest` hook checks the cache and, on a HIT, responds right away
15
+ * (short-circuit). On a MISS, the `onSend` hook stores the serialized payload.
16
16
  */
17
17
 
18
18
  interface CachePluginOptions {
19
- /** Instância de cache a usar. */
19
+ /** Cache instance to use. */
20
20
  cache: Cache;
21
- /** TTL aplicado às respostas guardadas (em segundos). */
21
+ /** TTL applied to stored responses (in seconds). */
22
22
  ttlSeconds?: number;
23
- /** Métodos HTTP elegíveis para cache. Padrão: `["GET"]`. */
23
+ /** HTTP methods eligible for caching. Default: `["GET"]`. */
24
24
  methods?: string[];
25
- /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */
25
+ /** Builds the cache key from the request. Default: `METHOD:url`. */
26
26
  keyGenerator?: (req: FastifyRequest) => string;
27
27
  }
28
28
  /**
29
- * Plugin Fastify que cacheia respostas JSON. Use com `fastify.register`.
29
+ * Fastify plugin that caches JSON responses. Use it with `fastify.register`.
30
30
  */
31
31
  declare function cachePlugin(fastify: FastifyInstance, options: CachePluginOptions): Promise<void>;
32
32
 
package/dist/fastify.d.ts CHANGED
@@ -2,31 +2,31 @@ import { FastifyRequest, FastifyInstance } from 'fastify';
2
2
  import { Cache } from './index.js';
3
3
 
4
4
  /**
5
- * Integração com Fastify: cache de respostas JSON via plugin.
5
+ * Fastify integration: caching of JSON responses through a plugin.
6
6
  *
7
- * Uso:
7
+ * Usage:
8
8
  * import { Cache } from "rust-node-cache";
9
9
  * import { cachePlugin } from "rust-node-cache/fastify";
10
10
  *
11
11
  * const cache = new Cache();
12
12
  * fastify.register(cachePlugin, { cache, ttlSeconds: 60 });
13
13
  *
14
- * Fluxo: o hook `onRequest` checa o cache e, num HIT, responde imediatamente
15
- * (curto-circuito). Num MISS, o hook `onSend` guarda o payload serializado.
14
+ * Flow: the `onRequest` hook checks the cache and, on a HIT, responds right away
15
+ * (short-circuit). On a MISS, the `onSend` hook stores the serialized payload.
16
16
  */
17
17
 
18
18
  interface CachePluginOptions {
19
- /** Instância de cache a usar. */
19
+ /** Cache instance to use. */
20
20
  cache: Cache;
21
- /** TTL aplicado às respostas guardadas (em segundos). */
21
+ /** TTL applied to stored responses (in seconds). */
22
22
  ttlSeconds?: number;
23
- /** Métodos HTTP elegíveis para cache. Padrão: `["GET"]`. */
23
+ /** HTTP methods eligible for caching. Default: `["GET"]`. */
24
24
  methods?: string[];
25
- /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */
25
+ /** Builds the cache key from the request. Default: `METHOD:url`. */
26
26
  keyGenerator?: (req: FastifyRequest) => string;
27
27
  }
28
28
  /**
29
- * Plugin Fastify que cacheia respostas JSON. Use com `fastify.register`.
29
+ * Fastify plugin that caches JSON responses. Use it with `fastify.register`.
30
30
  */
31
31
  declare function cachePlugin(fastify: FastifyInstance, options: CachePluginOptions): Promise<void>;
32
32
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/fastify.ts"],"sourcesContent":["/**\n * Integração com Fastify: cache de respostas JSON via plugin.\n *\n * Uso:\n * import { Cache } from \"rust-node-cache\";\n * import { cachePlugin } from \"rust-node-cache/fastify\";\n *\n * const cache = new Cache();\n * fastify.register(cachePlugin, { cache, ttlSeconds: 60 });\n *\n * Fluxo: o hook `onRequest` checa o cache e, num HIT, responde imediatamente\n * (curto-circuito). Num MISS, o hook `onSend` guarda o payload serializado.\n */\n\nimport type {\n FastifyInstance,\n FastifyReply,\n FastifyRequest,\n} from \"fastify\";\nimport type { Cache } from \"./index\";\n\nexport interface CachePluginOptions {\n /** Instância de cache a usar. */\n cache: Cache;\n /** TTL aplicado às respostas guardadas (em segundos). */\n ttlSeconds?: number;\n /** Métodos HTTP elegíveis para cache. Padrão: `[\"GET\"]`. */\n methods?: string[];\n /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */\n keyGenerator?: (req: FastifyRequest) => string;\n}\n\n// Guardamos a chave calculada na própria request entre os hooks.\nconst CACHE_KEY = Symbol(\"rustNodeCacheKey\");\n\n/**\n * Plugin Fastify que cacheia respostas JSON. Use com `fastify.register`.\n */\nexport async function cachePlugin(\n fastify: FastifyInstance,\n options: CachePluginOptions,\n): Promise<void> {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: FastifyRequest) => `${req.method}:${req.url}`);\n\n fastify.addHook(\n \"onRequest\",\n (request: FastifyRequest, reply: FastifyReply, done: () => void) => {\n if (!methods.includes(request.method)) {\n done();\n return;\n }\n\n const key = keyGenerator(request);\n const cached = cache.get(key);\n if (cached !== null) {\n reply.header(\"X-Cache\", \"HIT\");\n reply.send(cached);\n return; // não chama done(): a resposta já foi enviada.\n }\n\n reply.header(\"X-Cache\", \"MISS\");\n (request as unknown as Record<symbol, string>)[CACHE_KEY] = key;\n done();\n },\n );\n\n fastify.addHook(\n \"onSend\",\n (\n request: FastifyRequest,\n reply: FastifyReply,\n payload: unknown,\n done: (err: Error | null, value?: unknown) => void,\n ) => {\n const key = (request as unknown as Record<symbol, string | undefined>)[\n CACHE_KEY\n ];\n if (\n key &&\n typeof payload === \"string\" &&\n reply.statusCode >= 200 &&\n reply.statusCode < 300\n ) {\n try {\n cache.set(\n key,\n JSON.parse(payload),\n ttlSeconds ? { ttlSeconds } : undefined,\n );\n } catch {\n // payload não-JSON: simplesmente não cacheia.\n }\n }\n done(null, payload);\n },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCA,IAAM,YAAY,uBAAO,kBAAkB;AAK3C,eAAsB,YACpB,SACA,SACe;AACf,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAwB,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAE5E,UAAQ;AAAA,IACN;AAAA,IACA,CAAC,SAAyB,OAAqB,SAAqB;AAClE,UAAI,CAAC,QAAQ,SAAS,QAAQ,MAAM,GAAG;AACrC,aAAK;AACL;AAAA,MACF;AAEA,YAAM,MAAM,aAAa,OAAO;AAChC,YAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,UAAI,WAAW,MAAM;AACnB,cAAM,OAAO,WAAW,KAAK;AAC7B,cAAM,KAAK,MAAM;AACjB;AAAA,MACF;AAEA,YAAM,OAAO,WAAW,MAAM;AAC9B,MAAC,QAA8C,SAAS,IAAI;AAC5D,WAAK;AAAA,IACP;AAAA,EACF;AAEA,UAAQ;AAAA,IACN;AAAA,IACA,CACE,SACA,OACA,SACA,SACG;AACH,YAAM,MAAO,QACX,SACF;AACA,UACE,OACA,OAAO,YAAY,YACnB,MAAM,cAAc,OACpB,MAAM,aAAa,KACnB;AACA,YAAI;AACF,gBAAM;AAAA,YACJ;AAAA,YACA,KAAK,MAAM,OAAO;AAAA,YAClB,aAAa,EAAE,WAAW,IAAI;AAAA,UAChC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,WAAK,MAAM,OAAO;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../js/fastify.ts"],"sourcesContent":["/**\n * Fastify integration: caching of JSON responses through a plugin.\n *\n * Usage:\n * import { Cache } from \"rust-node-cache\";\n * import { cachePlugin } from \"rust-node-cache/fastify\";\n *\n * const cache = new Cache();\n * fastify.register(cachePlugin, { cache, ttlSeconds: 60 });\n *\n * Flow: the `onRequest` hook checks the cache and, on a HIT, responds right away\n * (short-circuit). On a MISS, the `onSend` hook stores the serialized payload.\n */\n\nimport type {\n FastifyInstance,\n FastifyReply,\n FastifyRequest,\n} from \"fastify\";\nimport type { Cache } from \"./index\";\n\nexport interface CachePluginOptions {\n /** Cache instance to use. */\n cache: Cache;\n /** TTL applied to stored responses (in seconds). */\n ttlSeconds?: number;\n /** HTTP methods eligible for caching. Default: `[\"GET\"]`. */\n methods?: string[];\n /** Builds the cache key from the request. Default: `METHOD:url`. */\n keyGenerator?: (req: FastifyRequest) => string;\n}\n\n// The computed key is kept on the request itself between hooks.\nconst CACHE_KEY = Symbol(\"rustNodeCacheKey\");\n\n/**\n * Fastify plugin that caches JSON responses. Use it with `fastify.register`.\n */\nexport async function cachePlugin(\n fastify: FastifyInstance,\n options: CachePluginOptions,\n): Promise<void> {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: FastifyRequest) => `${req.method}:${req.url}`);\n\n fastify.addHook(\n \"onRequest\",\n (request: FastifyRequest, reply: FastifyReply, done: () => void) => {\n if (!methods.includes(request.method)) {\n done();\n return;\n }\n\n const key = keyGenerator(request);\n const cached = cache.get(key);\n if (cached !== null) {\n reply.header(\"X-Cache\", \"HIT\");\n reply.send(cached);\n return; // done() is not called: the response was already sent.\n }\n\n reply.header(\"X-Cache\", \"MISS\");\n (request as unknown as Record<symbol, string>)[CACHE_KEY] = key;\n done();\n },\n );\n\n fastify.addHook(\n \"onSend\",\n (\n request: FastifyRequest,\n reply: FastifyReply,\n payload: unknown,\n done: (err: Error | null, value?: unknown) => void,\n ) => {\n const key = (request as unknown as Record<symbol, string | undefined>)[\n CACHE_KEY\n ];\n if (\n key &&\n typeof payload === \"string\" &&\n reply.statusCode >= 200 &&\n reply.statusCode < 300\n ) {\n try {\n cache.set(\n key,\n JSON.parse(payload),\n ttlSeconds ? { ttlSeconds } : undefined,\n );\n } catch {\n // non-JSON payload: simply not cached.\n }\n }\n done(null, payload);\n },\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCA,IAAM,YAAY,uBAAO,kBAAkB;AAK3C,eAAsB,YACpB,SACA,SACe;AACf,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAwB,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAE5E,UAAQ;AAAA,IACN;AAAA,IACA,CAAC,SAAyB,OAAqB,SAAqB;AAClE,UAAI,CAAC,QAAQ,SAAS,QAAQ,MAAM,GAAG;AACrC,aAAK;AACL;AAAA,MACF;AAEA,YAAM,MAAM,aAAa,OAAO;AAChC,YAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,UAAI,WAAW,MAAM;AACnB,cAAM,OAAO,WAAW,KAAK;AAC7B,cAAM,KAAK,MAAM;AACjB;AAAA,MACF;AAEA,YAAM,OAAO,WAAW,MAAM;AAC9B,MAAC,QAA8C,SAAS,IAAI;AAC5D,WAAK;AAAA,IACP;AAAA,EACF;AAEA,UAAQ;AAAA,IACN;AAAA,IACA,CACE,SACA,OACA,SACA,SACG;AACH,YAAM,MAAO,QACX,SACF;AACA,UACE,OACA,OAAO,YAAY,YACnB,MAAM,cAAc,OACpB,MAAM,aAAa,KACnB;AACA,YAAI;AACF,gBAAM;AAAA,YACJ;AAAA,YACA,KAAK,MAAM,OAAO;AAAA,YAClB,aAAa,EAAE,WAAW,IAAI;AAAA,UAChC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,WAAK,MAAM,OAAO;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/fastify.ts"],"sourcesContent":["/**\n * Integração com Fastify: cache de respostas JSON via plugin.\n *\n * Uso:\n * import { Cache } from \"rust-node-cache\";\n * import { cachePlugin } from \"rust-node-cache/fastify\";\n *\n * const cache = new Cache();\n * fastify.register(cachePlugin, { cache, ttlSeconds: 60 });\n *\n * Fluxo: o hook `onRequest` checa o cache e, num HIT, responde imediatamente\n * (curto-circuito). Num MISS, o hook `onSend` guarda o payload serializado.\n */\n\nimport type {\n FastifyInstance,\n FastifyReply,\n FastifyRequest,\n} from \"fastify\";\nimport type { Cache } from \"./index\";\n\nexport interface CachePluginOptions {\n /** Instância de cache a usar. */\n cache: Cache;\n /** TTL aplicado às respostas guardadas (em segundos). */\n ttlSeconds?: number;\n /** Métodos HTTP elegíveis para cache. Padrão: `[\"GET\"]`. */\n methods?: string[];\n /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */\n keyGenerator?: (req: FastifyRequest) => string;\n}\n\n// Guardamos a chave calculada na própria request entre os hooks.\nconst CACHE_KEY = Symbol(\"rustNodeCacheKey\");\n\n/**\n * Plugin Fastify que cacheia respostas JSON. Use com `fastify.register`.\n */\nexport async function cachePlugin(\n fastify: FastifyInstance,\n options: CachePluginOptions,\n): Promise<void> {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: FastifyRequest) => `${req.method}:${req.url}`);\n\n fastify.addHook(\n \"onRequest\",\n (request: FastifyRequest, reply: FastifyReply, done: () => void) => {\n if (!methods.includes(request.method)) {\n done();\n return;\n }\n\n const key = keyGenerator(request);\n const cached = cache.get(key);\n if (cached !== null) {\n reply.header(\"X-Cache\", \"HIT\");\n reply.send(cached);\n return; // não chama done(): a resposta já foi enviada.\n }\n\n reply.header(\"X-Cache\", \"MISS\");\n (request as unknown as Record<symbol, string>)[CACHE_KEY] = key;\n done();\n },\n );\n\n fastify.addHook(\n \"onSend\",\n (\n request: FastifyRequest,\n reply: FastifyReply,\n payload: unknown,\n done: (err: Error | null, value?: unknown) => void,\n ) => {\n const key = (request as unknown as Record<symbol, string | undefined>)[\n CACHE_KEY\n ];\n if (\n key &&\n typeof payload === \"string\" &&\n reply.statusCode >= 200 &&\n reply.statusCode < 300\n ) {\n try {\n cache.set(\n key,\n JSON.parse(payload),\n ttlSeconds ? { ttlSeconds } : undefined,\n );\n } catch {\n // payload não-JSON: simplesmente não cacheia.\n }\n }\n done(null, payload);\n },\n );\n}\n"],"mappings":";AAiCA,IAAM,YAAY,uBAAO,kBAAkB;AAK3C,eAAsB,YACpB,SACA,SACe;AACf,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAwB,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAE5E,UAAQ;AAAA,IACN;AAAA,IACA,CAAC,SAAyB,OAAqB,SAAqB;AAClE,UAAI,CAAC,QAAQ,SAAS,QAAQ,MAAM,GAAG;AACrC,aAAK;AACL;AAAA,MACF;AAEA,YAAM,MAAM,aAAa,OAAO;AAChC,YAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,UAAI,WAAW,MAAM;AACnB,cAAM,OAAO,WAAW,KAAK;AAC7B,cAAM,KAAK,MAAM;AACjB;AAAA,MACF;AAEA,YAAM,OAAO,WAAW,MAAM;AAC9B,MAAC,QAA8C,SAAS,IAAI;AAC5D,WAAK;AAAA,IACP;AAAA,EACF;AAEA,UAAQ;AAAA,IACN;AAAA,IACA,CACE,SACA,OACA,SACA,SACG;AACH,YAAM,MAAO,QACX,SACF;AACA,UACE,OACA,OAAO,YAAY,YACnB,MAAM,cAAc,OACpB,MAAM,aAAa,KACnB;AACA,YAAI;AACF,gBAAM;AAAA,YACJ;AAAA,YACA,KAAK,MAAM,OAAO;AAAA,YAClB,aAAa,EAAE,WAAW,IAAI;AAAA,UAChC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,WAAK,MAAM,OAAO;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../js/fastify.ts"],"sourcesContent":["/**\n * Fastify integration: caching of JSON responses through a plugin.\n *\n * Usage:\n * import { Cache } from \"rust-node-cache\";\n * import { cachePlugin } from \"rust-node-cache/fastify\";\n *\n * const cache = new Cache();\n * fastify.register(cachePlugin, { cache, ttlSeconds: 60 });\n *\n * Flow: the `onRequest` hook checks the cache and, on a HIT, responds right away\n * (short-circuit). On a MISS, the `onSend` hook stores the serialized payload.\n */\n\nimport type {\n FastifyInstance,\n FastifyReply,\n FastifyRequest,\n} from \"fastify\";\nimport type { Cache } from \"./index\";\n\nexport interface CachePluginOptions {\n /** Cache instance to use. */\n cache: Cache;\n /** TTL applied to stored responses (in seconds). */\n ttlSeconds?: number;\n /** HTTP methods eligible for caching. Default: `[\"GET\"]`. */\n methods?: string[];\n /** Builds the cache key from the request. Default: `METHOD:url`. */\n keyGenerator?: (req: FastifyRequest) => string;\n}\n\n// The computed key is kept on the request itself between hooks.\nconst CACHE_KEY = Symbol(\"rustNodeCacheKey\");\n\n/**\n * Fastify plugin that caches JSON responses. Use it with `fastify.register`.\n */\nexport async function cachePlugin(\n fastify: FastifyInstance,\n options: CachePluginOptions,\n): Promise<void> {\n const { cache } = options;\n const ttlSeconds = options.ttlSeconds;\n const methods = options.methods ?? [\"GET\"];\n const keyGenerator =\n options.keyGenerator ?? ((req: FastifyRequest) => `${req.method}:${req.url}`);\n\n fastify.addHook(\n \"onRequest\",\n (request: FastifyRequest, reply: FastifyReply, done: () => void) => {\n if (!methods.includes(request.method)) {\n done();\n return;\n }\n\n const key = keyGenerator(request);\n const cached = cache.get(key);\n if (cached !== null) {\n reply.header(\"X-Cache\", \"HIT\");\n reply.send(cached);\n return; // done() is not called: the response was already sent.\n }\n\n reply.header(\"X-Cache\", \"MISS\");\n (request as unknown as Record<symbol, string>)[CACHE_KEY] = key;\n done();\n },\n );\n\n fastify.addHook(\n \"onSend\",\n (\n request: FastifyRequest,\n reply: FastifyReply,\n payload: unknown,\n done: (err: Error | null, value?: unknown) => void,\n ) => {\n const key = (request as unknown as Record<symbol, string | undefined>)[\n CACHE_KEY\n ];\n if (\n key &&\n typeof payload === \"string\" &&\n reply.statusCode >= 200 &&\n reply.statusCode < 300\n ) {\n try {\n cache.set(\n key,\n JSON.parse(payload),\n ttlSeconds ? { ttlSeconds } : undefined,\n );\n } catch {\n // non-JSON payload: simply not cached.\n }\n }\n done(null, payload);\n },\n );\n}\n"],"mappings":";AAiCA,IAAM,YAAY,uBAAO,kBAAkB;AAK3C,eAAsB,YACpB,SACA,SACe;AACf,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,QAAQ;AAC3B,QAAM,UAAU,QAAQ,WAAW,CAAC,KAAK;AACzC,QAAM,eACJ,QAAQ,iBAAiB,CAAC,QAAwB,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAE5E,UAAQ;AAAA,IACN;AAAA,IACA,CAAC,SAAyB,OAAqB,SAAqB;AAClE,UAAI,CAAC,QAAQ,SAAS,QAAQ,MAAM,GAAG;AACrC,aAAK;AACL;AAAA,MACF;AAEA,YAAM,MAAM,aAAa,OAAO;AAChC,YAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,UAAI,WAAW,MAAM;AACnB,cAAM,OAAO,WAAW,KAAK;AAC7B,cAAM,KAAK,MAAM;AACjB;AAAA,MACF;AAEA,YAAM,OAAO,WAAW,MAAM;AAC9B,MAAC,QAA8C,SAAS,IAAI;AAC5D,WAAK;AAAA,IACP;AAAA,EACF;AAEA,UAAQ;AAAA,IACN;AAAA,IACA,CACE,SACA,OACA,SACA,SACG;AACH,YAAM,MAAO,QACX,SACF;AACA,UACE,OACA,OAAO,YAAY,YACnB,MAAM,cAAc,OACpB,MAAM,aAAa,KACnB;AACA,YAAI;AACF,gBAAM;AAAA,YACJ;AAAA,YACA,KAAK,MAAM,OAAO;AAAA,YAClB,aAAa,EAAE,WAAW,IAAI;AAAA,UAChC;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AACA,WAAK,MAAM,OAAO;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,63 +1,63 @@
1
1
  /**
2
- * rust-node-cache — API pública (TypeScript).
2
+ * rust-node-cache — public API (TypeScript).
3
3
  *
4
4
  * "Ultra-fast in-memory cache powered by Rust."
5
5
  *
6
- * Esta camada é um wrapper fino e tipado sobre a classe `Cache` nativa gerada
7
- * pelo Rust/napi-rs. Por que envolver em vez de re-exportar direto?
8
- * - permite **genéricos** ergonômicos: `cache.get<User>("user:1")`;
9
- * - normaliza `undefined`/`null` para sempre devolver `null` num miss;
10
- * - dá um único lugar para JSDoc e para evoluir a API sem quebrar o core Rust.
6
+ * This layer is a thin, typed wrapper over the native `Cache` class generated
7
+ * by Rust/napi-rs. Why wrap it instead of re-exporting it directly?
8
+ * - it allows ergonomic **generics**: `cache.get<User>("user:1")`;
9
+ * - it normalizes `undefined`/`null` so a miss always returns `null`;
10
+ * - it gives one place for the JSDoc and for evolving the API without breaking the Rust core.
11
11
  *
12
- * O custo é uma chamada de função extra por operação — desprezível frente ao
13
- * trabalho real (serialização + acesso ao DashMap) que acontece no Rust.
12
+ * The cost is one extra function call per operation — negligible next to the
13
+ * real work (serialization + DashMap access) done in Rust.
14
14
  */
15
- /** Estratégia de evicção quando `maxSize` é atingido. */
15
+ /** Eviction strategy when `maxSize` is reached. */
16
16
  type EvictionPolicy = "reject" | "lru";
17
- /** Opções do construtor do cache. */
17
+ /** Cache constructor options. */
18
18
  interface CacheOptions {
19
19
  /**
20
- * Limite máximo de chaves. O que acontece ao atingir depende de
21
- * `evictionPolicy`. Sem valor => cache ilimitado.
20
+ * Maximum number of keys. What happens when it is reached depends on
21
+ * `evictionPolicy`. No value => unlimited cache.
22
22
  */
23
23
  maxSize?: number;
24
24
  /**
25
- * Política ao atingir `maxSize` numa chave **nova**:
26
- * - `"reject"` (padrão): `set` retorna `false` (sobrescrever continua ok);
27
- * - `"lru"`: remove a entrada menos recentemente usada e prossegue.
25
+ * Policy when `maxSize` is reached on a **new** key:
26
+ * - `"reject"` (default): `set` returns `false` (overwriting still works);
27
+ * - `"lru"`: removes the least recently used entry and goes on.
28
28
  */
29
29
  evictionPolicy?: EvictionPolicy;
30
30
  /**
31
- * Se definido (> 0), liga uma thread que varre entradas expiradas a cada
32
- * N segundos (expiração em background, além da preguiçosa por acesso).
31
+ * When set (> 0), starts a thread that sweeps expired entries every N
32
+ * seconds (background expiration, on top of the lazy one on access).
33
33
  */
34
34
  cleanupIntervalSeconds?: number;
35
35
  }
36
- /** Opções por operação de escrita. */
36
+ /** Per-write options. */
37
37
  interface SetOptions {
38
- /** Tempo de vida em segundos. Ausente => a entrada não expira por tempo. */
38
+ /** Time to live in seconds. Absent => the entry does not expire by time. */
39
39
  ttlSeconds?: number;
40
40
  }
41
- /** Estatísticas acumuladas do cache (mais o tamanho atual). */
41
+ /** Accumulated cache statistics (plus the current size). */
42
42
  interface CacheStats {
43
- /** Leituras que encontraram uma entrada válida. */
43
+ /** Reads that found a valid entry. */
44
44
  hits: number;
45
- /** Leituras sem chave válida (ausente ou expirada). */
45
+ /** Reads without a valid key (missing or expired). */
46
46
  misses: number;
47
- /** Total de escritas (`set`). */
47
+ /** Total writes (`set`). */
48
48
  sets: number;
49
- /** Total de remoções explícitas (`delete`). */
49
+ /** Total explicit removals (`delete`). */
50
50
  deletes: number;
51
- /** Total de entradas removidas por expiração. */
51
+ /** Total entries removed by expiration. */
52
52
  expired: number;
53
- /** Total de entradas removidas por evicção (política LRU ao atingir `maxSize`). */
53
+ /** Total entries removed by eviction (LRU policy when `maxSize` is reached). */
54
54
  evicted: number;
55
- /** Número de chaves armazenadas agora. */
55
+ /** Number of keys stored right now. */
56
56
  size: number;
57
57
  }
58
58
  /**
59
- * Cache em memória ultrarrápido com núcleo em Rust (DashMap + contadores
60
- * atômicos). Thread-safe e com suporte a TTL por entrada.
59
+ * In-memory cache with a Rust core (DashMap + atomic counters). Thread-safe,
60
+ * with an optional TTL per entry.
61
61
  *
62
62
  * @example
63
63
  * ```ts
@@ -69,38 +69,38 @@ interface CacheStats {
69
69
  * ```
70
70
  */
71
71
  declare class Cache {
72
- /** Instância da classe nativa (Rust). */
72
+ /** Instance of the native (Rust) class. */
73
73
  private readonly native;
74
74
  constructor(options?: CacheOptions);
75
- /** A política de evicção ativa: `"reject"` ou `"lru"`. */
75
+ /** The active eviction policy: `"reject"` or `"lru"`. */
76
76
  get evictionPolicy(): EvictionPolicy;
77
77
  /**
78
- * Armazena (ou sobrescreve) um valor. O valor é serializado como JSON no core.
78
+ * Stores (or overwrites) a value. The value is serialized as JSON in the core.
79
79
  *
80
- * @returns `true` em sucesso; `false` se `maxSize` foi atingido e a chave é nova.
80
+ * @returns `true` on success; `false` if `maxSize` was reached and the key is new.
81
81
  */
82
82
  set<T>(key: string, value: T, options?: SetOptions): boolean;
83
83
  /**
84
- * Lê um valor. Aplica expiração preguiçosa: chaves vencidas contam como miss.
84
+ * Reads a value. Applies lazy expiration: expired keys count as a miss.
85
85
  *
86
- * @returns o valor desserializado, ou `null` se ausente/expirado.
86
+ * @returns the deserialized value, or `null` if missing or expired.
87
87
  */
88
88
  get<T = unknown>(key: string): T | null;
89
- /** Remove uma chave. Retorna `true` se ela existia. */
89
+ /** Removes a key. Returns `true` if it existed. */
90
90
  delete(key: string): boolean;
91
- /** Indica se a chave existe e está válida (não expirada). */
91
+ /** Whether the key exists and is still valid (not expired). */
92
92
  exists(key: string): boolean;
93
- /** Esvazia o cache (não zera os contadores históricos de `stats`). */
93
+ /** Empties the cache (does not reset the historical `stats` counters). */
94
94
  clear(): void;
95
- /** Número de chaves armazenadas no momento. */
95
+ /** Number of keys currently stored. */
96
96
  size(): number;
97
97
  /**
98
- * Varre e remove todas as entradas expiradas de uma só vez.
98
+ * Sweeps and removes every expired entry at once.
99
99
  *
100
- * @returns quantas entradas foram removidas.
100
+ * @returns how many entries were removed.
101
101
  */
102
102
  cleanupExpired(): number;
103
- /** Retorna as estatísticas acumuladas + o tamanho atual. */
103
+ /** Returns the accumulated statistics + the current size. */
104
104
  stats(): CacheStats;
105
105
  }
106
106
 
package/dist/index.d.ts CHANGED
@@ -1,63 +1,63 @@
1
1
  /**
2
- * rust-node-cache — API pública (TypeScript).
2
+ * rust-node-cache — public API (TypeScript).
3
3
  *
4
4
  * "Ultra-fast in-memory cache powered by Rust."
5
5
  *
6
- * Esta camada é um wrapper fino e tipado sobre a classe `Cache` nativa gerada
7
- * pelo Rust/napi-rs. Por que envolver em vez de re-exportar direto?
8
- * - permite **genéricos** ergonômicos: `cache.get<User>("user:1")`;
9
- * - normaliza `undefined`/`null` para sempre devolver `null` num miss;
10
- * - dá um único lugar para JSDoc e para evoluir a API sem quebrar o core Rust.
6
+ * This layer is a thin, typed wrapper over the native `Cache` class generated
7
+ * by Rust/napi-rs. Why wrap it instead of re-exporting it directly?
8
+ * - it allows ergonomic **generics**: `cache.get<User>("user:1")`;
9
+ * - it normalizes `undefined`/`null` so a miss always returns `null`;
10
+ * - it gives one place for the JSDoc and for evolving the API without breaking the Rust core.
11
11
  *
12
- * O custo é uma chamada de função extra por operação — desprezível frente ao
13
- * trabalho real (serialização + acesso ao DashMap) que acontece no Rust.
12
+ * The cost is one extra function call per operation — negligible next to the
13
+ * real work (serialization + DashMap access) done in Rust.
14
14
  */
15
- /** Estratégia de evicção quando `maxSize` é atingido. */
15
+ /** Eviction strategy when `maxSize` is reached. */
16
16
  type EvictionPolicy = "reject" | "lru";
17
- /** Opções do construtor do cache. */
17
+ /** Cache constructor options. */
18
18
  interface CacheOptions {
19
19
  /**
20
- * Limite máximo de chaves. O que acontece ao atingir depende de
21
- * `evictionPolicy`. Sem valor => cache ilimitado.
20
+ * Maximum number of keys. What happens when it is reached depends on
21
+ * `evictionPolicy`. No value => unlimited cache.
22
22
  */
23
23
  maxSize?: number;
24
24
  /**
25
- * Política ao atingir `maxSize` numa chave **nova**:
26
- * - `"reject"` (padrão): `set` retorna `false` (sobrescrever continua ok);
27
- * - `"lru"`: remove a entrada menos recentemente usada e prossegue.
25
+ * Policy when `maxSize` is reached on a **new** key:
26
+ * - `"reject"` (default): `set` returns `false` (overwriting still works);
27
+ * - `"lru"`: removes the least recently used entry and goes on.
28
28
  */
29
29
  evictionPolicy?: EvictionPolicy;
30
30
  /**
31
- * Se definido (> 0), liga uma thread que varre entradas expiradas a cada
32
- * N segundos (expiração em background, além da preguiçosa por acesso).
31
+ * When set (> 0), starts a thread that sweeps expired entries every N
32
+ * seconds (background expiration, on top of the lazy one on access).
33
33
  */
34
34
  cleanupIntervalSeconds?: number;
35
35
  }
36
- /** Opções por operação de escrita. */
36
+ /** Per-write options. */
37
37
  interface SetOptions {
38
- /** Tempo de vida em segundos. Ausente => a entrada não expira por tempo. */
38
+ /** Time to live in seconds. Absent => the entry does not expire by time. */
39
39
  ttlSeconds?: number;
40
40
  }
41
- /** Estatísticas acumuladas do cache (mais o tamanho atual). */
41
+ /** Accumulated cache statistics (plus the current size). */
42
42
  interface CacheStats {
43
- /** Leituras que encontraram uma entrada válida. */
43
+ /** Reads that found a valid entry. */
44
44
  hits: number;
45
- /** Leituras sem chave válida (ausente ou expirada). */
45
+ /** Reads without a valid key (missing or expired). */
46
46
  misses: number;
47
- /** Total de escritas (`set`). */
47
+ /** Total writes (`set`). */
48
48
  sets: number;
49
- /** Total de remoções explícitas (`delete`). */
49
+ /** Total explicit removals (`delete`). */
50
50
  deletes: number;
51
- /** Total de entradas removidas por expiração. */
51
+ /** Total entries removed by expiration. */
52
52
  expired: number;
53
- /** Total de entradas removidas por evicção (política LRU ao atingir `maxSize`). */
53
+ /** Total entries removed by eviction (LRU policy when `maxSize` is reached). */
54
54
  evicted: number;
55
- /** Número de chaves armazenadas agora. */
55
+ /** Number of keys stored right now. */
56
56
  size: number;
57
57
  }
58
58
  /**
59
- * Cache em memória ultrarrápido com núcleo em Rust (DashMap + contadores
60
- * atômicos). Thread-safe e com suporte a TTL por entrada.
59
+ * In-memory cache with a Rust core (DashMap + atomic counters). Thread-safe,
60
+ * with an optional TTL per entry.
61
61
  *
62
62
  * @example
63
63
  * ```ts
@@ -69,38 +69,38 @@ interface CacheStats {
69
69
  * ```
70
70
  */
71
71
  declare class Cache {
72
- /** Instância da classe nativa (Rust). */
72
+ /** Instance of the native (Rust) class. */
73
73
  private readonly native;
74
74
  constructor(options?: CacheOptions);
75
- /** A política de evicção ativa: `"reject"` ou `"lru"`. */
75
+ /** The active eviction policy: `"reject"` or `"lru"`. */
76
76
  get evictionPolicy(): EvictionPolicy;
77
77
  /**
78
- * Armazena (ou sobrescreve) um valor. O valor é serializado como JSON no core.
78
+ * Stores (or overwrites) a value. The value is serialized as JSON in the core.
79
79
  *
80
- * @returns `true` em sucesso; `false` se `maxSize` foi atingido e a chave é nova.
80
+ * @returns `true` on success; `false` if `maxSize` was reached and the key is new.
81
81
  */
82
82
  set<T>(key: string, value: T, options?: SetOptions): boolean;
83
83
  /**
84
- * Lê um valor. Aplica expiração preguiçosa: chaves vencidas contam como miss.
84
+ * Reads a value. Applies lazy expiration: expired keys count as a miss.
85
85
  *
86
- * @returns o valor desserializado, ou `null` se ausente/expirado.
86
+ * @returns the deserialized value, or `null` if missing or expired.
87
87
  */
88
88
  get<T = unknown>(key: string): T | null;
89
- /** Remove uma chave. Retorna `true` se ela existia. */
89
+ /** Removes a key. Returns `true` if it existed. */
90
90
  delete(key: string): boolean;
91
- /** Indica se a chave existe e está válida (não expirada). */
91
+ /** Whether the key exists and is still valid (not expired). */
92
92
  exists(key: string): boolean;
93
- /** Esvazia o cache (não zera os contadores históricos de `stats`). */
93
+ /** Empties the cache (does not reset the historical `stats` counters). */
94
94
  clear(): void;
95
- /** Número de chaves armazenadas no momento. */
95
+ /** Number of keys currently stored. */
96
96
  size(): number;
97
97
  /**
98
- * Varre e remove todas as entradas expiradas de uma só vez.
98
+ * Sweeps and removes every expired entry at once.
99
99
  *
100
- * @returns quantas entradas foram removidas.
100
+ * @returns how many entries were removed.
101
101
  */
102
102
  cleanupExpired(): number;
103
- /** Retorna as estatísticas acumuladas + o tamanho atual. */
103
+ /** Returns the accumulated statistics + the current size. */
104
104
  stats(): CacheStats;
105
105
  }
106
106
 
package/dist/index.js CHANGED
@@ -43,52 +43,52 @@ var Cache2 = class {
43
43
  cleanupIntervalSeconds: options.cleanupIntervalSeconds
44
44
  }) : new native.Cache();
45
45
  }
46
- /** A política de evicção ativa: `"reject"` ou `"lru"`. */
46
+ /** The active eviction policy: `"reject"` or `"lru"`. */
47
47
  get evictionPolicy() {
48
48
  return this.native.evictionPolicy;
49
49
  }
50
50
  /**
51
- * Armazena (ou sobrescreve) um valor. O valor é serializado como JSON no core.
51
+ * Stores (or overwrites) a value. The value is serialized as JSON in the core.
52
52
  *
53
- * @returns `true` em sucesso; `false` se `maxSize` foi atingido e a chave é nova.
53
+ * @returns `true` on success; `false` if `maxSize` was reached and the key is new.
54
54
  */
55
55
  set(key, value, options) {
56
56
  return this.native.set(key, value, options);
57
57
  }
58
58
  /**
59
- * Lê um valor. Aplica expiração preguiçosa: chaves vencidas contam como miss.
59
+ * Reads a value. Applies lazy expiration: expired keys count as a miss.
60
60
  *
61
- * @returns o valor desserializado, ou `null` se ausente/expirado.
61
+ * @returns the deserialized value, or `null` if missing or expired.
62
62
  */
63
63
  get(key) {
64
64
  const value = this.native.get(key);
65
65
  return value === null || value === void 0 ? null : value;
66
66
  }
67
- /** Remove uma chave. Retorna `true` se ela existia. */
67
+ /** Removes a key. Returns `true` if it existed. */
68
68
  delete(key) {
69
69
  return this.native.delete(key);
70
70
  }
71
- /** Indica se a chave existe e está válida (não expirada). */
71
+ /** Whether the key exists and is still valid (not expired). */
72
72
  exists(key) {
73
73
  return this.native.exists(key);
74
74
  }
75
- /** Esvazia o cache (não zera os contadores históricos de `stats`). */
75
+ /** Empties the cache (does not reset the historical `stats` counters). */
76
76
  clear() {
77
77
  this.native.clear();
78
78
  }
79
- /** Número de chaves armazenadas no momento. */
79
+ /** Number of keys currently stored. */
80
80
  size() {
81
81
  return this.native.size();
82
82
  }
83
83
  /**
84
- * Varre e remove todas as entradas expiradas de uma só vez.
84
+ * Sweeps and removes every expired entry at once.
85
85
  *
86
- * @returns quantas entradas foram removidas.
86
+ * @returns how many entries were removed.
87
87
  */
88
88
  cleanupExpired() {
89
89
  return this.native.cleanupExpired();
90
90
  }
91
- /** Retorna as estatísticas acumuladas + o tamanho atual. */
91
+ /** Returns the accumulated statistics + the current size. */
92
92
  stats() {
93
93
  return this.native.stats();
94
94
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/index.ts"],"sourcesContent":["/**\n * rust-node-cache — API pública (TypeScript).\n *\n * \"Ultra-fast in-memory cache powered by Rust.\"\n *\n * Esta camada é um wrapper fino e tipado sobre a classe `Cache` nativa gerada\n * pelo Rust/napi-rs. Por que envolver em vez de re-exportar direto?\n * - permite **genéricos** ergonômicos: `cache.get<User>(\"user:1\")`;\n * - normaliza `undefined`/`null` para sempre devolver `null` num miss;\n * - dá um único lugar para JSDoc e para evoluir a API sem quebrar o core Rust.\n *\n * O custo é uma chamada de função extra por operação — desprezível frente ao\n * trabalho real (serialização + acesso ao DashMap) que acontece no Rust.\n */\n\n// Namespace import: funciona igual em CommonJS e ESM ao consumir o addon nativo\n// (que é um módulo CJS gerado pelo napi-rs).\nimport * as native from \"../binding.js\";\n\n/** Estratégia de evicção quando `maxSize` é atingido. */\nexport type EvictionPolicy = \"reject\" | \"lru\";\n\n/** Opções do construtor do cache. */\nexport interface CacheOptions {\n /**\n * Limite máximo de chaves. O que acontece ao atingir depende de\n * `evictionPolicy`. Sem valor => cache ilimitado.\n */\n maxSize?: number;\n /**\n * Política ao atingir `maxSize` numa chave **nova**:\n * - `\"reject\"` (padrão): `set` retorna `false` (sobrescrever continua ok);\n * - `\"lru\"`: remove a entrada menos recentemente usada e prossegue.\n */\n evictionPolicy?: EvictionPolicy;\n /**\n * Se definido (> 0), liga uma thread que varre entradas expiradas a cada\n * N segundos (expiração em background, além da preguiçosa por acesso).\n */\n cleanupIntervalSeconds?: number;\n}\n\n/** Opções por operação de escrita. */\nexport interface SetOptions {\n /** Tempo de vida em segundos. Ausente => a entrada não expira por tempo. */\n ttlSeconds?: number;\n}\n\n/** Estatísticas acumuladas do cache (mais o tamanho atual). */\nexport interface CacheStats {\n /** Leituras que encontraram uma entrada válida. */\n hits: number;\n /** Leituras sem chave válida (ausente ou expirada). */\n misses: number;\n /** Total de escritas (`set`). */\n sets: number;\n /** Total de remoções explícitas (`delete`). */\n deletes: number;\n /** Total de entradas removidas por expiração. */\n expired: number;\n /** Total de entradas removidas por evicção (política LRU ao atingir `maxSize`). */\n evicted: number;\n /** Número de chaves armazenadas agora. */\n size: number;\n}\n\n/**\n * Cache em memória ultrarrápido com núcleo em Rust (DashMap + contadores\n * atômicos). Thread-safe e com suporte a TTL por entrada.\n *\n * @example\n * ```ts\n * import { Cache } from \"rust-node-cache\";\n *\n * const cache = new Cache();\n * cache.set(\"user:1\", { id: 1, name: \"Roberto\" });\n * cache.get<{ id: number; name: string }>(\"user:1\"); // { id: 1, name: \"Roberto\" }\n * ```\n */\nexport class Cache {\n /** Instância da classe nativa (Rust). */\n private readonly native: native.Cache;\n\n constructor(options: CacheOptions = {}) {\n // Só repassamos um objeto de opções ao Rust quando há algo relevante.\n const hasOptions =\n options.maxSize !== undefined ||\n options.evictionPolicy !== undefined ||\n options.cleanupIntervalSeconds !== undefined;\n this.native = hasOptions\n ? new native.Cache({\n maxSize: options.maxSize,\n evictionPolicy: options.evictionPolicy,\n cleanupIntervalSeconds: options.cleanupIntervalSeconds,\n })\n : new native.Cache();\n }\n\n /** A política de evicção ativa: `\"reject\"` ou `\"lru\"`. */\n get evictionPolicy(): EvictionPolicy {\n return this.native.evictionPolicy as EvictionPolicy;\n }\n\n /**\n * Armazena (ou sobrescreve) um valor. O valor é serializado como JSON no core.\n *\n * @returns `true` em sucesso; `false` se `maxSize` foi atingido e a chave é nova.\n */\n set<T>(key: string, value: T, options?: SetOptions): boolean {\n return this.native.set(key, value as unknown as object, options);\n }\n\n /**\n * Lê um valor. Aplica expiração preguiçosa: chaves vencidas contam como miss.\n *\n * @returns o valor desserializado, ou `null` se ausente/expirado.\n */\n get<T = unknown>(key: string): T | null {\n const value = this.native.get(key);\n return value === null || value === undefined ? null : (value as T);\n }\n\n /** Remove uma chave. Retorna `true` se ela existia. */\n delete(key: string): boolean {\n return this.native.delete(key);\n }\n\n /** Indica se a chave existe e está válida (não expirada). */\n exists(key: string): boolean {\n return this.native.exists(key);\n }\n\n /** Esvazia o cache (não zera os contadores históricos de `stats`). */\n clear(): void {\n this.native.clear();\n }\n\n /** Número de chaves armazenadas no momento. */\n size(): number {\n return this.native.size();\n }\n\n /**\n * Varre e remove todas as entradas expiradas de uma só vez.\n *\n * @returns quantas entradas foram removidas.\n */\n cleanupExpired(): number {\n return this.native.cleanupExpired();\n }\n\n /** Retorna as estatísticas acumuladas + o tamanho atual. */\n stats(): CacheStats {\n return this.native.stats();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,eAAAA;AAAA;AAAA;AAiBA,aAAwB;AA8DjB,IAAMA,SAAN,MAAY;AAAA,EAIjB,YAAY,UAAwB,CAAC,GAAG;AAEtC,UAAM,aACJ,QAAQ,YAAY,UACpB,QAAQ,mBAAmB,UAC3B,QAAQ,2BAA2B;AACrC,SAAK,SAAS,aACV,IAAW,aAAM;AAAA,MACf,SAAS,QAAQ;AAAA,MACjB,gBAAgB,QAAQ;AAAA,MACxB,wBAAwB,QAAQ;AAAA,IAClC,CAAC,IACD,IAAW,aAAM;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,iBAAiC;AACnC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAO,KAAa,OAAU,SAA+B;AAC3D,WAAO,KAAK,OAAO,IAAI,KAAK,OAA4B,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAiB,KAAuB;AACtC,UAAM,QAAQ,KAAK,OAAO,IAAI,GAAG;AACjC,WAAO,UAAU,QAAQ,UAAU,SAAY,OAAQ;AAAA,EACzD;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,OAAe;AACb,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAyB;AACvB,WAAO,KAAK,OAAO,eAAe;AAAA,EACpC;AAAA;AAAA,EAGA,QAAoB;AAClB,WAAO,KAAK,OAAO,MAAM;AAAA,EAC3B;AACF;","names":["Cache"]}
1
+ {"version":3,"sources":["../js/index.ts"],"sourcesContent":["/**\n * rust-node-cache — public API (TypeScript).\n *\n * \"Ultra-fast in-memory cache powered by Rust.\"\n *\n * This layer is a thin, typed wrapper over the native `Cache` class generated\n * by Rust/napi-rs. Why wrap it instead of re-exporting it directly?\n * - it allows ergonomic **generics**: `cache.get<User>(\"user:1\")`;\n * - it normalizes `undefined`/`null` so a miss always returns `null`;\n * - it gives one place for the JSDoc and for evolving the API without breaking the Rust core.\n *\n * The cost is one extra function call per operation — negligible next to the\n * real work (serialization + DashMap access) done in Rust.\n */\n\n// Namespace import: works the same in CommonJS and ESM when consuming the native\n// addon (a CJS module generated by napi-rs).\nimport * as native from \"../binding.js\";\n\n/** Eviction strategy when `maxSize` is reached. */\nexport type EvictionPolicy = \"reject\" | \"lru\";\n\n/** Cache constructor options. */\nexport interface CacheOptions {\n /**\n * Maximum number of keys. What happens when it is reached depends on\n * `evictionPolicy`. No value => unlimited cache.\n */\n maxSize?: number;\n /**\n * Policy when `maxSize` is reached on a **new** key:\n * - `\"reject\"` (default): `set` returns `false` (overwriting still works);\n * - `\"lru\"`: removes the least recently used entry and goes on.\n */\n evictionPolicy?: EvictionPolicy;\n /**\n * When set (> 0), starts a thread that sweeps expired entries every N\n * seconds (background expiration, on top of the lazy one on access).\n */\n cleanupIntervalSeconds?: number;\n}\n\n/** Per-write options. */\nexport interface SetOptions {\n /** Time to live in seconds. Absent => the entry does not expire by time. */\n ttlSeconds?: number;\n}\n\n/** Accumulated cache statistics (plus the current size). */\nexport interface CacheStats {\n /** Reads that found a valid entry. */\n hits: number;\n /** Reads without a valid key (missing or expired). */\n misses: number;\n /** Total writes (`set`). */\n sets: number;\n /** Total explicit removals (`delete`). */\n deletes: number;\n /** Total entries removed by expiration. */\n expired: number;\n /** Total entries removed by eviction (LRU policy when `maxSize` is reached). */\n evicted: number;\n /** Number of keys stored right now. */\n size: number;\n}\n\n/**\n * In-memory cache with a Rust core (DashMap + atomic counters). Thread-safe,\n * with an optional TTL per entry.\n *\n * @example\n * ```ts\n * import { Cache } from \"rust-node-cache\";\n *\n * const cache = new Cache();\n * cache.set(\"user:1\", { id: 1, name: \"Roberto\" });\n * cache.get<{ id: number; name: string }>(\"user:1\"); // { id: 1, name: \"Roberto\" }\n * ```\n */\nexport class Cache {\n /** Instance of the native (Rust) class. */\n private readonly native: native.Cache;\n\n constructor(options: CacheOptions = {}) {\n // An options object is passed to Rust only when it carries something.\n const hasOptions =\n options.maxSize !== undefined ||\n options.evictionPolicy !== undefined ||\n options.cleanupIntervalSeconds !== undefined;\n this.native = hasOptions\n ? new native.Cache({\n maxSize: options.maxSize,\n evictionPolicy: options.evictionPolicy,\n cleanupIntervalSeconds: options.cleanupIntervalSeconds,\n })\n : new native.Cache();\n }\n\n /** The active eviction policy: `\"reject\"` or `\"lru\"`. */\n get evictionPolicy(): EvictionPolicy {\n return this.native.evictionPolicy as EvictionPolicy;\n }\n\n /**\n * Stores (or overwrites) a value. The value is serialized as JSON in the core.\n *\n * @returns `true` on success; `false` if `maxSize` was reached and the key is new.\n */\n set<T>(key: string, value: T, options?: SetOptions): boolean {\n return this.native.set(key, value as unknown as object, options);\n }\n\n /**\n * Reads a value. Applies lazy expiration: expired keys count as a miss.\n *\n * @returns the deserialized value, or `null` if missing or expired.\n */\n get<T = unknown>(key: string): T | null {\n const value = this.native.get(key);\n return value === null || value === undefined ? null : (value as T);\n }\n\n /** Removes a key. Returns `true` if it existed. */\n delete(key: string): boolean {\n return this.native.delete(key);\n }\n\n /** Whether the key exists and is still valid (not expired). */\n exists(key: string): boolean {\n return this.native.exists(key);\n }\n\n /** Empties the cache (does not reset the historical `stats` counters). */\n clear(): void {\n this.native.clear();\n }\n\n /** Number of keys currently stored. */\n size(): number {\n return this.native.size();\n }\n\n /**\n * Sweeps and removes every expired entry at once.\n *\n * @returns how many entries were removed.\n */\n cleanupExpired(): number {\n return this.native.cleanupExpired();\n }\n\n /** Returns the accumulated statistics + the current size. */\n stats(): CacheStats {\n return this.native.stats();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,eAAAA;AAAA;AAAA;AAiBA,aAAwB;AA8DjB,IAAMA,SAAN,MAAY;AAAA,EAIjB,YAAY,UAAwB,CAAC,GAAG;AAEtC,UAAM,aACJ,QAAQ,YAAY,UACpB,QAAQ,mBAAmB,UAC3B,QAAQ,2BAA2B;AACrC,SAAK,SAAS,aACV,IAAW,aAAM;AAAA,MACf,SAAS,QAAQ;AAAA,MACjB,gBAAgB,QAAQ;AAAA,MACxB,wBAAwB,QAAQ;AAAA,IAClC,CAAC,IACD,IAAW,aAAM;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,iBAAiC;AACnC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAO,KAAa,OAAU,SAA+B;AAC3D,WAAO,KAAK,OAAO,IAAI,KAAK,OAA4B,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAiB,KAAuB;AACtC,UAAM,QAAQ,KAAK,OAAO,IAAI,GAAG;AACjC,WAAO,UAAU,QAAQ,UAAU,SAAY,OAAQ;AAAA,EACzD;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,OAAe;AACb,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAyB;AACvB,WAAO,KAAK,OAAO,eAAe;AAAA,EACpC;AAAA;AAAA,EAGA,QAAoB;AAClB,WAAO,KAAK,OAAO,MAAM;AAAA,EAC3B;AACF;","names":["Cache"]}
package/dist/index.mjs CHANGED
@@ -9,52 +9,52 @@ var Cache2 = class {
9
9
  cleanupIntervalSeconds: options.cleanupIntervalSeconds
10
10
  }) : new native.Cache();
11
11
  }
12
- /** A política de evicção ativa: `"reject"` ou `"lru"`. */
12
+ /** The active eviction policy: `"reject"` or `"lru"`. */
13
13
  get evictionPolicy() {
14
14
  return this.native.evictionPolicy;
15
15
  }
16
16
  /**
17
- * Armazena (ou sobrescreve) um valor. O valor é serializado como JSON no core.
17
+ * Stores (or overwrites) a value. The value is serialized as JSON in the core.
18
18
  *
19
- * @returns `true` em sucesso; `false` se `maxSize` foi atingido e a chave é nova.
19
+ * @returns `true` on success; `false` if `maxSize` was reached and the key is new.
20
20
  */
21
21
  set(key, value, options) {
22
22
  return this.native.set(key, value, options);
23
23
  }
24
24
  /**
25
- * Lê um valor. Aplica expiração preguiçosa: chaves vencidas contam como miss.
25
+ * Reads a value. Applies lazy expiration: expired keys count as a miss.
26
26
  *
27
- * @returns o valor desserializado, ou `null` se ausente/expirado.
27
+ * @returns the deserialized value, or `null` if missing or expired.
28
28
  */
29
29
  get(key) {
30
30
  const value = this.native.get(key);
31
31
  return value === null || value === void 0 ? null : value;
32
32
  }
33
- /** Remove uma chave. Retorna `true` se ela existia. */
33
+ /** Removes a key. Returns `true` if it existed. */
34
34
  delete(key) {
35
35
  return this.native.delete(key);
36
36
  }
37
- /** Indica se a chave existe e está válida (não expirada). */
37
+ /** Whether the key exists and is still valid (not expired). */
38
38
  exists(key) {
39
39
  return this.native.exists(key);
40
40
  }
41
- /** Esvazia o cache (não zera os contadores históricos de `stats`). */
41
+ /** Empties the cache (does not reset the historical `stats` counters). */
42
42
  clear() {
43
43
  this.native.clear();
44
44
  }
45
- /** Número de chaves armazenadas no momento. */
45
+ /** Number of keys currently stored. */
46
46
  size() {
47
47
  return this.native.size();
48
48
  }
49
49
  /**
50
- * Varre e remove todas as entradas expiradas de uma só vez.
50
+ * Sweeps and removes every expired entry at once.
51
51
  *
52
- * @returns quantas entradas foram removidas.
52
+ * @returns how many entries were removed.
53
53
  */
54
54
  cleanupExpired() {
55
55
  return this.native.cleanupExpired();
56
56
  }
57
- /** Retorna as estatísticas acumuladas + o tamanho atual. */
57
+ /** Returns the accumulated statistics + the current size. */
58
58
  stats() {
59
59
  return this.native.stats();
60
60
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/index.ts"],"sourcesContent":["/**\n * rust-node-cache — API pública (TypeScript).\n *\n * \"Ultra-fast in-memory cache powered by Rust.\"\n *\n * Esta camada é um wrapper fino e tipado sobre a classe `Cache` nativa gerada\n * pelo Rust/napi-rs. Por que envolver em vez de re-exportar direto?\n * - permite **genéricos** ergonômicos: `cache.get<User>(\"user:1\")`;\n * - normaliza `undefined`/`null` para sempre devolver `null` num miss;\n * - dá um único lugar para JSDoc e para evoluir a API sem quebrar o core Rust.\n *\n * O custo é uma chamada de função extra por operação — desprezível frente ao\n * trabalho real (serialização + acesso ao DashMap) que acontece no Rust.\n */\n\n// Namespace import: funciona igual em CommonJS e ESM ao consumir o addon nativo\n// (que é um módulo CJS gerado pelo napi-rs).\nimport * as native from \"../binding.js\";\n\n/** Estratégia de evicção quando `maxSize` é atingido. */\nexport type EvictionPolicy = \"reject\" | \"lru\";\n\n/** Opções do construtor do cache. */\nexport interface CacheOptions {\n /**\n * Limite máximo de chaves. O que acontece ao atingir depende de\n * `evictionPolicy`. Sem valor => cache ilimitado.\n */\n maxSize?: number;\n /**\n * Política ao atingir `maxSize` numa chave **nova**:\n * - `\"reject\"` (padrão): `set` retorna `false` (sobrescrever continua ok);\n * - `\"lru\"`: remove a entrada menos recentemente usada e prossegue.\n */\n evictionPolicy?: EvictionPolicy;\n /**\n * Se definido (> 0), liga uma thread que varre entradas expiradas a cada\n * N segundos (expiração em background, além da preguiçosa por acesso).\n */\n cleanupIntervalSeconds?: number;\n}\n\n/** Opções por operação de escrita. */\nexport interface SetOptions {\n /** Tempo de vida em segundos. Ausente => a entrada não expira por tempo. */\n ttlSeconds?: number;\n}\n\n/** Estatísticas acumuladas do cache (mais o tamanho atual). */\nexport interface CacheStats {\n /** Leituras que encontraram uma entrada válida. */\n hits: number;\n /** Leituras sem chave válida (ausente ou expirada). */\n misses: number;\n /** Total de escritas (`set`). */\n sets: number;\n /** Total de remoções explícitas (`delete`). */\n deletes: number;\n /** Total de entradas removidas por expiração. */\n expired: number;\n /** Total de entradas removidas por evicção (política LRU ao atingir `maxSize`). */\n evicted: number;\n /** Número de chaves armazenadas agora. */\n size: number;\n}\n\n/**\n * Cache em memória ultrarrápido com núcleo em Rust (DashMap + contadores\n * atômicos). Thread-safe e com suporte a TTL por entrada.\n *\n * @example\n * ```ts\n * import { Cache } from \"rust-node-cache\";\n *\n * const cache = new Cache();\n * cache.set(\"user:1\", { id: 1, name: \"Roberto\" });\n * cache.get<{ id: number; name: string }>(\"user:1\"); // { id: 1, name: \"Roberto\" }\n * ```\n */\nexport class Cache {\n /** Instância da classe nativa (Rust). */\n private readonly native: native.Cache;\n\n constructor(options: CacheOptions = {}) {\n // Só repassamos um objeto de opções ao Rust quando há algo relevante.\n const hasOptions =\n options.maxSize !== undefined ||\n options.evictionPolicy !== undefined ||\n options.cleanupIntervalSeconds !== undefined;\n this.native = hasOptions\n ? new native.Cache({\n maxSize: options.maxSize,\n evictionPolicy: options.evictionPolicy,\n cleanupIntervalSeconds: options.cleanupIntervalSeconds,\n })\n : new native.Cache();\n }\n\n /** A política de evicção ativa: `\"reject\"` ou `\"lru\"`. */\n get evictionPolicy(): EvictionPolicy {\n return this.native.evictionPolicy as EvictionPolicy;\n }\n\n /**\n * Armazena (ou sobrescreve) um valor. O valor é serializado como JSON no core.\n *\n * @returns `true` em sucesso; `false` se `maxSize` foi atingido e a chave é nova.\n */\n set<T>(key: string, value: T, options?: SetOptions): boolean {\n return this.native.set(key, value as unknown as object, options);\n }\n\n /**\n * Lê um valor. Aplica expiração preguiçosa: chaves vencidas contam como miss.\n *\n * @returns o valor desserializado, ou `null` se ausente/expirado.\n */\n get<T = unknown>(key: string): T | null {\n const value = this.native.get(key);\n return value === null || value === undefined ? null : (value as T);\n }\n\n /** Remove uma chave. Retorna `true` se ela existia. */\n delete(key: string): boolean {\n return this.native.delete(key);\n }\n\n /** Indica se a chave existe e está válida (não expirada). */\n exists(key: string): boolean {\n return this.native.exists(key);\n }\n\n /** Esvazia o cache (não zera os contadores históricos de `stats`). */\n clear(): void {\n this.native.clear();\n }\n\n /** Número de chaves armazenadas no momento. */\n size(): number {\n return this.native.size();\n }\n\n /**\n * Varre e remove todas as entradas expiradas de uma só vez.\n *\n * @returns quantas entradas foram removidas.\n */\n cleanupExpired(): number {\n return this.native.cleanupExpired();\n }\n\n /** Retorna as estatísticas acumuladas + o tamanho atual. */\n stats(): CacheStats {\n return this.native.stats();\n }\n}\n"],"mappings":";AAiBA,YAAY,YAAY;AA8DjB,IAAMA,SAAN,MAAY;AAAA,EAIjB,YAAY,UAAwB,CAAC,GAAG;AAEtC,UAAM,aACJ,QAAQ,YAAY,UACpB,QAAQ,mBAAmB,UAC3B,QAAQ,2BAA2B;AACrC,SAAK,SAAS,aACV,IAAW,aAAM;AAAA,MACf,SAAS,QAAQ;AAAA,MACjB,gBAAgB,QAAQ;AAAA,MACxB,wBAAwB,QAAQ;AAAA,IAClC,CAAC,IACD,IAAW,aAAM;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,iBAAiC;AACnC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAO,KAAa,OAAU,SAA+B;AAC3D,WAAO,KAAK,OAAO,IAAI,KAAK,OAA4B,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAiB,KAAuB;AACtC,UAAM,QAAQ,KAAK,OAAO,IAAI,GAAG;AACjC,WAAO,UAAU,QAAQ,UAAU,SAAY,OAAQ;AAAA,EACzD;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,OAAe;AACb,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAyB;AACvB,WAAO,KAAK,OAAO,eAAe;AAAA,EACpC;AAAA;AAAA,EAGA,QAAoB;AAClB,WAAO,KAAK,OAAO,MAAM;AAAA,EAC3B;AACF;","names":["Cache"]}
1
+ {"version":3,"sources":["../js/index.ts"],"sourcesContent":["/**\n * rust-node-cache — public API (TypeScript).\n *\n * \"Ultra-fast in-memory cache powered by Rust.\"\n *\n * This layer is a thin, typed wrapper over the native `Cache` class generated\n * by Rust/napi-rs. Why wrap it instead of re-exporting it directly?\n * - it allows ergonomic **generics**: `cache.get<User>(\"user:1\")`;\n * - it normalizes `undefined`/`null` so a miss always returns `null`;\n * - it gives one place for the JSDoc and for evolving the API without breaking the Rust core.\n *\n * The cost is one extra function call per operation — negligible next to the\n * real work (serialization + DashMap access) done in Rust.\n */\n\n// Namespace import: works the same in CommonJS and ESM when consuming the native\n// addon (a CJS module generated by napi-rs).\nimport * as native from \"../binding.js\";\n\n/** Eviction strategy when `maxSize` is reached. */\nexport type EvictionPolicy = \"reject\" | \"lru\";\n\n/** Cache constructor options. */\nexport interface CacheOptions {\n /**\n * Maximum number of keys. What happens when it is reached depends on\n * `evictionPolicy`. No value => unlimited cache.\n */\n maxSize?: number;\n /**\n * Policy when `maxSize` is reached on a **new** key:\n * - `\"reject\"` (default): `set` returns `false` (overwriting still works);\n * - `\"lru\"`: removes the least recently used entry and goes on.\n */\n evictionPolicy?: EvictionPolicy;\n /**\n * When set (> 0), starts a thread that sweeps expired entries every N\n * seconds (background expiration, on top of the lazy one on access).\n */\n cleanupIntervalSeconds?: number;\n}\n\n/** Per-write options. */\nexport interface SetOptions {\n /** Time to live in seconds. Absent => the entry does not expire by time. */\n ttlSeconds?: number;\n}\n\n/** Accumulated cache statistics (plus the current size). */\nexport interface CacheStats {\n /** Reads that found a valid entry. */\n hits: number;\n /** Reads without a valid key (missing or expired). */\n misses: number;\n /** Total writes (`set`). */\n sets: number;\n /** Total explicit removals (`delete`). */\n deletes: number;\n /** Total entries removed by expiration. */\n expired: number;\n /** Total entries removed by eviction (LRU policy when `maxSize` is reached). */\n evicted: number;\n /** Number of keys stored right now. */\n size: number;\n}\n\n/**\n * In-memory cache with a Rust core (DashMap + atomic counters). Thread-safe,\n * with an optional TTL per entry.\n *\n * @example\n * ```ts\n * import { Cache } from \"rust-node-cache\";\n *\n * const cache = new Cache();\n * cache.set(\"user:1\", { id: 1, name: \"Roberto\" });\n * cache.get<{ id: number; name: string }>(\"user:1\"); // { id: 1, name: \"Roberto\" }\n * ```\n */\nexport class Cache {\n /** Instance of the native (Rust) class. */\n private readonly native: native.Cache;\n\n constructor(options: CacheOptions = {}) {\n // An options object is passed to Rust only when it carries something.\n const hasOptions =\n options.maxSize !== undefined ||\n options.evictionPolicy !== undefined ||\n options.cleanupIntervalSeconds !== undefined;\n this.native = hasOptions\n ? new native.Cache({\n maxSize: options.maxSize,\n evictionPolicy: options.evictionPolicy,\n cleanupIntervalSeconds: options.cleanupIntervalSeconds,\n })\n : new native.Cache();\n }\n\n /** The active eviction policy: `\"reject\"` or `\"lru\"`. */\n get evictionPolicy(): EvictionPolicy {\n return this.native.evictionPolicy as EvictionPolicy;\n }\n\n /**\n * Stores (or overwrites) a value. The value is serialized as JSON in the core.\n *\n * @returns `true` on success; `false` if `maxSize` was reached and the key is new.\n */\n set<T>(key: string, value: T, options?: SetOptions): boolean {\n return this.native.set(key, value as unknown as object, options);\n }\n\n /**\n * Reads a value. Applies lazy expiration: expired keys count as a miss.\n *\n * @returns the deserialized value, or `null` if missing or expired.\n */\n get<T = unknown>(key: string): T | null {\n const value = this.native.get(key);\n return value === null || value === undefined ? null : (value as T);\n }\n\n /** Removes a key. Returns `true` if it existed. */\n delete(key: string): boolean {\n return this.native.delete(key);\n }\n\n /** Whether the key exists and is still valid (not expired). */\n exists(key: string): boolean {\n return this.native.exists(key);\n }\n\n /** Empties the cache (does not reset the historical `stats` counters). */\n clear(): void {\n this.native.clear();\n }\n\n /** Number of keys currently stored. */\n size(): number {\n return this.native.size();\n }\n\n /**\n * Sweeps and removes every expired entry at once.\n *\n * @returns how many entries were removed.\n */\n cleanupExpired(): number {\n return this.native.cleanupExpired();\n }\n\n /** Returns the accumulated statistics + the current size. */\n stats(): CacheStats {\n return this.native.stats();\n }\n}\n"],"mappings":";AAiBA,YAAY,YAAY;AA8DjB,IAAMA,SAAN,MAAY;AAAA,EAIjB,YAAY,UAAwB,CAAC,GAAG;AAEtC,UAAM,aACJ,QAAQ,YAAY,UACpB,QAAQ,mBAAmB,UAC3B,QAAQ,2BAA2B;AACrC,SAAK,SAAS,aACV,IAAW,aAAM;AAAA,MACf,SAAS,QAAQ;AAAA,MACjB,gBAAgB,QAAQ;AAAA,MACxB,wBAAwB,QAAQ;AAAA,IAClC,CAAC,IACD,IAAW,aAAM;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,iBAAiC;AACnC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAO,KAAa,OAAU,SAA+B;AAC3D,WAAO,KAAK,OAAO,IAAI,KAAK,OAA4B,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAiB,KAAuB;AACtC,UAAM,QAAQ,KAAK,OAAO,IAAI,GAAG;AACjC,WAAO,UAAU,QAAQ,UAAU,SAAY,OAAQ;AAAA,EACzD;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,OAAO,KAAsB;AAC3B,WAAO,KAAK,OAAO,OAAO,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,OAAe;AACb,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAyB;AACvB,WAAO,KAAK,OAAO,eAAe;AAAA,EACpC;AAAA;AAAA,EAGA,QAAoB;AAClB,WAAO,KAAK,OAAO,MAAM;AAAA,EAC3B;AACF;","names":["Cache"]}
package/dist/nestjs.d.mts CHANGED
@@ -3,36 +3,36 @@ import { Observable } from 'rxjs';
3
3
  import { Cache } from './index.mjs';
4
4
 
5
5
  /**
6
- * Integração com NestJS: interceptor de cache de respostas.
6
+ * NestJS integration: a response caching interceptor.
7
7
  *
8
- * Uso:
8
+ * Usage:
9
9
  * import { Cache } from "rust-node-cache";
10
10
  * import { CacheInterceptor } from "rust-node-cache/nestjs";
11
11
  *
12
12
  * const cache = new Cache();
13
13
  * app.useGlobalInterceptors(new CacheInterceptor({ cache, ttlSeconds: 60 }));
14
14
  *
15
- * Usamos `import type` para `@nestjs/common`, ou seja, NÃO há import em runtime
16
- * do Nest aqui — o pacote não força o Nest como dependência. A única dependência
17
- * de runtime são os operadores `of`/`tap` do RxJS (presentes em qualquer app Nest).
15
+ * `@nestjs/common` is imported with `import type`, so there is NO runtime import
16
+ * of Nest here — the package does not force Nest as a dependency. The only runtime
17
+ * dependencies are RxJS's `of`/`tap` operators (present in any Nest app).
18
18
  */
19
19
 
20
20
  interface CacheInterceptorOptions {
21
- /** Instância de cache a usar. */
21
+ /** Cache instance to use. */
22
22
  cache: Cache;
23
- /** TTL aplicado às respostas guardadas (em segundos). */
23
+ /** TTL applied to stored responses (in seconds). */
24
24
  ttlSeconds?: number;
25
- /** Métodos HTTP elegíveis para cache. Padrão: `["GET"]`. */
25
+ /** HTTP methods eligible for caching. Default: `["GET"]`. */
26
26
  methods?: string[];
27
- /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */
27
+ /** Builds the cache key from the request. Default: `METHOD:url`. */
28
28
  keyGenerator?: (req: {
29
29
  method: string;
30
30
  url: string;
31
31
  }) => string;
32
32
  }
33
33
  /**
34
- * Interceptor NestJS que cacheia o valor retornado pelos handlers. Num HIT,
35
- * devolve o valor do cache sem executar o handler.
34
+ * NestJS interceptor that caches the value returned by handlers. On a HIT, it
35
+ * returns the cached value without running the handler.
36
36
  */
37
37
  declare class CacheInterceptor implements NestInterceptor {
38
38
  private readonly cache;
package/dist/nestjs.d.ts CHANGED
@@ -3,36 +3,36 @@ import { Observable } from 'rxjs';
3
3
  import { Cache } from './index.js';
4
4
 
5
5
  /**
6
- * Integração com NestJS: interceptor de cache de respostas.
6
+ * NestJS integration: a response caching interceptor.
7
7
  *
8
- * Uso:
8
+ * Usage:
9
9
  * import { Cache } from "rust-node-cache";
10
10
  * import { CacheInterceptor } from "rust-node-cache/nestjs";
11
11
  *
12
12
  * const cache = new Cache();
13
13
  * app.useGlobalInterceptors(new CacheInterceptor({ cache, ttlSeconds: 60 }));
14
14
  *
15
- * Usamos `import type` para `@nestjs/common`, ou seja, NÃO há import em runtime
16
- * do Nest aqui — o pacote não força o Nest como dependência. A única dependência
17
- * de runtime são os operadores `of`/`tap` do RxJS (presentes em qualquer app Nest).
15
+ * `@nestjs/common` is imported with `import type`, so there is NO runtime import
16
+ * of Nest here — the package does not force Nest as a dependency. The only runtime
17
+ * dependencies are RxJS's `of`/`tap` operators (present in any Nest app).
18
18
  */
19
19
 
20
20
  interface CacheInterceptorOptions {
21
- /** Instância de cache a usar. */
21
+ /** Cache instance to use. */
22
22
  cache: Cache;
23
- /** TTL aplicado às respostas guardadas (em segundos). */
23
+ /** TTL applied to stored responses (in seconds). */
24
24
  ttlSeconds?: number;
25
- /** Métodos HTTP elegíveis para cache. Padrão: `["GET"]`. */
25
+ /** HTTP methods eligible for caching. Default: `["GET"]`. */
26
26
  methods?: string[];
27
- /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */
27
+ /** Builds the cache key from the request. Default: `METHOD:url`. */
28
28
  keyGenerator?: (req: {
29
29
  method: string;
30
30
  url: string;
31
31
  }) => string;
32
32
  }
33
33
  /**
34
- * Interceptor NestJS que cacheia o valor retornado pelos handlers. Num HIT,
35
- * devolve o valor do cache sem executar o handler.
34
+ * NestJS interceptor that caches the value returned by handlers. On a HIT, it
35
+ * returns the cached value without running the handler.
36
36
  */
37
37
  declare class CacheInterceptor implements NestInterceptor {
38
38
  private readonly cache;
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/nestjs.ts"],"sourcesContent":["/**\n * Integração com NestJS: interceptor de cache de respostas.\n *\n * Uso:\n * import { Cache } from \"rust-node-cache\";\n * import { CacheInterceptor } from \"rust-node-cache/nestjs\";\n *\n * const cache = new Cache();\n * app.useGlobalInterceptors(new CacheInterceptor({ cache, ttlSeconds: 60 }));\n *\n * Usamos `import type` para `@nestjs/common`, ou seja, NÃO há import em runtime\n * do Nest aqui — o pacote não força o Nest como dependência. A única dependência\n * de runtime são os operadores `of`/`tap` do RxJS (presentes em qualquer app Nest).\n */\n\nimport type {\n CallHandler,\n ExecutionContext,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport type { Observable } from \"rxjs\";\nimport { of, tap } from \"rxjs\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheInterceptorOptions {\n /** Instância de cache a usar. */\n cache: Cache;\n /** TTL aplicado às respostas guardadas (em segundos). */\n ttlSeconds?: number;\n /** Métodos HTTP elegíveis para cache. Padrão: `[\"GET\"]`. */\n methods?: string[];\n /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */\n keyGenerator?: (req: { method: string; url: string }) => string;\n}\n\n/**\n * Interceptor NestJS que cacheia o valor retornado pelos handlers. Num HIT,\n * devolve o valor do cache sem executar o handler.\n */\nexport class CacheInterceptor implements NestInterceptor {\n private readonly cache: Cache;\n private readonly ttlSeconds?: number;\n private readonly methods: string[];\n private readonly keyGenerator: (req: {\n method: string;\n url: string;\n }) => string;\n\n constructor(options: CacheInterceptorOptions) {\n this.cache = options.cache;\n this.ttlSeconds = options.ttlSeconds;\n this.methods = options.methods ?? [\"GET\"];\n this.keyGenerator =\n options.keyGenerator ?? ((req) => `${req.method}:${req.url}`);\n }\n\n intercept(\n context: ExecutionContext,\n next: CallHandler,\n ): Observable<unknown> {\n const req = context.switchToHttp().getRequest<{\n method: string;\n url: string;\n }>();\n\n if (!this.methods.includes(req.method)) {\n return next.handle();\n }\n\n const key = this.keyGenerator(req);\n const cached = this.cache.get(key);\n if (cached !== null) {\n return of(cached);\n }\n\n return next.handle().pipe(\n tap((body) => {\n if (body !== undefined && body !== null) {\n this.cache.set(\n key,\n body,\n this.ttlSeconds ? { ttlSeconds: this.ttlSeconds } : undefined,\n );\n }\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBA,kBAAwB;AAkBjB,IAAM,mBAAN,MAAkD;AAAA,EASvD,YAAY,SAAkC;AAC5C,SAAK,QAAQ,QAAQ;AACrB,SAAK,aAAa,QAAQ;AAC1B,SAAK,UAAU,QAAQ,WAAW,CAAC,KAAK;AACxC,SAAK,eACH,QAAQ,iBAAiB,CAAC,QAAQ,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAAA,EAC9D;AAAA,EAEA,UACE,SACA,MACqB;AACrB,UAAM,MAAM,QAAQ,aAAa,EAAE,WAGhC;AAEH,QAAI,CAAC,KAAK,QAAQ,SAAS,IAAI,MAAM,GAAG;AACtC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,MAAM,KAAK,aAAa,GAAG;AACjC,UAAM,SAAS,KAAK,MAAM,IAAI,GAAG;AACjC,QAAI,WAAW,MAAM;AACnB,iBAAO,gBAAG,MAAM;AAAA,IAClB;AAEA,WAAO,KAAK,OAAO,EAAE;AAAA,UACnB,iBAAI,CAAC,SAAS;AACZ,YAAI,SAAS,UAAa,SAAS,MAAM;AACvC,eAAK,MAAM;AAAA,YACT;AAAA,YACA;AAAA,YACA,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI;AAAA,UACtD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../js/nestjs.ts"],"sourcesContent":["/**\n * NestJS integration: a response caching interceptor.\n *\n * Usage:\n * import { Cache } from \"rust-node-cache\";\n * import { CacheInterceptor } from \"rust-node-cache/nestjs\";\n *\n * const cache = new Cache();\n * app.useGlobalInterceptors(new CacheInterceptor({ cache, ttlSeconds: 60 }));\n *\n * `@nestjs/common` is imported with `import type`, so there is NO runtime import\n * of Nest here — the package does not force Nest as a dependency. The only runtime\n * dependencies are RxJS's `of`/`tap` operators (present in any Nest app).\n */\n\nimport type {\n CallHandler,\n ExecutionContext,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport type { Observable } from \"rxjs\";\nimport { of, tap } from \"rxjs\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheInterceptorOptions {\n /** Cache instance to use. */\n cache: Cache;\n /** TTL applied to stored responses (in seconds). */\n ttlSeconds?: number;\n /** HTTP methods eligible for caching. Default: `[\"GET\"]`. */\n methods?: string[];\n /** Builds the cache key from the request. Default: `METHOD:url`. */\n keyGenerator?: (req: { method: string; url: string }) => string;\n}\n\n/**\n * NestJS interceptor that caches the value returned by handlers. On a HIT, it\n * returns the cached value without running the handler.\n */\nexport class CacheInterceptor implements NestInterceptor {\n private readonly cache: Cache;\n private readonly ttlSeconds?: number;\n private readonly methods: string[];\n private readonly keyGenerator: (req: {\n method: string;\n url: string;\n }) => string;\n\n constructor(options: CacheInterceptorOptions) {\n this.cache = options.cache;\n this.ttlSeconds = options.ttlSeconds;\n this.methods = options.methods ?? [\"GET\"];\n this.keyGenerator =\n options.keyGenerator ?? ((req) => `${req.method}:${req.url}`);\n }\n\n intercept(\n context: ExecutionContext,\n next: CallHandler,\n ): Observable<unknown> {\n const req = context.switchToHttp().getRequest<{\n method: string;\n url: string;\n }>();\n\n if (!this.methods.includes(req.method)) {\n return next.handle();\n }\n\n const key = this.keyGenerator(req);\n const cached = this.cache.get(key);\n if (cached !== null) {\n return of(cached);\n }\n\n return next.handle().pipe(\n tap((body) => {\n if (body !== undefined && body !== null) {\n this.cache.set(\n key,\n body,\n this.ttlSeconds ? { ttlSeconds: this.ttlSeconds } : undefined,\n );\n }\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBA,kBAAwB;AAkBjB,IAAM,mBAAN,MAAkD;AAAA,EASvD,YAAY,SAAkC;AAC5C,SAAK,QAAQ,QAAQ;AACrB,SAAK,aAAa,QAAQ;AAC1B,SAAK,UAAU,QAAQ,WAAW,CAAC,KAAK;AACxC,SAAK,eACH,QAAQ,iBAAiB,CAAC,QAAQ,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAAA,EAC9D;AAAA,EAEA,UACE,SACA,MACqB;AACrB,UAAM,MAAM,QAAQ,aAAa,EAAE,WAGhC;AAEH,QAAI,CAAC,KAAK,QAAQ,SAAS,IAAI,MAAM,GAAG;AACtC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,MAAM,KAAK,aAAa,GAAG;AACjC,UAAM,SAAS,KAAK,MAAM,IAAI,GAAG;AACjC,QAAI,WAAW,MAAM;AACnB,iBAAO,gBAAG,MAAM;AAAA,IAClB;AAEA,WAAO,KAAK,OAAO,EAAE;AAAA,UACnB,iBAAI,CAAC,SAAS;AACZ,YAAI,SAAS,UAAa,SAAS,MAAM;AACvC,eAAK,MAAM;AAAA,YACT;AAAA,YACA;AAAA,YACA,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI;AAAA,UACtD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../js/nestjs.ts"],"sourcesContent":["/**\n * Integração com NestJS: interceptor de cache de respostas.\n *\n * Uso:\n * import { Cache } from \"rust-node-cache\";\n * import { CacheInterceptor } from \"rust-node-cache/nestjs\";\n *\n * const cache = new Cache();\n * app.useGlobalInterceptors(new CacheInterceptor({ cache, ttlSeconds: 60 }));\n *\n * Usamos `import type` para `@nestjs/common`, ou seja, NÃO há import em runtime\n * do Nest aqui — o pacote não força o Nest como dependência. A única dependência\n * de runtime são os operadores `of`/`tap` do RxJS (presentes em qualquer app Nest).\n */\n\nimport type {\n CallHandler,\n ExecutionContext,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport type { Observable } from \"rxjs\";\nimport { of, tap } from \"rxjs\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheInterceptorOptions {\n /** Instância de cache a usar. */\n cache: Cache;\n /** TTL aplicado às respostas guardadas (em segundos). */\n ttlSeconds?: number;\n /** Métodos HTTP elegíveis para cache. Padrão: `[\"GET\"]`. */\n methods?: string[];\n /** Gera a chave de cache a partir da requisição. Padrão: `METHOD:url`. */\n keyGenerator?: (req: { method: string; url: string }) => string;\n}\n\n/**\n * Interceptor NestJS que cacheia o valor retornado pelos handlers. Num HIT,\n * devolve o valor do cache sem executar o handler.\n */\nexport class CacheInterceptor implements NestInterceptor {\n private readonly cache: Cache;\n private readonly ttlSeconds?: number;\n private readonly methods: string[];\n private readonly keyGenerator: (req: {\n method: string;\n url: string;\n }) => string;\n\n constructor(options: CacheInterceptorOptions) {\n this.cache = options.cache;\n this.ttlSeconds = options.ttlSeconds;\n this.methods = options.methods ?? [\"GET\"];\n this.keyGenerator =\n options.keyGenerator ?? ((req) => `${req.method}:${req.url}`);\n }\n\n intercept(\n context: ExecutionContext,\n next: CallHandler,\n ): Observable<unknown> {\n const req = context.switchToHttp().getRequest<{\n method: string;\n url: string;\n }>();\n\n if (!this.methods.includes(req.method)) {\n return next.handle();\n }\n\n const key = this.keyGenerator(req);\n const cached = this.cache.get(key);\n if (cached !== null) {\n return of(cached);\n }\n\n return next.handle().pipe(\n tap((body) => {\n if (body !== undefined && body !== null) {\n this.cache.set(\n key,\n body,\n this.ttlSeconds ? { ttlSeconds: this.ttlSeconds } : undefined,\n );\n }\n }),\n );\n }\n}\n"],"mappings":";AAqBA,SAAS,IAAI,WAAW;AAkBjB,IAAM,mBAAN,MAAkD;AAAA,EASvD,YAAY,SAAkC;AAC5C,SAAK,QAAQ,QAAQ;AACrB,SAAK,aAAa,QAAQ;AAC1B,SAAK,UAAU,QAAQ,WAAW,CAAC,KAAK;AACxC,SAAK,eACH,QAAQ,iBAAiB,CAAC,QAAQ,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAAA,EAC9D;AAAA,EAEA,UACE,SACA,MACqB;AACrB,UAAM,MAAM,QAAQ,aAAa,EAAE,WAGhC;AAEH,QAAI,CAAC,KAAK,QAAQ,SAAS,IAAI,MAAM,GAAG;AACtC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,MAAM,KAAK,aAAa,GAAG;AACjC,UAAM,SAAS,KAAK,MAAM,IAAI,GAAG;AACjC,QAAI,WAAW,MAAM;AACnB,aAAO,GAAG,MAAM;AAAA,IAClB;AAEA,WAAO,KAAK,OAAO,EAAE;AAAA,MACnB,IAAI,CAAC,SAAS;AACZ,YAAI,SAAS,UAAa,SAAS,MAAM;AACvC,eAAK,MAAM;AAAA,YACT;AAAA,YACA;AAAA,YACA,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI;AAAA,UACtD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../js/nestjs.ts"],"sourcesContent":["/**\n * NestJS integration: a response caching interceptor.\n *\n * Usage:\n * import { Cache } from \"rust-node-cache\";\n * import { CacheInterceptor } from \"rust-node-cache/nestjs\";\n *\n * const cache = new Cache();\n * app.useGlobalInterceptors(new CacheInterceptor({ cache, ttlSeconds: 60 }));\n *\n * `@nestjs/common` is imported with `import type`, so there is NO runtime import\n * of Nest here — the package does not force Nest as a dependency. The only runtime\n * dependencies are RxJS's `of`/`tap` operators (present in any Nest app).\n */\n\nimport type {\n CallHandler,\n ExecutionContext,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport type { Observable } from \"rxjs\";\nimport { of, tap } from \"rxjs\";\nimport type { Cache } from \"./index\";\n\nexport interface CacheInterceptorOptions {\n /** Cache instance to use. */\n cache: Cache;\n /** TTL applied to stored responses (in seconds). */\n ttlSeconds?: number;\n /** HTTP methods eligible for caching. Default: `[\"GET\"]`. */\n methods?: string[];\n /** Builds the cache key from the request. Default: `METHOD:url`. */\n keyGenerator?: (req: { method: string; url: string }) => string;\n}\n\n/**\n * NestJS interceptor that caches the value returned by handlers. On a HIT, it\n * returns the cached value without running the handler.\n */\nexport class CacheInterceptor implements NestInterceptor {\n private readonly cache: Cache;\n private readonly ttlSeconds?: number;\n private readonly methods: string[];\n private readonly keyGenerator: (req: {\n method: string;\n url: string;\n }) => string;\n\n constructor(options: CacheInterceptorOptions) {\n this.cache = options.cache;\n this.ttlSeconds = options.ttlSeconds;\n this.methods = options.methods ?? [\"GET\"];\n this.keyGenerator =\n options.keyGenerator ?? ((req) => `${req.method}:${req.url}`);\n }\n\n intercept(\n context: ExecutionContext,\n next: CallHandler,\n ): Observable<unknown> {\n const req = context.switchToHttp().getRequest<{\n method: string;\n url: string;\n }>();\n\n if (!this.methods.includes(req.method)) {\n return next.handle();\n }\n\n const key = this.keyGenerator(req);\n const cached = this.cache.get(key);\n if (cached !== null) {\n return of(cached);\n }\n\n return next.handle().pipe(\n tap((body) => {\n if (body !== undefined && body !== null) {\n this.cache.set(\n key,\n body,\n this.ttlSeconds ? { ttlSeconds: this.ttlSeconds } : undefined,\n );\n }\n }),\n );\n }\n}\n"],"mappings":";AAqBA,SAAS,IAAI,WAAW;AAkBjB,IAAM,mBAAN,MAAkD;AAAA,EASvD,YAAY,SAAkC;AAC5C,SAAK,QAAQ,QAAQ;AACrB,SAAK,aAAa,QAAQ;AAC1B,SAAK,UAAU,QAAQ,WAAW,CAAC,KAAK;AACxC,SAAK,eACH,QAAQ,iBAAiB,CAAC,QAAQ,GAAG,IAAI,MAAM,IAAI,IAAI,GAAG;AAAA,EAC9D;AAAA,EAEA,UACE,SACA,MACqB;AACrB,UAAM,MAAM,QAAQ,aAAa,EAAE,WAGhC;AAEH,QAAI,CAAC,KAAK,QAAQ,SAAS,IAAI,MAAM,GAAG;AACtC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,MAAM,KAAK,aAAa,GAAG;AACjC,UAAM,SAAS,KAAK,MAAM,IAAI,GAAG;AACjC,QAAI,WAAW,MAAM;AACnB,aAAO,GAAG,MAAM;AAAA,IAClB;AAEA,WAAO,KAAK,OAAO,EAAE;AAAA,MACnB,IAAI,CAAC,SAAS;AACZ,YAAI,SAAS,UAAa,SAAS,MAAM;AACvC,eAAK,MAAM;AAAA,YACT;AAAA,YACA;AAAA,YACA,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI;AAAA,UACtD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rust-node-cache",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Ultra-fast in-memory cache for Node.js powered by Rust.",
5
5
  "keywords": [
6
6
  "cache",
@@ -66,7 +66,9 @@
66
66
  "aarch64-apple-darwin",
67
67
  "aarch64-unknown-linux-gnu",
68
68
  "x86_64-unknown-linux-gnu",
69
- "x86_64-pc-windows-msvc"
69
+ "x86_64-pc-windows-msvc",
70
+ "x86_64-unknown-linux-musl",
71
+ "aarch64-unknown-linux-musl"
70
72
  ]
71
73
  }
72
74
  },
Binary file
Binary file
Binary file
Binary file