{"id":13514285,"url":"https://github.com/fed135/ha-store","last_synced_at":"2025-04-26T17:31:20.551Z","repository":{"id":32556303,"uuid":"131148278","full_name":"fed135/ha-store","owner":"fed135","description":"Efficient data fetching for your Javascript Applications","archived":false,"fork":false,"pushed_at":"2023-11-23T06:48:47.000Z","size":1625,"stargazers_count":79,"open_issues_count":2,"forks_count":8,"subscribers_count":9,"default_branch":"next","last_synced_at":"2025-04-14T22:21:49.231Z","etag":null,"topics":["cache","dataloader","hacktoberfest","javascript","nodejs"],"latest_commit_sha":null,"homepage":"https://ha-store.js.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fed135.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":["fed135"],"open_collective":"fredericcharette"}},"created_at":"2018-04-26T11:52:26.000Z","updated_at":"2024-01-02T17:36:34.000Z","dependencies_parsed_at":"2024-01-16T12:49:52.208Z","dependency_job_id":"699be1e3-3c3b-46ed-9638-2a8ce7776c16","html_url":"https://github.com/fed135/ha-store","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fed135%2Fha-store","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fed135%2Fha-store/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fed135%2Fha-store/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fed135%2Fha-store/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fed135","download_url":"https://codeload.github.com/fed135/ha-store/tar.gz/refs/heads/next","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251025768,"owners_count":21524860,"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":["cache","dataloader","hacktoberfest","javascript","nodejs"],"created_at":"2024-08-01T05:00:51.700Z","updated_at":"2025-04-26T17:31:20.256Z","avatar_url":"https://github.com/fed135.png","language":"JavaScript","funding_links":["https://github.com/sponsors/fed135","https://opencollective.com/fredericcharette"],"categories":["Projects"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg alt=\"HA-store\" width=\"300px\" src=\"./logo.png\" /\u003e\n  \u003cbr/\u003e\n  High-Availability store\n\u003c/h1\u003e\n\u003ch3 align=\"center\"\u003e\n  Efficient data fetching\n  \u003cbr/\u003e\u003cbr/\u003e\u003cbr/\u003e\n\u003c/h3\u003e\n\u003cbr/\u003e\n\n[![ha-store](https://img.shields.io/npm/v/ha-store.svg)](https://www.npmjs.com/package/ha-store)\n[![Node](https://img.shields.io/badge/node-\u003e%3D14.0-blue.svg)](https://nodejs.org)\n[![Dependencies Status](https://img.shields.io/librariesio/release/npm/ha-store)](https://github.com/fed135/ha-store/security/dependabot)\n\n---\n\n**HA-store** is a wrapper for your data queries, it features: \n\n- Smart TLRU cache for 'hot' information\n- Supports mutliple caching levels\n- Request coalescing and batching (solves the [Thundering Herd problem](https://en.wikipedia.org/wiki/Thundering_herd_problem))\n- Insightful stats and [events](#Monitoring-and-events)\n- Lightweight, configurable, battle-tested\n\nLearn how you can improve your app's performance, design and resiliancy [here](https://github.com/fed135/ha-store/wiki)!\n\n\n## Installing\n\n`npm install ha-store`\n\n\n## Usage\n\n```javascript\n// Create your store\nconst store = require('ha-store');\nconst itemStore = store({\n  resolver: getItems,\n  delimiter: ['language']\n});\n\n// Define your resolver\nfunction getItems(ids, params, contexts) {\n  // Ids will be a list of all the unique requested items\n  // Params will be the parameters for the request, which must be declared in the `delimiter` config of the store\n  // Contexts will be the list of originating context information\n\n  // Now perform some exensive network call or database lookup...\n\n  // Then, respond with your data formatted into this formats:\n  // { '123': { language: 'fr', name: 'fred' } }\n}\n\n// Now to use your store\nitemStore.get('123', { language: 'fr' }, { requestId: '123' })\n  .then(item =\u003e /* The item you requested */);\n\n// You can even ask for more than one item at a time\nitemStore.getMany(['123', '456'], { language: 'en' }, { requestId: '123' })\n  .then(items =\u003e /* All the items you requested, in Promise.allSettled fashion */);\n```\n\n\n## Options\n\nName | Required | Default | Description\n--- | --- | --- | ---\nresolver | true | - | The method to wrap, and how to interpret the returned data. Uses the format `\u003cfunction(ids, params)\u003e`\ndelimiter | false | `[]` | The list of parameters that, when passed, generate unique results. Ex: 'language', 'view', 'fields', 'country'. These will generate different combinations of cache keys.\ncache | false | \u003cpre\u003e{\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;enabled: false,\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;tiers: [\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;{\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;store: \u0026#60;instance of a store\u0026#62;,\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;limit: 5000,\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;ttl: 300000\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;}\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;]\u0026#13;\u0026#10;}\u003c/pre\u003e | A list of storage tiers for the data. The order indicates where to look first. It's recommended to keep an instance of an in-memory store, like `ha-store/stores/in-memory` as the first one, and then expend to external stores like [ha-store-redis](https://github.com/fed135/ha-redis-adapter). Caching options for the data - `limit` - the maximum number of records, and `ttl` - time to live for a record in milliseconds.\nbatch | false | \u003cpre\u003e{\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;enabled: false,\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;delay: 50,\u0026#13;\u0026#10;\u0026nbsp;\u0026nbsp;limit: 100\u0026#13;\u0026#10;}\u003c/pre\u003e | Batching options for the requests - `delay` is the amount of time to wait before sending the batch, `limit` is the maximum number of data items to send in a batch.\n\n*All options are in (ms)\n\n## Monitoring and events\n\nHA-store emits events to track cache hits, miss and outbound requests.\n\nEvent | Format | Description\n--- | --- | ---\nlocalCacheHit | `\u003cnumber\u003e` | When the requested item is present in the first listed local store (usually in-memory).\ncacheHit | `\u003cnumber\u003e` | When the requested item is present in a store.\ncacheMiss | `\u003cnumber\u003e` | When the requested item not cached or coalesced and must be fetched.\ncoalescedHit | `\u003cnumber\u003e` | When a record query successfully hooks to the promise of the same record in transit.\nquery | `\u003cobject\u003e` | When a batch of requests is about to be sent, gives the detail of the query and what triggered it.\nqueryFailed | `\u003cobject\u003e` | Indicates that the batch has failed. Retry policy will dictate if it should be re-attempted.\nquerySuccess | `\u003cobject\u003e` | Indicates that the batch request was successful.\n\nYou may also want to track the amount of `contexts` and `records` stored via the `size` method.\n\n\n## Testing\n\n`npm test`\n\n\n## Benchmarks\n\nRead instructions [here](./tests/profiling/README.md)\n\n`npm run bench`\n\n\n## Contribute\n\nPlease do! This is an open source project - if you see something that you want, [open an issue](https://github.com/fed135/ha-store/issues/new) or file a pull request.\n\nI am always looking for more maintainers, as well.\n\n\n## License \n\n[Apache 2.0](LICENSE) (c) Frederic Charette\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffed135%2Fha-store","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffed135%2Fha-store","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffed135%2Fha-store/lists"}