npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@honico/cache

v1.7.0

Published

Injectable named caches for Honico using cache-manager and Keyv

Readme

@honico/cache

Application-scoped, injectable registry of named caches backed by the official cache-manager v7. Each lookup returns its original Cache instance, including get, set, mget, mset, del, mdel, clear, ttl, wrap, events, stores, and disconnect.

App configuration

Install @honico/cache and the Keyv adapters your app uses, such as @keyv/redis.

import { defineConfig } from '@honico/core';
import { cachePlugin, createInMemoryCache } from '@honico/cache';
import { createKeyv as createRedisCache } from '@keyv/redis';

export default defineConfig({
  autoload: { providers: ['src/**/*.service.ts'] },
  plugins: [cachePlugin],
  cache: {
    local: () => ({ stores: [createInMemoryCache()] }),
    users: (name) => ({
      stores: [createRedisCache(process.env.REDIS_URL!, {
        namespace: `my-app:${name}`,
      })],
    }),
    layered: (name) => ({
      stores: [
        createInMemoryCache(),
        createRedisCache(process.env.REDIS_URL!, { namespace: `my-app:${name}` }),
      ],
    }),
  },
});

Cache names are unique object keys and must not be blank. Each value accepts the CacheOptions (upstream options with a required, non-empty stores list), or a synchronous/asynchronous factory receiving the name and returning those options. Factories run once during plugin setup; use them for adapters so build/type-generation tools can load configuration without opening network connections. Factories that fail before returning must clean up any resources they created. Previously created caches are disconnected if a later factory fails.

Startup readiness

The manager checks every store before registration, including every layer in a cache. Redis clients exposed by @keyv/redis are connected and checked with PING; Map-backed memory stores are immediately ready. Startup rejects on a connection error, authentication error, failed ping, or timeout. Redis reconnect loops are stopped on failure, and initialized caches are disconnected. Startup logs report ready only after all configured caches pass their checks.

startupTimeout sets the timeout per store in milliseconds (default: 5_000). For other adapters, provide startupCheck; Keyv has no universal readiness API. This callback is invoked for each store and overrides the built-in check:

custom: () => ({
  stores: [createMyKeyvStore()],
  startupTimeout: 3_000,
  startupCheck: async (store, signal) => {
    await verifyMyAdapterConnection(store, signal);
  },
})

The callback must reject on failure and honor the abort signal to stop pending work. It must not rely on a cache read that silently turns connection errors into cache misses. Redis PING verifies connectivity and authentication, not write permissions or readiness of every cluster node. There is no automatic degraded startup or memory fallback after a readiness failure.

Every named cache must declare at least one Keyv store. Missing stores and empty arrays are rejected by TypeScript and at runtime, including factory results. For memory caching, explicitly use stores: [createInMemoryCache()]. An empty cache registry is allowed.

All Keyv-compatible adapters are supported through stores: [new Keyv({ store: adapter })], or an adapter's official createKeyv helper. No adapter whitelist or Redis-specific configuration is imposed. Install adapters in the consuming app; Redis is not required by this package.

Give each cache its own Keyv/adapter instances and a distinct namespace when sharing a backend. Registry names do not rewrite adapter namespaces. This preserves adapter-specific configuration and prevents one cache's keys or clear() from affecting another. Follow the adapter's namespace/clear semantics. Leave cacheId unset unless you specifically need to override upstream's unique ID; reusing IDs can coalesce concurrent wrap calls between caches.

Injection

import { Inject, Provide } from '@honico/core';
import { CacheManager } from '@honico/cache';

@Provide()
export class UserService {
  @Inject(CacheManager)
  cacheManager!: CacheManager;

  getUser(id: string) {
    return this.cacheManager.getCache('users').wrap(
      `user:${id}`,
      async () => ({ id }), // Replace with the database lookup
      60_000, // Per-entry TTL in milliseconds
    );
  }
}

CacheManager is shared across requests in one app, not across app instances. getCache(name) returns the same instance each time and throws for unknown names. No implicit default cache is created. TTLs are milliseconds; cache misses return undefined. Error/event behavior follows cache-manager and the selected Keyv adapter without an additional wrapper.

Specify TTLs per entry where the data's freshness requirements are known: await cache.set('user:123', user, 60_000) or await cache.wrap('user:123', loadUser, 60_000). App configuration and examples omit default TTLs. The upstream default TTL option remains available, but is not required. Without a per-entry TTL or a cache/adapter default, entries have no time-based expiration.

For manual use, call await CacheManager.create(configuration). Call await manager.close() during your application's shutdown to disconnect all managed caches without clearing their data. Closing is idempotent and attempts every cache even if one fails. Honico currently has no plugin shutdown hook, so the package does not install process signal handlers. Do not share owned connections with unrelated services that must remain open after closing.

The example API configures local with memory and shared with @keyv/redis. REDIS_URL selects the Redis server (the adapter defaults to localhost when omitted). A CacheExampleService demonstrates injection. Run package build, typecheck and test scripts with npm run <script> --workspace=@honico/cache.