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

@gomomento-poc/momento-sequelize-cache

v0.3.1

Published

Momento read-aside cache client for sequelize

Downloads

905

Readme

project status project stability

Momento-Sequelize Read Aside Cache Client

What and why?

This project provides a Momento-backed read-aside caching implemenation for sequelize. The goal is to provide an interface for caching sequelize queries.

You can use Momento as your caching engine for any relational databases that are a part of sequelize's dialects.

Prerequisites

  • To use this library, you will need a Momento API key. You can generate one using the Momento Console.
  • The examples use a cache model-cache that you will need to create in your Momento account. You can create them on the console as well!
    • As an alternative, you can pass a flag while instantiating our caching wrapper (see snippet below).
  • The examples will utilize your API key via the environment variable MOMENTO_API_KEY you set.

Usage


import { Sequelize, DataTypes } from 'sequelize';
import { Configurations, CredentialProvider } from "@gomomento/sdk";
import { MomentoClientGenerator } from "@gomomento-poc/momento-sequelize-cache";
import { LoggerFactory } from "@gomomento-poc/momento-sequelize-cache";
import { modelCacheFactory } from "@gomomento-poc/momento-sequelize-cache";

const userSchema = {
    username: {
        type: DataTypes.STRING,
    },
    id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
    },
    birthday: DataTypes.DATE,
    age: DataTypes.INTEGER,
    isActive: DataTypes.BOOLEAN,
    accountBalance: DataTypes.FLOAT,
};

const User = sequelize.define("User", userSchema);

async function insertUser(username: string, birthday: Date, age: number, isActive: boolean, accountBalance: number) {
    await User.create({ username, birthday, age, isActive, accountBalance });
}

async function doWork() {


    await User.sync({force: true});
    await UserGroup.sync({force: true});
    
    const birthday = new Date(Date.UTC(1992, 5, 21));
    const age = 29;
    const isActive = true;
    const accountBalance = 70.07;

    // prepare the data; in real world these will happen elsewhere and we will be employing this project
    // primarily as a read-aside cache
    await insertUser('user1', birthday, age, isActive, accountBalance);
    await insertUser('user2', birthday, age, isActive, accountBalance);

    // prepare momento model cache client
    // pass {forceCreateCache: true} if want to force create caches
   // pass modelCacheName for a cache name else it defaults to model-cache
  const momentoClient = MomentoClientGenerator.getInstance({
        configuration: Configurations.Laptop.latest(),
        credentialProvider: CredentialProvider.fromEnvironmentVariable({environmentVariableName: 'MOMENTO_API_KEY'}),
        forceCreateCache: true,
        modelCacheName: "my-model-cache",
        defaultTtlSeconds: 60,
    });

    const log = LoggerFactory.createLogger({ logLevel: 'debug' })
    const momentoSequelizeClient = await modelCacheFactory(momentoClient, log);

    log.debug({ userId : 1 }, "Issuing a read for one user findByPk")
    const UserFoundByPK = await momentoSequelizeClient.wrap(User).findByPk(1)
    log.debug({user: JSON.stringify(UserFoundByPK)}, "Found user: ");
    

    const UserFindAll = await momentoSequelizeClient.wrap(User).findAll();
    log.debug({user: JSON.stringify(UserFindAll)}, "Found users: ");

}

doWork().catch(console.error);

You can find an example with more commands in our examples directory.

About the interface and mutating commands

The wrapper or interface provides a wrapper over the below sequelize operations: The wrapper or interface provides a wrapper over the below sequelize operations:

  • findOne()
  • findByPK()
  • findAll()
  • count()

When you make a query using the interface, you need to provide your sequelize model, such as User in the below command:

    const userFoundByPK = await momentoSequelizeClient.wrap(User).findByPk(1)

There are 3 things this command will do:

  • First query your Momento cache Users with an id (primary key) of 1. Note that a Momento cache with the name Users should exist in your account.
  • If there's a cache miss, it queries your database with a table Users using the sequelize Model that you provided.
  • It stores the result of the query in Momento using a custom cache key that mimics the sequelize query. For instance, the above findByPk query will translate to a cache key:

model-cache:findByPk:Users:{"where":{"id":1}}

Any future calls to the same query will result in a cache hit until the key expires.

The return type of the call is one or more instances of the sequelize model that matches the query. Sequelize models by default have commands such as save(), destroy(), update() that you'd potentially not want to be exposed from your returned cache instance. Therefore, the returned type will only allow to access the attributes directly through an attributeName, such as userFoundByPK.username or through an accessor such as userFoundByPK.get('username'). Any non-existent attributes or a method other than get() will result in a TypeError.