{"id":19551777,"url":"https://github.com/leapfrogtechnology/async-store","last_synced_at":"2025-08-19T19:25:55.627Z","repository":{"id":35023692,"uuid":"179055373","full_name":"leapfrogtechnology/async-store","owner":"leapfrogtechnology","description":"Global store utility for an async operation lifecycle and chain of callbacks.","archived":false,"fork":false,"pushed_at":"2025-04-09T13:01:18.000Z","size":1819,"stargazers_count":10,"open_issues_count":5,"forks_count":11,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-04-18T18:10:20.369Z","etag":null,"topics":["async","async-local-storage","async-operation-lifecycle","asynchronous","context","domain","hacktoberfest","nodejs","store"],"latest_commit_sha":null,"homepage":"https://yarn.pm/@leapfrogtechnology/async-store","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leapfrogtechnology.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-02T10:36:46.000Z","updated_at":"2024-11-25T03:57:49.000Z","dependencies_parsed_at":"2024-10-18T12:13:47.713Z","dependency_job_id":null,"html_url":"https://github.com/leapfrogtechnology/async-store","commit_stats":{"total_commits":366,"total_committers":14,"mean_commits":"26.142857142857142","dds":0.7622950819672132,"last_synced_commit":"f05a85af86f81af2620c3f00761e0a838ff31917"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapfrogtechnology%2Fasync-store","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapfrogtechnology%2Fasync-store/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapfrogtechnology%2Fasync-store/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leapfrogtechnology%2Fasync-store/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leapfrogtechnology","download_url":"https://codeload.github.com/leapfrogtechnology/async-store/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251051388,"owners_count":21528787,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","async-local-storage","async-operation-lifecycle","asynchronous","context","domain","hacktoberfest","nodejs","store"],"created_at":"2024-11-11T04:15:03.142Z","updated_at":"2025-04-26T20:31:17.573Z","avatar_url":"https://github.com/leapfrogtechnology.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Async Store\n\n[![npm](https://img.shields.io/npm/v/@leapfrogtechnology/async-store.svg?style=flat-square)](https://www.npmjs.com/package/@leapfrogtechnology/async-store)\n[![Codecov](https://img.shields.io/codecov/c/github/leapfrogtechnology/async-store?style=flat-square)](https://codecov.io/gh/leapfrogtechnology/async-store)\n[![LICENSE](https://img.shields.io/github/license/leapfrogtechnology/async-store.svg?style=flat-square)](https://github.com/leapfrogtechnology/async-store/blob/master/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/leapfrogtechnology/async-store#contributing)\n\nGlobal store utility for an async operation lifecycle and chain of callbacks. It is a utility tool similar to [continuation-local-storage](https://github.com/othiym23/node-continuation-local-storage) which allows us to set and get values that are scoped to the lifetime of these chains of callbacks.\n\n**Note: async-store uses [domain](https://nodejs.org/api/domain.html) Node.js module under the hood.**\n\nIt is recommended that you read about domain before using this package.\n\n## Installation\n\n```sh\nnpm install @leapfrogtechnology/async-store\n```\n\n```sh\nyarn add @leapfrogtechnology/async-store\n```\n\n## Version Compatibility\n\n| Node Version      | Async Store Version |\n| ----------------- | ------------------- |\n| 14.17.0 and above | \u003e= 2.0.0            |\n| 14.17.0 and below | \u003e= 1.0.0 \u003c 2.0.0    |\n\n## Usage\n\n### JavaScript Example\n\n```js\nconst store = require('@leapfrogtechnology/async-store');\n\nstore.initialize()(callback);\n\nfunction callback() {\n  store.set({ foo: 'Hello', bar: 'World' });\n\n  Promise.resolve()\n    .then(() =\u003e {\n      console.log('Value of foo: ', store.get('foo'));\n    })\n    .then(() =\u003e {\n      console.log('Value of bar: ', store.get('bar'));\n    })\n    .then(() =\u003e {\n      console.log('Value of foo: ', store.get('foo'));\n    })\n    .then(() =\u003e {\n      console.log('Value of bar: ', store.get('bar'));\n    });\n}\n```\n\n#### Output\n\nOn initialization the following output in the console is seen:\n\n```\nValue of foo:  Hello\nValue of bar:  World\nValue of foo:  Hello\nValue of bar:  World\n```\n\n### TypeScript Example\n\n```js\nimport * as store from '@leapfrogtechnology/async-store';\n\nstore.initialize()(callback);\n\nfunction callback() {\n  store.set({ foo: 'Hello', bar: 'World' });\n\n  Promise.resolve()\n    .then(() =\u003e {\n      console.log('Value of foo: ', store.get('foo'));\n    })\n    .then(() =\u003e {\n      console.log('Value of bar: ', store.get('bar'));\n    })\n    .then(() =\u003e {\n      console.log('Value of foo: ', store.get('foo'));\n    })\n    .then(() =\u003e {\n      console.log('Value of bar: ', store.get('bar'));\n    });\n}\n```\n\n#### Output\n\nOn initialization the following output in the console is seen:\n\n```\nValue of foo:  Hello\nValue of bar:  World\nValue of foo:  Hello\nValue of bar:  World\n```\n\n### Express Example\n\n```js\nconst { randomUUID } = require('crypto');\nconst express = require('express');\nconst store = require('@leapfrogtechnology/async-store');\n\nconst app = express();\nconst port = 3000;\n\n// Initialize async store\napp.use(store.initializeMiddleware());\n\n// Set request Id in store\napp.use((req, res, next) =\u003e {\n  store.set({ reqId: randomUUID() });\n  next();\n});\n\n// Get request Id from store\napp.get('/', (req, res) =\u003e {\n  const reqId = store.get('reqId');\n  console.log(`Request Id: ${reqId}`);\n\n  res.json({ message: 'Hello World', reqId });\n});\n\napp.listen(port, () =\u003e console.log(`Example app listening on port ${port}!`));\n```\n\n#### Output\n\nOn request to `http://localhost:3000`, the following output in the console is seen:\n\n```\nExample app listening on port 3000!\nRequest Id: 03d8bd27-9097-427a-9460-7d8d9576f156\n```\n\n### Fastify Example\n\n```js\nconst { randomUUID } = require('crypto');\nconst fastifyPlugin = require('fastify-plugin');\nconst store = require('@leapfrogtechnology/async-store');\n\nconst fastifyServer = require('fastify')({ logger: true });\n\nconst port = 3000;\n\nfastifyServer.register(fastifyPlugin(store.initializeFastifyPlugin()));\n\nfastifyServer.register((fastifyInstance, opts, done) =\u003e {\n  fastifyInstance.addHook('preHandler', (req, reply, done) =\u003e {\n    store.set({ reqId: randomUUID() });\n    done();\n  });\n\n  fastifyInstance.get('/', (req, reply) =\u003e {\n    const reqId = store.get('reqId');\n    console.log(`Request Id: ${reqId}`);\n\n    reply.send({ message: 'Hello World', reqId });\n  });\n\n  done();\n});\n\nconst start = async () =\u003e {\n  try {\n    await fastifyServer.listen(port);\n    fastifyServer.log.info(`Server is listening at ${port}`);\n  } catch (err) {\n    fastifyServer.log.error(err);\n    process.exit(1);\n  }\n};\n\nstart();\n```\n\n#### Output\n\nOn request to `http://localhost:3000`, the following output in the console is seen:\n\n```\n{\"level\":30,\"time\":1641890535421,\"pid\":12489,\"hostname\":\"macbookpro\",\"msg\":\"Server listening at http://[::1]:3000\"}\n{\"level\":30,\"time\":1641890535421,\"pid\":12489,\"hostname\":\"macbookpro\",\"msg\":\"Server is listening at 3000\"}\n{\"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\"}\nRequest Id: aa6e86e9-c9d4-414a-8670-9aeaf2a8d932\n{\"level\":30,\"time\":1641890539759,\"pid\":12489,\"hostname\":\"macbookpro\",\"reqId\":\"req-1\",\"res\":{\"statusCode\":200},\"responseTime\":3.7935830000787973,\"msg\":\"request completed\"}\n```\n\n## API Docs\n\n### initialize()\n\nInitialize the async store based on the adapter provided.\n\n- `@param {AsyncStoreAdapter} [adapter=AsyncStoreAdapter.DOMAIN]` - Async store adapter to use.\n- `@returns {(params: AsyncStoreParams) =\u003e void}` - Returns a function that takes a callback which will be triggered once the store has been initialized.\n\n```js\nconst store = require('@leapfrogtechnology/async-store');\n\nstore.initialize()(callback);\n\nfunction callback() {\n  // Do something with the store.\n}\n```\n\n### initializeMiddleware()\n\nMiddleware to initialize the async store and make it accessible from all the subsequent middlewares or async operations triggered afterwards.\n\n- `@param {AsyncStoreAdapter} [adapter=AsyncStoreAdapter.DOMAIN]` - Async store adapter to use.\n- `@returns {(req, res, next) =\u003e void}` - Returns the express middleware function.\n\n```js\nconst express = require('express');\nconst store = require('@leapfrogtechnology/async-store');\n\n// Initialize async store\napp.use(store.initializeMiddleware());\n```\n\n### initializeFastifyPlugin()\n\nPlugin to initialize the async store and make it accessible from all the subsequent plugin or async operations triggered afterwards from fastify server.\n\n- `@param {AsyncStoreAdapter} [adapter=AsyncStoreAdapter.DOMAIN]` - Async store adapter to use.\n- `@returns {(fastifyInstance, opts, next) =\u003e void}` - Returns the fastify plugin callback.\n\n```js\nconst fastify = require('fastify');\nconst fastifyPlugin = require('fastify-plugin');\nconst store = require('@leapfrogtechnology/async-store');\n\n// Initialize async store\nfastify.register(fastifyPlugin(store.initializeFastifyPlugin()));\n```\n\n### isInitialized()\n\nCheck if the store has been initialized or not.\n\n- `@returns {boolean}` - Returns either true or false.\n\n```js\nif (store.isInitialized()) {\n  // Do something.\n}\n```\n\n### set()\n\nPersists properties in the store.\n\n- `@params {any} properties` - Persist properties to set in store.\n- `@returns {void}`\n\n```js\nstore.set({ foo: 'Hello', bar: 'World' });\n```\n\n### get()\n\nGets a value by a key from the store.\n\n- `@params {string} key` - Key to get from the store.\n- `@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.\n\n```js\nconst foo = store.get('foo');\n```\n\n### getAll()\n\nGets all values from the store.\n\n- `@returns {any}` - Returns all values persisted in the store. Any error caught during the retrieval will be thrown and cascaded.\n\n```js\nstore.set({ foo: 'Hello', bar: 'World', baz: 'Baz' });\n\n// Get all the values from the store.\nconst values = store.getAll(); // { foo: 'Hello', bar: 'World', baz: 'Baz' }\n\n// De-structure and get only few of them.\nconst { foo, baz } = store.getAll();\n```\n\n### getByKeys()\n\nGets multiple values from the store for each of the keys provided.\n\n- `@params {string[] keys}` - Keys to get from the store.\n- `@returns {T[]}` - Returns an array of values. Order of the values is same as the order of the keys in the array.\n\n```js\nconst [a, b, sum] = store.getByKeys(['a', 'b', 'sum']);\n```\n\n### find()\n\nGets a value by a key from the store. If anything fails, it returns `null` without emitting error event.\n\n- `@params {string} key` - Key to get from the store.\n- `@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.\n\n```js\nconst foo = store.find('foo');\n```\n\n### getId()\n\nGets the unique store id created for the current context/scope.\nExample: If used in express, it returns unique store id per request.\n\n- `@returns {string | undefined}` - Returns the unique store id.\n\n```js\nconst requestIdentifier = store.getId();\n```\n\n### getShortId()\n\nGets the short unique store id created for the current context/scope.\n\nNote: This is same as `getId();` the difference being it only returns the first 8 characters.\n\n- `@returns {string | undefined}` - Returns the short unique store id.\n\n```js\nconst requestIdentifier = store.getShortId();\n```\n\n## Example Projects\n\n1. [Node Web Server (TypeScript)](examples/node-http-server-ts)\n2. [Express Web Server (TypeScript)](examples/express-http-server-ts)\n3. [Koa Web Server (TypeScript)](examples/koa-http-server-ts)\n4. [Fastify Web Server (TypeScript)](examples/fastify-http-server-ts)\n\n## Changelog\n\nCheck the [CHANGELOG](CHANGELOG.md) for release history.\n\n## Contributing\n\nAny types of contributions are welcome. Feel free to send pull requests or create issues.\n\n## License\n\nLicensed under [The MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleapfrogtechnology%2Fasync-store","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleapfrogtechnology%2Fasync-store","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleapfrogtechnology%2Fasync-store/lists"}