
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
A lightweight, universal JavaScript cache library with multiple caching strategies
Uma biblioteca de cache JavaScript leve, universal e modular com múltiplas estratégias de cache.
npm install cachemind
yarn add cachemind
pnpm add cachemind
import { BaseCache, TTLCache } from 'cachemind';
import { BaseCache } from 'cachemind';
// Criar uma instância de cache
const cache = new BaseCache<string>();
// Armazenar valores
cache.set('user:1', 'John Doe');
cache.set('user:2', 'Jane Smith');
// Recuperar valores
const user1 = cache.get('user:1'); // 'John Doe'
const user2 = cache.get('user:2'); // 'Jane Smith'
// Verificar existência
if (cache.has('user:1')) {
console.log('Usuário existe no cache');
}
// Remover item
cache.delete('user:1');
// Limpar todo o cache
cache.clear();
import { TTLCache } from 'cachemind';
// Criar cache com TTL padrão de 1 hora
const cache = new TTLCache<string>({ defaultTTL: 3600000 });
// Armazenar com TTL padrão
cache.set('user:1', 'John Doe');
// Armazenar com TTL customizado (5 minutos)
cache.set('session:123', 'active', { ttl: 5 * 60 * 1000 });
// Verificar se item está expirado (stale)
if (cache.isStale('user:1')) {
// Item existe mas está expirado - pode fazer refresh
cache.set('user:1', await fetchFreshData(), { ttl: 3600000 });
}
// Verificar tempo restante até expiração
const remaining = cache.getRemainingTTL('session:123');
if (remaining !== undefined) {
console.log(`Sessão expira em ${remaining}ms`);
}
import { SWRCache } from 'cachemind';
// Criar cache SWR com TTL padrão de 1 hora
const cache = new SWRCache<string>({ defaultTTL: 3600000 });
// Configurar item com função de fetch para revalidação automática
await cache.setWithFetch('user:1', 'John Doe', {
ttl: 3600000,
fetch: async () => {
const response = await fetch('/api/user/1');
const data = await response.json();
return data.name;
}
});
// Primeira vez: retorna valor imediatamente
const user = cache.get('user:1'); // 'John Doe'
// Após expirar: retorna valor stale imediatamente e revalida em background
// (o valor stale é retornado sem esperar pela revalidação)
const staleUser = cache.get('user:1'); // 'John Doe' (stale, mas retornado)
// Em background: fetch é chamado e cache é atualizado silenciosamente
import { LRUCache } from 'cachemind';
// Criar cache LRU com capacidade máxima de 3 itens
const cache = new LRUCache<string>({ maxSize: 3 });
// Preenche cache até capacidade máxima
cache.set('key1', 'value1');
cache.set('key2', 'value2');
cache.set('key3', 'value3');
// Acessa key1 (torna-se mais recentemente usado)
cache.get('key1');
// Adiciona novo item - key2 é removido (menos recentemente usado)
cache.set('key4', 'value4');
// key2 não está mais no cache
import { DTTCache } from 'cachemind';
const cache = new DTTCache<string>();
// TTL baseado em headers HTTP
await cache.setWithDynamicTTL('api:data', 'response data', {
ttlCalculator: (value, metadata) => {
const cacheControl = metadata?.headers?.['cache-control'];
if (cacheControl) {
const maxAgeMatch = cacheControl.match(/max-age=(\d+)/);
if (maxAgeMatch) {
return parseInt(maxAgeMatch[1], 10) * 1000; // Converte para ms
}
}
return 3600000; // Fallback: 1 hora
},
metadata: {
headers: {
'cache-control': 'max-age=300', // 5 minutos
},
},
});
// TTL baseado em propriedade do dado
interface Product {
isPremium: boolean;
category: string;
}
const productCache = new DTTCache<Product>();
await productCache.setWithDynamicTTL('product:1', product, {
ttlCalculator: (value) => {
// Produtos premium têm TTL maior
return value.isPremium ? 7200000 : 3600000;
},
});
BaseCache<T>Classe base para cache em memória. Permite TTL opcional.
TTLCache<T>Estratégia de cache baseada em TTL (Time-To-Live). Garante que todos os itens tenham TTL definido.
new TTLCache<T>(options: { defaultTTL: number })
Cria uma nova instância de cache com TTL obrigatório.
Parâmetros:
options.defaultTTL: TTL padrão em milissegundos (obrigatório)Exemplo:
// Cache com TTL padrão de 1 hora
const cache = new TTLCache<string>({ defaultTTL: 3600000 });
// Cache com TTL padrão de 5 minutos
const sessionCache = new TTLCache<Session>({ defaultTTL: 5 * 60 * 1000 });
isStale(key: string): booleanVerifica se um item está expirado (stale) sem removê-lo.
Complexidade: O(1)
Parâmetros:
key: Chave do item a ser verificadoRetorna: true se o item existe mas está expirado, false caso contrário
Exemplo:
if (cache.isStale('key')) {
// Item expirado - fazer refresh
cache.set('key', await fetchFreshData(), { ttl: 3600000 });
}
getRemainingTTL(key: string): number | undefinedRetorna o tempo restante até a expiração de um item.
Complexidade: O(1)
Parâmetros:
key: Chave do item a ser verificadoRetorna: Tempo restante em milissegundos, ou undefined se o item não existe
Exemplo:
const remaining = cache.getRemainingTTL('session:123');
if (remaining !== undefined && remaining < 60000) {
// Menos de 1 minuto restante - avisar usuário
console.log('Sessão expira em breve');
}
TTLCache implementa a interface ICache<T>, então todos os métodos de BaseCache estão disponíveis:
get(key), getAsync(key), set(key, value, options), has(key), delete(key), clear(), sizeNota: Em TTLCache, o método set() sempre aplica TTL. Se options.ttl não for fornecido, usa o defaultTTL.
SWRCache<T>Estratégia de cache baseada em Stale-While-Revalidate (SWR). Retorna dados stale imediatamente enquanto revalida em background.
new SWRCache<T>(options: { defaultTTL: number })
Cria uma nova instância de cache SWR com TTL obrigatório.
Parâmetros:
options.defaultTTL: TTL padrão em milissegundos (obrigatório)Exemplo:
// Cache SWR com TTL padrão de 1 hora
const cache = new SWRCache<string>({ defaultTTL: 3600000 });
setWithFetch(key: string, initialValue: T | Promise<T>, options: SWROptions<T>): Promise<void>Configura um item no cache com função de fetch para revalidação automática.
Parâmetros:
key: Chave do iteminitialValue: Valor inicial (ou Promise que resolve para o valor)options: Opções incluindo ttl e fetchExemplo:
await cache.setWithFetch('user:1', 'John Doe', {
ttl: 3600000,
fetch: async () => {
const response = await fetch('/api/user/1');
return response.json().name;
}
});
isStale(key: string): booleanVerifica se um item está expirado (stale).
Complexidade: O(1)
Parâmetros:
key: Chave do item a ser verificadoRetorna: true se o item está stale, false caso contrário
SWRCache implementa a interface ICache<T>, então todos os métodos de BaseCache estão disponíveis:
get(key), getAsync(key), set(key, value, options), has(key), delete(key), clear(), sizeNota: Quando um item está stale, get() retorna o valor stale imediatamente e inicia revalidação em background (se houver função de fetch configurada).
LRUCache<T>Estratégia de cache baseada em LRU (Least Recently Used). Remove o item menos recentemente usado quando a capacidade máxima é atingida.
new LRUCache<T>(options: { maxSize: number })
Cria uma nova instância de cache LRU com capacidade máxima.
Parâmetros:
options.maxSize: Capacidade máxima do cache (obrigatório, mínimo 1)Exemplo:
// Cache LRU com capacidade máxima de 100 itens
const cache = new LRUCache<string>({ maxSize: 100 });
maxSizeProperty: number (readonly)Retorna a capacidade máxima do cache.
Complexidade: O(1)
LRUCache implementa a interface ICache<T>, então todos os métodos de BaseCache estão disponíveis:
get(key), getAsync(key), set(key, value, options), has(key), delete(key), clear(), sizeNota:
get() ou set()), ele torna-se mais recentemente usadoDTTCache<T>Estratégia de cache baseada em Dynamic TTL (TTL Dinâmico). Calcula TTL dinamicamente com base em metadados da resposta (headers HTTP, propriedades do dado, etc.).
new DTTCache<T>()
Cria uma nova instância de cache DTTC.
Exemplo:
const cache = new DTTCache<string>();
setWithDynamicTTL(key: string, value: T | Promise<T>, options: DTTCOptions<T>): Promise<void>Armazena um valor no cache com TTL calculado dinamicamente.
Parâmetros:
key: Chave do itemvalue: Valor a ser armazenado (ou Promise que resolve para o valor)options: Opções incluindo função de cálculo de TTL e metadadosExemplo:
// TTL baseado em headers HTTP
await cache.setWithDynamicTTL('api:data', responseData, {
ttlCalculator: (value, metadata) => {
const maxAge = metadata?.headers?.['cache-control'];
return parseMaxAge(maxAge) * 1000;
},
metadata: { headers: response.headers },
});
// TTL baseado em propriedade do dado
await cache.setWithDynamicTTL('product:1', product, {
ttlCalculator: (value) => {
return value.isPremium ? 7200000 : 3600000;
},
});
Nota:
ttlCalculator retornar undefined ou lançar erro, o ttl estático será usado como fallback (se fornecido)DTTCache implementa a interface ICache<T>, então todos os métodos de BaseCache estão disponíveis:
get(key), getAsync(key), set(key, value, options), has(key), delete(key), clear(), sizeNota: Para usar TTL dinâmico, use setWithDynamicTTL(). O método set() padrão funciona normalmente com TTL estático.
BaseCache<T>Classe base para cache em memória. Permite TTL opcional.
new BaseCache<T>()
Cria uma nova instância de cache.
Exemplo:
const cache = new BaseCache<string>();
const numberCache = new BaseCache<number>();
get(key: string): T | undefinedRecupera um valor do cache pela chave (síncrono).
Complexidade: O(1)
Parâmetros:
key: Chave do item a ser recuperadoRetorna: O valor associado à chave (síncrono), ou undefined se não existir, tiver expirado, ou for uma Promise ainda pendente
Nota: Para valores assíncronos (Promises), use getAsync.
Exemplo:
const value = cache.get('myKey');
if (value !== undefined) {
console.log(value);
}
getAsync(key: string): Promise<T | undefined>Recupera um valor do cache pela chave, aguardando resolução de Promises se necessário.
Complexidade: O(1) para acesso, mas pode aguardar resolução de Promise
Este método é inteligente o suficiente para:
Parâmetros:
key: Chave do item a ser recuperadoRetorna: Promise que resolve para o valor, ou undefined se não existir ou tiver expirado
Exemplo:
// Valor síncrono
const syncValue = await cache.getAsync('syncKey'); // Retorna imediatamente
// Valor assíncrono
const asyncValue = await cache.getAsync('asyncKey'); // Aguarda resolução
set(key: string, value: T | Promise<T>, options?: CacheOptions): booleanArmazena um valor no cache. Suporta valores síncronos e assíncronos (Promises).
Complexidade: O(1)
Parâmetros:
key: Chave do item a ser armazenadovalue: Valor a ser armazenado (síncrono ou Promise)options (opcional): Opções adicionais
ttl: Tempo de vida em milissegundosRetorna: true se o valor foi armazenado com sucesso
Exemplo:
// Armazenar valor síncrono
cache.set('key', 'value');
// Armazenar Promise
cache.set('key', fetch('/api/data').then(r => r.json()));
// Armazenar com TTL de 1 hora
cache.set('key', 'value', { ttl: 3600000 });
has(key: string): booleanVerifica se uma chave existe no cache e não expirou.
Complexidade: O(1)
Parâmetros:
key: Chave a ser verificadaRetorna: true se a chave existe e não expirou, false caso contrário
Exemplo:
if (cache.has('myKey')) {
const value = cache.get('myKey');
}
delete(key: string): booleanRemove um item do cache pela chave.
Complexidade: O(1)
Parâmetros:
key: Chave do item a ser removidoRetorna: true se o item foi removido, false se não existia
Exemplo:
const removed = cache.delete('myKey');
if (removed) {
console.log('Item removido com sucesso');
}
clear(): voidRemove todos os itens do cache.
Complexidade: O(n) onde n é o número de itens
Exemplo:
cache.clear();
console.log(cache.size); // 0
size: number (readonly)Retorna o número de itens ativos no cache (não expirados).
Exemplo:
cache.set('key1', 'value1');
cache.set('key2', 'value2');
console.log(cache.size); // 2
import { BaseCache } from 'cachemind';
const cache = new BaseCache<string>();
// Armazenar com expiração de 1 hora (3600000ms)
cache.set('session:user123', 'active', { ttl: 3600000 });
// Armazenar com expiração de 5 minutos
cache.set('temp:data', 'temporary', { ttl: 5 * 60 * 1000 });
// O item será automaticamente removido após expirar
setTimeout(() => {
const value = cache.get('temp:data'); // undefined (expirado)
}, 6 * 60 * 1000);
import { BaseCache } from 'cachemind';
interface User {
id: number;
name: string;
email: string;
}
const userCache = new BaseCache<User>();
userCache.set('user:1', {
id: 1,
name: 'John Doe',
email: 'john@example.com'
});
const user = userCache.get('user:1');
console.log(user?.name); // 'John Doe'
import { BaseCache } from 'cachemind';
const resultCache = new BaseCache<number>();
function expensiveCalculation(n: number): number {
// Verifica se o resultado já está em cache
const cached = resultCache.get(`calc:${n}`);
if (cached !== undefined) {
return cached;
}
// Realiza cálculo caro
const result = n * n * n; // Exemplo simplificado
// Armazena no cache por 1 hora
resultCache.set(`calc:${n}`, result, { ttl: 3600000 });
return result;
}
// Primeira chamada: calcula e armazena
const result1 = expensiveCalculation(10); // Calcula
// Segunda chamada: retorna do cache
const result2 = expensiveCalculation(10); // Cache hit!
import { BaseCache } from 'cachemind';
const apiCache = new BaseCache<{ id: string; name: string }>();
async function fetchUserData(userId: string) {
const cacheKey = `api:user:${userId}`;
// Verifica cache síncrono (valores já resolvidos)
const cached = apiCache.get(cacheKey);
if (cached) {
return cached;
}
// Faz requisição e armazena a Promise no cache
const promise = fetch(`/api/users/${userId}`)
.then(r => r.json());
// Armazena a Promise no cache por 5 minutos
apiCache.set(cacheKey, promise, { ttl: 5 * 60 * 1000 });
// Aguarda resolução (primeira vez) ou retorna valor cacheado
return await apiCache.getAsync(cacheKey);
}
import { BaseCache } from 'cachemind';
const resultCache = new BaseCache<number>();
async function expensiveAsyncCalculation(n: number): Promise<number> {
const cacheKey = `calc:${n}`;
// Verifica se já está em cache
const cached = await resultCache.getAsync(cacheKey);
if (cached !== undefined) {
return cached;
}
// Realiza cálculo assíncrono caro
const promise = new Promise<number>(resolve => {
setTimeout(() => {
resolve(n * n * n);
}, 1000);
});
// Armazena a Promise no cache
resultCache.set(cacheKey, promise, { ttl: 3600000 });
// Aguarda e retorna o resultado
return await resultCache.getAsync(cacheKey);
}
// Primeira chamada: calcula e cacheia
const result1 = await expensiveAsyncCalculation(10); // Aguarda 1s
// Segunda chamada: retorna do cache imediatamente
const result2 = await expensiveAsyncCalculation(10); // Retorna instantaneamente
A biblioteca foi projetada com modularidade em mente (RNF06). A interface ICache define o contrato base que todas as estratégias devem seguir:
interface ICache<T> {
get(key: string): T | undefined;
set(key: string, value: T, options?: CacheOptions): boolean;
has(key: string): boolean;
delete(key: string): boolean;
clear(): void;
readonly size: number;
}
Isso permite que futuras estratégias (LRU, FIFO, LFU, etc.) sejam facilmente adicionadas mantendo a mesma API.
A implementação utiliza Map nativo do JavaScript, garantindo:
get, set, has e deleteclear e size (onde n é o número de itens)Em testes com 10.000 itens:
set: ~0.001ms por operaçãoget: ~0.001ms por operaçãohas: ~0.001ms por operaçãodelete: ~0.001ms por operaçãoExecute os testes:
npm test
Com cobertura:
npm run test:coverage
Interface de testes (UI):
npm run test:ui
Estratégia baseada em TTL (Time-To-Live) que garante que todos os itens tenham tempo de expiração definido.
Características:
isStale() e getRemainingTTL() para gerenciamento avançadoExemplo:
const cache = new TTLCache<string>({ defaultTTL: 3600000 });
// Todos os itens terão TTL
cache.set('key1', 'value1'); // Usa defaultTTL
cache.set('key2', 'value2', { ttl: 5000 }); // TTL customizado
// Verificar expiração
if (cache.isStale('key1')) {
// Fazer refresh
}
Estratégia Stale-While-Revalidate (SWR) que retorna dados stale imediatamente enquanto revalida em background.
Características:
Exemplo:
import { SWRCache } from 'cachemind';
const cache = new SWRCache<string>({ defaultTTL: 3600000 });
// Configurar item com função de fetch
await cache.setWithFetch('user:1', 'initial value', {
ttl: 3600000,
fetch: async () => {
const response = await fetch('/api/user/1');
return response.json().name;
}
});
// Primeira vez: retorna valor imediatamente
const user = cache.get('user:1'); // 'initial value'
// Após expirar: retorna valor stale e revalida em background
// (o valor stale é retornado imediatamente, enquanto a revalidação acontece)
const staleUser = cache.get('user:1'); // 'initial value' (stale, mas retornado)
// Em background: fetch é chamado e cache é atualizado silenciosamente
Estratégia Least Recently Used (LRU) que remove o item menos recentemente usado quando a capacidade máxima é atingida.
Características:
Exemplo:
const cache = new LRUCache<string>({ maxSize: 3 });
// Preenche cache até capacidade máxima
cache.set('key1', 'value1');
cache.set('key2', 'value2');
cache.set('key3', 'value3');
// Acessa key1 (torna-se mais recentemente usado)
cache.get('key1');
// Adiciona novo item - key2 é removido (menos recentemente usado)
cache.set('key4', 'value4');
// key2 não está mais no cache
Estratégia Dynamic TTL (TTL Dinâmico) que calcula TTL dinamicamente com base em metadados da resposta.
Características:
Exemplo:
const cache = new DTTCache<string>();
// TTL baseado em Cache-Control header
await cache.setWithDynamicTTL('api:data', 'response data', {
ttlCalculator: (value, metadata) => {
const cacheControl = metadata?.headers?.['cache-control'];
if (cacheControl) {
const maxAgeMatch = cacheControl.match(/max-age=(\d+)/);
if (maxAgeMatch) {
return parseInt(maxAgeMatch[1], 10) * 1000;
}
}
return 3600000; // Fallback
},
metadata: {
headers: { 'cache-control': 'max-age=300' },
},
});
MIT
Contribuições são bem-vindas! Por favor, abra uma issue ou pull request.
Desenvolvido com foco em performance, modularidade e simplicidade.
FAQs
A lightweight, universal JavaScript cache library with multiple caching strategies
The npm package cachemind receives a total of 1 weekly downloads. As such, cachemind popularity was classified as not popular.
We found that cachemind demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.