{"id":13818089,"url":"https://github.com/chartshq/hyperdis","last_synced_at":"2026-01-29T05:22:57.521Z","repository":{"id":32921869,"uuid":"146285121","full_name":"chartshq/hyperdis","owner":"chartshq","description":" A high performance reactive state store for web apps ","archived":false,"fork":false,"pushed_at":"2024-09-18T10:27:09.000Z","size":2351,"stargazers_count":48,"open_issues_count":18,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-23T04:13:44.937Z","etag":null,"topics":["observable","reactive","redux","state-store"],"latest_commit_sha":null,"homepage":null,"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/chartshq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2018-08-27T10:56:07.000Z","updated_at":"2025-04-11T02:23:42.000Z","dependencies_parsed_at":"2024-11-19T16:41:20.737Z","dependency_job_id":"149cdba7-4308-451a-8158-aa99dc34aa81","html_url":"https://github.com/chartshq/hyperdis","commit_stats":{"total_commits":40,"total_committers":4,"mean_commits":10.0,"dds":0.375,"last_synced_commit":"ca2737c3dbcd42d30ad8da97bdf856c46f0c25f6"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/chartshq/hyperdis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chartshq%2Fhyperdis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chartshq%2Fhyperdis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chartshq%2Fhyperdis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chartshq%2Fhyperdis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chartshq","download_url":"https://codeload.github.com/chartshq/hyperdis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chartshq%2Fhyperdis/sbom","scorecard":{"id":274733,"data":{"date":"2025-08-11","repo":{"name":"github.com/chartshq/hyperdis","commit":"1b3afca8f105ee05b84ab3e2892e4025babf6859"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"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":"Code-Review","score":0,"reason":"Found 0/20 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":"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":"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":"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":"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":"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":"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"68 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-h6ch-v84p-w6p9","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-j4f2-536g-r55m","Warn: Project is vulnerable to: GHSA-r7qp-cfhv-p84w","Warn: Project is vulnerable to: GHSA-qh2h-chj9-jffq","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-7x7c-qm48-pq9c","Warn: Project is vulnerable to: GHSA-rc3x-jf5g-xvc5","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","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-82v2-mx6x-wq7q","Warn: Project is vulnerable to: GHSA-xf5p-87ch-gxw2","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w9mr-4mfr-499f","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-q75g-2496-mxpp","Warn: Project is vulnerable to: GHSA-6fx8-h7jm-663j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-fxwf-4rqh-v8g3","Warn: Project is vulnerable to: GHSA-25hc-qcg6-38wj","Warn: Project is vulnerable to: GHSA-xfhh-g9f5-x4m4","Warn: Project is vulnerable to: GHSA-qm95-pgcg-qqfq","Warn: Project is vulnerable to: GHSA-cqmj-92xf-r6r9","Warn: Project is vulnerable to: GHSA-mxhp-79qh-mcx6","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-cf4h-3jhx-xvhq","Warn: Project is vulnerable to: GHSA-mgfv-m47x-4wqp","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-5v72-xg48-5rpm","Warn: Project is vulnerable to: GHSA-72mh-269x-7mh5","Warn: Project is vulnerable to: GHSA-h4j5-c7cj-74xg","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-17T14:09:46.767Z","repository_id":32921869,"created_at":"2025-08-17T14:09:46.767Z","updated_at":"2025-08-17T14:09:46.767Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28863536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T22:56:21.783Z","status":"online","status_checked_at":"2026-01-29T02:00:06.714Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["observable","reactive","redux","state-store"],"created_at":"2024-08-04T07:00:32.040Z","updated_at":"2026-01-29T05:22:57.500Z","avatar_url":"https://github.com/chartshq.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"[![NPM version](https://img.shields.io/npm/v/hyperdis.svg)](https://www.npmjs.com/package/hyperdis)\n[![NPM total downloads](https://img.shields.io/npm/dt/hyperdis.svg)](https://www.npmjs.com/package/hyperdis)\n[![Contributors](https://img.shields.io/github/contributors/chartshq/hyperdis.svg)](https://github.com/chartshq/hyperdis/graphs/contributors)\n[![License](https://img.shields.io/github/license/chartshq/hyperdis.svg)](https://github.com/chartshq/hyperdis/blob/master/LICENSE)\n\n## What is Hyperdis?\n\nA high performance reactive state store for web apps. Hyperdis takes an plain old JavaScript object and provides an\ninterface to observe or change the object through the interface.\n\n## Features\n\n* 👀 Makes any object observable.\n* 👂 Listeners for property which gets fired in the current animation frame or in the next animation frame.\n* ⚡️ Calculated property, which gets called only when the dependent property gets changed.\n* 🚿 Commit mass mutation by acquiring locking.\n\n## Installation\n\nInstall hyperdis from NPM:\n\n```bash\n$ npm install --save hyperdis\n```\n\nAnd import it as follows:\n\n```javascript\nimport State from 'hyperdis';\n```\n\n## API\n\n### Static Methods\n\n#### `create()`\n\nTakes a simple JavaScript Object and make it observable. This returns the new object as a state instance.\n\n```javascript\nlet state = State.create({ \n    range: {\n        start: 1,\n        end: 5 \n    },\n    visible: true \n   });\n```\n\n### Instance Methods\n\n#### `serialize()`\n\nSince `State.create` does not return the JavaScript object back as it deserialize the JavaScript object to native data-structure, `serialize` function comes to the rescue to get the JavaScript object back.\n\n```javascript\n    state.serialize();\n    // Output:\n    //  {\n    //     range: {\n    //         start: 1,\n    //         end: 5 \n    //     },\n    //     visible: true\n    //  }\n```\n\n#### `append()`\n\nAppends property in the existing state (mutates the original state). The is called using two parameters. The first parameter is where to append the state and the second being what property to append.\n\n```javascript\nmyState.append('range.type', { absolute: true });\n```\n\nWhen serialized using `myState.serialize()` the following output is shown:\n\n```javascript\n// Output\n//  {\n//     range: {\n//         start: 1,\n//         end: 5, \n//         type: {\n//             absolute: true \n//         }\n//     },\n//     visible: true \n//  }\n```\n\nThe same function can be called with only one parameter, just by passing the new state properties. In this case it appends the property in the base.\n\n```javascript\nmyState.create({ focus: null });\n```\n\nIf `myState.serialize()` is called the following output is shown:\n\n```javascript\nmyState.serialize();\n// Output\n//  {\n//     range: {\n//         start: 1,\n//         end: 5, \n//         type: {\n//             absolute: true \n//         }\n//     },\n//     visible: true, \n//     focus: null\n//  }\n```\n\nThis function returns the same state on which the method was called.\n\n#### `prop()`\n\nThis acts as getter and setter. If the function is called by passing only one argument, it retrieve the value associated with the property.\n\n```javascript\nmyState.prop('range.type');\n// Output\n//  {\n//     absolute: true\n//  }\n```\n\nIf the same function is called using two parameters, first one being the property and second one being the value, then the value is set for the property and the handlers are called (if any) which got registered using the `on` function.\n\n```javascript\nmyState.prop('visible', true);\n```\n\nThis returns the instance on which it was called for chaining.\n\n#### `on()`\n\nThis function takes a single or group of property and handler which is called when any of the properties are changed.\nWhen a single property is changed the handler is called with two parameter, what was the old value of the state property and what is the new value.\n\n```javascript\nmyState.on('range.start', (oldValue, newValue) =\u003e {\n    console.log('Value before prop change', oldValue);\n    console.log('Value after prop change', newValue);\n});\n\nmyState.prop('range.start', 9);\n// Output:\n// Value before prop change 1 Value after prop change 9\n```\n\nIf a handler is registered on change of a property which has another state property as value, then the handler gets called whenever any state property connected to it gets changed.\n\n```javascript\nmyState.on('range', (oldValue, newValue) =\u003e {\n    console.log('Value before prop change', oldValue);\n    console.log('Value after prop change', newValue);\n});\n\nmyState.prop('range.start', 10);\nmyState.prop('range.type.absolute', false);\n// Output:\n// Value before prop change range {\n//     start: 9,\n//     end: 5,\n//     type: {\n//         absolute: true\n//     }\n// }\n// Value after prop change range: {\n//     start: 10,\n//     end: 5,\n//     type: {\n//         absolute: false\n//     }\n// }\n```\n\nIf a handler is registered with more than one property change then, the handler is called when any of the properties gets changed. In this cast the handler is called with more than one parameter : each for one state property which is registered for listening.Each parameter is of type array containing `[oldValue, newValue]`.\n\n```javascript\nmyState.on('range.start', 'range.end', (start, end) =\u003e {\n    console.log('Start', start);\n    console.log('End', end);\n});\n\nmyState.prop('range.start', 12);\n// Output:\n// Start [10, 12]\n// End [5, 5]\nmyState.prop('range.end', 7);\n// Output:\n// Start [12, 12]\n// End [5, 7]\n```\n\nThe `on` returns a function which if called the listener registered gets unregistered.\n\n```javascript\nlet unsub = myState.on('range.start', 'range.end', (start, end) =\u003e {\n    console.log('Start', start);\n    console.log('End', end);\n});\n\n// Call to unsubscribe\nunsub();\n```\n\n`On` takes an optional boolean value as the last parameter, which if passed as a true value the handler gets called during registration itself.\n\n#### `next()`\n\nJust like the way on works, it just calls the handlers at the start of next event loop.\n\n#### `lock()` and `unlock()`\n\nThis helps control the call of handler when a property is changed.\n\n```javascript\nmyState.on('range.start', 'range.end', (start, end) =\u003e {\n    console.log('Start', start);\n    console.log('End', end);\n});\n\nmyState.prop('range.start', 12);\n// Output:\n// Start [10, 12]\n// End [5, 5]\nmyState.prop('range.end', 7);\n// Output:\n// Start [12, 12]\n// End [5, 7]\n```\n\nHere the handler is called twice, because two times the property was changed. This is not always desirable. For updating group of same property the user might want to the handler to get executed only once.\nThis time locking and unlocking comes in picture.\n\n```javascript\nmyState.on('range.start', 'range.end', (start, end) =\u003e {\n    console.log('Start', start);\n    console.log('End', end);\n});\n\nmyState.lock().prop('range.start', 12).prop('range.end', 7).unlock()\n// Output:\n// Start [10, 12] End [5, 7]\n```\n\nOnce `lock()` is called the state caches all the change that comes after this. When `unlock()` is called it applies all the changes to the state and the handler is called.\n\n## Contributing\n\nYour PRs and stars are always welcome :). Checkout the [Contributing](https://github.com/chartshq/hyperdis/CONTRIBUTING.md) guides.\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchartshq%2Fhyperdis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchartshq%2Fhyperdis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchartshq%2Fhyperdis/lists"}