{"id":19422974,"url":"https://github.com/houfeng/mota","last_synced_at":"2025-04-06T10:14:19.661Z","repository":{"id":26540849,"uuid":"83758946","full_name":"Houfeng/mota","owner":"Houfeng","description":"🎡 An extremely lightweight and responsive state management library","archived":false,"fork":false,"pushed_at":"2024-02-15T04:13:41.000Z","size":6252,"stargazers_count":181,"open_issues_count":0,"forks_count":19,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-03T02:37:57.090Z","etag":null,"topics":["observability","observable","react","state-management"],"latest_commit_sha":null,"homepage":"http://houfeng.net/mota","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/Houfeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2017-03-03T04:55:24.000Z","updated_at":"2024-12-27T10:02:39.000Z","dependencies_parsed_at":"2024-06-18T17:07:19.285Z","dependency_job_id":"e3a2d9a4-ccae-401f-8bf9-fe890378099c","html_url":"https://github.com/Houfeng/mota","commit_stats":{"total_commits":390,"total_committers":2,"mean_commits":195.0,"dds":0.1974358974358974,"last_synced_commit":"cf2acb4c4cd8ccd4b472b4ae8a5890e0cb6da037"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Houfeng%2Fmota","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Houfeng%2Fmota/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Houfeng%2Fmota/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Houfeng%2Fmota/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Houfeng","download_url":"https://codeload.github.com/Houfeng/mota/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247464226,"owners_count":20942970,"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":["observability","observable","react","state-management"],"created_at":"2024-11-10T13:36:21.383Z","updated_at":"2025-04-06T10:14:19.628Z","avatar_url":"https://github.com/Houfeng.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](http://houfeng.net/mota/logo.jpg)\n\n\u003cdiv align=\"center\"\u003e\n\n[![npm](https://img.shields.io/npm/l/mota.svg)](LICENSE.md)\n[![NPM Version](https://img.shields.io/npm/v/mota.svg)](https://www.npmjs.com/package/mota)\n[![Coverage Status](https://coveralls.io/repos/github/Houfeng/mota/badge.svg?branch=master)](https://coveralls.io/github/Houfeng/mota?branch=master)\n[![npm](https://img.shields.io/npm/dt/mota.svg)](https://www.npmjs.com/package/mota)\n\u003c!-- [![Build Status](https://www.travis-ci.org/Houfeng/mota.svg?branch=master)](https://www.travis-ci.org/Houfeng/mota) --\u003e\n\n\u003c/div\u003e\n\n# Overview\n\nMota is a \"lightweight and responsive\" state management library, which is less than 5KB. Developers can use it to write \"almost framework independent pure js/ts business models\", and then use Mota to simply let react components respond to model changes.\n\n# Install\n\nInstall through NPM as follows\n```sh\n$ npm install mota --save\n```\n\n# Usage\n\n**Example 1**: Hello Mota\n\n```jsx\nimport { observable, observer } from \"mota\";\n\nconst model = observable({ count: 0 });\nconst add = ()=\u003emodel.count++;\n\nconst View1 = observer(() =\u003e {\n  return \u003cdiv\u003e{model.count}\u003c/div\u003e;\n});\n\nconst View2 = observer(() =\u003e {\n  return \u003cdiv\u003e\n    \u003cspan\u003e{model.count}\u003c/span\u003e\n    \u003cbutton onClick={add}\u003eclick\u003cbutton\u003e\n  \u003c/div\u003e;\n});\n```\n\n**Example 2**: Using useObservable\n\n```jsx\nimport { observer, useObservable } from \"mota\";\n\nconst View = observer(() =\u003e {\n  const model = useObservable({ count: 0 });\n  return \u003cdiv\u003e\n    \u003cspan\u003e{model.count}\u003c/span\u003e\n    \u003cbutton onClick={()=\u003emodel.count++}\u003eclick\u003cbutton\u003e\n  \u003c/div\u003e;\n});\n```\n\n**Example 3**: Using useComputed\n\n```jsx\nimport { observer, observable, useComputed } from \"mota\";\n\nconst user = observable({ \n  firstName: 'Feng',\n  lastName: 'Hou'\n});\n\nconst View = observer(() =\u003e {\n  // The fullName will be cached and responsive\n  const fullName = useComputed(()=\u003e{\n    return `${user.firstName} ${user.lastName}`;\n  });\n  return \u003cdiv\u003e{fullName}\u003c/div\u003e;\n});\n```\n\n\n**Example 4**: Using useAutoRun\n\n```jsx\nimport { observer, observable, useAutoRun } from \"mota\";\n\nconst model = observable({ count: 0 });\n\nconst View = observer(() =\u003e {\n  // When the count changes, \n  // it will be automatically re executed and printed 'count: n'\n  useAutoRun(()=\u003e{\n    console.log('count:', model.count);\n  });\n  return \u003cdiv\u003e{model.count}\u003c/div\u003e;\n});\n```\n\n**Example 5**: Using useWatch\n\n```jsx\nimport { observer, observable, useWatch } from \"mota\";\n\nconst model = observable({ count: 0 });\n\nconst View = observer(() =\u003e {\n  // When the result of the evaluation function changes,\n  // the processing function is re executed.\n  useWatch(()=\u003emodel.count%10, (oldValue, newValue)=\u003e{\n    console.log(`old: ${oldValue}, new: ${newValue}`);\n  });\n  return \u003cdiv\u003e{model.count}\u003c/div\u003e;\n});\n```\n\n**Example 6**: Using in class components\n\n```jsx\nimport { observer, observable, autorun, watch } from \"mota\";\n\nconst model = observable({ count: 0 });\n\n@observer\nclass View extends React.Component {\n  add = ()=\u003e model.count++;\n\n  componentDidMount(){\n    this.destroyAutoRun = autorun(()=\u003e{\n      console.log('autorun count: ', model.count);\n    });\n    this.destroyWatch = watch(()=\u003e model.count%10, ()=\u003e{\n      console.log('autorun count: ', model.count);\n    });\n  }\n\n  componentWillUnmount(){\n    this.destroyAutoRun();\n    this.destroyWatch();\n  }\n\n  @computed get message(){\n    return `count: ${model.count}`;\n  }\n\n  render() {\n    return \u003cdiv\u003e\n      \u003cspan\u003e{this.message}\u003c/span\u003e\n      \u003cbutton onClick={this.add}\u003eclick\u003cbutton\u003e\n    \u003c/div\u003e;\n  }\n}\n```\n\n**Example 7**: Using multiple instances in class components\n\n```jsx\nimport { observer, observable, autorun, watch } from \"mota\";\n\n@observable\nclass Model {\n  count = 0;\n  add () {\n    this.count++;\n  }\n  @computed get message(){\n    return `count: ${model.count}`;\n  }\n}\n\n@observer\nclass View extends React.Component {\n  model = new Model();\n  render() {\n    return \u003cdiv\u003e\n      \u003cspan\u003e{this.model.message}\u003c/span\u003e\n      \u003cbutton onClick={()=\u003ethis.model.add()}\u003eclick\u003cbutton\u003e\n    \u003c/div\u003e;\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoufeng%2Fmota","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoufeng%2Fmota","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoufeng%2Fmota/lists"}