zustand-lite 0.1.2
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 +191 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/lib/createStore.d.ts +15 -0
- package/dist/lib/createStore.js +56 -0
- package/dist/lib/extendGetters.d.ts +2 -0
- package/dist/lib/extendGetters.js +23 -0
- package/dist/lib/extendSetters.d.ts +2 -0
- package/dist/lib/extendSetters.js +9 -0
- package/dist/lib/generateStateGet.d.ts +3 -0
- package/dist/lib/generateStateGet.js +11 -0
- package/dist/lib/generateStateSet.d.ts +3 -0
- package/dist/lib/generateStateSet.js +16 -0
- package/dist/lib/generateStateUse.d.ts +3 -0
- package/dist/lib/generateStateUse.js +12 -0
- package/dist/lib/restrictState.d.ts +2 -0
- package/dist/lib/restrictState.js +13 -0
- package/dist/plugins/reset.d.ts +6 -0
- package/dist/plugins/reset.js +10 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.js +1 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Piotr Siatkowski
|
|
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,191 @@
|
|
|
1
|
+
# π§ Zustand Lite
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/zustand-lite)
|
|
4
|
+
[](https://bundlephobia.com/package/zustand-lite)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://github.com/PiotrSiatkowski/zustand-lite)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Zustand Lite is a **zero-boilerplate** state management wrapper built specifically for **frontend developers** who want powerful and scalable global state without the usual complexity. Designed for simplicity, it gives you everything you need out-of-the-box β from selectors to setters to middleware β while remaining lightweight and extensible. With seamless support for plugins, devtools, and state encapsulation, managing state becomes a breeze, not a chore.
|
|
12
|
+
|
|
13
|
+
> A zero-boilerplate wrapper around [Zustand](https://github.com/pmndrs/zustand), focused on ergonomics, plugins, and powerful dynamic extension β inspired by [zustand-x](https://github.com/udecode/zustand-x) and selector auto-generation patterns.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## π Features
|
|
18
|
+
|
|
19
|
+
- π Write only code that matters -> save lines
|
|
20
|
+
- β
Type-safe getter/setter generators for every field
|
|
21
|
+
- π First-class **plugin system**
|
|
22
|
+
- π§© Optional **middleware integration** (devtools, persist)
|
|
23
|
+
- π Chainable API: `.extendGetters(...)`, `.extendSetters(...)`, `.restrictState(...)`
|
|
24
|
+
- π Named devtools actions and store labeling
|
|
25
|
+
- π§Ό No runtime dependencies other than Zustand
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## π¦ Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install zustand zustand-lite
|
|
33
|
+
# or
|
|
34
|
+
pnpm add zustand zustand-lite
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## π Basic Usage
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { createStore } from 'zustand-lite';
|
|
43
|
+
|
|
44
|
+
const initialState: {
|
|
45
|
+
foo: string;
|
|
46
|
+
bar: {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
}
|
|
50
|
+
} = {
|
|
51
|
+
foo: '',
|
|
52
|
+
bar: {
|
|
53
|
+
x: 0,
|
|
54
|
+
y: 0,
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const store = createStore(initialState)
|
|
59
|
+
.extendGetters(({ get }) => ({
|
|
60
|
+
area: () => get.bar().x * get.bar().y,
|
|
61
|
+
}))
|
|
62
|
+
.extendSetters(({ get, set }) => ({
|
|
63
|
+
translateX: (dx: number) => set.bar(({ x: get.bar().x + dx, y: get.bar().y })),
|
|
64
|
+
}))
|
|
65
|
+
.restrictState(['bar']);
|
|
66
|
+
|
|
67
|
+
// Usage
|
|
68
|
+
store.use.area(); // React-friendly subscription, re-renders only when area changes.
|
|
69
|
+
store.get.foo(); // Synchronous accessor
|
|
70
|
+
store.set.translateX(2); // Safe setter
|
|
71
|
+
store.api.getState(); // Native Zustand store API
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## π§ API Overview
|
|
77
|
+
|
|
78
|
+
### `createStore(initialState, options)`
|
|
79
|
+
|
|
80
|
+
Creates a typed store with optional plugins and middleware.
|
|
81
|
+
|
|
82
|
+
**Options:**
|
|
83
|
+
|
|
84
|
+
| Key | Type | Description |
|
|
85
|
+
|--------------|----------------------------------------------------------------------------|----------------------------------------|
|
|
86
|
+
| `name` | `string` | Name shown in Redux DevTools |
|
|
87
|
+
| `plugins` | `StoreApiPlugin[]` | Array of plugins to extend the store |
|
|
88
|
+
| `middlewares`| `{ devtools?: true or DevtoolsOptions, persist?: true or PersistOptions }` | Middleware configuration |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### Chainable Methods
|
|
93
|
+
|
|
94
|
+
- **`.extendGetters(fn)`**
|
|
95
|
+
Add additional derived getters based on current state.
|
|
96
|
+
|
|
97
|
+
- **`.extendSetters(fn)`**
|
|
98
|
+
Add additional typed setters.
|
|
99
|
+
|
|
100
|
+
- **`.restrictState(keys?: string[])`**
|
|
101
|
+
Hide selected fields from the public API, returning a minimal store (removes config methods as well).
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Store Interface
|
|
106
|
+
|
|
107
|
+
After creation, your store includes:
|
|
108
|
+
|
|
109
|
+
| Property | Purpose |
|
|
110
|
+
|--------------------|---------------------------------------------------------|
|
|
111
|
+
| `store.use.foo()` | React hook getter for subscribing to `foo` |
|
|
112
|
+
| `store.get.foo()` | Direct synchronous access to `foo` |
|
|
113
|
+
| `store.set.foo(v)` | Set a new value for `foo` |
|
|
114
|
+
| `store.api` | The native Zustand store API (getState, setState, etc.) |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## π§© Plugin System
|
|
119
|
+
|
|
120
|
+
You can define plugins that inject additional state or behavior:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { StoreApiPlugin } from 'zustand-lite';
|
|
124
|
+
|
|
125
|
+
type Setters = {
|
|
126
|
+
reset: () => void;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const reset: StoreApiPlugin<{}, {}, Setters> = {
|
|
130
|
+
extends: store => {
|
|
131
|
+
return store.extendSetters(({ api }) => ({
|
|
132
|
+
reset: () => {
|
|
133
|
+
const initialState = api.getInitialState?.() ?? {};
|
|
134
|
+
api.setState(() => initialState, true);
|
|
135
|
+
},
|
|
136
|
+
}));
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Apply it like this:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
const store = createStore({}, { plugins: [reset] });
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## π§ͺ DevTools Integration
|
|
150
|
+
|
|
151
|
+
You can add the most useful middlewares:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
{
|
|
155
|
+
name: 'MyApp/CounterStore',
|
|
156
|
+
middlewares: {
|
|
157
|
+
devtools: true,
|
|
158
|
+
persist: {
|
|
159
|
+
...options,
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## π§± Built With
|
|
168
|
+
|
|
169
|
+
- [Zustand](https://github.com/pmndrs/zustand)
|
|
170
|
+
- Inspired by [zustand-x](https://github.com/udecode/zustand-x)
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## π License
|
|
175
|
+
|
|
176
|
+
MIT β free to use, extend, and improve.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## π€ Contributing
|
|
181
|
+
|
|
182
|
+
Pull requests, feedback, and ideas are welcome!
|
|
183
|
+
If you'd like to publish your own plugins, we recommend namespacing them under:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
zustand-lite/plugin-*
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
or adding them to the main repository under the plugins directory.
|
|
190
|
+
|
|
191
|
+
---
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entire zustand-lite no-boilerplate functionality is inspired by this recipe:
|
|
3
|
+
* https://docs.pmnd.rs/zustand/guides/auto-generating-selectors and 3th party
|
|
4
|
+
* zustand-x repository: https://github.com/udecode/zustand-x.
|
|
5
|
+
**/
|
|
6
|
+
import { DevtoolsOptions, PersistOptions } from 'zustand/middleware';
|
|
7
|
+
import { AugmentedApiData, AugmentedGetters, AugmentedSetters, State, StoreApi, StoreApiPluginList } from '../types';
|
|
8
|
+
export declare function createStore<T extends State, Plugins extends StoreApiPluginList = []>(initialState: T, options?: {
|
|
9
|
+
name?: string;
|
|
10
|
+
plugins?: [...Plugins];
|
|
11
|
+
middlewares?: {
|
|
12
|
+
devtools?: true | DevtoolsOptions;
|
|
13
|
+
persist?: true | PersistOptions<any>;
|
|
14
|
+
};
|
|
15
|
+
}): StoreApi<AugmentedApiData<T, Plugins>, AugmentedGetters<Plugins>, AugmentedSetters<Plugins>>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entire zustand-lite no-boilerplate functionality is inspired by this recipe:
|
|
3
|
+
* https://docs.pmnd.rs/zustand/guides/auto-generating-selectors and 3th party
|
|
4
|
+
* zustand-x repository: https://github.com/udecode/zustand-x.
|
|
5
|
+
**/
|
|
6
|
+
import { devtools, persist } from 'zustand/middleware';
|
|
7
|
+
import { createStore as createVanillaStore } from 'zustand/vanilla';
|
|
8
|
+
import { extendGetters } from './extendGetters';
|
|
9
|
+
import { extendSetters } from './extendSetters';
|
|
10
|
+
import { generateStateGet } from './generateStateGet';
|
|
11
|
+
import { generateStateSet } from './generateStateSet';
|
|
12
|
+
import { generateStateUse } from './generateStateUse';
|
|
13
|
+
import { restrictState } from './restrictState';
|
|
14
|
+
export function createStore(initialState, options) {
|
|
15
|
+
const { name = 'zustand-lite', plugins = [], middlewares = {} } = options ?? {};
|
|
16
|
+
// Merge state from plugins to be available for future use.
|
|
17
|
+
let mergedState = initialState;
|
|
18
|
+
plugins.forEach(plugin => {
|
|
19
|
+
if (plugin.creates) {
|
|
20
|
+
mergedState = { ...mergedState, ...plugin.creates() };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
// Apply supported middlewares.
|
|
24
|
+
let initializer = () => mergedState;
|
|
25
|
+
if (middlewares.devtools) {
|
|
26
|
+
initializer = devtools(initializer, middlewares.devtools === true ? { name } : middlewares.devtools);
|
|
27
|
+
}
|
|
28
|
+
if (middlewares.persist) {
|
|
29
|
+
initializer = persist(initializer, middlewares.persist === true ? { name } : middlewares.persist);
|
|
30
|
+
}
|
|
31
|
+
// Create a vanilla zustand store to wrap.
|
|
32
|
+
const storeApi = createVanillaStore(initializer);
|
|
33
|
+
// Create zustand-lite wrapper.
|
|
34
|
+
let store = {
|
|
35
|
+
api: storeApi,
|
|
36
|
+
get: generateStateGet(storeApi),
|
|
37
|
+
set: generateStateSet(storeApi, !!middlewares.devtools, name),
|
|
38
|
+
use: generateStateUse(storeApi),
|
|
39
|
+
extendGetters(builder) {
|
|
40
|
+
return extendGetters(builder, this);
|
|
41
|
+
},
|
|
42
|
+
extendSetters(builder) {
|
|
43
|
+
return extendSetters(builder, this);
|
|
44
|
+
},
|
|
45
|
+
restrictState(publicState = []) {
|
|
46
|
+
return restrictState(publicState, mergedState, this);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
// Extend store getters and setters with plugins.
|
|
50
|
+
plugins.forEach(plugin => {
|
|
51
|
+
if (plugin.extends) {
|
|
52
|
+
store = plugin.extends(store);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return store;
|
|
56
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Default, GettersBuilder, State, StoreApi } from '../types';
|
|
2
|
+
export declare function extendGetters<Builder extends GettersBuilder<T, Getters, Setters>, T extends State = Default, Getters = Default, Setters = Default>(builder: Builder, thisApi: StoreApi<T, Getters, Setters>): StoreApi<T, Getters & ReturnType<Builder>, Setters>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { shallow } from 'zustand/shallow';
|
|
2
|
+
import { useStoreWithEqualityFn } from 'zustand/traditional';
|
|
3
|
+
export function extendGetters(builder, thisApi) {
|
|
4
|
+
const use = { ...thisApi.use };
|
|
5
|
+
const get = { ...thisApi.get };
|
|
6
|
+
Object.keys(builder(thisApi)).forEach(key => {
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
use[key] = (...args) =>
|
|
9
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
10
|
+
useStoreWithEqualityFn(thisApi.api, () => {
|
|
11
|
+
return builder(thisApi)[key](...args);
|
|
12
|
+
}, shallow);
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
get[key] = (...args) => {
|
|
15
|
+
return builder(thisApi)[key](...args);
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
...thisApi,
|
|
20
|
+
get,
|
|
21
|
+
use,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Default, SettersBuilder, State, StoreApi } from '../types';
|
|
2
|
+
export declare function extendSetters<Builder extends SettersBuilder<T, Getters, Setters>, T extends State = Default, Getters = Default, Setters = Default>(builder: Builder, thisApi: StoreApi<T, Getters, Setters>): StoreApi<T, Getters, Setters & ReturnType<Builder>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function generateStateGet(api) {
|
|
2
|
+
const getters = {};
|
|
3
|
+
const initialState = api.getState();
|
|
4
|
+
Object.keys(initialState).forEach(key => {
|
|
5
|
+
getters[key] = () => api.getState()[key];
|
|
6
|
+
});
|
|
7
|
+
Object.getOwnPropertySymbols(initialState).forEach(symbol => {
|
|
8
|
+
getters[symbol] = () => api.getState()[symbol];
|
|
9
|
+
});
|
|
10
|
+
return getters;
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function generateStateSet(api, hasDevtools, storeName) {
|
|
2
|
+
const setters = {};
|
|
3
|
+
Object.keys(api.getState()).forEach(key => {
|
|
4
|
+
setters[key] = (value) => {
|
|
5
|
+
if (api.getState()[key] === value) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const setState = api.setState;
|
|
9
|
+
setState(state => ({
|
|
10
|
+
...state,
|
|
11
|
+
[key]: value,
|
|
12
|
+
}), false, hasDevtools ? { type: `${storeName}/${key}`, payload: { [key]: value } } : undefined);
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
return setters;
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { shallow } from 'zustand/shallow';
|
|
2
|
+
import { useStoreWithEqualityFn } from 'zustand/traditional';
|
|
3
|
+
export function generateStateUse(api) {
|
|
4
|
+
const getters = {};
|
|
5
|
+
Object.keys(api.getState()).forEach(key => {
|
|
6
|
+
getters[key] = (equalityFn = shallow) => {
|
|
7
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
8
|
+
return useStoreWithEqualityFn(api, (state) => state[key], equalityFn);
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
return getters;
|
|
12
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Empty, GetRecord, SetRecord, State, StoreApi, StoreApiEncapsulated } from '../types';
|
|
2
|
+
export declare function restrictState<T extends State, Key extends keyof T, Getters extends GetRecord<any> = Empty, Setters extends SetRecord<any> = Empty>(privateState: Key[], mergedState: T, thisApi: StoreApi<T, Getters, Setters>): StoreApiEncapsulated<Omit<T, Key>, Getters, Setters>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function restrictState(privateState, mergedState, thisApi) {
|
|
2
|
+
return {
|
|
3
|
+
api: thisApi.api,
|
|
4
|
+
set: thisApi.set,
|
|
5
|
+
use: thisApi.use,
|
|
6
|
+
get: Object.keys(thisApi.get).reduce((acc, key) => mergedState[key] && privateState.includes(key)
|
|
7
|
+
? acc
|
|
8
|
+
: {
|
|
9
|
+
...acc,
|
|
10
|
+
[key]: thisApi.get[key],
|
|
11
|
+
}, {}),
|
|
12
|
+
};
|
|
13
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { StoreApi as StoreApiLib } from 'zustand';
|
|
2
|
+
export type State = Record<string | symbol, unknown>;
|
|
3
|
+
export type Empty = Record<string, never>;
|
|
4
|
+
export type Default = Record<string | symbol, any>;
|
|
5
|
+
export type EqualityChecker<T> = (state: T, newState: T) => boolean;
|
|
6
|
+
export type StoreApiGet<T extends State, Getters> = Required<GetRecord<T>> & Getters;
|
|
7
|
+
export type StoreApiUse<T extends State, Getters> = Required<UseRecord<T>> & Getters;
|
|
8
|
+
export type StoreApiSet<T extends State, Setters> = Required<SetRecord<T>> & Setters;
|
|
9
|
+
export type StoreApiEncapsulated<T extends State = Empty, Getters = Default, Setters = Default> = {
|
|
10
|
+
api: StoreApiLib<T>;
|
|
11
|
+
get: StoreApiGet<T, Getters>;
|
|
12
|
+
set: StoreApiSet<T, Setters>;
|
|
13
|
+
use: StoreApiUse<T, Getters>;
|
|
14
|
+
};
|
|
15
|
+
export type StoreApi<T extends State = Empty, Getters = Default, Setters = Default> = {
|
|
16
|
+
api: StoreApiLib<T>;
|
|
17
|
+
get: StoreApiGet<T, Getters>;
|
|
18
|
+
set: StoreApiSet<T, Setters>;
|
|
19
|
+
use: StoreApiUse<T, Getters>;
|
|
20
|
+
extendGetters<Builder extends GettersBuilder<T, Getters, Setters>>(builder: Builder): StoreApi<T, Getters & ReturnType<Builder>, Setters>;
|
|
21
|
+
extendSetters<Builder extends SettersBuilder<T, Getters, Setters>>(builder: Builder): StoreApi<T, Getters, Setters & ReturnType<Builder>>;
|
|
22
|
+
restrictState(): StoreApiEncapsulated<T, Getters, Setters>;
|
|
23
|
+
restrictState<Key extends keyof T>(publicState: Key[]): StoreApiEncapsulated<Pick<T, Key>, Getters, Setters>;
|
|
24
|
+
};
|
|
25
|
+
export type GettersBuilder<T extends State, Getters = Default, Setters = Default> = (args: {
|
|
26
|
+
api: StoreApiLib<T>;
|
|
27
|
+
get: StoreApiGet<T, Getters>;
|
|
28
|
+
set: StoreApiSet<T, Setters>;
|
|
29
|
+
}) => Record<string, (...args: any[]) => {} | null>;
|
|
30
|
+
export type SettersBuilder<T extends State, Getters = Default, Setters = Default> = (args: {
|
|
31
|
+
api: StoreApiLib<T>;
|
|
32
|
+
get: StoreApiGet<T, Getters>;
|
|
33
|
+
set: StoreApiSet<T, Setters>;
|
|
34
|
+
}) => Record<string, (...args: any[]) => void>;
|
|
35
|
+
export type GetRecord<O extends Record<string, any>> = {
|
|
36
|
+
[K in keyof O]: () => O[K];
|
|
37
|
+
};
|
|
38
|
+
export type UseRecord<O extends Record<string, any>> = {
|
|
39
|
+
[K in keyof O]: (equalityFn?: EqualityChecker<O[K]>) => O[K];
|
|
40
|
+
};
|
|
41
|
+
export type SetRecord<O extends Record<string, any>> = {
|
|
42
|
+
[K in keyof O]: (value: O[K]) => void;
|
|
43
|
+
};
|
|
44
|
+
export type StoreApiPlugin<NewApiData extends State, NewGetters, NewSetters> = {
|
|
45
|
+
creates?: () => NewApiData;
|
|
46
|
+
extends?: (store: StoreApi<NewApiData, NewGetters, NewSetters>) => StoreApi<NewApiData, NewGetters, NewSetters>;
|
|
47
|
+
};
|
|
48
|
+
export type StoreApiPluginList = StoreApiPlugin<any, any, any>[];
|
|
49
|
+
export type AugmentedApiData<T, Plugins extends StoreApiPluginList> = T & UnionToIntersection<ExtractPluginTypes<Plugins, 'create'>[number]>;
|
|
50
|
+
export type AugmentedGetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['getters']>;
|
|
51
|
+
export type AugmentedSetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['setters']>;
|
|
52
|
+
type ExtractPluginTypes<Plugins extends StoreApiPluginList, Key extends 'create' | 'extend'> = {
|
|
53
|
+
[K in keyof Plugins]: Plugins[K] extends StoreApiPlugin<infer S, infer G, infer A> ? Key extends 'create' ? S : Key extends 'extend' ? {
|
|
54
|
+
getters: G;
|
|
55
|
+
setters: A;
|
|
56
|
+
} : never : never;
|
|
57
|
+
};
|
|
58
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
59
|
+
export {};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zustand-lite",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Zustand Lite builds upon zustand, by auto-generating selectors and simplifying API even more.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git://github.com/PiotrSiatkowski/zustand-lite.git",
|
|
10
|
+
"web": "https://github.com/PiotrSiatkowski/zustand-lite"
|
|
11
|
+
},
|
|
12
|
+
"author": "Piotr Siatkowski <p.siatkowski@gmail.com>",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"zustand",
|
|
15
|
+
"state-management",
|
|
16
|
+
"react",
|
|
17
|
+
"store",
|
|
18
|
+
"plugin",
|
|
19
|
+
"typescript",
|
|
20
|
+
"no-boilerplate"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc"
|
|
24
|
+
},
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"zustand": "^5.0.5"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"typescript": "^5.5.3"
|
|
34
|
+
},
|
|
35
|
+
"private": false
|
|
36
|
+
}
|