{"id":20285695,"url":"https://github.com/marcisbee/radi-pure","last_synced_at":"2026-06-03T22:31:02.391Z","repository":{"id":99012043,"uuid":"147859105","full_name":"Marcisbee/radi-pure","owner":"Marcisbee","description":null,"archived":false,"fork":false,"pushed_at":"2018-12-04T19:46:10.000Z","size":44,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-05-06T22:43:32.142Z","etag":null,"topics":[],"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/Marcisbee.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-07T18:13:24.000Z","updated_at":"2019-08-26T13:48:20.000Z","dependencies_parsed_at":"2023-04-20T01:31:33.570Z","dependency_job_id":null,"html_url":"https://github.com/Marcisbee/radi-pure","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Marcisbee/radi-pure","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Marcisbee%2Fradi-pure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Marcisbee%2Fradi-pure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Marcisbee%2Fradi-pure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Marcisbee%2Fradi-pure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Marcisbee","download_url":"https://codeload.github.com/Marcisbee/radi-pure/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Marcisbee%2Fradi-pure/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33883102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","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":[],"created_at":"2024-11-14T14:28:30.740Z","updated_at":"2026-06-03T22:31:02.369Z","avatar_url":"https://github.com/Marcisbee.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# radi-pure\n\nThis is **Radi** core idea but user interface is as a pure functions. If this proves to be better than current Radi solutions, this will become Radi v1.0.\n\nExperimental stuff!! You should not use it in production.\n\n## Examples\n\nHeres some very basic example of how components and rendering looks.\n\n```jsx\n/** @jsx h **/\nconst { h, mount } = RadiExperiment\n\nfunction Hello() {\n  return (\n    \u003ch1\u003eHello World !\u003c/h1\u003e\n  )\n}\n\nmount(\u003cHello/\u003e, document.body)\n```\n\n```jsx\n/** @jsx h **/\nconst { h, mount, Store } = RadiExperiment\n\n/* Firstly we define state */\nconst state = new Store({\n  count: 0\n})\n\n/* Then we define some actions that will change state */\nconst up = ({count}, by) =\u003e ({count: count + by})\nconst down = ({count}, by) =\u003e ({count: count - by})\n\n/* Then comes pure function component */\nfunction Counter() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003e{ state.render(s =\u003e s.count) }\u003c/h1\u003e\n      \u003cbutton onclick={ () =\u003e state.dispatch(up, 1) }\u003eUp\u003c/button\u003e\n      \u003cbutton onclick={ () =\u003e state.dispatch(down, 1) }\u003eDown\u003c/button\u003e\n    \u003c/div\u003e\n  )\n}\n\n/* Finally we mount it */\nmount(\u003cCounter/\u003e, document.body)\n```\n\nSo now everything is based on pure functions. Testing can be quite easy now. Only thing to test is output of functions.\nImagine this:\n\n```jsx\nconst mockState = { count: 0 };\n\nexpect(Hello()).toBe('\u003ch1\u003eHello World !\u003c/h1\u003e')\nexpect(up(mockState, 1)).toBe(1)\nexpect(down(mockState, 1)).toBe(0)\nexpect(up(mockState, 10)).toBe(10)\nexpect(down(mockState, 10)).toBe(0)\n```\n\nAlso not losing any of the responsiveness. For example lifecycles, totally there!\n\n```jsx\nconst state = new Store({\n  person: {\n    name: 'John Doe'\n  }\n})\n\nfunction App() {\n  this.onMount = () =\u003e {}\n  this.onDestroy = () =\u003e {}\n\n  state.map(s =\u003e s.person).subscribe(({name}) =\u003e {\n    console.log('Persons name changed to', name)\n  })\n\n  return \u003cPerson/\u003e\n}\n```\n\n## More about state management `.Store` \u0026 `.Fetch`\n\nAlso one truly annoying thing is to manage data coming from API, passing it to dozens of components. Intention is to eliminate this hustle.\n\nWhat if you could just write your Schema for API calls and include it in your state and update it in any part of your app.\n\n```jsx\n// First we define Schema for our data from API\nconst User = new Fetch.get(\n  '/users/:id',\n  (data) =\u003e ({\n    id: data._key,\n    firstname: data.firstname,\n    lastname: data.lastname,\n  })\n)\n\n// Then we create store where we include our User Schema\nconst userStore = new Store({\n  foo: 'bar',\n  user: User({id: 10}),\n})\n\n// This part is not necessary, but for demo purpose it's here\n// Here we inject `userStore` store into another store\nconst appStore = new Store({\n  person: {\n    fakeAge: 21,\n    data: userStore.inject,\n  }\n})\n\n// Finally we can use our data. API will gather data automatically\nfunction App() {\n  return (\n    \u003ch1\u003e\n      {appState.render(({person}) =\u003e (\n        person.data.firstname + ' ' + person.data.lastname\n      ))}\n    \u003c/h1\u003e\n  )\n}\n```\n\nIt's possible to add store inside of another store and same for API returned data\n\n\n## Stay In Touch\n\n- [Twitter](https://twitter.com/radi_js)\n- [Slack](https://join.slack.com/t/radijs/shared_invite/enQtMjk3NTE2NjYxMTI2LWFmMTM5NTgwZDI5NmFlYzMzYmMxZjBhMGY0MGM2MzY5NmExY2Y0ODBjNDNmYjYxZWYxMjEyNjJhNjA5OTJjNzQ)\n\n## License\n\n[MIT](http://opensource.org/licenses/MIT)\n\nCopyright (c) 2018-present, Marcis (Marcisbee) Bergmanis\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcisbee%2Fradi-pure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcisbee%2Fradi-pure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcisbee%2Fradi-pure/lists"}