{"id":45161092,"url":"https://github.com/alesmenzel/cache","last_synced_at":"2026-02-20T05:32:05.786Z","repository":{"id":33660591,"uuid":"157032193","full_name":"alesmenzel/cache","owner":"alesmenzel","description":"Async function cache 🎲","archived":false,"fork":false,"pushed_at":"2023-01-03T15:18:29.000Z","size":1259,"stargazers_count":2,"open_issues_count":15,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-28T19:56:11.795Z","etag":null,"topics":["cache","function","memoize"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/alesmenzel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-10T23:53:29.000Z","updated_at":"2019-06-26T08:52:38.000Z","dependencies_parsed_at":"2023-01-15T01:55:00.120Z","dependency_job_id":null,"html_url":"https://github.com/alesmenzel/cache","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/alesmenzel/cache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alesmenzel%2Fcache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alesmenzel%2Fcache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alesmenzel%2Fcache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alesmenzel%2Fcache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alesmenzel","download_url":"https://codeload.github.com/alesmenzel/cache/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alesmenzel%2Fcache/sbom","scorecard":{"id":179467,"data":{"date":"2025-08-11","repo":{"name":"github.com/alesmenzel/cache","commit":"6fb19cf91913450b1d4c0ebd8c64e01c5084f375"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"65 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-3gx7-xhv7-5mx3","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-6fw4-hr69-g3rv","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-35q2-47q7-3pc3","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7","Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg","Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8","Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2","Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T18:31:37.349Z","repository_id":33660591,"created_at":"2025-08-16T18:31:37.349Z","updated_at":"2025-08-16T18:31:37.349Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29642855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T05:21:04.652Z","status":"ssl_error","status_checked_at":"2026-02-20T05:21:04.238Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cache","function","memoize"],"created_at":"2026-02-20T05:32:05.723Z","updated_at":"2026-02-20T05:32:05.775Z","avatar_url":"https://github.com/alesmenzel.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎲 Cache [![npm version](https://badge.fury.io/js/%40alesmenzel%2Fcache.svg)](https://badge.fury.io/js/%40alesmenzel%2Fcache)\n\nCaching module for asynchrounous callback functions.\n\n## Installation\n\n```bash\nnpm i @alesmenzel/cache\n```\n\n## Storages (built in)\n\nSee [examples](./example) directory too see the usage of each storage.\n\n| code                            | description                                                                          |\n| ------------------------------- | ------------------------------------------------------------------------------------ |\n| `new RedisStorage(redisClient)` | Redis storage, requires [redis](https://www.npmjs.com/package/redis) module to work. |\n\n## Usage\n\n### Configuration\n\nSet up the cache service with appropriete storage, in our case it is redis. Function `createCache` accepts the storage and also [options](#options), those can be overridden when registering a function (see code below).\n\n```js\nconst redis = require('redis');\nconst { createCache, RedisStorage } = require('@alesmenzel/cache');\n\nconst redis = redis.createClient('redis://localhost:6379');\nredis.on('error', err =\u003e {\n  // handle error\n});\n\nconst Cache = createCache({\n  storage: new RedisStorage(redis),\n  ttl: '30min', // time to keep the cache in storage\n  precache: '25min', // if we call the cached function after 25minutes and before the cache is expired (30min), it will seamlessly recache and update the ttl for another 30mins (when precaching, the data are returned from cache immediately and the original function is run in the background)\n  prefix: 'cache', // prefix all cache keys\n});\nCache.on('error', err =\u003e {\n  // handle error (e.g. when storage fails, or original function call fails in precaching)\n});\n```\n\n### Registering a function\n\nThe following code illustrates our service we want to cache. Note, that the function must\nalways have a callback as its last parameter.\n\n```js\n// Function to cache, must have a callback as last parameter\nconst getSum = (a, b, next) =\u003e {\n  setTimeout(() =\u003e {\n    next(null, a + b);\n  }, 5000);\n};\n```\n\nHere we create the actual caching function. Function `Cache.register` accepts the function to cache and options as the second parameter. Those [options](#options) will override the default configuration (set in `createCache`) for this particular caching function.\n\n```js\n// Expensive function we want to cache\nconst myCostlyFunction = (a, b, next) =\u003e {\n  setTimeout(() =\u003e {\n    next(null, a + b);\n  }, 10000);\n}\n\n// Here we use the `register` function from the configuratino example\n// Notice we can override the global TTL and precache options\nconst { cache, clear } = Cache.register(myCostlyFunction, {\n  ttl: '60min',\n  precache: '45min',\n  key: 'app:myCostlyFunction'\n});\n\n// `cache` is a wrapper function that accepts the same parameters as your original function\n// `clear` is function that lets you clear the cache (it will delete cache for all\n// inputs of the function)\ncache(10, 30, (err, sum) =\u003e {\n  // returns `sum = 40` from the original function (because no cache was found)\n}\n\n// Imagine some time passed (e.g. 30min)\n// We call the same function with the same parameters\ncache(10, 30, (err, sum) =\u003e {\n  // returns `sum = 40` from the cache (because we set the ttl to 60min)\n}\n\n// More time passes (e.g. another 20min)\ncache(10, 30, (err, sum) =\u003e {\n  // returns `sum = 40` from the cache (because we set the ttl to 60min)\n  // but also requests new data from the original function because we are in precache phase\n  // Note that we still return cached data immediately and call the original\n  // function in the background.\n}\n```\n\n## Options\n\n### Create cache options\n\nAny option that is used on `register` can also be set as a default value in `createCache`.\n\n| name      | description                                                                                                                                                  | default |\n| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |\n| `storage` | Storage engine to use. Choose from the built-in `MemoryStorage` or `RedisStorage`. Otherwise you can iplement a custom one (see (storages)[`./src/storage`]) | -       |\n| `options` | Global options (see cache options below)                                                                                                                     | `{}`    |\n\n### Register cache options\n\n| name       | description                                                                                                                                                                                                                                                                                                                     | default                                | overridable |\n| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------- |\n| `key`      | Key is used to uniquely identify a memoized function, by default it uses filepath to the function and its position in the file to determine uniqness. Note that the path is taken from the process´s cwd. (e.g. `/src/service/data.js:58:18`) If you want to control the name, set it to a unique string per register function. | `md5(\u003cfunction-filepath\u003e:\u003crow\u003e:\u003ccol\u003e)` | `true`      |\n| `ttl`      | Time to live in seconds or a ms string like `2h`.                                                                                                                                                                                                                                                                               | `3600` seconds (1 hour)                | `true`      |\n| `precache` | Time in seconds or ms package string like `24hours`. It defines the after which it should precache the function if you call it. (e.g. You can update the cache before it expires, so there are no \"down times\" after the cache expires.) Set to `null` or `-1` to disable.                                                      | `null` (disabled)                      | `true`      |\n| `hash`     | Hashing function is used to stringify arguments of a function and create unique arguments key. Note that by default it uses `fast-stable-json-stringify` to guarantee the same result for objects with different key order.                                                                                                     | `key =\u003e md5(stringify(key))`           | `true`      |\n| `timeout`  | Time in seconds to wait for storage to return any data before calling the original function. Cache needs to be fast, in case it does not return any data in time, it should call the original function. Set to `null` or `-1` to disable.                                                                                       | `null` (disabled)                      | `true`      |\n\n## License\n\nThis package is developed under the [MIT license]('./LICENSE').\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falesmenzel%2Fcache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falesmenzel%2Fcache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falesmenzel%2Fcache/lists"}