{"id":24440074,"url":"https://github.com/qianmiopen/plume2","last_synced_at":"2025-08-29T05:07:19.342Z","repository":{"id":17355700,"uuid":"81734318","full_name":"QianmiOpen/plume2","owner":"QianmiOpen","description":"🚀a lightweight React state container for web and app","archived":false,"fork":false,"pushed_at":"2022-12-09T08:14:31.000Z","size":3388,"stargazers_count":75,"open_issues_count":79,"forks_count":23,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-09T19:26:36.752Z","etag":null,"topics":["elegant","flux","lightweight-framework","predictable","react","react-native","simple","state-container"],"latest_commit_sha":null,"homepage":"https://qianmiopen.github.io/plume2","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/QianmiOpen.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}},"created_at":"2017-02-12T15:07:06.000Z","updated_at":"2024-10-10T06:43:49.000Z","dependencies_parsed_at":"2023-01-14T00:15:10.750Z","dependency_job_id":null,"html_url":"https://github.com/QianmiOpen/plume2","commit_stats":null,"previous_names":["hufeng/plume"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/QianmiOpen/plume2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QianmiOpen%2Fplume2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QianmiOpen%2Fplume2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QianmiOpen%2Fplume2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QianmiOpen%2Fplume2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QianmiOpen","download_url":"https://codeload.github.com/QianmiOpen/plume2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QianmiOpen%2Fplume2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272631696,"owners_count":24967120,"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","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"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":["elegant","flux","lightweight-framework","predictable","react","react-native","simple","state-container"],"created_at":"2025-01-20T20:28:00.653Z","updated_at":"2025-08-29T05:07:19.320Z","avatar_url":"https://github.com/QianmiOpen.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e New Idea, New the World. 🔥🔥🔥\n\n\u003cpre\u003e\n技术也是时尚驱动的，我们常常臣服于时尚,面对快速的变化常常让我们局促不安,\n开始焦虑，唯恐错过了些什么,怎么打破这种焦虑？\n需要在快速变化得世界里保持清醒，保持独立的思考和认知。\n让我们回归到技术的本质, 因为解决了真实的问题，技术才变得有价值。\n\u003cstrong\u003e真正牛\\*的技术，都是静悄悄的跑在线上...\u003c/strong\u003e\n\u003c/pre\u003e\n\n### plume2 🚀🚀🚀\n\nlight-weight predict scalable framework React for web and mobile\n\n[![NPM](https://nodei.co/npm/plume2.png?downloads=true\u0026downloadRank=true\u0026stars=true)](https://nodei.co/npm/plume2)\n\nReactive and Predictable state container for React or ReactNative.\n\n### Features\n\n- Light-weight\n- Reactive\n- Predict\n- Scalable\n- Trace Data Flow\n\n### Thanks\n\n- React/Native\n- Immutable.js\n- MapReduce\n- Functional Reactive Programming.\n\n### iflux\n\n很早很早之前，我们爱上了 React and immutable，所以就有了很简单的 iflux。\n\n_[iflux](https://github.com/QianmiOpen/iflux) = immutable.js + react.js_\n\n[![NPM](https://nodei.co/npm/iflux.png?downloads=true\u0026downloadRank=true\u0026stars=true)](https://nodei.co/npm/iflux)\n\n保持简单\n\n```\n+-----------------------+\n|       WebApi          |\n+-----------------------+\n          |\n         \\|/\n+-----------------------+\n|   Store（immutable）   |\u003c-----+\n+-----------------------+      |\n           | //es5 style       |\n           | StoreMixin        | msg(EventEmitter)\n          \\|/                  |\n+------------------------+     |\n|     React App          |-----|\n+------------------------+\n|      \u003cLayout\u003e          |\n|        \u003cSearchForm/\u003e   |\n|        \u003cToolbar/\u003e      |\n|        \u003cDataGrid/\u003e     |\n|       \u003c/Layout\u003e        |\n+------------------------+\n```\n\n优点：\n\n- 简单直接，几乎没有什么规则\n- 单根数据源(single data source)\n- Immutable fronted UI\n- High Performance\n\n但是随着业务的不断的发展，数据层的复杂度也在上升。这时候 iflux 就会暴露出很多的缺点\n\n- Big Store, Store 中大量的数据和业务的处理，代码膨胀的厉害\n- Store 是单例，不销毁，有共享的问题\n- store 的数据通过 props 不断的透传，代码写的很费劲\n- 大量的数据之间的依赖关系，需要手动的保证和处理\n\n### 怎么解决?\n\n- 使用 MapReduce 的理念解决 big Store\n- 使用@Relax 自动注入 store 中的数据和事件\n- Store 不再是单例\n- 使用 FRP 的理念, 简单的实现反应式数据，抽象源数据和派生数据\n\n这就是我们的 plume2\n\n```text\n+------------------+\n|     BFF-API      |\n+------------------+\n        ||\n        \\/\n+------------------+\n|     WebApi       |\n+------------------+\n        ||\n        \\/\n+------------------+\n|     Store        | ====\u003e [Actor1, Actor2, Actor3]\n+------------------+\n        ||\n        \\/\n+------------------+\n|  @StoreProvider  |\n+------------------+\n        ||\n        \\/\n+------------------+\n|     @Relax       |\n+------------------+\n        ||\n        \\/\n+------------------+\n|     QL/DQL       |\n+------------------+\n```\n\n# Getting Started\n\n```sh\n# add dependencies\nyarn add plume2 # npm install plume2\n\n# web\nyarn add react react-dom # yarn add preact preact-compat\n```\n\n# quick demo\n\n```js\n//domain Object\n//Actor, Store, StoreProvider, Relax, ViewAction\n\nclass HelloActor extends Actor {\n  defaultState() {\n    return { text: 'hello world' };\n  }\n}\n\nclass HelloViewAction extends ViewAction {\n  sayHello = text =\u003e {\n    this.store.dispatch('say:hello', text);\n  };\n}\n\nclass AppStore extends Store {\n  bindActor() {\n    return [HelloActor];\n  }\n\n  bindViewAction() {\n    return {\n      HelloViewAction\n    };\n  }\n}\n\n@Relax\nclass Text extends React.Component {\n  static relaxProps = {\n    text: 'text',\n    viewAction: 'viewAction'\n  };\n\n  render() {\n    const { text, viewAction } = this.props.relaxProps;\n    return (\n      \u003cdiv onClick={() =\u003e viewAction.HelloViewAction.sayHello(text)}\u003e\n        {text}\n      \u003c/div\u003e\n    );\n  }\n}\n\n@StoreProvider(AppStore)\nclass HelloApp extends React.Component {\n  render() {\n    return \u003cText /\u003e;\n  }\n}\n\nReactDOM.render(\u003cHelloApp /\u003e, document.getElementById('app'));\n```\n\n## contributes\n\n**thanks all(pr, issue)**\n\n## document\n\n[plume2](https://hufeng.github.io/plume2/)\n\n## FAQ\n\n1.  TypeError: Class constructor Store can not be invoked without 'new'?\n\n![err](https://raw.githubusercontent.com/hufeng/plume2/master/docs/screenshot/err.png)\n\n默认我们的 plume2 发布的模块级别是 es6，为了让我们调试方便，没有编译到 es5 的 level。这样在和 webpack 的配合的时候，webpack 一般在配置 babel-loader 的时候，会忽略 node_modules\n这样会导致我们业务代码编译级别是 es5,plume2 是 es6，就会报这个错误。\n\nplume2@0.3.4 默认发布的就是 es5 module 不再需要提前的任意转换\n\u003cstrong\u003e在 plume2@1.0.0 之后，默认发布的就是 es5 module，不在需要这种转换 \u003c/strong\u003e\n\n2.  ReactNative can not find react-dom module\n\n这是什么原因呢？因为我们的 store 模块依赖了 react-dom，在 react-native 的环境是没有 react-dom 这个模块，所以请使用我们的一个自定义的 babel 插件来解决问题。\n\n```sh\nyarn add babel-plugin-plume2 --dev\n```\n\n```js\n//.babelrc\n{\n  \"plugins\": [\n    [\"plume2\", {\"reactnative\": true}]\n  ]\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqianmiopen%2Fplume2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqianmiopen%2Fplume2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqianmiopen%2Fplume2/lists"}