New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-hooks-global-state

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-hooks-global-state - npm Package Compare versions

Comparing version 2.0.0-alpha.3 to 2.0.0-alpha.4

dist/index.modern.mjs

10

CHANGELOG.md
# Change Log
## [Unreleased]
### Changed
- Re-implemented with zustand as a dependency
- BREAKING CHANGE: `useGlobalState` created with `createStore` doesn't return the second part of the tuple
### Removed
- BREAKING CHANGE: drop reduxDevToolsExt
- Reference implementation in `examples/08_thunk/src/devtools.ts`
## [1.0.2] - 2021-08-14
### Changed
- Fix package.json properly for ESM
## [1.0.1] - 2020-07-04

@@ -6,0 +16,0 @@ ### Changed

4

dist/index.modern.js

@@ -1,2 +0,2 @@

import{unstable_createMutableSource as t,useCallback as e,unstable_useMutableSource as r}from"react";const o=(t,e)=>"function"==typeof e?e(t):e,n=(t,e)=>{if(!t.includes(e))throw new Error(`'${e}' not found. It must be provided in initialState as a property key.`)};function s(e,r){const s=Object.keys(e);let a=e;const c=(()=>{const t=new Map;return s.forEach(e=>{t.set(e,new Set)}),t.set(null,new Set),t})(),u=(t,e)=>{s.forEach(r=>{t[r]!==e[r]&&c.get(r).forEach(t=>{t()})}),c.get(null).forEach(t=>{t()})},i={getState:()=>a,setState:t=>{const e=a;a=o(e,t),u(e,a)},getStateByKey:t=>("production"!==process.env.NODE_ENV&&n(s,t),a[t]),setStateByKey:(t,e)=>{var r;"production"!==process.env.NODE_ENV&&n(s,t),r=a,a={...r,[t]:o(r[t],e)},c.get(t).forEach(t=>{t()}),c.get(null).forEach(t=>{t()})},dispatch:t=>{if(!r)throw new Error("no reducer specified");const e=a;return a=r(e,t),u(e,a),t},subscribe:(t,e)=>{const r=c.get(t);return r.add(e),()=>{r.delete(e)}},mutableSource:void 0};return i.mutableSource=t(i,()=>a),i}function a(t,o){const n=e(t=>o?t.getStateByKey(o):t.getState(),[o]),s=e((t,e)=>t.subscribe(o||null,e),[o]);return[r(t.mutableSource,n,s),e(e=>{o?t.setStateByKey(o,e):t.setState(e)},[t,o])]}const c=t=>{const e=s(t);return{useGlobalState:t=>a(e,t),getGlobalState:e.getStateByKey,setGlobalState:e.setStateByKey}},u=(t,e=t(void 0,{type:void 0}),r)=>{if(r)return r(u)(t,e);const o=s(e,t);return{useGlobalState:t=>a(o,t),getState:o.getState,setState:o.setState,dispatch:o.dispatch}},i=()=>{if(!window.__REDUX_DEVTOOLS_EXTENSION__)return t=>t;const{before:t,after:e}=(()=>{let t,e;return{before:r=>(o,n,s)=>{if(t=o,e=n,s)return s(r)(o,n);const a=r(o,n);return{...a,useGlobalState:t=>{const[e]=a.useGlobalState(t);return[e,()=>{throw new Error("Update is not allowed when using DevTools")}]}}},after:r=>(o,n,s)=>{if(s)return s(r)(o,n);const a=r(t,e);let c={...o(n,{type:"@@redux/INIT"}),...e};const u=[];return{...a,getState:()=>c,dispatch:t=>(c=o(c,t),a.setState(c.computedStates[c.currentStateIndex].state),u.forEach(t=>t()),t),subscribe:t=>(u.push(t),()=>{const e=u.indexOf(t);u.splice(e,1)})}}}})();return((...t)=>t.reduce((t,e)=>(...r)=>t(e(...r))))(t,window.__REDUX_DEVTOOLS_EXTENSION__(),e)};export{s as createAtom,c as createGlobalState,u as createStore,i as reduxDevToolsExt,a as useAtom};
//# sourceMappingURL=index.modern.js.map
import{useCallback as t}from"react";import e from"zustand";import{redux as o}from"zustand/middleware";const r=(t,e)=>{if(!t.includes(e))throw new Error(`'${e}' not found. It must be provided in initialState as a property key.`)},n=o=>{const n=e(()=>o),s=Object.keys(o),i=(t,e)=>{"production"!==process.env.NODE_ENV&&r(s,t),n.setState(o=>{return{[t]:(r=o[t],n=e,"function"==typeof n?n(r):n)};var r,n})};return{useGlobalState:e=>{"production"!==process.env.NODE_ENV&&r(s,e);const o=t(t=>t[e],[e]);return[n(o),t(t=>i(e,t),[e])]},getGlobalState:t=>("production"!==process.env.NODE_ENV&&r(s,t),n.getState()[t]),setGlobalState:i}},s=(r,n=r(void 0,{type:void 0}),i)=>{if(i)return i(s)(r,n);const a=e(o(r,n)),p=Object.keys(n);return{useGlobalState:e=>{"production"!==process.env.NODE_ENV&&((t,e)=>{if(!t.includes(e))throw new Error(`'${e}' not found. It must be provided in initialState as a property key.`)})(p,e);const o=t(t=>t[e],[e]);return[a(o)]},getState:()=>a.getState(),dispatch:t=>a.dispatch(t)}};export{n as createGlobalState,s as createStore};
//# sourceMappingURL=index.modern.mjs.map

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((t=t||self).reactHooksGlobalState={},t.react)}(this,function(t,e){function n(){return(n=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t}).apply(this,arguments)}var r=function(t,e){return"function"==typeof e?e(t):e},u=function(t,e){if(!t.includes(e))throw new Error("'"+e+"' not found. It must be provided in initialState as a property key.")};function o(t,o){var a=Object.keys(t),c=t,i=function(){var t=new Map;return a.forEach(function(e){t.set(e,new Set)}),t.set(null,new Set),t}(),f=function(t,e){a.forEach(function(n){t[n]!==e[n]&&i.get(n).forEach(function(t){t()})}),i.get(null).forEach(function(t){t()})},s={getState:function(){return c},setState:function(t){var e=c;c=r(e,t),f(e,c)},getStateByKey:function(t){return"production"!==process.env.NODE_ENV&&u(a,t),c[t]},setStateByKey:function(t,e){var o,f;"production"!==process.env.NODE_ENV&&u(a,t),c=n({},o=c,((f={})[t]=r(o[t],e),f)),i.get(t).forEach(function(t){t()}),i.get(null).forEach(function(t){t()})},dispatch:function(t){if(!o)throw new Error("no reducer specified");var e=c;return c=o(e,t),f(e,c),t},subscribe:function(t,e){var n=i.get(t);return n.add(e),function(){n.delete(e)}},mutableSource:void 0};return s.mutableSource=e.unstable_createMutableSource(s,function(){return c}),s}function a(t,n){var r=e.useCallback(function(t){return n?t.getStateByKey(n):t.getState()},[n]),u=e.useCallback(function(t,e){return t.subscribe(n||null,e)},[n]);return[e.unstable_useMutableSource(t.mutableSource,r,u),e.useCallback(function(e){n?t.setStateByKey(n,e):t.setState(e)},[t,n])]}t.createAtom=o,t.createGlobalState=function(t){var e=o(t);return{useGlobalState:function(t){return a(e,t)},getGlobalState:e.getStateByKey,setGlobalState:e.setStateByKey}},t.createStore=function t(e,n,r){if(void 0===n&&(n=e(void 0,{type:void 0})),r)return r(t)(e,n);var u=o(n,e);return{useGlobalState:function(t){return a(u,t)},getState:u.getState,setState:u.setState,dispatch:u.dispatch}},t.reduxDevToolsExt=function(){return window.__REDUX_DEVTOOLS_EXTENSION__?function(){return[].slice.call(arguments).reduce(function(t,e){return function(){return t(e.apply(void 0,[].slice.call(arguments)))}})}(function(r){return function(u,o,a){if(t=u,e=o,a)return a(r)(u,o);var c=r(u,o);return n({},c,{useGlobalState:function(t){return[c.useGlobalState(t)[0],function(){throw new Error("Update is not allowed when using DevTools")}]}})}},window.__REDUX_DEVTOOLS_EXTENSION__(),function(r){return function(u,o,a){if(a)return a(r)(u,o);var c=r(t,e),i=n({},u(o,{type:"@@redux/INIT"}),e),f=[];return n({},c,{getState:function(){return i},dispatch:function(t){return i=u(i,t),c.setState(i.computedStates[i.currentStateIndex].state),f.forEach(function(t){return t()}),t},subscribe:function(t){return f.push(t),function(){var e=f.indexOf(t);f.splice(e,1)}}})}}):function(t){return t};var t,e},t.useAtom=a});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("zustand"),require("zustand/middleware")):"function"==typeof define&&define.amd?define(["exports","react","zustand","zustand/middleware"],e):e((t||self).reactHooksGlobalState={},t.react,t.zustand,t.middleware)}(this,function(t,e,n,r){function o(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var u=o(n),a=function(t,e){if(!t.includes(e))throw new Error("'"+e+"' not found. It must be provided in initialState as a property key.")};t.createGlobalState=function(t){var n=u.default(function(){return t}),r=Object.keys(t),o=function(t,e){"production"!==process.env.NODE_ENV&&a(r,t),n.setState(function(n){var r,o;return(r={})[t]="function"==typeof(o=e)?o(n[t]):o,r})};return{useGlobalState:function(t){"production"!==process.env.NODE_ENV&&a(r,t);var u=e.useCallback(function(e){return e[t]},[t]);return[n(u),e.useCallback(function(e){return o(t,e)},[t])]},getGlobalState:function(t){return"production"!==process.env.NODE_ENV&&a(r,t),n.getState()[t]},setGlobalState:o}},t.createStore=function t(n,o,a){if(void 0===o&&(o=n(void 0,{type:void 0})),a)return a(t)(n,o);var i=u.default(r.redux(n,o)),c=Object.keys(o);return{useGlobalState:function(t){"production"!==process.env.NODE_ENV&&function(t,e){if(!t.includes(e))throw new Error("'"+e+"' not found. It must be provided in initialState as a property key.")}(c,t);var n=e.useCallback(function(e){return e[t]},[t]);return[i(n)]},getState:function(){return i.getState()},dispatch:function(t){return i.dispatch(t)}}}});
//# sourceMappingURL=index.umd.js.map

@@ -1,4 +0,4 @@

/// <reference types="react" />
import { SetStateAction } from 'react';
/**
* create a gloal state
* create a global state
*

@@ -20,6 +20,6 @@ * It returns a set of functions

*/
export declare const createGlobalState: <State>(initialState: State) => {
useGlobalState: <StateKey extends keyof State>(stateKey: StateKey) => [State[StateKey], (u: import("react").SetStateAction<State[StateKey]>) => void];
getGlobalState: <StateKey_1 extends keyof State>(key: StateKey_1) => State[StateKey_1];
setGlobalState: <StateKey_2 extends keyof State>(key: StateKey_2, update: import("react").SetStateAction<State[StateKey_2]>) => void;
export declare const createGlobalState: <State extends object>(initialState: State) => {
useGlobalState: <StateKey extends keyof State>(stateKey: StateKey) => readonly [State[StateKey], (u: SetStateAction<State[StateKey]>) => void];
getGlobalState: <StateKey_1 extends keyof State>(stateKey: StateKey_1) => State[StateKey_1];
setGlobalState: <StateKey_2 extends keyof State>(stateKey: StateKey_2, update: SetStateAction<State[StateKey_2]>) => void;
};
import { Reducer } from 'react';
declare type Enhancer<Creator> = (creator: Creator) => Creator;
/**

@@ -24,8 +23,8 @@ * create a global store

*/
export declare const createStore: <State, Action>(reducer: Reducer<State, Action>, initialState?: State, enhancer?: Enhancer<any> | undefined) => {
useGlobalState: <StateKey extends keyof State>(stateKey: StateKey) => [State[StateKey], (u: import("react").SetStateAction<State[StateKey]>) => void];
export declare const createStore: <State extends object, Action extends {
type: unknown;
}>(reducer: Reducer<State, Action>, initialState?: State, enhancer?: any) => {
useGlobalState: <StateKey extends keyof State>(stateKey: StateKey) => readonly [State[StateKey]];
getState: () => State;
setState: (update: import("react").SetStateAction<State>) => void;
dispatch: (action: Action) => Action;
};
export {};

@@ -1,5 +0,2 @@

export { createAtom } from './createAtom';
export { useAtom } from './useAtom';
export { createGlobalState } from './createGlobalState';
export { createStore } from './createStore';
export { reduxDevToolsExt } from './devtools';
{
"name": "react-hooks-global-state",
"description": "Simple global state for React with Hooks API",
"version": "2.0.0-alpha.3",
"description": "Simple global state for React with Hooks API without Context API",
"version": "2.0.0-alpha.4",
"publishConfig": {

@@ -17,2 +17,11 @@ "tag": "next"

"types": "./dist/src/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/src/index.d.ts",
"module": "./dist/index.modern.js",
"import": "./dist/index.modern.mjs",
"default": "./dist/index.umd.js"
}
},
"sideEffects": false,

@@ -25,2 +34,3 @@ "files": [

"compile": "microbundle build -f modern,umd",
"postcompile": "cp dist/index.modern.mjs dist/index.modern.js && cp dist/index.modern.mjs.map dist/index.modern.js.map",
"test": "run-s eslint tsc-test jest e2e-test:*",

@@ -30,3 +40,3 @@ "eslint": "eslint --ext .js,.ts,.tsx --ignore-pattern dist .",

"tsc-test": "tsc --project . --noEmit",
"apidoc": "documentation readme --section API --markdown-toc false --parse-extension ts src/*.ts",
"apidoc": "documentation readme --section API --markdown-toc false --parse-extension ts src/createGlobalState.ts src/createStore.ts",
"e2e-test:01_minimal": "server-test examples:01_minimal 8080 'jest --preset jest-puppeteer __tests__/e2e/01_minimal.ts'",

@@ -45,16 +55,22 @@ "e2e-test:02_typescript": "server-test examples:02_typescript 8080 'jest --preset jest-puppeteer __tests__/e2e/02_typescript.ts'",

"e2e-test:13_persistence": "server-test examples:13_persistence 8080 'jest --preset jest-puppeteer __tests__/e2e/13_persistence.ts'",
"examples:01_minimal": "DIR=01_minimal EXT=js webpack-dev-server",
"examples:02_typescript": "DIR=02_typescript webpack-dev-server",
"examples:03_actions": "DIR=03_actions webpack-dev-server",
"examples:04_fetch": "DIR=04_fetch webpack-dev-server",
"examples:05_onmount": "DIR=05_onmount webpack-dev-server",
"examples:06_reducer": "DIR=06_reducer webpack-dev-server",
"examples:07_middleware": "DIR=07_middleware webpack-dev-server",
"examples:08_thunk": "DIR=08_thunk webpack-dev-server",
"examples:09_comparison": "DIR=09_comparison webpack-dev-server",
"examples:10_immer": "DIR=10_immer webpack-dev-server",
"examples:11_deep": "DIR=11_deep webpack-dev-server",
"examples:12_effect": "DIR=12_effect webpack-dev-server",
"examples:13_persistence": "DIR=13_persistence webpack-dev-server"
"examples:01_minimal": "DIR=01_minimal EXT=js webpack-cli serve",
"examples:02_typescript": "DIR=02_typescript webpack-cli serve",
"examples:03_actions": "DIR=03_actions webpack-cli serve",
"examples:04_fetch": "DIR=04_fetch webpack-cli serve",
"examples:05_onmount": "DIR=05_onmount webpack-cli serve",
"examples:06_reducer": "DIR=06_reducer webpack-cli serve",
"examples:07_middleware": "DIR=07_middleware webpack-cli serve",
"examples:08_thunk": "DIR=08_thunk webpack-cli serve",
"examples:09_comparison": "DIR=09_comparison webpack-cli serve",
"examples:10_immer": "DIR=10_immer webpack-cli serve",
"examples:11_deep": "DIR=11_deep webpack-cli serve",
"examples:12_effect": "DIR=12_effect webpack-cli serve",
"examples:13_persistence": "DIR=13_persistence webpack-cli serve"
},
"jest": {
"testEnvironment": "jsdom",
"transform": {
"^.+\\.ts$": "ts-jest"
}
},
"keywords": [

@@ -69,48 +85,49 @@ "react",

"license": "MIT",
"dependencies": {},
"dependencies": {
"zustand": "^3.5.10"
},
"devDependencies": {
"@babel/core": "^7.11.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.1",
"@testing-library/react": "^10.4.7",
"@types/expect-puppeteer": "^4.4.3",
"@types/jest": "^26.0.8",
"@types/jest-environment-puppeteer": "^4.3.2",
"@types/puppeteer": "^3.0.1",
"@types/react": "^16.9.44",
"@types/react-dom": "^16.9.8",
"@types/redux-logger": "^3.0.8",
"@typescript-eslint/eslint-plugin": "^3.8.0",
"@typescript-eslint/parser": "^3.8.0",
"babel-loader": "^8.1.0",
"documentation": "^13.0.2",
"eslint": "^7.6.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-react": "^7.20.5",
"eslint-plugin-react-hooks": "^4.0.8",
"html-webpack-plugin": "^4.3.0",
"immer": "^7.0.7",
"jest": "^26.2.2",
"jest-puppeteer": "^4.4.0",
"microbundle": "^0.12.3",
"@testing-library/react": "^12.0.0",
"@types/expect-puppeteer": "^4.4.6",
"@types/jest": "^27.0.1",
"@types/jest-environment-puppeteer": "^4.4.1",
"@types/puppeteer": "^5.4.4",
"@types/react": "^17.0.20",
"@types/react-dom": "^17.0.9",
"@types/redux-logger": "^3.0.9",
"@typescript-eslint/eslint-plugin": "^4.31.0",
"@typescript-eslint/parser": "^4.31.0",
"documentation": "^13.2.5",
"eslint": "^7.32.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.25.1",
"eslint-plugin-react-hooks": "^4.2.0",
"html-webpack-plugin": "^5.3.2",
"immer": "^9.0.6",
"jest": "^27.1.1",
"jest-puppeteer": "^5.0.4",
"microbundle": "^0.13.3",
"npm-run-all": "^4.1.5",
"puppeteer": "^5.2.1",
"react": "experimental",
"react-dom": "experimental",
"react-refresh": "^0.8.3",
"redux": "^4.0.5",
"puppeteer": "^10.2.0",
"react": "^16.13.1",
"react-dom": "^17.0.2",
"redux": "^4.1.1",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"start-server-and-test": "^1.11.2",
"ts-jest": "^26.1.4",
"ts-loader": "^8.0.2",
"typescript": "^3.9.7",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
"start-server-and-test": "^1.14.0",
"ts-jest": "^27.0.5",
"ts-loader": "^9.2.5",
"typescript": "^4.4.2",
"webpack": "^5.52.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.1.1"
},
"peerDependencies": {
"react": ">=16.14.0"
"react": ">=16.8.0"
},
"resolutions": {
"@types/node": "^15"
}
}

@@ -6,4 +6,5 @@ # react-hooks-global-state

[![size](https://img.shields.io/bundlephobia/minzip/react-hooks-global-state)](https://bundlephobia.com/result?p=react-hooks-global-state)
[![discord](https://img.shields.io/discord/627656437971288081)](https://discord.gg/MrQdmzd)
Simple global state for React with Hooks API
Simple global state for React with Hooks API without Context API

@@ -15,15 +16,8 @@ ## Introduction

- React Hooks only API without React Context
- You don't need Context for global state.
- Hardly misusable selector by state keys
- For most of cases, function selectors are not necessary.
- Optimization for shallow state getter and setter.
- The library cares the state object only one-level deep.
- TypeScript type definitions
- A creator function creates hooks with types inferred.
- Analogous APIs
- useGlobalState works like React.useState.
- useAtom resembles with the concept of Recoil.
- createStore implies Redux.
- Concurrent Mode support
- Under the hood, it's implemented with useMutableSource.
- (For external stores like this, state branching is never possible.)
- Redux middleware support to some extent
- Some of libraries in Redux ecosystem can be used.

@@ -38,36 +32,6 @@ ## Install

### createAtom style
### setState style
```javascript
import React from 'react';
import { createAtom, useAtom } from 'react-hooks-global-state';
const initialState = { count: 0 };
const atom1 = createAtom(initialState);
const Counter = () => {
const [count, setCount] = useAtom(atom1, 'count');
return (
<div>
<span>Counter: {count}</span>
{/* update state by passing callback function */}
<button onClick={() => setCount(v => v + 1)}>+1</button>
{/* update state by passing new value */}
<button onClick={() => setCount(count - 1)}>-1</button>
</div>
);
};
const App = () => (
<>
<Counter />
<Counter />
</>
);
```
### createGlobalState style
```javascript
import React from 'react';
import { createGlobalState } from 'react-hooks-global-state';

@@ -99,3 +63,3 @@

### createStore style
### reducer style

@@ -139,32 +103,5 @@ ```javascript

### createAtom
create an atom
It returns a set of functions to be called outside React
- `getStateByKey`: a function to get the part of state by key outside React
- `setStateByKey`: a function to set the part of state by key outside React
- `getState`: a function to get the entire state
- `setState`: a function to get the entire state
- `dispatch`: an optional function that can be used if reducer is provided
#### Parameters
- `initialState` **State**
- `reducer` **Reducer&lt;State, Action>?**
#### Examples
```javascript
import { createAtom } from 'react-hooks-global-state';
const atom = createAtom({ count: 0 });
atom.setStateByKey('count', 1);
```
### createGlobalState
create a gloal state
create a global state

@@ -225,26 +162,2 @@ It returns a set of functions

### useAtom
use atom
a custom hook that works like React.useState
#### Parameters
- `atom` **Atom&lt;State, any>**
- `stateKey` **any?**
#### Examples
```javascript
import { createAtom, useAtom } from 'react-hooks-global-state';
const atom = createAtom({ count: 0 });
const Component = () => {
const [count, setCount] = useAtom(atom, 'count');
...
};
```
## Examples

@@ -262,15 +175,15 @@

You can also try them in codesandbox.io:
[01](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/01_minimal)
[02](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/02_typescript)
[03](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/03_actions)
[04](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/04_fetch)
[05](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/05_onmount)
[06](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/06_reducer)
[07](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/07_middleware)
[08](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/08_thunk)
[09](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/09_comparison)
[10](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/10_immer)
[11](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/11_deep)
[12](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/12_effect)
[13](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/master/examples/13_persistence)
[01](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/01_minimal)
[02](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/02_typescript)
[03](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/03_actions)
[04](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/04_fetch)
[05](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/05_onmount)
[06](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/06_reducer)
[07](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/07_middleware)
[08](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/08_thunk)
[09](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/09_comparison)
[10](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/10_immer)
[11](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/11_deep)
[12](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/12_effect)
[13](https://codesandbox.io/s/github/dai-shi/react-hooks-global-state/tree/main/examples/13_persistence)

@@ -277,0 +190,0 @@ ## Blogs

@@ -1,6 +0,22 @@

import { createAtom } from './createAtom';
import { useAtom } from './useAtom';
import { SetStateAction, useCallback } from 'react';
import create from 'zustand';
const validateStateKey = (keys: string[], stateKey: string) => {
if (!keys.includes(stateKey)) {
throw new Error(`'${stateKey}' not found. It must be provided in initialState as a property key.`);
}
};
const isFunction = (fn: unknown): fn is Function => (typeof fn === 'function');
const updateValue = <Value>(oldValue: Value, newValue: SetStateAction<Value>) => {
if (isFunction(newValue)) {
return newValue(oldValue);
}
return newValue;
};
/**
* create a gloal state
* create a global state
*

@@ -22,11 +38,45 @@ * It returns a set of functions

*/
export const createGlobalState = <State>(initialState: State) => {
const atom = createAtom(initialState);
export const createGlobalState = <State extends object>(initialState: State) => {
const useStore = create<State>(() => initialState);
type StateKeys = keyof State;
const keys = Object.keys(initialState);
const setGlobalState = <StateKey extends StateKeys>(
stateKey: StateKey,
update: SetStateAction<State[StateKey]>,
) => {
if (process.env.NODE_ENV !== 'production') {
validateStateKey(keys, stateKey as string);
}
useStore.setState((previousState) => ({
[stateKey]: updateValue(previousState[stateKey], update),
} as Pick<State, StateKey>));
};
const useGlobalState = <StateKey extends StateKeys>(stateKey: StateKey) => {
if (process.env.NODE_ENV !== 'production') {
validateStateKey(keys, stateKey as string);
}
const selector = useCallback((state: State) => state[stateKey], [stateKey]);
const partialState = useStore(selector);
const updater = useCallback(
(u: SetStateAction<State[StateKey]>) => setGlobalState(stateKey, u),
[stateKey],
);
return [partialState, updater] as const;
};
const getGlobalState = <StateKey extends StateKeys>(stateKey: StateKey) => {
if (process.env.NODE_ENV !== 'production') {
validateStateKey(keys, stateKey as string);
}
return useStore.getState()[stateKey];
};
return {
useGlobalState: <StateKey extends keyof State>(stateKey: StateKey) => (
useAtom<State, StateKey>(atom, stateKey)
),
getGlobalState: atom.getStateByKey,
setGlobalState: atom.setStateByKey,
useGlobalState,
getGlobalState,
setGlobalState,
};
};
/* eslint @typescript-eslint/no-explicit-any: off */
import { Reducer } from 'react';
import { Reducer, useCallback } from 'react';
import { Atom, createAtom } from './createAtom';
import { useAtom } from './useAtom';
import create from 'zustand';
import { redux } from 'zustand/middleware';
type Enhancer<Creator> = (creator: Creator) => Creator;
const validateStateKey = (keys: string[], stateKey: string) => {
if (!keys.includes(stateKey)) {
throw new Error(`'${stateKey}' not found. It must be provided in initialState as a property key.`);
}
};

@@ -31,17 +35,32 @@ /**

*/
export const createStore = <State, Action>(
export const createStore = <State extends object, Action extends { type: unknown }>(
reducer: Reducer<State, Action>,
initialState: State = (reducer as any)(undefined, { type: undefined }),
enhancer?: Enhancer<any>,
enhancer?: any,
) => {
if (enhancer) return enhancer(createStore)(reducer, initialState) as never;
const atom = createAtom(initialState, reducer);
const useStore = create<State>(redux(reducer, initialState));
type StateKeys = keyof State;
const keys = Object.keys(initialState);
const useGlobalState = <StateKey extends StateKeys>(stateKey: StateKey) => {
if (process.env.NODE_ENV !== 'production') {
validateStateKey(keys, stateKey as string);
}
const selector = useCallback((state: State) => state[stateKey], [stateKey]);
const partialState = useStore(selector);
return [partialState] as const;
};
const getState = (): State => useStore.getState();
const dispatch = (action: Action): Action => (useStore as any).dispatch(action);
return {
useGlobalState: <StateKey extends keyof State>(stateKey: StateKey) => (
useAtom<State, StateKey>(atom as Atom<State, any>, stateKey)
),
getState: atom.getState,
setState: atom.setState, // for library use
dispatch: atom.dispatch,
useGlobalState,
getState,
dispatch,
};
};

@@ -1,6 +0,2 @@

export { createAtom } from './createAtom';
export { useAtom } from './useAtom';
export { createGlobalState } from './createGlobalState';
export { createStore } from './createStore';
export { reduxDevToolsExt } from './devtools';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc