{"_id":"@8baselabs/react-simple-state","_rev":"3-3bbd45e5c301684ac9ff95b85267e9fe","name":"@8baselabs/react-simple-state","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@8baselabs/react-simple-state","version":"0.0.1","description":"Simple and Lightweight state management for react applications. ","main":"lib/index.js","types":"./lib/index.d.ts","scripts":{"test":"jest --collect-coverage","build":"tsc","dev":"tsc -w","docs":"typedoc --out docs --theme markdown --categorizeByGroup false --exclude src/index.ts --exclude src/__tests__ --readme none --plugin typedoc-plugin-markdown src","format":"prettier --write \"src/**/*.ts\" \"src/**/*.js\"","lint":"eslint -c .eslintrc.js src/**/*.ts"},"homepage":"https://github.com/8base-services/react-simple-state","bugs":{"url":"https://github.com/8base-services/react-simple-state/issues"},"author":{"name":"8baselabs"},"license":"GPL-3.0","devDependencies":{"@babel/core":"^7.9.6","@babel/preset-env":"^7.9.6","@babel/preset-react":"^7.0.0","@babel/preset-typescript":"^7.9.0","@testing-library/react-hooks":"^3.3.0","@types/jest":"^25.2.1","@types/node":"^13.13.5","@types/react":"^16.9.35","@typescript-eslint/eslint-plugin":"^4.15.2","@typescript-eslint/parser":"^4.15.2","babel-jest":"^26.0.1","eslint":"^7.10.0","eslint-config-prettier":"^6.15.0","eslint-plugin-jest":"^23.13.1","eslint-plugin-jsdoc":"^32.2.0","eslint-plugin-react-hooks":"^4.2.0","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","prettier":"^2.0.5","react":"17.0.2","react-test-renderer":"^16.13.1","ts-jest":"^25.5.1","typedoc":"^0.17.8","typedoc-plugin-markdown":"^2.3.1","typescript":"^4.4.2"},"peerDependencies":{"react":">=16.13.1"},"peerDependenciesMeta":{"react-dom":{"optional":true},"react-native":{"optional":true}},"husky":{"hooks":{"pre-commit":"npm run docs && lint-staged","pre-push":"npm run build && npm run test"}},"lint-staged":{"*.js":["prettier --write","eslint --fix"]},"repository":{"type":"git","url":"git+https://github.com/8base-services/react-simple-state.git"},"keywords":["8baselabs"],"gitHead":"363b22806ba73ebe0be52a2074cfb5a568ea6da2","_id":"@8baselabs/react-simple-state@0.0.1","_nodeVersion":"14.18.3","_npmVersion":"8.5.0","dist":{"integrity":"sha512-on6ul2ublJZkEAg9mFL31a/ewHG5/jLp5ZFOrf1MOrrFH5RVonlUmmiPiy3xEG7Ca21u8bQWLTIrmVvwEcNmcQ==","shasum":"660a5fedc184133ac50a3b5aa8329fe81006ca13","tarball":"https://registry.npmjs.org/@8baselabs/react-simple-state/-/react-simple-state-0.0.1.tgz","fileCount":28,"unpackedSize":60678,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDHQZGIWO+Rld3gfarS/qmR3OMfDyZoMeEFBZsSyOUeXgIgLtYutM9XXSxUv1najjGhTbAFSTiXqIKTp78SLrqWd5o="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRZ9WACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpz8Q//Y3sR2s/AYcUPvm5i+XQkTDAl3jYNCnbwmldijRD0pIw99x7A\r\niAlTQzSEffgUFbUS7tVqRufDYzUwdNVA5yuvjVhKCfc/LzzipSQU0bKyHS/O\r\nQQ6Dp+n9ulP7BUwq//uEDCdPE2fgJh65ZAkSa3eolMir3WA/Z4aRlPDweeGw\r\nrLn0539IgkkwtpUMCmQsRUsz5HVRDUBxrilrCmjeJK12PNCuCST5osI+Zsnc\r\nrskIPj4R+qLocbNnBZgdHeY81rxBitcB+kPxdrW71sX6Jj/op3dcF8BTObqi\r\nk+tiVan2/pWsPfIne+X8+fKDgDF5RfrnPhjzZQ3ILLOT+wgnwcpsjHbref4b\r\nvprLO2FqY6fetA8S+gvbWybzsb0d+d204hPMRqr0n6J+wjjdnwr4+ee5CZrE\r\nUm7U7ducQZBG3cY3e3C+kfDSM6Mw71ESoQldoRzA5ZCHB/oESnkNZIume6Xe\r\nzvM4YHBn1z0yizQg+ReUG74NvpZeIhMSyq4hOKQ7Pab73kif//sO2FWuNU3k\r\n3xaCi3yx2DCJbf/zlhH9843XYNnz02PpXf+6FWZtQj7jOYfPE402iKz3Wmsu\r\ng4MJ90Z9Jii+HxdyjAw/LtwX1oAQtOKyM4i37KbXrfB741WOfO0IgWBRhB87\r\nBadfTJsdyeAfrWvOOYmCt8MqeHfcZYLOR8Y=\r\n=F55u\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"8baselabsadmin","email":"8baselabsadmin@8baselabs.com"},"directories":{},"maintainers":[{"name":"8baselabsadmin","email":"8baselabsadmin@8baselabs.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-simple-state_0.0.1_1648729942032_0.21135873752508982"},"_hasShrinkwrap":false},"0.0.2":{"name":"@8baselabs/react-simple-state","version":"0.0.2","description":"Simple and Lightweight state management for react applications. ","main":"lib/index.js","types":"./lib/index.d.ts","scripts":{"test":"jest --collect-coverage","build":"tsc","dev":"tsc -w","docs":"typedoc --out docs --theme markdown --categorizeByGroup false --exclude src/index.ts --exclude src/__tests__ --readme none --plugin typedoc-plugin-markdown src","format":"prettier --write \"src/**/*.ts\" \"src/**/*.js\"","lint":"eslint -c .eslintrc.js src/**/*.ts"},"homepage":"https://github.com/8base-services/react-simple-state","bugs":{"url":"https://github.com/8base-services/react-simple-state/issues"},"author":{"name":"8baselabs"},"license":"GPL-3.0","devDependencies":{"@babel/core":"^7.9.6","@babel/preset-env":"^7.9.6","@babel/preset-react":"^7.0.0","@babel/preset-typescript":"^7.9.0","@testing-library/react-hooks":"^3.3.0","@types/jest":"^25.2.1","@types/node":"^13.13.5","@types/react":"^16.9.35","@typescript-eslint/eslint-plugin":"^4.15.2","@typescript-eslint/parser":"^4.15.2","babel-jest":"^26.0.1","eslint":"^7.10.0","eslint-config-prettier":"^6.15.0","eslint-plugin-jest":"^23.13.1","eslint-plugin-jsdoc":"^32.2.0","eslint-plugin-react-hooks":"^4.2.0","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","prettier":"^2.0.5","react":"17.0.2","react-test-renderer":"^16.13.1","ts-jest":"^25.5.1","typedoc":"^0.17.8","typedoc-plugin-markdown":"^2.3.1","typescript":"^4.4.2"},"peerDependencies":{"react":">=16.13.1"},"peerDependenciesMeta":{"react-dom":{"optional":true},"react-native":{"optional":true}},"husky":{"hooks":{"pre-commit":"npm run docs && lint-staged","pre-push":"npm run build && npm run test"}},"lint-staged":{"*.js":["prettier --write","eslint --fix"]},"repository":{"type":"git","url":"git+https://github.com/8base-services/react-simple-state.git"},"keywords":["8baselabs"],"gitHead":"363b22806ba73ebe0be52a2074cfb5a568ea6da2","_id":"@8baselabs/react-simple-state@0.0.2","_nodeVersion":"14.18.3","_npmVersion":"8.5.0","dist":{"integrity":"sha512-M7nhhvVH/XlMOzDPqmFf0hqYcclt3jlag2q90CPI3Bwa41kJaoyK6alwmCayTZ2HxrZFJXxI0Vfy1EUHlm7t9w==","shasum":"dc1c56a168dbb2386171f7f390eb2c59777afdf4","tarball":"https://registry.npmjs.org/@8baselabs/react-simple-state/-/react-simple-state-0.0.2.tgz","fileCount":50,"unpackedSize":102573,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDBJ5pTH6o46pJEgjdNH0qb+NoYF8eMGLemzbEtbUZERAIhALXw4aFkiooutdj99qKCKushl+7s2hRltJ0vmjTUX77x"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRhHFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqbAA/+PPu7uMnOrFqJeM0nDaY2BCgjFT7UuOickr2oR2A7S94STJUk\r\nvBiNikSLdB72AQzIxyJ863wS0Tz4XqqknzpOZc6fV9KF8Sd7zYoAITCiHhtR\r\nDt2WrFLmteIx18O1+hu/4UkrS5CjTXHstGO4jf1fCOLT+vl4zFvkU3U4pGfT\r\ne3s7euqF1OpxzIPkEPkL2hAP5K2uNHfSGdmaqpcpBNghAtlIqFPb+Os8rBy8\r\n28zNYl1LHxIrPh7aieSzO9tFw0fwRgX7rbblo7Sc50jaexKhOm8kF5VpRrPu\r\nYhnMx7n0MU99au14+yrBzEVIMNlF1IK1k3G2vF4bY07bsvKPwtXtXberN7Tz\r\nNiqG16cWhd8vohNUiXW37eg5StA++wShF/fpd+E/ZNAYow7UCVXTQZ+o/RtN\r\nJjlHu8jspJy8p7L5LSKw4EYfexwzv7oEmsFVf92wst0QgFS2idvmxidK3cxM\r\nZyNNz7i5p6Z6iO0ZS9FG948y5+dOQf5R07hE9UVarB5WGc4fcNtzO+nJw6IQ\r\nI3Yhrb/t+X5dDbHNCXQYOsXc8k/DsPJi8gRne8s+UVXfSCovqbzWUIEhIPbF\r\n4lgztd2xcXsX/+/msW4tWeRQ0fASrHzcBwdWvIQhnQfgyn4MrEyGK1s7rzNb\r\ne+ml9EA2F8d6ClPRDkmfL40MOxBuuRCZdGY=\r\n=dIWO\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"8baselabsadmin","email":"8baselabsadmin@8baselabs.com"},"directories":{},"maintainers":[{"name":"8baselabsadmin","email":"8baselabsadmin@8baselabs.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-simple-state_0.0.2_1648759237554_0.16541964084459448"},"_hasShrinkwrap":false}},"time":{"created":"2022-03-31T12:32:21.960Z","0.0.1":"2022-03-31T12:32:22.236Z","modified":"2023-02-06T11:21:38.285Z","0.0.2":"2022-03-31T20:40:37.753Z"},"maintainers":[{"email":"marcelo.garciaprieto@8baselabs.com","name":"magarciaprieto"},{"email":"ariel.deagustini@8baselabs.com","name":"ariel.deagustini.8baselabs"},{"email":"8baselabsadmin@8baselabs.com","name":"8baselabsadmin"}],"description":"Simple and Lightweight state management for react applications. ","homepage":"https://github.com/8base-services/react-simple-state","keywords":["8baselabs"],"repository":{"type":"git","url":"git+https://github.com/8base-services/react-simple-state.git"},"author":{"name":"8baselabs"},"bugs":{"url":"https://github.com/8base-services/react-simple-state/issues"},"license":"GPL-3.0","readme":"# React Simple State\n\nA simple and predictable state management for React and React Native Applications.\n\n## Goals:\n\n- Easy to use and to maintain state management on a React Application.\n- Scalable\n- Easy to organize\n- Compatible with Hooks and Class based Components.\n\n\n## Installation\n\n1. Run on your terminal the following command:\n\n```sh\n$ npm i --save @8baselabs/react-simple-state\n```\n\n2. To import the library anywhere you would like to use it:\n\n```js\nimport {\n  createEvent,\n  useSubscription,\n  useEvent,\n  View,\n} from '@8baselabs/react-simple-state';\n```\n\n## API Docsw\n\n| Object                                | Description                                                                                           |\n| ------------------------------------- | ----------------------------------------------------------------------------------------------------- |\n| [`EventParams`](#EventParams)         | Params for the createEvent function.                                                                  |\n| [`createEvent`](#createEvent)         | Helper function to create state events.                                                               |\n| [`View`](#View)                       | Subclass of `React.View` that includes a `this.subscribe` method to subscribe to changes on an Event. |\n| [`useSubscription`](#useSubscription) | A hook for subscribe to specific events with a callback.                                              |\n| [`EventHookParams`](#EventHookParams) | Params for the `useEvent`                                                                             |\n| [`useEvent`](#useEvent)               | A declarative alternative to the `useSubscription`.                                                   |\n\n### `EventParams`\n\n- `initialValue` - An initial value for the event.\n- `reducer` A function that mutates the state before it gets propagated.\n\n### `createEvent(params: EventParams)`\n\n- Allows you to create a subscribable event.\n- The result object can be used for subscriptions with the `View` or the hooks: `useEvent` and `useSubscription`\n\n[`Example`](#Examples)\n\n```javascript\n// agency-events.js\nimport { createEvent } from '@8baselabs/react-simple-state';\n\nexport const OnAgencyList = createEvent();\nexport const OnAgencyListError = createEvent();\nexport const OnNewAgent = createEvent({\n  initialValue: new Agent(),\n  reducer: (prevState) => {\n    prevState.agencies = OnAgencyList.get();\n    return prevState;\n  },\n});\n```\n\n### `View`\n\n- Allows you to create subscription to events from Class based components\n- It handles the subscription lifecycle: subscribe and unsubscribe on react lifecycle events.\n\n[`Example`](#Examples)\n\n```javascript\n// AgencyView.js\n\nimport {View} from \"@8baselabs/react-simple-state\";\nimport {OnAgencyList, OnNewAgent} from \"./agency-events.js\"\n\nclass AgencyView extend View{\n\n  componentDidMount () {\n    this.subscribe(OnAgencyList, (state)=> {\n      // So something with the state.\n    })\n\n    this.subscribe(OnNewAgent, (state)=> {\n      // So something with the state.\n    })\n\n  }\n}\n```\n\n### `useSubscription(store, eventName, callback)`\n\n- It subscribes a `callback` to an Event from functional components using hooks.\n- It handles the subscription lifecycle\n\n[`Example`](#Examples)\n\n```javascript\n\n// AgencyView.js\n\nimport {useSubscription} from \"@8baselabs/react-simple-state\";\nimport {OnAgencyList, OnNewAgent} from \"./agency-events.js\"\n\nconst AgencyView = ()=> {\n    useSubscription(OnAgencyList, (state)=>{\n        // Do something with the state\n    });\n\n    useSubscription(OnNewAgent, (state)=>{\n        // Do something with the state\n    });\n\n    return ();\n}\n```\n\n### `EventHookParams`\n\n- `initialValue` - An initial value for the event.\n- `reducer` A function that mutates the state before it gets propagated.\n\n### `useEvent(eventName, initialValue, reducer)`\n\n- It subscribes ton event from functional components using hooks with a declarative approach.\n- It handles the subscription lifecycle\n- It handles initial values for the events\n- It handles a reducer function for the state.\n\n[`Example`](#Examples)\n\n```javascript\n\n// AgencyView.js\n\nimport {useEvent} from \"@8baselabs/react-simple-state\";\nimport {OnAgencyList, OnNewAgent} from \"./agency-events.js\"\n\nconst AgencyView = ()=> {\n    const state = useEvent(OnAgencyList);\n    const agent = useEvent(OnNewAgent, {initialValue: {}, reducer: (prevState) => prevState.agent});\n\n    return ();\n}\n```\n\n### Full Example\n\nLet's build a Flux Workflow for authentication\n\n### 1) First, declare your Events\n\n```js\nimport { createEvent } from '@8baselabs/react-simple-state';\n\nexport const LogoutEvent = createEvent({\n  reducer: (prevState) => {\n    localStorage.clear();\n    return prevState;\n  },\n});\nexport const LoginEvent = createEvent();\nexport const PermissionError = createEvent({\n  reducer: (prevState) => {\n    LogoutEvent.dispatch();\n    return prevState;\n  },\n});\n\nexport { LogoutEvent, LoginEvent, PermissionError };\n```\n\n### 2) Registering with the Store changes\n\n```js\nimport React from 'react';\nimport {LogoutEvent, LoginEvent,PermissionError } from \"./agency-events.js\";\nimport {View, useSubscription, useEvent} from '@8baselabs/react-simple-state';\n\n// Class Based\nclass View extends View {\n      constructor(){\n          super();\n      }\n      componentDidMount() {\n          this.subscribe(LoginEvent, (state) => {\n              // Do something useful with the Event Data\n              const userName = state.user.name;\n              this.setState({userName});\n          });\n          // Register some method\n          this.subscribe(LogoutEvent this.logOutEvent);\n      }\n\n      logOutEvent = (state) => {\n        //DO something with the state or the state of the Store\n        const storeState = LogoutEvent.get();\n      }\n  }\n\n// or Functional with React Hooks\nconst View = (props) => {\n  // Set an Initial Value\n  const loginState = useEvent(LoginEvent);\n  const userState = useEvent(LogoutEvent, {reducer:(state) => state.user});\n\n  useSubscription(LoginEvent, (state) => {\n    // setError\n    // toast.error()\n  });\n\n  return (\n    {loginState && <User user={loginState}>}\n  )\n};\n```\n\n### 3) Define some actions that will trigger the event\n\n```js\nimport { LoginEvent, LogoutEvent } from './agency-events.js';\n\nconst authenticateAction = (username, password) => {\n  if (username === undefined) return LogoutEvent.dispatch();\n\n  let dataToSave = {\n    authenticated: true,\n    username,\n    password,\n  };\n  LoginEvent.dispatch(dataToSave);\n};\n\nexport { authenticateAction };\n```\n\n### 4) Actions can be created with `createAction` helper\n\n```js\nimport { createAction } from '@8baselabs/react-simple-state';\nimport { OnFecthUserEvent, OnFetchUserErrorEvent } from './events';\nimport { apiClient } from './api';\n\n// single declarition of the async service and the action\nexport const fetchUserAction = createAction(\n  OnFecthUserEvent,\n  OnFetchUserErrorEvent,\n  async (id) => {\n    const user = await apiClient.fetch({ user: id });\n\n    return user;\n  },\n);\n\n// Or we could declare the async service and then use in with diferent actions\n\nexport const fetchUserService = async (id) => {\n  const user = await apiClient.fetch({ user: id });\n\n  return user;\n};\n\nexport const fetchMainUserAction = createAction(\n  OnFecthMainUserEvent,\n  OnFetchMainUserErrorEvent,\n  fetchUserService,\n);\nexport const fetchSecondaryUserAction = createAction(\n  OnFecthSecondaryUserEvent,\n  OnFetchSecondaryUserErrorEvent,\n  fetchUserService,\n);\n```\n\n### 5) Fetch can be done with `useFetchAction` hook\n\n```js\nimport { useFetchAction } from '@8baselabs/react-simple-state';\nimport { fetchUser } from './actions';\n\n// UserProfile component\nexport const UserProfile = ({ userId, loadingToken }) => {\n  const [user, loadingUser] = useFetchAction(fetchUser, [userId]);\n\n  // OR... skip the fetch ultil the token loads\n  const [user, loadingUser] = useFetchAction(fetchUser, [userId], {\n    skip: loadingToken,\n  });\n  // OR...\n\n  const [user, loadingUser] = useFetchAction(fetchUser, [userId], {\n    onCompleted: () => {\n      toast.success('user fetched');\n    },\n    onError: () => {\n      toast.error('Error when fetching user');\n    },\n  });\n\n  // OR...\n\n  const [user, loadingUser, { refetch }] = useFetchAction(fetchUser, [userId], {\n    onCompleted: () => {\n      toast.success('user fetched');\n    },\n    onError: () => {\n      toast.error('Error when fetching user');\n    },\n  });\n\n  useSubscription(OnSaveUserEvent, () => {\n    // refetch the user after saving form for example\n    refetch();\n  });\n  return; // profile view\n};\n```\n\n### 6) callable fetch can be done with `useCallAction` hook\n\n```js\nimport { useCallAction } from '@8baselabs/react-simple-state';\nimport { saveUser } from './actions';\n\n// UserProfile component\nexport const UserProfile = ({ userId }) => {\n  const userData = userDataState;\n  const [save, loadingSubmit] = useCallAction(saveUser);\n  // OR...\n\n  // setup the action, and return a function that will trigger the action when it needed.\n  const [save, loadingSubmit] = useCallAction(saveUser, {\n    onCompleted: () => {\n      toast.success('user saved');\n    },\n    onError: () => {\n      toast.error('Error when saving user');\n    },\n  });\n\n  return (\n    <Form>\n      <SubmitButton onClick={() => save(userId, useCallAction)} />\n    </Form>\n  );\n};\n```\n\n## Changelog\n### v0.0.1:\n\n- State Draft\n","readmeFilename":"README.md"}