{"id":13825585,"url":"https://github.com/jviide/flowponent","last_synced_at":"2025-07-08T22:31:36.892Z","repository":{"id":47929590,"uuid":"227853632","full_name":"jviide/flowponent","owner":"jviide","description":"A small Preact/React library for defining workflow-like evolving views via generators","archived":true,"fork":false,"pushed_at":"2022-07-20T18:47:51.000Z","size":363,"stargazers_count":129,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-02-17T08:34:59.221Z","etag":null,"topics":["generators","higher-order-component","preact","react"],"latest_commit_sha":null,"homepage":"","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/jviide.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}},"created_at":"2019-12-13T14:08:16.000Z","updated_at":"2023-09-18T08:59:36.000Z","dependencies_parsed_at":"2022-08-12T14:30:50.177Z","dependency_job_id":null,"html_url":"https://github.com/jviide/flowponent","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jviide%2Fflowponent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jviide%2Fflowponent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jviide%2Fflowponent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jviide%2Fflowponent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jviide","download_url":"https://codeload.github.com/jviide/flowponent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225470631,"owners_count":17479366,"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":["generators","higher-order-component","preact","react"],"created_at":"2024-08-04T09:01:23.763Z","updated_at":"2024-11-20T04:30:36.740Z","avatar_url":"https://github.com/jviide.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Related"],"sub_categories":["These are libraries I have found that seem to be atleast tangentially related to the Concur model."],"readme":"# flowponent [![npm](https://img.shields.io/npm/v/flowponent.svg)](https://www.npmjs.com/package/flowponent)\n\nA small library for [Preact 10.x](https://preactjs.com/) (and [React](https://reactjs.org/) - see [the note](#a-note-on-react-support)) for defining workflow-like evolving views via generators.\n\nHere's the canonical counter example (also available [at Codesandbox](https://codesandbox.io/s/flowponent-in-action-ebfq2)):\n\n```js\nimport { render } from \"preact\";\nimport flowponent from \"flowponent\";\n\nconst App = flowponent(function*() {\n  let count = 0;\n\n  for (;;) {\n    count += yield resolve =\u003e (\n      \u003cdiv\u003e\n        \u003cdiv\u003ecurrent value: {count}\u003c/div\u003e\n        \u003cbutton onClick={() =\u003e resolve(1)}\u003e+1\u003c/button\u003e\n        \u003cbutton onClick={() =\u003e resolve(-1)}\u003e-1\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n});\n\nrender(\u003cApp /\u003e, document.getElementById(\"root\"));\n```\n\nFor a more involved one see [here's a Codesandbox](https://codesandbox.io/s/flowponent-in-action-88vb9) demonstrating composition, additional props \u0026 cleanups upon unmount:\n\n[![A Codesandbox sandbox demonstrating flowponent](https://user-images.githubusercontent.com/19776768/70826521-d10e8380-1def-11ea-82fd-0004f1caa6fc.png)](https://codesandbox.io/s/flowponent-in-action-88vb9)\n\n## Installation\n\n```sh\n$ npm install --save flowponent\n```\n\n### A Note on React Support\n\nThe use flowponent with React, import from `\"flowponent/react\"` instead of `\"flowponent\"`:\n\n```js\nimport React from \"react\";\nimport { render } from \"react-dom\";\nimport flowponent from \"flowponent/react\";\n```\n\nOtherwise it all works the same way as before. Here's a React example featuring a random selection of very good dogs: [Codesandbox](https://codesandbox.io/s/flowponentreact-in-action-8q16y).\n\n## Error Propagation\n\nIf an error is throw inside the yielded functions it can be caught in the flowponent.\n\nThe function can also fail after it's result has been rendered by calling its second parameter (`reject`):\n\n```js\nconst App = flowponent(function*() {\n  try {\n    const data = yield (resolve, reject) =\u003e (\n      \u003cDownloader onSuccess={resolve} onFailure={reject} /\u003e\n    );\n    yield () =\u003e \u003cp\u003eDownload succeeded: {data}\u003c/p\u003e\n  } catch (err) {\n    yield () =\u003e \u003cp\u003eDownload failed: {err.message}\u003c/p\u003e;\n  }\n});\n```\n\n## Async Mode\n\nAsync mode is activated by using async generators instead of regular ones. In fact, regular flowponents are actually just a special case of async ones! Here's the first example implemented with async flowponents:\n\n```js\nconst App = flowponent(async function*() {\n  let count = 0;\n\n  for (;;) {\n    const promise = yield resolve =\u003e (\n      \u003cdiv\u003e\n        \u003cdiv\u003ecurrent value: {count}\u003c/div\u003e\n        \u003cbutton onClick={() =\u003e resolve(1)}\u003e+1\u003c/button\u003e\n        \u003cbutton onClick={() =\u003e resolve(-1)}\u003e-1\u003c/button\u003e\n      \u003c/div\u003e\n    );\n    count += await promise;\n  }\n});\n```\n\nThis allows doing things between the time that the view has been rendered and `resolve` has been called.\n\nCheck out a bit more involved downloader widget example: [Codesandbox](https://codesandbox.io/s/flowponent-async-mode-in-action-97wk1)\n\n## See Also\n\n- The [tweet with the initial idea](https://twitter.com/jviide/status/1204492830594473985), but still using async generators.\n- For a more sophisticated approach check out [`concur-js`](https://github.com/ajnsit/concur-js) from which this library ~~stole~~borrowed further ideas 🙂\n\n## License\n\nThis library is licensed under the MIT license. See [LICENSE](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjviide%2Fflowponent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjviide%2Fflowponent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjviide%2Fflowponent/lists"}