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

@leapfrogtechnology/async-store

v2.1.0

Published

Global store utility for an async operation lifecycle and chain of callbacks

Downloads

4,323

Readme

Async Store

npm Codecov LICENSE PRs Welcome

Global store utility for an async operation lifecycle and chain of callbacks. It is a utility tool similar to continuation-local-storage which allows us to set and get values that are scoped to the lifetime of these chains of callbacks.

Note: async-store uses domain Node.js module under the hood.

It is recommended that you read about domain before using this package.

Installation

npm install @leapfrogtechnology/async-store
yarn add @leapfrogtechnology/async-store

Version Compatibility

| Node Version | Async Store Version | | ----------------- | ------------------- | | 14.17.0 and above | >= 2.0.0 | | 14.17.0 and below | >= 1.0.0 < 2.0.0 |

Usage

JavaScript Example

const store = require('@leapfrogtechnology/async-store');

store.initialize()(callback);

function callback() {
  store.set({ foo: 'Hello', bar: 'World' });

  Promise.resolve()
    .then(() => {
      console.log('Value of foo: ', store.get('foo'));
    })
    .then(() => {
      console.log('Value of bar: ', store.get('bar'));
    })
    .then(() => {
      console.log('Value of foo: ', store.get('foo'));
    })
    .then(() => {
      console.log('Value of bar: ', store.get('bar'));
    });
}

Output

On initialization the following output in the console is seen:

Value of foo:  Hello
Value of bar:  World
Value of foo:  Hello
Value of bar:  World

TypeScript Example

import * as store from '@leapfrogtechnology/async-store';

store.initialize()(callback);

function callback() {
  store.set({ foo: 'Hello', bar: 'World' });

  Promise.resolve()
    .then(() => {
      console.log('Value of foo: ', store.get('foo'));
    })
    .then(() => {
      console.log('Value of bar: ', store.get('bar'));
    })
    .then(() => {
      console.log('Value of foo: ', store.get('foo'));
    })
    .then(() => {
      console.log('Value of bar: ', store.get('bar'));
    });
}

Output

On initialization the following output in the console is seen:

Value of foo:  Hello
Value of bar:  World
Value of foo:  Hello
Value of bar:  World

Express Example

const { randomUUID } = require('crypto');
const express = require('express');
const store = require('@leapfrogtechnology/async-store');

const app = express();
const port = 3000;

// Initialize async store
app.use(store.initializeMiddleware());

// Set request Id in store
app.use((req, res, next) => {
  store.set({ reqId: randomUUID() });
  next();
});

