{"id":18358866,"url":"https://github.com/uppercod/store","last_synced_at":"2025-04-10T03:04:20.542Z","repository":{"id":113251534,"uuid":"172825644","full_name":"UpperCod/store","owner":"UpperCod","description":null,"archived":false,"fork":false,"pushed_at":"2019-04-04T02:50:17.000Z","size":86,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-23T22:26:56.005Z","etag":null,"topics":["asynchronous","generators","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":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UpperCod.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":"2019-02-27T02:13:50.000Z","updated_at":"2020-01-20T03:30:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"7bcc1500-ee8d-49b5-a749-a77cc8def294","html_url":"https://github.com/UpperCod/store","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpperCod%2Fstore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpperCod%2Fstore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpperCod%2Fstore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UpperCod%2Fstore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UpperCod","download_url":"https://codeload.github.com/UpperCod/store/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239036164,"owners_count":19571454,"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":["asynchronous","generators","store"],"created_at":"2024-11-05T22:19:45.695Z","updated_at":"2025-02-15T18:30:02.147Z","avatar_url":"https://github.com/UpperCod.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @atomico/store\n\n[![npm](https://badgen.net/npm/v/@atomico/store)](http://npmjs.com/@atomico/store)\n[![gzip](https://badgen.net/bundlephobia/minzip/@atomico/store)](https://bundlephobia.com/result?p=@atomico/store)\n\nLittle state manager based on spaces, can consume normal functions, asynchronous, generators and asynchronous generators.\n\n## Store\n\nThe store allows you to store the status and actions. this will send the subscribers the changes made by the actions, **the changes generated by the actions must be immutable, since it is the only way to send a new state to the subscribers**.\n\n### Flow of the store\n\n![Flow](assets/flow.png)\n\n### Creation of a store\n\n```js\nlet {actions,state, subscribe} = Store( initialActions[, initialState[, logger]]);\n```\n\n- `initialActions` : grouping of actions.\n- `[initialState]` : initial state.\n- `[logger]`: function that read the modifications issued.\n- `actions` : actions created by the store from `initialActions`.\n- `state` : current state of the store\n- `subscribe` : allows subscribing a function to the store, this returns a function layers to eliminate the subscription.\n\n### Store example\n\n```js\n\nimport {Store} from \"@atomico/store\";\n\nfunction *takeoff(){\n    yield \"tree\" // state {rocket:\"tree\"}\n    yield \"thow\" // state {rocket:\"two\"}\n    yield \"one\"  // state {rocket:\"one\"}\n    return \"🚀 takeoff!\" // state {rocket: \"🚀 takeoff!\"}\n}\n\nlet store = Store({rocket:{takeoff}})\n\nstore.actions.rocket.takeoff().then(()=\u003e{\n    console.log(\"done\")\n})\n    \nstore.subscribe((state)=\u003e{\n    console.log(state) \n})\n\n```\n\n## spaces\n\nThe spaces are aliased to store the state of the actions, the following example shows how `@atomico/store` simplifies access to the action through the camelCase pattern.\n\n![actions](assets/actions.png)\n\nThe objective of this is to simplify the maintenance of the store, limiting the status and actions only to a depth level.\n\n## action\n\nfunction that allows the store to change state, actions can be simple in return, like the one shown below\n\n```js\nexport function increment(state=0){\n    return state+1;\n}\n```\n\nActions can also have a simple asynchronous behavior:\n\n```js\nexport function increment(state,payload){\n    return fetch(payload.url).then((response)=\u003eresponse.json())\n}\n```\n\n\u003e to action, you can receive a second argument transmitted by the ** UI **, in this case that argument is `payload`\n\nThe potential use of `@atomico/store`, is the recursive reading allowing a conversation between the action and the store with the use of [**generators**](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Generador)\n\n```js\nexport function *increment(state) { \n\t  yield  1;\n\t  yield  2;\n\t  return 3;\n}\n```\n\nRecursive reading? ... the store reads the return of the action and consumes it until the end of its reading, be it a promise or a generator\n\n```js\nfunction *generatorIncrement1to3(){\n    yield 1;\n    yield 2;\n    return 3;\n}\nfunction *generatorIncrement3to6(){\n    yield 4;\n    yield 5;\n    return 6;\n}\nexport function *increment(state) { \n\t  yield  generatorIncrement1to3();\n\t  return  generatorIncrement4to6();\n}\n```\n\nThe benefit of this is that you can communicate to the subscribers the current status of a process with the intention of following its execution.\n\n```js\nexport function *request(state={},payload){\n    if(state.loading)return state;// does not emit change\n    yield  {loading:true}; // Emit change\n    return fetch(payload.url)\n    \t\t.then((res)=\u003eres.json())\n    \t\t.then((data)=\u003e{loading:false,data});  // Emit change\n}\n```\n\nThe support applies even to asynchronous generators.\n\n```js\nexport async function *request(state={},payload){\n    if(state.loading)return state;// does not emit change\n    yield  {loading:true}; // Emit change\n    let res = await fetch(payload.url),\n        data = await res.json();\n    return {loading:false,data}; // Emit change\n} \n```\n\n\n## Components\n\n`@atomico/store/components` allows access to the store through components and hooks.\n\n### Provider\n\nNecessary context to invoke `a Store` at component runtime.\n\n```jsx\nimport { h, render } from \"@atomico/core\";\nimport { Store } from \"@atomico/store\";\nimport { Provider } from \"@atomico/store/components\";\nimport App from \"./app\";\n\nlet store = Store(\n    // actions\n    {count : {\n        increment(state){\n            return state+1\n        }\n    }},\n    // initialState\n    {count:0}\n)\n\nrender(\n    \u003cProvider store={store}\u003e\n        \u003cApp/\u003e\n    \u003c/Provider\u003e\n)\n```\n\n### Consumer\n\nallows you to consume and subscribe to the content of the store.\n\n```jsx\n\u003cConsumer space={optionalSpace}\u003e\n    {(state,actions)=\u003e{\n\n    }}\n\u003c/Consumer\u003e\n```\n\n### useStore\n\nuseStored to access the context created by the `\u003cProvider/\u003e` component, obtaining by default the actions and the global state. this hook also allows the suscrición before the changes of the store.\n\n```jsx\nimport { h } from \"@atomico/core\";\nimport { useStore } from \"@atomico/store/components\";\n\nexport function App(){\n    let [ state ,actions]= useStore();\n\n    return \u003cdiv\u003e\n        \u003ch1\u003ecount : {state.count}\u003c/h1\u003e\n        \u003cbutton onClick={action.count.increment}\u003eincrement\u003c/button\u003e  \n    \u003c/div\u003e\n}\n```\n\n### useStore with nameSpace\n\nallows to subscribe to changes only from a nameSpace, in turn groups the actions avoiding the use of the space selector.\n\n```jsx\nimport { h } from \"@atomico/core\";\nimport { useStore } from \"@atomico/store/components\";\n\nexport function App(){\n    let [ state, actions ] = useStore(\"count\");\n\n    return \u003cdiv\u003e\n        \u003ch1\u003ecount : {state}\u003c/h1\u003e\n        \u003cbutton onClick={action.increment}\u003eincrement\u003c/button\u003e  \n    \u003c/div\u003e\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuppercod%2Fstore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuppercod%2Fstore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuppercod%2Fstore/lists"}