{"id":26154523,"url":"https://github.com/zeptosec/event-cache","last_synced_at":"2026-04-20T12:34:28.645Z","repository":{"id":281420281,"uuid":"945156717","full_name":"Zeptosec/event-cache","owner":"Zeptosec","description":"An in-memory cache with event-driven expiration.","archived":false,"fork":false,"pushed_at":"2025-03-27T20:49:59.000Z","size":152,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-12T03:43:38.674Z","etag":null,"topics":["cache","caching","deno","event-driven","in-memory","typescript"],"latest_commit_sha":null,"homepage":"","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/Zeptosec.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-08T19:36:44.000Z","updated_at":"2025-03-27T20:49:45.000Z","dependencies_parsed_at":"2025-03-27T21:30:19.810Z","dependency_job_id":null,"html_url":"https://github.com/Zeptosec/event-cache","commit_stats":null,"previous_names":["zeptosec/event-cache"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/Zeptosec/event-cache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zeptosec%2Fevent-cache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zeptosec%2Fevent-cache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zeptosec%2Fevent-cache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zeptosec%2Fevent-cache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zeptosec","download_url":"https://codeload.github.com/Zeptosec/event-cache/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zeptosec%2Fevent-cache/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32047350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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","caching","deno","event-driven","in-memory","typescript"],"created_at":"2025-03-11T08:30:04.756Z","updated_at":"2026-04-20T12:34:28.633Z","avatar_url":"https://github.com/Zeptosec.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Tests](https://github.com/zeptosec/event-cache/actions/workflows/test.yml/badge.svg)\n[![codecov](https://codecov.io/gh/Zeptosec/event-cache/graph/badge.svg?token=QEGCXKRS8P)](https://codecov.io/gh/Zeptosec/event-cache)\n[![JSR](https://jsr.io/badges/@zeptosec/event-cache)](https://jsr.io/@zeptosec/event-cache)\n[![NPM Version](https://img.shields.io/npm/v/%40riposte%2Fevent-cache)](https://www.npmjs.com/package/@riposte/event-cache)\n![Publish](https://github.com/zeptosec/event-cache/actions/workflows/publish.yml/badge.svg)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](/LICENSE)\n![GitHub last commit (branch)](https://img.shields.io/github/last-commit/zeptosec/event-cache/main)\n\n# Event Cache\n\nThe main purpose of this libary is to store key-value pairs while also managing\nthe expiration of those entries and emitting events when items expire. This is\nuseful for scenarios where you need a cache that automatically removes stale\ndata and notifies other parts of your application when that happens.\n\n# Library description\n\n## Provided functions\n\nA table documenting all public methods of each class\n\n### EventCache class\n\n| Method Name      | Parameters                                                                                                                                                                          | Description                                                                                                                                   |\n| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| constructor      | `options: EventCacheProps\u003cK\u003e - deleteOnExpire?: boolean`: Whether to delete expired items (defaults to `true`). - `eventStrategy: EventStrategy\u003cK\u003e`: The event expiration strategy. | Initializes a new EventCache instance, setting the deleteOnExpire option and the eventStrategy.                                               |\n| set              | `key: K` `value: V`. `key`: The key to add/update in the cache. `value`: The value to store associated with the key.                                                                | Adds or updates a key-value pair in the cache. It also manages the expiration event for the item. Returns `this` (the `EventCache` instance). |\n| delete           | `key: K`. The key to remove from the cache.                                                                                                                                         | Removes a key-value pair from the cache and the associated expiration event. Returns `true` if an item was removed, false otherwise.          |\n| get              | `key: K`. The key to retrieve from the cache.                                                                                                                                       | Retrieves the value associated with the given key. Returns the value if found, `undefined` otherwise.                                         |\n| clear            | None                                                                                                                                                                                | Clears all key-value pairs from the cache and removes all expiration events.                                                                  |\n| size             | None                                                                                                                                                                                | A getter that returns the number of items currently in the cache.                                                                             |\n| entries          | Returns an iterator of `[key, value]` pairs for each entry in the cache                                                                                                             | Returns an iterator of `[key, value]` pairs for each entry in the cache.                                                                      |\n| keys             | None                                                                                                                                                                                | Returns an iterator of keys for each entry in the cache.                                                                                      |\n| values           | None                                                                                                                                                                                | Returns an iterator of values for each entry in the cache.                                                                                    |\n| has              | `key: K`. The key to check for.                                                                                                                                                     | Checks if the cache contains a key. Returns `true` if the key exists, `false` otherwise.                                                      |\n| forEach          | `callback: (value: V, key: K, map: Map\u003cK, V\u003e) =\u003e void` A function to execute for each key-value pair. It receives the value, key, and the map as arguments.                         | Iterates over each key-value pair in the cache and executes the provided callback function.                                                   |\n| addEventListener | `type: T extends keyof EventCacheEvents\u003cK, V\u003e listener: (event: EventCacheEvents\u003cK, V\u003e[T]) =\u003e void` options?: boolean                                                               | A function that will be called when an item in a cache expires.                                                                               |\n\n## Business problems that library solves\n\nThis library helps to solve several business problems related to caching and\nevent management:\n\n- **Managing expired data:** Many applications need to cache data for\n  permormance, but that data often has a limited lifespan. This library\n  automates removal of old data while still working as a cache.\n- **Event based notifications:** Provides a convenient way of knowing when data\n  becomes outdated through events.\n- **Flexible expiration strategies:** For better performance there's `interval`\n  based strategy which can handle many more events. For more accuracy there's\n  `timeout` based strategy.\n\n## Intended use\n\nThis library is intended for use in applications that requires caching with data\nexpiration.\n\n- **Real-time data:** frequently updated data, such as price discounts, weather\n  information. Once data expires it can easily be updated again when event is\n  received.\n- **Rate-limiting:** Caching responses from APIs with rate limits. It can cache\n  frequently fetched responses so that the database isn't used on every request.\n- **Web applications:** Caching frequently used data to improve performance and\n  user expirience. Caching API responses on the front end.\n\nThis library is useful in any situation where data needs to be cached for\nperformance while expired data is removed.\n\n## Restrictions for library usage\n\nHere are outlined the main restrictions for using the library\n\n### Technical restrictions\n\n- **Event Listener Management:** `addEventListener` provides a way to attach an\n  event to an object to receive events after the data expired. This event should\n  be removed with `AbortController` after it is no longer needed.\n- **Implementation limitations:** `EventCache` triggers events asynchronously.\n  This means that expiration events are not guaranteed to happen **exactly** at\n  specified time. Slight delays should be expected.\n\n### Business restrictions\n\n- **Expiry requirement:** This libary is primarily for caching data that will\n  expire. If your data never expires then a simpler caching solutions might be\n  more appropriate.\n\n- **Data sensitivy:** This library doesn't provide any data encryption. It is\n  stored as provided.\n\n## Other important information\n\n### Performance\n\nThe performance of event cache is directly related to `EventStrategy`. So it is\nvery important to choose event strategy that you need. `IntervalStrategy` is\nmore performant, but events may not be received on time. `TimeoutStrategy`\nshould be more accurate than `IntervalStrategy`, but it may consume more memory\nwhen there's a lot of data.\n\n## Features\n\n- **Time-based expiration (TimeoutStrategy):** Items expire after a specified\n  time-to-live (TTL).\n- **Interval-based expiration (IntervalStrategy):** Items are checked for\n  expiration at regular intervals.\n- **Event-driven expiration:** Events are emitted when items expire, allowing\n  you to perform cleanup or other actions.\n- **Configurable deleteOnExpire:** Choose whether to automatically remove\n  expired items from the cache or retain them.\n- **Extensible:** Easily create custom expiration strategies.\n- **Simple API:** Easy to use and integrate into your projects.\n\n## Class diagram\n\nBelow is the class diagram illustrating the architecture of the Event Cache\nlibrary.\n\n[![Class diagram](./assets/class_diagram.jpg)](./assets/class_diagram.jpg)\n\n## Examples\n\nThe `EventCacheFactory` provides convenient methods to create caches with\npredefined strategies:\n\n```ts\nimport { EventCacheFactory } from \"@zeptosec/event-cache\";\n\n// Time-based expiration using TimeoutStrategy\nconst timeoutCache = EventCacheFactory.createEventCacheTimeout\u003cstring, number\u003e(\n  5000,\n); // Items expire after 5 seconds\n\n// Create AbortController for removing event listener if needed\nconst abortController = new AbortController();\n\ntimeoutCache.addEventListener(\"expire\", (expiredItem) =\u003e {\n  console.log(`Item '${expiredItem.key}' expired. Value: ${expiredItem.value}`);\n}, {\n  signal: abortController.signal,\n});\n\ntimeoutCache.set(\"myKey\", 123);\n\nsetTimeout(() =\u003e {\n  console.log(`myKey (3000 ms): ${timeoutCache.get(\"myKey\")}`);\n  // Access the value before expiration\n}, 3000);\n\nsetTimeout(() =\u003e {\n  console.log(`myKey (7000 ms): ${timeoutCache.get(\"myKey\")}`);\n  // Access the value after expiration\n\n  abortController.abort(); // Remove event listener\n}, 7000);\n\n// Interval-based expiration using IntervalStrategy\nconst intervalCache = EventCacheFactory.createEventCacheInterval\u003c\n  string,\n  string\n\u003e(2000); // Items are checked every 2 seconds\n\nintervalCache.addEventListener(\"expire\", (expiredItem) =\u003e {\n  console.log(`Item '${expiredItem.key}' expired. Value: ${expiredItem.value}`);\n});\n\nintervalCache.set(\"key2\", \"hello\");\n\nsetTimeout(() =\u003e {\n  console.log(`key2 (1000 ms): ${intervalCache.get(\"anotherKey\")}`);\n  // Access the value before expiration\n}, 1000);\n\nsetTimeout(() =\u003e {\n  console.log(`key2 (3000 ms): ${intervalCache.get(\"anotherKey\")}`);\n  // Access the value after expiration\n}, 3000);\n```\n\nUsing `EventCacheBuilder` to build your own `EventCache`:\n\n```ts\nimport { EventCacheBuilder, IntervalStrategy } from \"@zeptosec/event-cache\";\n\nconst builder = new EventCacheBuilder\u003cnumber, string\u003e();\n// Items are checked every 500ms, TTL is 1000ms, and expired items are NOT deleted.\nconst intervalCacheCustom = builder\n  .withStrategy(\n    new IntervalStrategy(1000, 500),\n    false,\n  ).build();\n\nintervalCacheCustom.addEventListener(\"expire\", (expiredItem) =\u003e {\n  console.log(`Item '${expiredItem.key}' expired. Value: ${expiredItem.value}`);\n});\n\nintervalCacheCustom.set(1, \"test\");\n\nsetTimeout(() =\u003e {\n  console.log(`1 (2000ms): ${intervalCacheCustom.get(1)}`); // Value should still be present even after expiration.\n}, 2000);\n\nsetTimeout(() =\u003e {\n  console.log(`1 (3000ms): ${intervalCacheCustom.get(1)}`); // Value should still be present even after expiration.\n}, 3000);\n```\n\nUsing `EventCache` with strategy directly:\n\n```ts\nimport { EventCache, TimeoutStrategy } from \"@zeptosec/event-cache\";\n\nconst eventCache = new EventCache\u003cnumber, string\u003e({\n  deleteOnExpire: false, // do not delete after expired\n  eventStrategy: new TimeoutStrategy(1000), // TTL: 1 second\n});\n\neventCache.set(42, \"answer\");\n\neventCache.addEventListener(\"expire\", ({ key, value }) =\u003e {\n  console.log(`expired: ${key}: ${value}`);\n});\n\nsetTimeout(() =\u003e {\n  console.log(`Before expired: ${eventCache.get(42)}`);\n  // value is defined\n}, 500);\n\nsetTimeout(() =\u003e {\n  console.log(`After expired: ${eventCache.get(42)}`);\n  // value is still defined\n}, 2000);\n```\n\n## Analysis of alternative packages\n\nThere are many different packages for caching data and receiving event when it\nexpires.\n\n[@cacheable](https://www.npmjs.com/package/cacheable) has more features and is\nvery popular.\n\n[@cache-manager](https://www.npmjs.com/package/cache-manager) Similar to\n[@cacheable](https://www.npmjs.com/package/cacheable) has a lot of different\nfunctionality for managing the cache like emitting event when key is set or\ndeleted.\n\n[@node-cache](https://www.npmjs.com/package/node-cache) Also very popular\npackage with the similar functionaly and many more features.\n\n[@buffered-queue](https://www.npmjs.com/package/buffered-queue) stores a list of\nitems and then after specified time returns an event with all the data in the\nqueue or if the size limit is reached.\n\nSo there are many other packages to choose from if you find that this pacakage\nis lacking some features that you need.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeptosec%2Fevent-cache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzeptosec%2Fevent-cache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeptosec%2Fevent-cache/lists"}