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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@seedcompany/cache

v0.3.1

Published

NestJS library wrapper for external caching

Downloads

117

Readme

Yet another cache library for NestJS

This is for data that will be shared across multiple processes. Thus, the keys are strings and the values are serializable.

The goals of this library are:

  • Provide a nice interface for usage in Nestjs classes
  • Integrate easily with the existing Nestjs ecosystem
  • Leverage existing npm ecosystem for storage implementations

Setup

Import the module in your app.

CacheModule.registerAsync({
  inject: [/* config */],
  useFactory: (/* config */): CacheModuleOptions => ({
    store: // create store implementation from config
  }),
})

Usage

Decorators

@Injectable()
class Service {

  @Cache({
    key: 'foo-bar',
    ttl: { minutes: 5 },
  })
  async fooBar() {
    // ...
  }

}

However, you will probably need to cache based on the args given, so:

@Injectable()
class Service {

  @Cache((id: string, year: number) => ({
    key: `foo-bar:${id}-${year}`,
    ttl: { minutes: 5 },
  }))
  async fooBar(id: string, year: number) {
    // ...
  }

}

Service

The task you always most always want to do is skip expensive calculation if possible. So the most useful method is getOrCalculate, which saves you the boilerplate for this logic.

declare const cache: CacheService; // injected somewhere

const result = await cache.getOrCalculate({
  key: `fooBar:${id}`,
  calculate: async () => {
    // do expensive calculation
  },
  ttl: { hour: 1 },
});

Naive functionality exists as well:

await cache.get('foo');
await cache.set('foo', 'bar');
await cache.delete('foo');

Namespaces

A common use case is to namespace your cache keys, to help segment your cache store. There's a namespace method which returns a modified cache service with the given prefix.

const usersCache = cache.namespace('users:');

Note that chaining these will stack the prefixes, not override them.

cache.namespace('foo:').namespace('bar:').get('baz'); // foo:bar:baz

CacheItem

A wrapper is provided around a single cache keys as well. This could help prevent having to store another variable for a computed key, or allow it to be passed around.

const cached = cache.item('1234');
const value = cached.getOrCalculate(async () => {
  // do expensive calculation
});
handleInvalidation(cached);
function handleInvalidation(cached: CacheItem) {
  if (isStale) {
    cached.delete();
  }
}

Stores

Stores are the actual storage implementations the CacheService is backed by.

We provide stores for ioredis, keyv, lru-cache. This should cover most use cases, but you can also implement your own.

LRU / In Memory

import { LruStore } from '@seedcompany/cache/store/lru';

CacheModule.register({
  store: new LruStore({
    // options
  })
})

Redis

import { RedisStore } from '@seedcompany/cache/store/redis';
import Redis from 'ioredis';

CacheModule.register({
  store: new RedisStore(
    new Redis('redis://localhost:6379')
  )
})

Keyv

import { KeyvStore } from '@seedcompany/cache/store/keyv';
import Keyv from 'keyv';

CacheModule.register({
  store: new KeyvStore(
    new Keyv()
  )
})

Chaining Multiple Stores

Multiple stores can be chained together with the ChainStore. This could provide faster in memory cache falling back to a shared network cache.

import { ChainStore } from '@seedcompany/cache/store/chain';

CacheModule.register({
  store: new ChainStore([
    new LruStore({ max: 100 }),
    new RedisStore(),
  ])
})

Adapters

We provide a few adapters to help integrate with other libraries.

NestJS Cache Manager

Here's how to set up the NestJS Cache Manager module to be based on this one.

import { CacheModule as NestHttpCacheModule } from '@nestjs/cache-manager';
import { CacheModule, CacheService } from '@seedcompany/cache';

NestHttpCacheModule.registerAsync({
  imports: [CacheModule],
  inject: [CacheService],
  useFactory: (cache: CacheService): CacheModuleOptions => ({
    store: cache.namespace('http:').adaptTo.cacheManager(),
  }),
});

Continue on with the NestJS docs: https://docs.nestjs.com/techniques/caching#interacting-with-the-cache-store

Apollo Cache

Here's how to set up the Apollo cache to be based on this one.

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [CacheModule],
  inject: [CacheService],
  useFactory: (cache: CacheService) => ({
    cache: cache.namespace('apollo:').adaptTo.apollo(),
  }),
});

Keyv Cache

Keyv cache is a very popular cache library. Here's how to adapt our cache to its interface.

declare const cache: CacheService;

const kv = new Keyv({
  store: cache.adaptTo.keyv(),
});