zeno-state 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/dist/createStore.d.ts +3 -0
- package/dist/createStore.d.ts.map +1 -0
- package/dist/createStore.js +22 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/simpleState.d.ts +12 -0
- package/dist/simpleState.d.ts.map +1 -0
- package/dist/simpleState.js +1 -0
- package/dist/useStore.d.ts +3 -0
- package/dist/useStore.d.ts.map +1 -0
- package/dist/useStore.js +4 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Rob Watson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Simple state
|
|
2
|
+
|
|
3
|
+
A (hopefully) simple global state management system.
|
|
4
|
+
|
|
5
|
+
## Demo (this repository)
|
|
6
|
+
|
|
7
|
+
1. Download the code (`git checkout`, or some other way of downloading)
|
|
8
|
+
2. Run `pnpm install`
|
|
9
|
+
3. Run `pnpm run dev`
|
|
10
|
+
4. Open your browser at the location given by pnpm (usually http://localhost:5173)
|
|
11
|
+
5. Open your browser dev tools and enable the React dev tools feature of "Highlight updates when components render."
|
|
12
|
+
6. Have a play and watch how the different start management types handle their rendering
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install zeno-state
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Library usage
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Step 1: Define a store
|
|
24
|
+
|
|
25
|
+
I recommend setting a default value that contains all your keys alongside specifying the shape of the data to help
|
|
26
|
+
reduce null value exceptions and to help define the shape of objects contained within empty arrays
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { createStore } from 'zeno-state'
|
|
31
|
+
|
|
32
|
+
const carStore = createStore<{
|
|
33
|
+
cars: [{
|
|
34
|
+
make: 'Ford'|'Jaguar',
|
|
35
|
+
model: string,
|
|
36
|
+
engineSize: number,
|
|
37
|
+
colour: string
|
|
38
|
+
}]
|
|
39
|
+
}>({ cars: [] })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Step 2: Use it
|
|
44
|
+
|
|
45
|
+
The second argument of `useStore` is a _selector function_. This allows a portion of the whole state to be used by your
|
|
46
|
+
component and enables re-rendering only when that selection changes.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { useStore } from 'zeno-state'
|
|
50
|
+
|
|
51
|
+
function CarList() {
|
|
52
|
+
const cars = useStore(carStore, state => state.cars)
|
|
53
|
+
|
|
54
|
+
return cars.map((car, index) => (
|
|
55
|
+
<p>{ car.make } - { car.model }</p>
|
|
56
|
+
))
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Step 3: Update state inside a store
|
|
62
|
+
|
|
63
|
+
`createStore` returns `get` and `set` methods to update the state, you can use these directly and any components that
|
|
64
|
+
have selected part of the state you update will be re-rendered. The `set` function accepts an object which is merged
|
|
65
|
+
with the current state object, allowing additions and partial updates to the state.
|
|
66
|
+
|
|
67
|
+
> Note: this only allows for updating and adding keys to the stored state, not deleting any root-level keys not directly
|
|
68
|
+
> updating deep-nested properties.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
function addCar() {
|
|
72
|
+
carStore.set({ cars: [...cars, { make: 'Ford', model: 'Focus', engineSize: 1.6, colour: 'silver'}]})
|
|
73
|
+
}
|
|
74
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createStore.d.ts","sourceRoot":"","sources":["../src/lib/simple-state/createStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAA6B,MAAM,eAAe,CAAC;AAEhE,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CA2B7D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function createStore(state) {
|
|
2
|
+
const subscribers = new Set();
|
|
3
|
+
function subscribe(callback) {
|
|
4
|
+
subscribers.add(callback);
|
|
5
|
+
return () => subscribers.delete(callback);
|
|
6
|
+
}
|
|
7
|
+
function getSnapshot() {
|
|
8
|
+
return state;
|
|
9
|
+
}
|
|
10
|
+
function alertSubscribers() {
|
|
11
|
+
subscribers.forEach(subscriber => subscriber(state));
|
|
12
|
+
}
|
|
13
|
+
function updateState(slice) {
|
|
14
|
+
state = { ...state, ...slice };
|
|
15
|
+
alertSubscribers();
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
subscribe,
|
|
19
|
+
get: getSnapshot,
|
|
20
|
+
set: updateState,
|
|
21
|
+
};
|
|
22
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/simple-state/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SubscribeFn<State> = (state: State) => void;
|
|
2
|
+
export type UnsubscribeFn = () => void;
|
|
3
|
+
type SubscriberFn<State> = (callback: SubscribeFn<State>) => UnsubscribeFn;
|
|
4
|
+
type GetSnapshotFn<State> = () => State;
|
|
5
|
+
type UpdateStateFn<State> = (state: Partial<State>) => void;
|
|
6
|
+
export type Store<State> = {
|
|
7
|
+
subscribe: SubscriberFn<State>;
|
|
8
|
+
get: GetSnapshotFn<State>;
|
|
9
|
+
set: UpdateStateFn<State>;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=simpleState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simpleState.d.ts","sourceRoot":"","sources":["../src/lib/simple-state/simpleState.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,WAAW,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;AACvD,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAA;AAEtC,KAAK,YAAY,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,aAAa,CAAA;AAC1E,KAAK,aAAa,CAAC,KAAK,IAAI,MAAM,KAAK,CAAA;AACvC,KAAK,aAAa,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAA;AAE3D,MAAM,MAAM,KAAK,CAAC,KAAK,IAAI;IACzB,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAC9B,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;IACzB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;CAC1B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStore.d.ts","sourceRoot":"","sources":["../src/lib/simple-state/useStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEpC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,SAI5F"}
|
package/dist/useStore.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zeno-state",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "A simple global state management library for React",
|
|
7
|
+
"keywords": ["react", "state", "state-management", "hooks", "global-state"],
|
|
8
|
+
"author": "Rob Watson",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "vite",
|
|
21
|
+
"build": "tsc -b && vite build",
|
|
22
|
+
"build:lib": "vite build --mode lib && tsc --project tsconfig.lib.json",
|
|
23
|
+
"lint": "eslint .",
|
|
24
|
+
"preview": "vite preview",
|
|
25
|
+
"prepublishOnly": "npm run build:lib"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/js": "^9.19.0",
|
|
32
|
+
"@tailwindcss/vite": "^4.0.6",
|
|
33
|
+
"@types/react": "^19.0.8",
|
|
34
|
+
"@types/react-dom": "^19.0.3",
|
|
35
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
36
|
+
"eslint": "^9.19.0",
|
|
37
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
38
|
+
"eslint-plugin-react-refresh": "^0.4.18",
|
|
39
|
+
"globals": "^15.14.0",
|
|
40
|
+
"react": "^19.0.0",
|
|
41
|
+
"react-dom": "^19.0.0",
|
|
42
|
+
"tailwindcss": "^4.0.6",
|
|
43
|
+
"typescript": "~5.7.2",
|
|
44
|
+
"typescript-eslint": "^8.22.0",
|
|
45
|
+
"vite": "^6.1.0"
|
|
46
|
+
}
|
|
47
|
+
}
|