// Get request Id from store
app.get('/', (req, res) => {
  const reqId = store.get('reqId');
  console.log(`Request Id: ${reqId}`);

  res.json({ message: 'Hello World', reqId });
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Output

On request to http://localhost:3000, the following output in the console is seen:

Example app listening on port 3000!
Request Id: 03d8bd27-9097-427a-9460-7d8d9576f156

Fastify Example

const { randomUUID } = require('crypto');
const fastifyPlugin = require('fastify-plugin');
const store = require('@leapfrogtechnology/async-store');

const fastifyServer = require('fastify')({ logger: true });

const port = 3000;

fastifyServer.register(fastifyPlugin(store.initializeFastifyPlugin()));

fastifyServer.register((fastifyInstance, opts, done) => {
  fastifyInstance.addHook('preHandler', (req, reply, done) => {
    store.set({ reqId: randomUUID() });
    done();
  });

  fastifyInstance.get('/', (req, reply) => {
    const reqId = store.get('reqId');
    console.log(`Request Id: ${reqId}`);

    reply.send({ message: 'Hello World', reqId });
  });

  done();
});

const start = async () => {
  try {
    await fastifyServer.listen(port);
    fastifyServer.log.info(`Server is listening at ${port}`);
  } catch (err) {
    fastifyServer.log.error(err);
    process.exit(1);
  }
};

start();

Output

On request to http://localhost:3000, the following output in the console is seen:

{"level":30,"time":1641890535421,"pid":12489,"hostname":"macbookpro","msg":"Server listening at http://[::1]:3000"}
{"level":30,"time":1641890535421,"pid":12489,"hostname":"macbookpro","msg":"Server is listening at 3000"}
{"level":30,"time":1641890539755,"pid":12489,"hostname":"macbookpro","reqId":"req-1","req":{"method":"GET","url":"/","hostname":"localhost:3000","remoteAddress":"::1","remotePort":51539},"msg":"incoming request"}
Request Id: aa6e86e9-c9d4-414a-8670-9aeaf2a8d932
{"level":30,"time":1641890539759,"pid":12489,"hostname":"macbookpro","reqId":"req-1","res":{"statusCode":200},"responseTime":3.7935830000787973,"msg":"request completed"}

API Docs

initialize()

Initialize the async store based on the adapter provided.

  • @param {AsyncStoreAdapter} [adapter=AsyncStoreAdapter.DOMAIN] - Async store adapter to use.
  • @returns {(params: AsyncStoreParams) => void} - Returns a function that takes a callback which will be triggered once the store has been initialized.
const store = require('@leapfrogtechnology/async-store');

store.initialize()(callback);

function callback() {
  // Do something with the store.
}

initializeMiddleware()

Middleware to initialize the async store and make it accessible from all the subsequent middlewares or async operations triggered afterwards.

  • @param {AsyncStoreAdapter} [adapter=AsyncStoreAdapter.DOMAIN] - Async store adapter to use.
  • @returns {(req, res, next) => void} - Returns the express middleware function.
const express = require('express');
const store = require('@leapfrogtechnology/async-store');

// Initialize async store
app.use(store.initializeMiddleware());

initializeFastifyPlugin()

Plugin to initialize the async store and make it accessible from all the subsequent plugin or async operations triggered afterwards from fastify server.

  • @param {AsyncStoreAdapter} [adapter=AsyncStoreAdapter.DOMAIN] - Async store adapter to use.
  • @returns {(fastifyInstance, opts, next) => void} - Returns the fastify plugin callback.
const fastify = require('fastify');
const fastifyPlugin = require('fastify-plugin');
const store = require('@leapfrogtechnology/async-store');

// Initialize async store
fastify.register(fastifyPlugin(store.initializeFastifyPlugin()));

isInitialized()

Check if the store has been initialized or not.

  • @returns {boolean} - Returns either true or false.
if (store.isInitialized()) {
  // Do something.
}

set()

Persists properties in the store.

  • @params {any} properties - Persist properties to set in store.
  • @returns {void}
store.set({ foo: 'Hello', bar: 'World' });

get()

Gets a value by a key from the store.

  • @params {string} key - Key to get from the store.
  • @returns {any} - Returns the value persisted in the store by key which could be null if key not found. Any error caught during the retrieval will be thrown and cascaded.
const foo = store.get('foo');

getAll()

Gets all values from the store.

  • @returns {any} - Returns all values persisted in the store. Any error caught during the retrieval will be thrown and cascaded.
store.set({ foo: 'Hello', bar: 'World', baz: 'Baz' });

// Get all the values from the store.
const values = store.getAll(); // { foo: 'Hello', bar: 'World', baz: 'Baz' }

// De-structure and get only few of them.
const { foo, baz } = store.getAll();

getByKeys()

Gets multiple values from the store for each of the keys provided.

  • @params {string[] keys} - Keys to get from the store.
  • @returns {T[]} - Returns an array of values. Order of the values is same as the order of the keys in the array.
const [a, b, sum] = store.getByKeys(['a', 'b', 'sum']);

find()

Gets a value by a key from the store. If anything fails, it returns null without emitting error event.

  • @params {string} key - Key to get from the store.
  • @returns {any} - Returns the value persisted in the store by key which could be null if key not found. Any error caught during the retrieval will be supressed and null value is returned.
const foo = store.find('foo');

getId()

Gets the unique store id created for the current context/scope. Example: If used in express, it returns unique store id per request.

  • @returns {string | undefined} - Returns the unique store id.
const requestIdentifier = store.getId();

getShortId()

Gets the short unique store id created for the current context/scope.

Note: This is same as getId(); the difference being it only returns the first 8 characters.

  • @returns {string | undefined} - Returns the short unique store id.
const requestIdentifier = store.getShortId();

Example Projects

  1. Node Web Server (TypeScript)
  2. Express Web Server (TypeScript)
  3. Koa Web Server (TypeScript)
  4. Fastify Web Server (TypeScript)

Changelog

Check the CHANGELOG for release history.

Contributing

Any types of contributions are welcome. Feel free to send pull requests or create issues.

License

Licensed under The MIT License.