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

seqache

v0.0.5

Published

Simple and effective redis cache for sequelize :)

Downloads

7

Readme

seqache

Simple and effective redis cache for sequelize :)

Why?

Caching modules for sequelize are very complicated. I wanted something easy that implements the following basic strategy.

  • Cache all findAll and findOne queries per model.
  • Have model level TTL (time to live) values so different models can be cached differently.
  • Automatically invalidate/purge caches whenever an update/insert/delete command is run on the model
  • Use redis. Yes, because what else is there to use?

Using Seqache

Install:

npm install --save seqache or yar add seqache.

Require and initialize.

let Cache = require('seqache');
let options = {
    redis: myRedisInstance,
    log: true,
    keyPrefix: 'seqache',
    maxSize: 1000,
};
let cache = new Cache(options);

All Options

redis

Type: Object Expects an instance of redis or ioredis

Defaults to ioredis with default redis port and database.

log

Type: Boolean|Function A function used to print your logs or simply true to enable default (console.log) logging or false to disable logging.

Default is false

keyPrefix

Type: String A string used to prefix all keys as they are cached.

Default is seqache

maxSize

Type: Integer Caches can balloon in size. Set maximum redis hash size.

Default is 1000

This global option can be overridden for each model.

ttl

Type: Integer Total time to live. This determines how long a cache is kept. Value is in seconds as it uses redis.expire method.

Default is 86,400.

This global option can be overridden for each model.

Wrapping your models

Seqache works by adding special cache methods to your sequelize models. To do so, you need to wrap the models as shown below.

    // sequelize initialization & other code
    ...
    // our model
    const User = sequelize.define('User', {
        // Model attributes are defined here
        firstName: {
            type: DataTypes.STRING,
            allowNull: false
        },
        lastName: {
            type: DataTypes.STRING
            // allowNull defaults to true
        }
        }, {
        // Other model options go here
        hooks : {...}
    });

    // wrap the model
    cache.wrap(User, [ttl, maxSize]);

Wrapping a model adds the .cache key to the model object. .cache contains the convenience methods findOne, findAll and purge, all of which return promises.

NOTE: You can pass model level ttl and maxSize values while wrapping a model.

These will be respected and used for caching that model only!

Querying With Cache

To see how seqache improves your cached queries, simply do the following:

// findAll
User.cache.findAll().then(console.log).catch(console.error);

// findOne
User.cache.findOne().then(console.log).catch(console.error);

// in case you want to purge the cache for any reason
User.cache.purge().then(console.log).catch(console.error);

NOTE:

Wrapping your model adds extra afterUpdate, afterDestroy and afterCreate hooks that are used to purge model caches.

As a result, you almost will never need to manually run .cache.purge() as it is done automagically for you whenever the data changes.

These hooks do not override your other hooks so sequelize functions exactly as expected.


Also, under the hood, cache.findAll and cache.FindOne run the respective sequelize functions and pass all your intended parameters. No monkey patching or other shenanigans :)


When using paranoid tables, AfterDestroy hooks are not triggered as expected. This issue has been extensively discussed Here. You will need to add individualHooks:true to force the hook to fire. This is important because the hook is used to invalidate old caches. See example below.

User.destroy({
    where: {
        id: 1234,
    },
    individualHooks: true,
});

Overall, this is very good practice as even in associations, it escalates individual hooks across all affected models which in turn invalidates all related caches!

Contributing

I need your support. Hit me up and let's make this a better module!