zustand-lite 0.7.2 → 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/README.md CHANGED
@@ -1,6 +1,6 @@
1
- ![Zustand Lite Image](./image-small.png)
1
+ ![Zustand Lite Image](./image.png)
2
2
 
3
- # 🧠 Zustand Lite
3
+ # Zustand Lite
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/zustand-lite?color=blue)](https://www.npmjs.com/package/zustand-lite)
6
6
  [![bundle size](https://img.shields.io/bundlephobia/minzip/zustand-lite)](https://bundlephobia.com/package/zustand-lite)
@@ -8,431 +8,370 @@
8
8
  [![Types](https://img.shields.io/badge/TypeScript-ready-blue?logo=typescript)](https://www.typescriptlang.org/)
9
9
  [![GitHub stars](https://img.shields.io/github/stars/PiotrSiatkowski/zustand-lite?style=social)](https://github.com/PiotrSiatkowski/zustand-lite)
10
10
 
11
- Zustand Lite is a **zero-boilerplate** state management built specifically for frontend
12
- developers who want **powerful and scalable** global state **without the usual complexity**.
13
- Designed for simplicity, it gives you everything you need out-of-the-box — from selectors to
14
- setters to middleware while remaining lightweight and extensible. With seamless support for
15
- plugins, devtools, and state encapsulation, managing state becomes a breeze, not a chore.
11
+ A thin wrapper around [Zustand](https://github.com/pmndrs/zustand) that generates getters, setters, and hooks for you.
12
+
13
+ ```ts
14
+ import { createStore } from 'zustand-lite'
16
15
 
17
- _A zero-boilerplate wrapper around [Zustand](https://github.com/pmndrs/zustand), focused on
18
- ergonomics, plugins, and dynamic extension — inspired by [zustand-x](https://github.com/udecode/zustand-x) and getters/setters auto-generation patterns._
16
+ const store = createStore({ count: 0 })
17
+ .extendSetters(({ get, set }) => ({
18
+ increment: () => set.count(get().count + 1),
19
+ }))
20
+
21
+ store.use.count() // React hook
22
+ store.get().count // Direct access
23
+ store.set.increment() // Action
24
+ ```
19
25
 
20
- ## 🛠️ Why **zustand‑lite**?
26
+ That's it. No providers, no boilerplate, full TypeScript support.
21
27
 
22
- ### ✅ In short
28
+ ---
23
29
 
24
- _**Zustand Lite** delivers a **simple**, **performant**, and **predictable** way to manage UI
25
- state, letting your code stay focused on business logic, not infrastructure. Try it today and
26
- see how effortless frontend state can be!_
30
+ ## Why?
27
31
 
28
- _While tools like React‑Query handle server state, UI state often gets bogged down by excessive
29
- boilerplate, tangled data flows, and hard‑to‑control side effects. **Zustand Lite** cuts through
30
- the noise._
32
+ Zustand Lite is a **zero-boilerplate** state management built specifically for frontend
33
+ developers who want **powerful and scalable** global state **without the usual complexity**.
34
+ Designed for simplicity, it gives you everything you need out-of-the-box — from selectors to
35
+ setters to middleware — while remaining lightweight and extensible. With seamless support for
36
+ plugins, devtools, and state encapsulation, managing state becomes a breeze, not a chore.
31
37
 
32
- ### Why it matters
38
+ Zustand is great, but you still end up writing repetitive code: selectors for each field, actions that follow the same patterns, hooks that look almost identical.
33
39
 
34
- Boilerplate is the killer of productivity and obscures your real goal: **business logic**, which is usually far simpler than it appears.
35
- Thanks to **zustand‑lite**, you can move faster without sacrificing clarity or flexibility.
40
+ Zustand Lite fixes that. You define your state once, and it generates:
41
+ - `store.use.fieldName()` - React hooks with proper subscriptions
42
+ - `store.set.fieldName(value)` - Type-safe setters
43
+ - `store.get()` - Synchronous access to current state
36
44
 
37
- 1. **No context providers** or React-specific setup.
38
- 2. **No mocking** during tests
39
- 3. **No bloated dependency arrays**
40
- 4. **Type-safe, simple API** - simple usage with IDE support
45
+ Plus a chainable API for computed values, custom actions, and plugins.
41
46
 
42
- ### 🚀 Features
47
+ ## Install
43
48
 
44
- - ⚛️ **Minimal & Typed**: Built on top of lightweight Zustand core, fully typed with TypeScript.
45
- - 🔄 **Clean Separation**: State and operations are well separated to minimize confusion.
46
- - 🚀 **Blazing Performance**: Selective updates and lean subscriptions keep things snappy.
47
- - 🪄 **Zero Boilerplate**: Does not require writing any idle code.
48
- - 🧪 **Test Friendly**: Easy to test, no additional hacks or mocks required.
49
- - 🔌 **Shareable plugins**: Plug custom logic directly into your store for extended capabilities.
50
- - 🧩 **Optional middlewares**: Seamlessly add devtools and persist middleware layers.
51
- - 🌱 **Chainable API**: create the store in a few simple composable steps.
52
- - 👁 **Redux devtools labeling**: Built-in clear, traceable action labeling useful for debugging.
49
+ ```bash
50
+ npm install zustand-lite zustand
51
+ ```
53
52
 
54
53
  ---
55
54
 
56
- ## 🛠 Common Recipes
55
+ ## Examples
57
56
 
58
- ### Simple store
57
+ ### Basic usage
59
58
 
60
59
  ```ts
61
60
  import { createStore } from 'zustand-lite'
62
61
 
63
- export const store = createStore({ foo: '' })
62
+ export const store = createStore({ name: '', email: '' })
64
63
 
65
- // Subscribe for your data changes.
66
- function Component() {
67
- const foo = store.use.foo()
68
- }
69
-
70
- // Synchronous state accessor.
71
- function onClick() {
72
- console.log(store.get().foo)
64
+ // In your component
65
+ function Profile() {
66
+ const name = store.use.name()
67
+ const email = store.use.email()
68
+
69
+ return <div>{name} ({email})</div>
73
70
  }
74
71
 
75
- // Setting value with auto-generated setter.
76
- function onClick() {
77
- store.set.foo('new-value')
78
- }
72
+ // Update from anywhere
73
+ store.set.name('John')
74
+ store.set.email('john@example.com')
79
75
  ```
80
76
 
81
- ### Custom Setters
77
+ ### Custom setters
82
78
 
83
79
  ```ts
84
80
  const store = createStore({ count: 0 })
85
81
  .extendSetters(({ get, set }) => ({
86
- increment: () => set.count(get().count + 1)
87
- }))
88
-
89
- function Counter() {
90
- const count = store.use.count()
91
- return (
92
- <button onClick={store.set.increment}>
93
- Count: {count}
94
- </button>
95
- )
96
- }
82
+ increment: () => set.count(get().count + 1),
83
+ decrement: () => set.count(get().count - 1),
84
+ reset: () => set.count(0),
85
+ }))
86
+
87
+ // Use them directly
88
+ store.set.increment()
89
+ store.set.reset()
90
+
91
+ // Or in components
92
+ <button onClick={store.set.increment}>+</button>
97
93
  ```
98
94
 
99
- ### Advanced store
95
+ ### Computed values (getters)
100
96
 
101
97
  ```ts
102
- const initialState: {
103
- point: { x: number; y: number }
104
- rectangle: { a: number; b: number }
105
- } = {
106
- point: { x: 0, y: 0 },
107
- rectangle: { a: 20, b: 10 }
108
- }
109
-
110
- export const store = createStore(initialState)
98
+ const store = createStore({
99
+ items: [] as { price: number; qty: number }[]
100
+ })
111
101
  .extendGetters(({ get }) => ({
112
- area: () => get().rectangle.x * get().rectangle.y,
102
+ total: () => get().items.reduce((sum, item) => sum + item.price * item.qty, 0),
103
+ itemCount: () => get().items.length,
113
104
  }))
114
- .extendSetters(({ get, set }) => ({
115
- translateX: (dx: number) =>
116
- set.bar({ x: get().point.x + dx, y: get().point.y }),
117
- }))
118
- .restrictState(['rectangle'])
119
- // ^ Seal the store, so that certain fields are unavailable for
120
- // the outside context, while still being available for getters and setters.
121
-
122
- // Subscribe for computed data changes. This new selector is auto-generated.
123
- function Component() {
124
- const area = store.use.area()
125
- }
126
-
127
- // Make private value inaccessible.
128
- function onClick() {
129
- console.log(store.get().rectangle)
130
- // ^ TS error, no value. It is not accessible
131
- // anymore from outside the store.
132
- }
133
-
134
- // Call custom action.
135
- function onClick() {
136
- store.set.translateX(7)
137
- }
138
105
 
139
- // Access native Zustand api (expect getState, setState,
140
- // which are available thrugh store.get() and store.set()
141
- // for simplicity and additional expresivness).
142
- function Component() {
143
- const state = store.api.getInitialState()
106
+ // Computed values work as hooks too
107
+ function CartSummary() {
108
+ const total = store.use.total()
109
+ const count = store.use.itemCount()
110
+
111
+ return <div>{count} items, ${total}</div>
144
112
  }
145
113
  ```
146
114
 
147
- ### Deep value getters
115
+ ### Deep selectors
148
116
 
149
- ```ts
150
- const initialState: { my: { foo: { bar: string} } } = {
151
- my: { foo: { bar: 'value' } },
152
- }
117
+ Nested state? No problem. Zustand Lite auto-generates deep selectors:
153
118
 
154
- export const store = createStore(initialState)
155
- .myFooBar(({ get }) => ({
156
- // Entire state is accessible with store.get()
157
- return get().my.foo.bar;
158
- }))
159
- .restrictState()
119
+ ```ts
120
+ const store = createStore({
121
+ user: {
122
+ profile: {
123
+ name: 'John'
124
+ }
125
+ }
126
+ })
160
127
 
161
- // Component will update only if deeply nested value will update.
162
- function Component() {
163
- const myFooBar = store.use.myFooBar()
164
- }
128
+ // These are all valid and properly subscribed
129
+ store.use.user()
130
+ store.use.user.profile()
131
+ store.use.user.profile.name()
165
132
  ```
166
133
 
167
- ### Automatic deep selectors
134
+ ### Select multiple fields
168
135
 
169
136
  ```ts
170
- const initialState: { my: { foo: { bar: string } } } = {
171
- my: { foo: { bar: 'value' } },
172
- }
173
-
174
- export const store = createStore(initialState)
137
+ const store = createStore({ a: 1, b: 2, c: 3, d: 4 })
175
138
 
176
- // Component will update only if deeply nested value will update.
177
- // Those selectors will be generated only for required attributes.
178
139
  function Component() {
179
- const myFooBar = store.use.my.foo.bar()
140
+ // Only re-renders when a or c change
141
+ const { a, c } = store.use(['a', 'c'])
180
142
  }
181
143
  ```
182
144
 
183
- ### Ad-hoc selectors
145
+ ### Custom equality
184
146
 
185
147
  ```ts
186
- const initialState: { my: { foo: { bar: string } } } = {
187
- my: { foo: { bar: 'value' } },
188
- }
148
+ const store = createStore({ data: { id: 1, name: 'test', updatedAt: Date.now() } })
189
149
 
190
- export const store = createStore(initialState)
150
+ // Default uses shallow equality
151
+ const data = store.use.data()
191
152
 
192
- // If no auto-generated selector is available,
193
- // custom one may still be used.
194
- function Component() {
195
- const myFooBar = store.use((state) => state.my.foo, customEquality)
196
- }
153
+ // Custom equality for auto-generated selectors
154
+ const data = store.use.data((a, b) => a.id === b.id)
155
+
156
+ // Custom equality for ad-hoc selectors
157
+ const data = store.use(
158
+ (state) => state.data,
159
+ (a, b) => a.id === b.id
160
+ )
197
161
  ```
198
162
 
199
- ### Multi selectors
163
+ For getters with parameters, pass `{ eq }` as the last argument:
200
164
 
201
165
  ```ts
202
- const initialState = {
203
- a: 'a', b: 'b', c: 'c', d: 'd',
204
- }
205
-
206
- export const store = createStore(initialState)
166
+ const store = createStore({ items: [{ id: 1, name: 'Item', meta: {} }] })
167
+ .extendGetters(({ get }) => ({
168
+ getById: (id: number) => get().items.find(i => i.id === id),
169
+ }))
207
170
 
208
- // Listen to multiple properties of the store at the same time
209
- // for maximal brevity.
210
- function Component() {
211
- const { a, c } = store.use(['a', 'c'])
171
+ function Item({ id }: { id: number }) {
172
+ // Only re-render when id or name changes, ignore meta
173
+ const item = store.use.getById(id, {
174
+ eq: (a, b) => a?.id === b?.id && a?.name === b?.name
175
+ })
212
176
  }
213
177
  ```
214
178
 
215
- ### Setting whole state
216
-
217
- ```ts
218
- const initialState: { my: { foo: { bar: string } } } = {
219
- my: { foo: { bar: 'value' } },
220
- }
179
+ ### Extending state
221
180
 
222
- export const store = createStore(initialState)
181
+ Add more state fields after creation:
223
182
 
224
- // State can be set with first level auto-generated
225
- // setters or with store.set
226
- store.set((state) => ({ ...state, newField: 'newField' }))
227
- // By default state is shallowly merged.
228
- store.set({ newField: 'newField' })
229
- // Emptying the state with replace: true flag.
230
- store.set({}, true)
183
+ ```ts
184
+ const store = createStore({ a: 'a' })
185
+ .extendByState({ b: 'b' }) // Plain object
186
+ .extendByState(({ get }) => ({ c: get().a + get().b })) // Derived from existing state
231
187
  ```
232
188
 
233
189
  ### Overriding getters and setters
234
190
 
235
- ```ts
236
- const initialState: {
237
- point: { x: number; y: number }
238
- rectangle: { a: number; b: number }
239
- } = {
240
- point: { x: 0, y: 0 },
241
- rectangle: { a: 20, b: 10 }
242
- }
191
+ Chain multiple `extendGetters` or `extendSetters` to override previous definitions. The new definition can access the previous one via `get.previousGetter()`:
243
192
 
244
- export const store = createStore(initialState)
193
+ ```ts
194
+ const store = createStore({ price: 100 })
245
195
  .extendGetters(({ get }) => ({
246
- // get().point refers to the store value
247
- myPoint: () => transformToDifferentCoordinates(get().point),
196
+ displayPrice: () => get().price,
248
197
  }))
249
198
  .extendGetters(({ get }) => ({
250
- // get.myPoint() will refer to the already transformed point
251
- // from the previous getter. It will override the previous
252
- // one, but can still accesess anything defined before.
253
- myPoint: () => soSomethingWithTransformedPoint(get.myPoint()),
199
+ // Override: add currency formatting, but use previous getter
200
+ displayPrice: () => `$${get.displayPrice().toFixed(2)}`,
254
201
  }))
255
- .restrictState()
256
- ```
257
-
258
- ### Custom equality
259
-
260
- ```ts
261
- const initialState: { rectangle: { a: number; b: number } } = {
262
- rectangle: { a: 20, b: 10 },
263
- }
264
202
 
265
- export const store = createStore(initialState)
266
-
267
- // By default shallow equality is being used.
268
- function Component() {
269
- const rectangle = store.use.rectangle(customEqualityFn)
270
- }
203
+ store.get.displayPrice() // "$100.00"
271
204
  ```
272
205
 
273
- ### Extending state
206
+ ### Setting state
274
207
 
275
- ```ts
276
- const initialState: { rectangle: { a: number; b: number } } = {
277
- rectangle: { a: 20, b: 10 },
278
- }
208
+ Multiple ways to update state:
279
209
 
280
- export const store = createStore(initialState)
281
- .extendByState({ h: 30 })
282
- .extendGetters(({ get }) => ({
283
- volume() {
284
- return get().rectangle.a * get().rectange.b * get().h
285
- }
286
- }))
210
+ ```ts
211
+ const store = createStore({ a: 1, b: 2 })
287
212
 
288
- // By default shallow equality is being used.
289
- function Component() {
290
- store.set.h(50)
291
- const rectangle = store.use.volume()
292
- }
293
- ```
213
+ // Auto-generated setters
214
+ store.set.a(10)
294
215
 
295
- ### Testing features
216
+ // Partial update (shallow merge)
217
+ store.set({ a: 10 })
296
218
 
297
- ```ts
298
- function Component() {
299
- const dependencyA = store.use.dependencyA()
300
- }
219
+ // Function update
220
+ store.set((state) => ({ a: state.a + 1 }))
301
221
 
302
- // No need to mock the store or add additional providers, just
303
- // interact with it in the usual way. Wrapping setter with act
304
- // might be needed to sync react updates.
305
- test('Testing Component', () => ({
306
- render(<Component />)
307
- act(() => store.set.dependencyA(someValue))
308
- expect(storeDependantText).toBe(someValue)
309
- })
222
+ // Replace entire state (second arg = true)
223
+ store.set({ a: 100, b: 200 }, true)
310
224
  ```
311
225
 
312
- ---
313
-
314
- ## 🧠 API Overview
226
+ ### Private state
315
227
 
316
- ### `createStore(initialState, options)`
228
+ Sometimes you want internal state that components can't access directly:
317
229
 
318
- Creates a typed store with your state and optional middleware.
319
-
320
- **Options:**
230
+ ```ts
231
+ const store = createStore({
232
+ publicValue: 'visible',
233
+ _internalCache: new Map(),
234
+ })
235
+ .extendGetters(({ get }) => ({
236
+ getCached: (key: string) => get()._internalCache.get(key),
237
+ }))
238
+ .restrictState(['_internalCache'])
321
239
 
322
- | Key | Type | Description |
323
- | ------------- | -------------------------------------------------------------------------- | ------------------------------------ |
324
- | `name` | `string` | Name shown in Redux DevTools |
325
- | `middlewares` | `{ devtools?: true or DevtoolsOptions, persist?: true or PersistOptions }` | Middleware configuration |
326
-
327
- ### Chainable Methods
328
-
329
- - **`.extendByState(fn | object)`**
330
- Add additional state that can be reused later.
331
- - **`.extendGetters(fn)`**
332
- Add additional derived getters based on current state.
333
- - **`.extendSetters(fn)`**
334
- Add additional typed setters.
335
- - **`.composePlugin(plugin)`**
336
- Composes functionality of existing plugin ito your own store.
337
- - **`.restrictState(keys?: string[])`**
338
- Hide selected fields from the public API, returning a minimal store (removes config methods as well).
339
-
340
- ### Store Interface
341
-
342
- After creation, your store includes:
343
-
344
- | Property | Purpose |
345
- | --------------------- | --------------------------------------------------------------- |
346
- | `store.use.foo()` | React hook for subscribing to `foo` |
347
- | `store.use(selector)` | React hook for subscribing to custom selector result |
348
- | `store.get()` | Direct synchronous access to whole state |
349
- | `store.set.foo(v)` | Set a new value for `foo` |
350
- | `store.set(state)` | Set an entire new state |
351
- | `store.api` | The native Zustand store API (getInitialState, subscribe, etc.) |
240
+ // Works
241
+ store.get().publicValue
242
+ store.get.getCached('key')
352
243
 
353
- ---
244
+ // TypeScript error - _internalCache is hidden
245
+ store.get()._internalCache
246
+ ```
354
247
 
355
- ## 🧩 Plugin System
248
+ ### Plugins
356
249
 
357
- You can define plugins that inject additional state or behavior:
250
+ Extract reusable patterns into plugins:
358
251
 
359
252
  ```ts
360
253
  import { definePlugin } from 'zustand-lite'
361
254
 
362
- export const withMyPlugin = definePlugin((store) =>
363
- // If plugin defines data, that and only that data is available inside
364
- // setters and getters.
365
- store
366
- .extendByState({ side: 1 })
367
- .extendGetters(({ get }) => ({
368
- // Every piece od data, getter or setter will be available in the custom
369
- // extendGetter and extendSetter, allowing for even more interactions.
370
- area() {
371
- return get().side * get().side
372
- },
373
- }))
374
- .extendSetters(({ set }) => ({
375
- area(area: number) {
376
- return set.side(Math.sqrt(area))
377
- },
378
- }))
255
+ // A loading state plugin
256
+ const withLoading = definePlugin((store) =>
257
+ store
258
+ .extendByState({ isLoading: false, error: null as string | null })
259
+ .extendSetters(({ set }) => ({
260
+ startLoading: () => { set.isLoading(true); set.error(null) },
261
+ stopLoading: () => set.isLoading(false),
262
+ setError: (error: string) => { set.error(error); set.isLoading(false) },
263
+ }))
379
264
  )
380
- ```
381
-
382
- Apply newly created plugin like this:
383
265
 
384
- ```ts
385
- const store = createStore({}).composePlugin(withMyPlugin)
266
+ // Use it
267
+ const store = createStore({ data: null })
268
+ .composePlugin(withLoading)
269
+ .extendSetters(({ set }) => ({
270
+ async fetchData() {
271
+ set.startLoading()
272
+ try {
273
+ const data = await api.getData()
274
+ set.data(data)
275
+ } catch (e) {
276
+ set.setError(e.message)
277
+ } finally {
278
+ set.stopLoading()
279
+ }
280
+ },
281
+ }))
386
282
  ```
387
283
 
388
- **Any plugin state, getters and setters will be available for usage inside your own store.**
389
-
390
- ## 🧪 Middlewares Integration
391
-
392
- You can enable the most useful middlewares:
284
+ ### Middleware (devtools & persist)
393
285
 
394
286
  ```ts
395
- {
396
- name: 'MyApp/CounterStore',
397
- middlewares: {
398
- devtools: true,
399
- persist: {
400
- ...options,
287
+ const store = createStore(
288
+ { count: 0 },
289
+ {
290
+ name: 'CounterStore',
291
+ middlewares: {
292
+ devtools: true, // Redux DevTools integration
293
+ persist: true, // localStorage persistence
401
294
  },
402
295
  }
403
- }
296
+ )
404
297
  ```
405
298
 
299
+ Actions show up in DevTools with clear labels like `CounterStore/count` or `CounterStore/myOwnAction`.
300
+
406
301
  ---
407
302
 
408
- ## 🛠 Planned improvements
303
+ ## API Reference
409
304
 
410
- - Configurable level of auto-generation. While I advise to keep store as flat as possible, good
411
- structured data is important. For deeper properties it might be more convenient to auto
412
- generate getters and setters for deeply nested properties as well. **(partially done with hooks, entire
413
- state is selected for get from version 3.0.0, setters still generated for level one only)**
414
- - Ability to specify equality function for extended getters. It's possible now, but requires to
415
- import hook from 'zustand' package, which is suboptimal **(available from version 3.0.0 with
416
- use() function or deep auto-generated selectors. Still no possible for custom getters)**.
417
- - Implement subscribe with selector middleware
305
+ ### `createStore(initialState, options?)`
418
306
 
419
- ## 🧱 Built With
307
+ Creates a store with auto-generated hooks and setters.
420
308
 
421
- - [Zustand](https://github.com/pmndrs/zustand)
422
- - Inspired by [zustand-x](https://github.com/udecode/zustand-x)
309
+ **Options:**
310
+ | Key | Type | Description |
311
+ |-----|------|-------------|
312
+ | `name` | `string` | Name for DevTools |
313
+ | `middlewares` | `{ devtools?, persist? }` | Enable middleware |
314
+
315
+ ### Chainable methods
316
+
317
+ | Method | Description |
318
+ |--------|-------------|
319
+ | `.extendByState(obj \| fn)` | Add more state fields |
320
+ | `.extendGetters(fn)` | Add computed values |
321
+ | `.extendSetters(fn)` | Add custom actions |
322
+ | `.composePlugin(plugin)` | Apply a plugin |
323
+ | `.restrictState(keys?)` | Hide fields from public API |
324
+
325
+ ### Store interface
326
+
327
+ | Property | Description |
328
+ |----------|-------------|
329
+ | `store.use.field()` | React hook for `field` |
330
+ | `store.use(selector, eq?)` | Hook with custom selector |
331
+ | `store.use(['a', 'b'])` | Hook for multiple fields |
332
+ | `store.get()` | Current state (no subscription) |
333
+ | `store.get.getter()` | Call a computed getter |
334
+ | `store.set.field(value)` | Update a field |
335
+ | `store.set(partial)` | Merge partial state |
336
+ | `store.set(fn)` | Update with function |
337
+ | `store.api` | Raw Zustand API |
423
338
 
424
- ## 📘 License
339
+ ---
425
340
 
426
- MIT — free to use, extend, and improve.
341
+ ## Testing
427
342
 
343
+ No mocks needed. Just use the store directly:
428
344
 
429
- ## 🤝 Contributing
345
+ ```ts
346
+ import { store } from './store'
430
347
 
431
- Pull requests, feedback, and ideas are welcome!
432
- If you'd like to publish your own plugins, we recommend namespacing them under:
348
+ test('increment works', () => {
349
+ store.set.count(0)
350
+ store.set.increment()
351
+ expect(store.get().count).toBe(1)
352
+ })
433
353
 
354
+ test('component updates', () => {
355
+ render(<Counter />)
356
+ act(() => store.set.count(5))
357
+ expect(screen.getByText('5')).toBeInTheDocument()
358
+ })
434
359
  ```
435
- zustand-lite/plugin-*
436
- ```
437
360
 
438
- or adding them to the main repository under the plugins directory.
361
+ ---
362
+
363
+ ## Roadmap
364
+
365
+ - [x] Custom equality for parameterized getters
366
+ - [ ] Auto-generate deep setters (currently only first level)
367
+ - [ ] Subscribe with selector middleware
368
+
369
+ ---
370
+
371
+ ## Credits
372
+
373
+ Built on [Zustand](https://github.com/pmndrs/zustand). Inspired by [zustand-x](https://github.com/udecode/zustand-x).
374
+
375
+ ## License
376
+
377
+ MIT
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var $=Object.create;var p=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,V=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var r in t)p(e,r,{get:t[r],enumerable:!0})},A=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of J(t))!V.call(e,o)&&o!==r&&p(e,o,{get:()=>t[o],enumerable:!(n=k(t,o))||n.enumerable});return e};var H=(e,t,r)=>(r=e!=null?$(T(e)):{},A(t||!e||!e.__esModule?p(r,"default",{value:e,enumerable:!0}):r,e)),Q=e=>A(p({},"__esModule",{value:!0}),e);var Z={};v(Z,{createStore:()=>_,definePlugin:()=>F,setGlobalConfig:()=>z,withReset:()=>q});module.exports=Q(Z);function F(e){return e}var y=require("zustand/middleware"),C=require("zustand/vanilla");var h=require("zustand/shallow");var L=require("zustand/shallow");var B=H(require("error-stack-parser"),1);function u(){let e=B.default.parse(new Error),t=e.findIndex(r=>r.functionName?.includes("_zustandLiteInferName_"));return t-1>=0?e[t-1].functionName:null}function d(e,t){return(r,n,o)=>{let i=e.getState(),s=typeof r=="function"?r(i):r;(0,L.shallow)(i,s)||e.setState(s,n,t?{type:u()??o??"setState",payload:s}:void 0)}}function c(e,t,r){let n=d(e,r);return t.forEach(o=>{n[o]=i=>{(0,h.shallow)(e.getState()[o],i)||e.setState(s=>({...s,[o]:i}),!1,r?{type:u()??o,payload:{[o]:i}}:void 0)}}),n}var b=e=>e,g=(e,t)=>t.reduce((r,n)=>(n in e&&(r[n]=e[n]),r),{});var O=require("zustand/shallow"),w=require("zustand/traditional");function G(e,t,r,n){typeof e=="object"&&e!==null&&Object.keys(e).forEach(o=>{let i=[...r,o];Object.defineProperty(t,o,{value:(s=O.shallow)=>(0,w.useStoreWithEqualityFn)(n,a=>X(a,i),s),writable:!0,configurable:!0,enumerable:!0}),G(e[o],t[o],i,n)})}function X(e,t){let r=e;for(let n of t)if(r=r[n],!r)return r;return r}var R=require("zustand/shallow"),j=require("zustand/traditional");function m(e){return(t=b,r=R.shallow)=>(0,j.useStoreWithEqualityFn)(e,Array.isArray(t)?n=>g(n,t):t??b,r)}function l(e,t){let r=m(e);return G(g(e.getState(),t),r,[],e),r}function N(e,t,r,n){let o=typeof e=="function"?e(t):e;return r.setState(o),t.use={...t.use,...l(r,Object.keys(o))},t.set={...t.set,...c(r,Object.keys(o),n)},t}var E=require("zustand/shallow"),P=require("zustand/traditional");function x(e){return()=>e.getState()}function U(e,t,r){let n=e({get:t.get}),o={};return Object.keys(n).forEach(i=>{o[i]=(...s)=>(0,P.useStoreWithEqualityFn)(r,()=>n[i](...s),E.shallow)}),t.use=Object.assign(m(r),t.use,o),t.get=Object.assign(x(r),t.get,n),t}function W(e,t,r,n){let o=d(r,n),i=Object.entries(e(t)).reduce((s,[a,S])=>(s[a]=function(...K){return S(...K)},s),{});return t.set=Object.assign(o,t.set,i),t}function D(e,t){return{getInitialState:e.getInitialState,getState:e.getState,persist:Y(e,t),setState:e.setState,subscribe:e.subscribe}}function Y(e,t){if("persist"in e){let r=e.persist;return r.read=()=>{try{return JSON.parse(localStorage?.getItem(t)??"")?.state}catch{return}},r}}function I(e){return x(e)}function M(e,t,r,n){return{api:r.api,set:r.set,use:e?(()=>{let o=Object.keys(r.use).reduce((i,s)=>t[s]&&e.includes(s)?i:{...i,[s]:r.use[s]},{});return Object.assign(m(n),o)})():r.use,get:e?Object.assign(()=>Object.entries(r.get()).reduce((i,[s,a])=>t[s]&&e.includes(s)?i:{...i,[s]:a},{}),r.get):r.get}}var f={appName:"zustand-lite",logging:!1};function z(e){f={...f,...e}}function _(e,t){let{name:r="zustand-lite",middlewares:n={}}=t??{},o=()=>e,i=`${f.appName.replace(/\s/,"-")}.${r}}`,s=f.logging||!!n.devtools;s&&(o=(0,y.devtools)(o,{name:f.appName,store:r,...typeof n.devtools=="object"?n.devtools:{}})),n.persist&&(o=(0,y.persist)(o,{name:i,...typeof n.persist=="object"?n.persist:{}}));let a=(0,C.createStore)(o);return{api:D(a,i),get:I(a),use:l(a,Object.keys(e)),set:c(a,Object.keys(e),s),composePlugin(S){return S(this)},extendGetters(S){return U(S,this,a)},extendSetters(S){return W(S,this,a,s)},extendByState(S){return N(S,this,a,s)},restrictState(S=[]){return M(S,e,this,a)}}}var q=e=>e.extendSetters(({api:t,set:r})=>({reset:()=>{r(t.getInitialState?.()??{},!0)}}));0&&(module.exports={createStore,definePlugin,setGlobalConfig,withReset});
1
+ "use strict";var $=Object.create;var p=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var H=(e,r)=>{for(var t in r)p(e,t,{get:r[t],enumerable:!0})},F=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of T(r))!k.call(e,n)&&n!==t&&p(e,n,{get:()=>r[n],enumerable:!(o=J(r,n))||o.enumerable});return e};var Q=(e,r,t)=>(t=e!=null?$(V(e)):{},F(r||!e||!e.__esModule?p(t,"default",{value:e,enumerable:!0}):t,e)),X=e=>F(p({},"__esModule",{value:!0}),e);var ee={};H(ee,{createStore:()=>z,definePlugin:()=>B,setGlobalConfig:()=>C,withReset:()=>_});module.exports=X(ee);function B(e){return e}var y=require("zustand/middleware"),q=require("zustand/vanilla");var O=require("zustand/shallow");var h=require("zustand/shallow");var L=Q(require("error-stack-parser"),1);function u(){let e=L.default.parse(new Error),r=e.findIndex(t=>t.functionName?.includes("_zustandLiteInferName_"));return r-1>=0?e[r-1].functionName:null}function c(e,r){return(t,o,n)=>{let i=e.getState(),s=typeof t=="function"?t(i):t;(0,h.shallow)(i,s)||e.setState(s,o,r?{type:u()??n??"setState",payload:s}:void 0)}}function d(e,r,t){let o=c(e,t);return r.forEach(n=>{o[n]=i=>{(0,O.shallow)(e.getState()[n],i)||e.setState(s=>({...s,[n]:i}),!1,t?{type:u()??n,payload:{[n]:i}}:void 0)}}),o}var b=e=>e,g=(e,r)=>r.reduce((t,o)=>(o in e&&(t[o]=e[o]),t),{});var R=require("zustand/shallow"),w=require("zustand/traditional");function G(e,r,t,o){typeof e=="object"&&e!==null&&Object.keys(e).forEach(n=>{let i=[...t,n];Object.defineProperty(r,n,{value:(s=R.shallow)=>(0,w.useStoreWithEqualityFn)(o,a=>Y(a,i),s),writable:!0,configurable:!0,enumerable:!0}),G(e[n],r[n],i,o)})}function Y(e,r){let t=e;for(let o of r)if(t=t[o],!t)return t;return t}var j=require("zustand/shallow"),N=require("zustand/traditional");function m(e){return(r=b,t=j.shallow)=>(0,N.useStoreWithEqualityFn)(e,Array.isArray(r)?o=>g(o,r):r??b,t)}function l(e,r){let t=m(e);return G(g(e.getState(),r),t,[],e),t}function U(e,r,t,o){let n=typeof e=="function"?e(r):e;return t.setState({...n,...t.getState()}),r.use={...r.use,...l(t,Object.keys(n))},r.set={...r.set,...d(t,Object.keys(n),o)},r}var E=require("zustand/shallow"),A=require("zustand/traditional");function x(e){return()=>e.getState()}function Z(e){return typeof e=="object"&&e!==null&&"eq"in e&&typeof e.eq=="function"}function P(e,r,t){let o=e({get:r.get}),n={};return Object.keys(o).forEach(i=>{n[i]=(...s)=>{let a=s[s.length-1];if(Z(a)){let S=s.slice(0,-1);return(0,A.useStoreWithEqualityFn)(t,()=>o[i](...S),a.eq)}return(0,A.useStoreWithEqualityFn)(t,()=>o[i](...s),E.shallow)}}),r.use=Object.assign(m(t),r.use,n),r.get=Object.assign(x(t),r.get,o),r}function W(e,r,t,o){let n=c(t,o),i=Object.entries(e(r)).reduce((s,[a,S])=>(s[a]=function(...K){return S(...K)},s),{});return r.set=Object.assign(n,r.set,i),r}function D(e,r){return{getInitialState:e.getInitialState,getState:e.getState,persist:v(e,r),setState:e.setState,subscribe:e.subscribe}}function v(e,r){if("persist"in e){let t=e.persist;return t.read=()=>{try{return JSON.parse(localStorage?.getItem(r)??"")?.state}catch{return}},t}}function I(e){return x(e)}function M(e,r,t,o){return{api:t.api,set:t.set,use:e?(()=>{let n=Object.keys(t.use).reduce((i,s)=>r[s]&&e.includes(s)?i:{...i,[s]:t.use[s]},{});return Object.assign(m(o),n)})():t.use,get:e?Object.assign(()=>Object.entries(t.get()).reduce((i,[s,a])=>r[s]&&e.includes(s)?i:{...i,[s]:a},{}),t.get):t.get}}var f={appName:"zustand-lite",logging:!1};function C(e){f={...f,...e}}function z(e,r){let{name:t="zustand-lite",middlewares:o={}}=r??{},n=()=>e,i=`${f.appName.replace(/\s/,"-")}.${t}}`,s=f.logging||!!o.devtools;s&&(n=(0,y.devtools)(n,{name:f.appName,store:t,...typeof o.devtools=="object"?o.devtools:{}})),o.persist&&(n=(0,y.persist)(n,{name:i,...typeof o.persist=="object"?o.persist:{}}));let a=(0,q.createStore)(n);return{api:D(a,i),get:I(a),use:l(a,Object.keys(e)),set:d(a,Object.keys(e),s),composePlugin(S){return S(this)},extendGetters(S){return P(S,this,a)},extendSetters(S){return W(S,this,a,s)},extendByState(S){return U(S,this,a,s)},restrictState(S=[]){return M(S,e,this,a)}}}var _=e=>e.extendSetters(({api:r,set:t})=>({reset:()=>{t(r.getInitialState?.()??{},!0)}}));0&&(module.exports={createStore,definePlugin,setGlobalConfig,withReset});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/definePlugin.ts","../src/lib/createStore.ts","../src/lib/generateSetFn.ts","../src/lib/generateSetFnBase.ts","../src/lib/generateSetterName.ts","../src/utils/utils.ts","../src/lib/generateUseFnStep.ts","../src/lib/generateUseFnBase.ts","../src/lib/generateUseFn.ts","../src/lib/extendByState.ts","../src/lib/extendGetters.ts","../src/lib/generateGetFnBase.ts","../src/lib/extendSetters.ts","../src/lib/generateApiFn.ts","../src/lib/generateGetFn.ts","../src/lib/restrictState.ts","../src/plugins/reset.ts"],"sourcesContent":["export { definePlugin } from './lib/definePlugin'\nexport { createStore, setGlobalConfig } from './lib/createStore'\nexport { withReset } from './plugins/reset'\n","import { State, StoreApi } from '../types'\n\n/**\n * Identity helper that provides a typed `store` param and preserves the plugin's return type.\n */\nexport function definePlugin<F extends (store: StoreApi) => StoreApi>(fn: F) {\n\treturn fn as unknown as <S extends State, G, A, MW>(\n\t\tstore: StoreApi<S, G, A, MW>\n\t) => ReturnType<F>\n}\n","/**\n * Entire no-boilerplate functionality inspired by this recipe:\n * https://docs.pmnd.rs/zustand/guides/auto-generating-selectors.\n * It has few utilities described here: https://www.npmjs.com/package/zustand-lite\n * for:\n * 1) Generating getters for flat state (1-level deep selectors).\n * 2) Generating setters for flat state (1-level deep setters).\n * 3) Automatic devtools messaging.\n * 4) Annotating functions with proper TS types to avoid some bloating and TS frenzy.\n * 5) Extending getters and setters\n * 6) Extending state and restricting state\n * 7) Reuse plugins\n *\n * Idea is to support small store without complicated data reducing (it can be done as well,\n * but may indicate something is not right with the use case itself).\n **/\nimport { devtools, persist } from 'zustand/middleware'\nimport { createStore as createVanillaStore } from 'zustand/vanilla'\n\nimport {\n\tGetRecord,\n\tGlobalConfig,\n\tMWConfiguration,\n\tSetRecord,\n\tState,\n\tStoreApi,\n\tStorePersist,\n} from '../types'\n\nimport { extendByState } from './extendByState'\nimport { extendGetters } from './extendGetters'\nimport { extendSetters } from './extendSetters'\nimport { generateApiFn } from './generateApiFn'\nimport { generateGetFn } from './generateGetFn'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\nimport { restrictState } from './restrictState'\n\nlet config: GlobalConfig = { appName: 'zustand-lite', logging: false }\n\nexport function setGlobalConfig(newConfig: Partial<GlobalConfig>) {\n\tconfig = { ...config, ...newConfig }\n}\n\nexport function createStore<S extends State, ExtraMW extends MWConfiguration = {}>(\n\tinitialState: S,\n\toptions?: { name?: string; middlewares?: ExtraMW }\n): StoreApi<\n\tS,\n\tGetRecord<S>,\n\tSetRecord<S>,\n\tExtraMW extends { persist: any } ? StorePersist<S> : {}\n> {\n\tconst { name = 'zustand-lite', middlewares = {} as ExtraMW } = options ?? {}\n\n\t// Apply supported middlewares.\n\tlet initializer: any = () => initialState\n\n\tconst persistId = `${config.appName.replace(/\\s/, '-')}.${name}}`\n\tconst shouldLog = config.logging || !!middlewares.devtools\n\n\tif (shouldLog) {\n\t\tinitializer = devtools(initializer, {\n\t\t\tname: config.appName,\n\t\t\tstore: name,\n\t\t\t...(typeof middlewares.devtools === 'object' ? middlewares.devtools : {}),\n\t\t})\n\t}\n\n\tif (middlewares.persist) {\n\t\tinitializer = persist(initializer, {\n\t\t\tname: persistId,\n\t\t\t...(typeof middlewares.persist === 'object' ? middlewares.persist : {}),\n\t\t})\n\t}\n\n\t// Create a vanilla zustand store to wrap.\n\tconst storeLib: any = createVanillaStore(initializer)\n\n\t// Create zustand-lite wrapper.\n\treturn {\n\t\tapi: generateApiFn(storeLib, persistId),\n\t\tget: generateGetFn(storeLib),\n\t\tuse: generateUseFn(storeLib, Object.keys(initialState)),\n\t\tset: generateSetFn(storeLib, Object.keys(initialState), shouldLog),\n\t\tcomposePlugin(plugin) {\n\t\t\treturn plugin(this)\n\t\t},\n\t\textendGetters(builder) {\n\t\t\treturn extendGetters(builder, this, storeLib)\n\t\t},\n\t\textendSetters(builder) {\n\t\t\treturn extendSetters(builder, this, storeLib, shouldLog)\n\t\t},\n\t\textendByState(builder) {\n\t\t\treturn extendByState(builder, this, storeLib, shouldLog)\n\t\t},\n\t\trestrictState(publicState = []) {\n\t\t\treturn restrictState(publicState, initialState, this, storeLib)\n\t\t},\n\t} as any\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { SetRecord, State } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setters like store.set.foo(value)\n *\n * @param lib Zustand api interface\n * @param key Keys to generate setters for\n * @param log If devtools were activated for this store\n */\nexport function generateSetFn<S extends State>(lib: StoreLib<S>, key: string[], log: boolean) {\n\tconst setters: any = generateSetFnBase(lib, log)\n\n\tkey.forEach((key) => {\n\t\tsetters[key] = (value: any) => {\n\t\t\tif (shallow(lib.getState()[key], value)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlib.setState(\n\t\t\t\t(state) => ({ ...state, [key]: value }),\n\t\t\t\tfalse,\n\t\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\t\tlog ? { type: generateSetterName() ?? key, payload: { [key]: value } } : undefined\n\t\t\t)\n\t\t}\n\t})\n\n\treturn setters as SetRecord<S>\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setState function for store like store.set({ value })\n *\n * @param lib Zustand api interface\n * @param log If devtools were activated for this store\n */\nexport function generateSetFnBase<S extends State>(lib: StoreLib<S>, log: boolean) {\n\treturn (updater: S | ((state: S) => S), replace?: boolean, name?: string) => {\n\t\tconst current = lib.getState()\n\t\tconst payload = typeof updater === 'function' ? updater(current) : updater\n\n\t\tif (shallow(current, payload)) {\n\t\t\treturn\n\t\t}\n\n\t\tlib.setState(\n\t\t\tpayload,\n\t\t\treplace,\n\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\tlog ? { type: generateSetterName() ?? name ?? 'setState', payload } : undefined\n\t\t)\n\t}\n}\n","import ErrorStackParser from 'error-stack-parser'\n\n/**\n * Hacky, but working (and possibly only one there is) method of fetching proper caller\n * name of the extended function.\n */\nexport function generateSetterName() {\n\t// Proper setter name should hide at 2nd position in the normalized stack.\n\tconst stack = ErrorStackParser.parse(new Error())\n\tconst index = stack.findIndex((entry) => entry.functionName?.includes('_zustandLiteInferName_'))\n\treturn index - 1 >= 0 ? stack[index - 1].functionName : null\n}\n","export const identity = (arg: any) => arg\nexport const pick = (obj: Record<string, any>, keys: string[]) =>\n\tkeys.reduce<Record<string, any>>((acc, k) => (k in obj ? ((acc[k] = obj[k]), acc) : acc), {})\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\n/**\n * Generates automatic getters like store.use.foo() (recursive steps for each level).\n * Getters are created as side effects.\n *\n * @param state State at nth level\n * @param getters Getters at nth level\n * @param path Property access path at nth level like ['foo', 'bar']\n * @param lib Zustand api interface\n */\nexport function generateUseFnStep(state: any, getters: any, path: string[], lib: any) {\n\tif (typeof state === 'object' && state !== null) {\n\t\tObject.keys(state).forEach((key) => {\n\t\t\tconst newPath = [...path, key]\n\t\t\tObject.defineProperty(getters, key, {\n\t\t\t\tvalue: (equalityFn = shallow) => {\n\t\t\t\t\treturn useStoreWithEqualityFn(\n\t\t\t\t\t\tlib,\n\t\t\t\t\t\t(state) => getFromPath(state, newPath),\n\t\t\t\t\t\tequalityFn\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t})\n\n\t\t\tgenerateUseFnStep(state[key], getters[key], newPath, lib)\n\t\t})\n\t}\n}\n\nfunction getFromPath(state: any, path: string[]) {\n\tlet data = state\n\n\tfor (const key of path) {\n\t\tdata = data[key]\n\t\tif (!data) {\n\t\t\treturn data\n\t\t}\n\t}\n\n\treturn data\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\nimport { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { identity, pick } from '../utils/utils'\n\n/**\n * Generates automatic getters like store.use.foo()\n *\n * @param lib Zustand api interface\n */\nexport function generateUseFnBase<S extends State, U>(lib: StoreLib<S>) {\n\treturn (selector = identity, equality = shallow) => {\n\t\treturn useStoreWithEqualityFn(\n\t\t\tlib,\n\t\t\tArray.isArray(selector) ? (s) => pick(s, selector) : (selector ?? identity),\n\t\t\tequality\n\t\t)\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { pick } from '../utils/utils'\nimport { generateUseFnStep } from './generateUseFnStep'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Generates automatic store hook subscribe function store.use()\n *\n * @param lib Zustand api interface\n * @param key State keys to use\n */\nexport function generateUseFn<S extends State>(lib: StoreLib<S>, key: string[]) {\n\tconst getters = generateUseFnBase(lib)\n\tgenerateUseFnStep(pick(lib.getState(), key), getters, [], lib)\n\treturn getters\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { ByStateBuilder, State, StoreApi } from '../types'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\n\n/**\n * Extends the store by adding new state fields, either by:\n * - passing an object patch: `{ b: 'x' }`\n * - or using a builder: `({ get }) => ({ c: get().b + 'y' })`\n *\n * @param builder Object patch or function producing new state fields.\n * @param api The extended store API before widening.\n * @param lib The underlying Zustand vanilla store.\n * @param log Enables logging for generated setters.\n *\n * @returns The same API instance, but with widened state (via overloads).\n */\nexport function extendByState<\n\tNewData extends State,\n\tOldData extends State,\n\tGetters,\n\tSetters,\n\tBuilder extends ByStateBuilder<NewData, OldData, Getters>,\n>(\n\tbuilder: Builder | NewData,\n\tapi: StoreApi<OldData, Getters, Setters>,\n\tlib: StoreLib<OldData>,\n\tlog: boolean\n) {\n\t// Calculate new state to be added to the store.\n\tconst newState: NewData = typeof builder === 'function' ? builder(api) : builder\n\n\t// Merge the new keys into the zustand state.\n\tlib.setState(newState as unknown as OldData)\n\n\t// Generate basic getters and setters from the newly added record.\n\tapi.use = { ...api.use, ...generateUseFn(lib, Object.keys(newState)) }\n\tapi.set = { ...api.set, ...generateSetFn(lib, Object.keys(newState), log) }\n\n\t// Return the same object, but with widened state type (handled by overloads).\n\treturn api\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GettersBuilder, State, StoreApi } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Adds derived getters to the store.\n *\n * @param builder Function returning new getter methods.\n * @param api Current store API to extend.\n * @param lib Underlying Zustand store.\n */\nexport function extendGetters<\n\tBuilder extends GettersBuilder<S, Getters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\tconst methods: any = builder({ get: api.get })\n\tconst getters: any = {}\n\n\tObject.keys(methods).forEach((key) => {\n\t\tgetters[key] = (...args: any[]) =>\n\t\t\tuseStoreWithEqualityFn(lib, () => methods[key](...args), shallow)\n\t})\n\n\tapi.use = Object.assign(generateUseFnBase(lib), api.use, getters)\n\tapi.get = Object.assign(generateGetFnBase(lib), api.get, methods)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Generates getState function for store.get()\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFnBase<S extends State>(lib: StoreLib<S>) {\n\treturn () => lib.getState()\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { SettersBuilder, State, StoreApi } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\n\n/**\n * Adds custom setter methods to the store.\n *\n * @param builder Function returning new setter methods.\n * @param api Store API to extend.\n * @param lib Underlying Zustand store.\n * @param log Enables optional debug logging.\n */\nexport function extendSetters<\n\tBuilder extends SettersBuilder<S, Getters, Setters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>, log: boolean) {\n\tconst setters = generateSetFnBase(lib, log)\n\tconst baseSet = Object.entries(builder(api)).reduce(\n\t\t(acc, [name, func]) => {\n\t\t\tacc[name] = function _zustandLiteInferName_(...args: any[]) {\n\t\t\t\treturn func(...args)\n\t\t\t}\n\n\t\t\treturn acc\n\t\t},\n\t\t{} as Record<string, any>\n\t)\n\n\tapi.set = Object.assign(setters, api.set, baseSet)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Required to wrap original Zustand interface without getState and setState, which are handled\n * by get and set (we should allow only one way of doing certain things).\n *\n * @param lib Zustand api interface\n * @param key Zustand persist local storage key\n */\nexport function generateApiFn<S extends State>(lib: StoreLib<S>, key: string) {\n\treturn {\n\t\tgetInitialState: lib.getInitialState,\n\t\tgetState: lib.getState,\n\t\tpersist: augmentPersist(lib, key),\n\t\tsetState: lib.setState,\n\t\tsubscribe: lib.subscribe,\n\t}\n}\n\nfunction augmentPersist<S extends State>(lib: StoreLib<S>, key: string) {\n\tif ('persist' in lib) {\n\t\tconst augmented: any = lib.persist\n\t\taugmented.read = () => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(localStorage?.getItem(key) ?? '')?.state\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\n\t\treturn augmented\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\n\n/**\n * Generates getters for store.get. In the past getters were generated as functions, but I\n * came to the conclusion that it's better and simpler to return the whole state.\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFn<S extends State>(lib: StoreLib<S>) {\n\treturn generateGetFnBase(lib)\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GetRecord, SetRecord, State, StoreApi, UseRecord } from '../types'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Function that restrict access to the store and store api.\n *\n * @param privateState Property names to be made private like ['foo', 'bar']\n * @param mergedState Final state of the store\n * @param api Returned store API\n * @param lib Zustand api interface\n */\nexport function restrictState<\n\tS extends State,\n\tKey extends keyof S,\n\tGetters extends GetRecord<any>,\n\tSetters extends SetRecord<any>,\n>(privateState: Key[], mergedState: S, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\treturn {\n\t\tapi: api.api,\n\t\tset: api.set,\n\t\tuse: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getters = Object.keys(api.use).reduce(\n\t\t\t\t\t\t(acc, key) =>\n\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t: { ...acc, [key]: (api.use as UseRecord<any>)[key] },\n\t\t\t\t\t\t{}\n\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(generateUseFnBase(lib), getters)\n\t\t\t\t})()\n\t\t\t: api.use,\n\t\tget: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getFn = () =>\n\t\t\t\t\t\tObject.entries(api.get()).reduce(\n\t\t\t\t\t\t\t(acc, [key, val]) =>\n\t\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t\t: { ...acc, [key]: val },\n\t\t\t\t\t\t\t{}\n\t\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(getFn, api.get)\n\t\t\t\t})()\n\t\t\t: api.get,\n\t}\n}\n","import { definePlugin } from '../lib/definePlugin'\n\n/**\n * Basic plugin example, that extends store with custom setter.\n */\nexport const withReset = definePlugin((store) =>\n\tstore.extendSetters(({ api, set }) => ({\n\t\treset: () => {\n\t\t\tset(api.getInitialState?.() ?? {}, true)\n\t\t},\n\t}))\n)\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,iBAAAC,EAAA,oBAAAC,EAAA,cAAAC,IAAA,eAAAC,EAAAN,GCKO,SAASO,EAAsDC,EAAO,CAC5E,OAAOA,CAGR,CCOA,IAAAC,EAAkC,8BAClCC,EAAkD,2BCjBlD,IAAAC,EAAwB,2BCAxB,IAAAC,EAAwB,2BCAxB,IAAAC,EAA6B,mCAMtB,SAASC,GAAqB,CAEpC,IAAMC,EAAQ,EAAAC,QAAiB,MAAM,IAAI,KAAO,EAC1CC,EAAQF,EAAM,UAAWG,GAAUA,EAAM,cAAc,SAAS,wBAAwB,CAAC,EAC/F,OAAOD,EAAQ,GAAK,EAAIF,EAAME,EAAQ,CAAC,EAAE,aAAe,IACzD,CDCO,SAASE,EAAmCC,EAAkBC,EAAc,CAClF,MAAO,CAACC,EAAgCC,EAAmBC,IAAkB,CAC5E,IAAMC,EAAUL,EAAI,SAAS,EACvBM,EAAU,OAAOJ,GAAY,WAAaA,EAAQG,CAAO,EAAIH,KAE/D,WAAQG,EAASC,CAAO,GAI5BN,EAAI,SACHM,EACAH,EAEAF,EAAM,CAAE,KAAMM,EAAmB,GAAKH,GAAQ,WAAY,QAAAE,CAAQ,EAAI,MACvE,CACD,CACD,CDdO,SAASE,EAA+BC,EAAkBC,EAAeC,EAAc,CAC7F,IAAMC,EAAeC,EAAkBJ,EAAKE,CAAG,EAE/C,OAAAD,EAAI,QAASA,GAAQ,CACpBE,EAAQF,CAAG,EAAKI,GAAe,IAC1B,WAAQL,EAAI,SAAS,EAAEC,CAAG,EAAGI,CAAK,GAItCL,EAAI,SACFM,IAAW,CAAE,GAAGA,EAAO,CAACL,CAAG,EAAGI,CAAM,GACrC,GAEAH,EAAM,CAAE,KAAMK,EAAmB,GAAKN,EAAK,QAAS,CAAE,CAACA,CAAG,EAAGI,CAAM,CAAE,EAAI,MAC1E,CACD,CACD,CAAC,EAEMF,CACR,CGjCO,IAAMK,EAAYC,GAAaA,EACzBC,EAAO,CAACC,EAA0BC,IAC9CA,EAAK,OAA4B,CAACC,EAAKC,KAAOA,KAAKH,IAAQE,EAAIC,CAAC,EAAIH,EAAIG,CAAC,GAAID,GAAa,CAAC,CAAC,ECF7F,IAAAE,EAAwB,2BACxBC,EAAuC,+BAWhC,SAASC,EAAkBC,EAAYC,EAAcC,EAAgBC,EAAU,CACjF,OAAOH,GAAU,UAAYA,IAAU,MAC1C,OAAO,KAAKA,CAAK,EAAE,QAASI,GAAQ,CACnC,IAAMC,EAAU,CAAC,GAAGH,EAAME,CAAG,EAC7B,OAAO,eAAeH,EAASG,EAAK,CACnC,MAAO,CAACE,EAAa,eACb,0BACNH,EACCH,GAAUO,EAAYP,EAAOK,CAAO,EACrCC,CACD,EAED,SAAU,GACV,aAAc,GACd,WAAY,EACb,CAAC,EAEDP,EAAkBC,EAAMI,CAAG,EAAGH,EAAQG,CAAG,EAAGC,EAASF,CAAG,CACzD,CAAC,CAEH,CAEA,SAASI,EAAYP,EAAYE,EAAgB,CAChD,IAAIM,EAAOR,EAEX,QAAWI,KAAOF,EAEjB,GADAM,EAAOA,EAAKJ,CAAG,EACX,CAACI,EACJ,OAAOA,EAIT,OAAOA,CACR,CC7CA,IAAAC,EAAwB,2BACxBC,EAAuC,+BAYhC,SAASC,EAAsCC,EAAkB,CACvE,MAAO,CAACC,EAAWC,EAAUC,EAAW,eAChC,0BACNH,EACA,MAAM,QAAQC,CAAQ,EAAKG,GAAMC,EAAKD,EAAGH,CAAQ,EAAKA,GAAYC,EAClEC,CACD,CAEF,CCRO,SAASG,EAA+BC,EAAkBC,EAAe,CAC/E,IAAMC,EAAUC,EAAkBH,CAAG,EACrC,OAAAI,EAAkBC,EAAKL,EAAI,SAAS,EAAGC,CAAG,EAAGC,EAAS,CAAC,EAAGF,CAAG,EACtDE,CACR,CCAO,SAASI,EAOfC,EACAC,EACAC,EACAC,EACC,CAED,IAAMC,EAAoB,OAAOJ,GAAY,WAAaA,EAAQC,CAAG,EAAID,EAGzE,OAAAE,EAAI,SAASE,CAA8B,EAG3CH,EAAI,IAAM,CAAE,GAAGA,EAAI,IAAK,GAAGI,EAAcH,EAAK,OAAO,KAAKE,CAAQ,CAAC,CAAE,EACrEH,EAAI,IAAM,CAAE,GAAGA,EAAI,IAAK,GAAGK,EAAcJ,EAAK,OAAO,KAAKE,CAAQ,EAAGD,CAAG,CAAE,EAGnEF,CACR,CCzCA,IAAAM,EAAwB,2BACxBC,EAAuC,+BCQhC,SAASC,EAAmCC,EAAkB,CACpE,MAAO,IAAMA,EAAI,SAAS,CAC3B,CDIO,SAASC,EAKdC,EAAkBC,EAAoCC,EAAkB,CACzE,IAAMC,EAAeH,EAAQ,CAAE,IAAKC,EAAI,GAAI,CAAC,EACvCG,EAAe,CAAC,EAEtB,cAAO,KAAKD,CAAO,EAAE,QAASE,GAAQ,CACrCD,EAAQC,CAAG,EAAI,IAAIC,OAClB,0BAAuBJ,EAAK,IAAMC,EAAQE,CAAG,EAAE,GAAGC,CAAI,EAAG,SAAO,CAClE,CAAC,EAEDL,EAAI,IAAM,OAAO,OAAOM,EAAkBL,CAAG,EAAGD,EAAI,IAAKG,CAAO,EAChEH,EAAI,IAAM,OAAO,OAAOO,EAAkBN,CAAG,EAAGD,EAAI,IAAKE,CAAO,EACzDF,CACR,CEpBO,SAASQ,EAKdC,EAAkBC,EAAoCC,EAAkBC,EAAc,CACvF,IAAMC,EAAUC,EAAkBH,EAAKC,CAAG,EACpCG,EAAU,OAAO,QAAQN,EAAQC,CAAG,CAAC,EAAE,OAC5C,CAACM,EAAK,CAACC,EAAMC,CAAI,KAChBF,EAAIC,CAAI,EAAI,YAAmCE,EAAa,CAC3D,OAAOD,EAAK,GAAGC,CAAI,CACpB,EAEOH,GAER,CAAC,CACF,EAEA,OAAAN,EAAI,IAAM,OAAO,OAAOG,EAASH,EAAI,IAAKK,CAAO,EAC1CL,CACR,CCrBO,SAASU,EAA+BC,EAAkBC,EAAa,CAC7E,MAAO,CACN,gBAAiBD,EAAI,gBACrB,SAAUA,EAAI,SACd,QAASE,EAAeF,EAAKC,CAAG,EAChC,SAAUD,EAAI,SACd,UAAWA,EAAI,SAChB,CACD,CAEA,SAASE,EAAgCF,EAAkBC,EAAa,CACvE,GAAI,YAAaD,EAAK,CACrB,IAAMG,EAAiBH,EAAI,QAC3B,OAAAG,EAAU,KAAO,IAAM,CACtB,GAAI,CACH,OAAO,KAAK,MAAM,cAAc,QAAQF,CAAG,GAAK,EAAE,GAAG,KACtD,MAAQ,CACP,MACD,CACD,EAEOE,CACR,CACD,CCvBO,SAASC,EAA+BC,EAAkB,CAChE,OAAOC,EAAkBD,CAAG,CAC7B,CCAO,SAASE,EAKdC,EAAqBC,EAAgBC,EAAoCC,EAAkB,CAC5F,MAAO,CACN,IAAKD,EAAI,IACT,IAAKA,EAAI,IACT,IAAKF,GACD,IAAM,CACP,IAAMI,EAAU,OAAO,KAAKF,EAAI,GAAG,EAAE,OACpC,CAACG,EAAKC,IACLL,EAAYK,CAAG,GAAMN,EAA0B,SAASM,CAAG,EACxDD,EACA,CAAE,GAAGA,EAAK,CAACC,CAAG,EAAIJ,EAAI,IAAuBI,CAAG,CAAE,EACtD,CAAC,CACF,EAEA,OAAO,OAAO,OAAOC,EAAkBJ,CAAG,EAAGC,CAAO,CACrD,GAAG,EACFF,EAAI,IACP,IAAKF,EAWK,OAAO,OATA,IACb,OAAO,QAAQE,EAAI,IAAI,CAAC,EAAE,OACzB,CAACG,EAAK,CAACC,EAAKE,CAAG,IACdP,EAAYK,CAAG,GAAMN,EAA0B,SAASM,CAAG,EACxDD,EACA,CAAE,GAAGA,EAAK,CAACC,CAAG,EAAGE,CAAI,EACzB,CAAC,CACF,EAE2BN,EAAI,GAAG,EAEnCA,EAAI,GACR,CACD,CdZA,IAAIO,EAAuB,CAAE,QAAS,eAAgB,QAAS,EAAM,EAE9D,SAASC,EAAgBC,EAAkC,CACjEF,EAAS,CAAE,GAAGA,EAAQ,GAAGE,CAAU,CACpC,CAEO,SAASC,EACfC,EACAC,EAMC,CACD,GAAM,CAAE,KAAAC,EAAO,eAAgB,YAAAC,EAAc,CAAC,CAAa,EAAIF,GAAW,CAAC,EAGvEG,EAAmB,IAAMJ,EAEvBK,EAAY,GAAGT,EAAO,QAAQ,QAAQ,KAAM,GAAG,CAAC,IAAIM,CAAI,IACxDI,EAAYV,EAAO,SAAW,CAAC,CAACO,EAAY,SAE9CG,IACHF,KAAc,YAASA,EAAa,CACnC,KAAMR,EAAO,QACb,MAAOM,EACP,GAAI,OAAOC,EAAY,UAAa,SAAWA,EAAY,SAAW,CAAC,CACxE,CAAC,GAGEA,EAAY,UACfC,KAAc,WAAQA,EAAa,CAClC,KAAMC,EACN,GAAI,OAAOF,EAAY,SAAY,SAAWA,EAAY,QAAU,CAAC,CACtE,CAAC,GAIF,IAAMI,KAAgB,EAAAC,aAAmBJ,CAAW,EAGpD,MAAO,CACN,IAAKK,EAAcF,EAAUF,CAAS,EACtC,IAAKK,EAAcH,CAAQ,EAC3B,IAAKI,EAAcJ,EAAU,OAAO,KAAKP,CAAY,CAAC,EACtD,IAAKY,EAAcL,EAAU,OAAO,KAAKP,CAAY,EAAGM,CAAS,EACjE,cAAcO,EAAQ,CACrB,OAAOA,EAAO,IAAI,CACnB,EACA,cAAcC,EAAS,CACtB,OAAOC,EAAcD,EAAS,KAAMP,CAAQ,CAC7C,EACA,cAAcO,EAAS,CACtB,OAAOE,EAAcF,EAAS,KAAMP,EAAUD,CAAS,CACxD,EACA,cAAcQ,EAAS,CACtB,OAAOG,EAAcH,EAAS,KAAMP,EAAUD,CAAS,CACxD,EACA,cAAcY,EAAc,CAAC,EAAG,CAC/B,OAAOC,EAAcD,EAAalB,EAAc,KAAMO,CAAQ,CAC/D,CACD,CACD,CehGO,IAAMa,EAA0BC,GACtCA,EAAM,cAAc,CAAC,CAAE,IAAAC,EAAK,IAAAC,CAAI,KAAO,CACtC,MAAO,IAAM,CACZA,EAAID,EAAI,kBAAkB,GAAK,CAAC,EAAG,EAAI,CACxC,CACD,EAAE","names":["index_exports","__export","createStore","definePlugin","setGlobalConfig","withReset","__toCommonJS","definePlugin","fn","import_middleware","import_vanilla","import_shallow","import_shallow","import_error_stack_parser","generateSetterName","stack","ErrorStackParser","index","entry","generateSetFnBase","lib","log","updater","replace","name","current","payload","generateSetterName","generateSetFn","lib","key","log","setters","generateSetFnBase","value","state","generateSetterName","identity","arg","pick","obj","keys","acc","k","import_shallow","import_traditional","generateUseFnStep","state","getters","path","lib","key","newPath","equalityFn","getFromPath","data","import_shallow","import_traditional","generateUseFnBase","lib","selector","identity","equality","s","pick","generateUseFn","lib","key","getters","generateUseFnBase","generateUseFnStep","pick","extendByState","builder","api","lib","log","newState","generateUseFn","generateSetFn","import_shallow","import_traditional","generateGetFnBase","lib","extendGetters","builder","api","lib","methods","getters","key","args","generateUseFnBase","generateGetFnBase","extendSetters","builder","api","lib","log","setters","generateSetFnBase","baseSet","acc","name","func","args","generateApiFn","lib","key","augmentPersist","augmented","generateGetFn","lib","generateGetFnBase","restrictState","privateState","mergedState","api","lib","getters","acc","key","generateUseFnBase","val","config","setGlobalConfig","newConfig","createStore","initialState","options","name","middlewares","initializer","persistId","shouldLog","storeLib","createVanillaStore","generateApiFn","generateGetFn","generateUseFn","generateSetFn","plugin","builder","extendGetters","extendSetters","extendByState","publicState","restrictState","withReset","store","api","set"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/definePlugin.ts","../src/lib/createStore.ts","../src/lib/generateSetFn.ts","../src/lib/generateSetFnBase.ts","../src/lib/generateSetterName.ts","../src/utils/utils.ts","../src/lib/generateUseFnStep.ts","../src/lib/generateUseFnBase.ts","../src/lib/generateUseFn.ts","../src/lib/extendByState.ts","../src/lib/extendGetters.ts","../src/lib/generateGetFnBase.ts","../src/lib/extendSetters.ts","../src/lib/generateApiFn.ts","../src/lib/generateGetFn.ts","../src/lib/restrictState.ts","../src/plugins/reset.ts"],"sourcesContent":["export { definePlugin } from './lib/definePlugin'\nexport { createStore, setGlobalConfig } from './lib/createStore'\nexport { withReset } from './plugins/reset'\nexport type { UseGetterOptions } from './types'\n","import { State, StoreApi } from '../types'\n\n/**\n * Identity helper that provides a typed `store` param and preserves the plugin's return type.\n */\nexport function definePlugin<F extends (store: StoreApi) => StoreApi>(fn: F) {\n\treturn fn as unknown as <S extends State, G, A, MW>(\n\t\tstore: StoreApi<S, G, A, MW>\n\t) => ReturnType<F>\n}\n","/**\n * Entire no-boilerplate functionality inspired by this recipe:\n * https://docs.pmnd.rs/zustand/guides/auto-generating-selectors.\n * It has few utilities described here: https://www.npmjs.com/package/zustand-lite\n * for:\n * 1) Generating getters for flat state (1-level deep selectors).\n * 2) Generating setters for flat state (1-level deep setters).\n * 3) Automatic devtools messaging.\n * 4) Annotating functions with proper TS types to avoid some bloating and TS frenzy.\n * 5) Extending getters and setters\n * 6) Extending state and restricting state\n * 7) Reuse plugins\n *\n * Idea is to support small store without complicated data reducing (it can be done as well,\n * but may indicate something is not right with the use case itself).\n **/\nimport { devtools, persist } from 'zustand/middleware'\nimport { createStore as createVanillaStore } from 'zustand/vanilla'\n\nimport {\n\tGetRecord,\n\tGlobalConfig,\n\tMWConfiguration,\n\tSetRecord,\n\tState,\n\tStoreApi,\n\tStorePersist,\n} from '../types'\n\nimport { extendByState } from './extendByState'\nimport { extendGetters } from './extendGetters'\nimport { extendSetters } from './extendSetters'\nimport { generateApiFn } from './generateApiFn'\nimport { generateGetFn } from './generateGetFn'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\nimport { restrictState } from './restrictState'\n\nlet config: GlobalConfig = { appName: 'zustand-lite', logging: false }\n\nexport function setGlobalConfig(newConfig: Partial<GlobalConfig>) {\n\tconfig = { ...config, ...newConfig }\n}\n\nexport function createStore<S extends State, ExtraMW extends MWConfiguration = {}>(\n\tinitialState: S,\n\toptions?: { name?: string; middlewares?: ExtraMW }\n): StoreApi<\n\tS,\n\tGetRecord<S>,\n\tSetRecord<S>,\n\tExtraMW extends { persist: any } ? StorePersist<S> : {}\n> {\n\tconst { name = 'zustand-lite', middlewares = {} as ExtraMW } = options ?? {}\n\n\t// Apply supported middlewares.\n\tlet initializer: any = () => initialState\n\n\tconst persistId = `${config.appName.replace(/\\s/, '-')}.${name}}`\n\tconst shouldLog = config.logging || !!middlewares.devtools\n\n\tif (shouldLog) {\n\t\tinitializer = devtools(initializer, {\n\t\t\tname: config.appName,\n\t\t\tstore: name,\n\t\t\t...(typeof middlewares.devtools === 'object' ? middlewares.devtools : {}),\n\t\t})\n\t}\n\n\tif (middlewares.persist) {\n\t\tinitializer = persist(initializer, {\n\t\t\tname: persistId,\n\t\t\t...(typeof middlewares.persist === 'object' ? middlewares.persist : {}),\n\t\t})\n\t}\n\n\t// Create a vanilla zustand store to wrap.\n\tconst storeLib: any = createVanillaStore(initializer)\n\n\t// Create zustand-lite wrapper.\n\treturn {\n\t\tapi: generateApiFn(storeLib, persistId),\n\t\tget: generateGetFn(storeLib),\n\t\tuse: generateUseFn(storeLib, Object.keys(initialState)),\n\t\tset: generateSetFn(storeLib, Object.keys(initialState), shouldLog),\n\t\tcomposePlugin(plugin) {\n\t\t\treturn plugin(this)\n\t\t},\n\t\textendGetters(builder) {\n\t\t\treturn extendGetters(builder, this, storeLib)\n\t\t},\n\t\textendSetters(builder) {\n\t\t\treturn extendSetters(builder, this, storeLib, shouldLog)\n\t\t},\n\t\textendByState(builder) {\n\t\t\treturn extendByState(builder, this, storeLib, shouldLog)\n\t\t},\n\t\trestrictState(publicState = []) {\n\t\t\treturn restrictState(publicState, initialState, this, storeLib)\n\t\t},\n\t} as any\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { SetRecord, State } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setters like store.set.foo(value)\n *\n * @param lib Zustand api interface\n * @param key Keys to generate setters for\n * @param log If devtools were activated for this store\n */\nexport function generateSetFn<S extends State>(lib: StoreLib<S>, key: string[], log: boolean) {\n\tconst setters: any = generateSetFnBase(lib, log)\n\n\tkey.forEach((key) => {\n\t\tsetters[key] = (value: any) => {\n\t\t\tif (shallow(lib.getState()[key], value)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlib.setState(\n\t\t\t\t(state) => ({ ...state, [key]: value }),\n\t\t\t\tfalse,\n\t\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\t\tlog ? { type: generateSetterName() ?? key, payload: { [key]: value } } : undefined\n\t\t\t)\n\t\t}\n\t})\n\n\treturn setters as SetRecord<S>\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setState function for store like store.set({ value })\n *\n * @param lib Zustand api interface\n * @param log If devtools were activated for this store\n */\nexport function generateSetFnBase<S extends State>(lib: StoreLib<S>, log: boolean) {\n\treturn (updater: S | ((state: S) => S), replace?: boolean, name?: string) => {\n\t\tconst current = lib.getState()\n\t\tconst payload = typeof updater === 'function' ? updater(current) : updater\n\n\t\tif (shallow(current, payload)) {\n\t\t\treturn\n\t\t}\n\n\t\tlib.setState(\n\t\t\tpayload,\n\t\t\treplace,\n\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\tlog ? { type: generateSetterName() ?? name ?? 'setState', payload } : undefined\n\t\t)\n\t}\n}\n","import ErrorStackParser from 'error-stack-parser'\n\n/**\n * Hacky, but working (and possibly only one there is) method of fetching proper caller\n * name of the extended function.\n */\nexport function generateSetterName() {\n\t// Proper setter name should hide at 2nd position in the normalized stack.\n\tconst stack = ErrorStackParser.parse(new Error())\n\tconst index = stack.findIndex((entry) => entry.functionName?.includes('_zustandLiteInferName_'))\n\treturn index - 1 >= 0 ? stack[index - 1].functionName : null\n}\n","export const identity = (arg: any) => arg\nexport const pick = (obj: Record<string, any>, keys: string[]) =>\n\tkeys.reduce<Record<string, any>>((acc, k) => (k in obj ? ((acc[k] = obj[k]), acc) : acc), {})\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\n/**\n * Generates automatic getters like store.use.foo() (recursive steps for each level).\n * Getters are created as side effects.\n *\n * @param state State at nth level\n * @param getters Getters at nth level\n * @param path Property access path at nth level like ['foo', 'bar']\n * @param lib Zustand api interface\n */\nexport function generateUseFnStep(state: any, getters: any, path: string[], lib: any) {\n\tif (typeof state === 'object' && state !== null) {\n\t\tObject.keys(state).forEach((key) => {\n\t\t\tconst newPath = [...path, key]\n\t\t\tObject.defineProperty(getters, key, {\n\t\t\t\tvalue: (equalityFn = shallow) => {\n\t\t\t\t\treturn useStoreWithEqualityFn(\n\t\t\t\t\t\tlib,\n\t\t\t\t\t\t(state) => getFromPath(state, newPath),\n\t\t\t\t\t\tequalityFn\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t})\n\n\t\t\tgenerateUseFnStep(state[key], getters[key], newPath, lib)\n\t\t})\n\t}\n}\n\nfunction getFromPath(state: any, path: string[]) {\n\tlet data = state\n\n\tfor (const key of path) {\n\t\tdata = data[key]\n\t\tif (!data) {\n\t\t\treturn data\n\t\t}\n\t}\n\n\treturn data\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\nimport { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { identity, pick } from '../utils/utils'\n\n/**\n * Generates automatic getters like store.use.foo()\n *\n * @param lib Zustand api interface\n */\nexport function generateUseFnBase<S extends State, U>(lib: StoreLib<S>) {\n\treturn (selector = identity, equality = shallow) => {\n\t\treturn useStoreWithEqualityFn(\n\t\t\tlib,\n\t\t\tArray.isArray(selector) ? (s) => pick(s, selector) : (selector ?? identity),\n\t\t\tequality\n\t\t)\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { pick } from '../utils/utils'\nimport { generateUseFnStep } from './generateUseFnStep'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Generates automatic store hook subscribe function store.use()\n *\n * @param lib Zustand api interface\n * @param key State keys to use\n */\nexport function generateUseFn<S extends State>(lib: StoreLib<S>, key: string[]) {\n\tconst getters = generateUseFnBase(lib)\n\tgenerateUseFnStep(pick(lib.getState(), key), getters, [], lib)\n\treturn getters\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { ByStateBuilder, State, StoreApi } from '../types'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\n\n/**\n * Extends the store by adding new state fields, either by:\n * - passing an object patch: `{ b: 'x' }`\n * - or using a builder: `({ get }) => ({ c: get().b + 'y' })`\n *\n * @param builder Object patch or function producing new state fields.\n * @param api The extended store API before widening.\n * @param lib The underlying Zustand vanilla store.\n * @param log Enables logging for generated setters.\n *\n * @returns The same API instance, but with widened state (via overloads).\n */\nexport function extendByState<\n\tNewData extends State,\n\tOldData extends State,\n\tGetters,\n\tSetters,\n\tBuilder extends ByStateBuilder<NewData, OldData, Getters>,\n>(\n\tbuilder: Builder | NewData,\n\tapi: StoreApi<OldData, Getters, Setters>,\n\tlib: StoreLib<OldData>,\n\tlog: boolean\n) {\n\t// Calculate new state to be added to the store.\n\tconst newState: NewData = typeof builder === 'function' ? builder(api) : builder\n\n\t// Merge the new keys into the zustand state in such a way that the old keys are preserved.\n\tlib.setState({ ...newState, ...lib.getState() })\n\n\t// Generate basic getters and setters from the newly added record.\n\tapi.use = { ...api.use, ...generateUseFn(lib, Object.keys(newState)) }\n\tapi.set = { ...api.set, ...generateSetFn(lib, Object.keys(newState), log) }\n\n\t// Return the same object, but with widened state type (handled by overloads).\n\treturn api\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GettersBuilder, State, StoreApi, UseGetterOptions } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Type guard to check if a value is an equality options object.\n * Detects plain objects with an `eq` property that is a function.\n */\nfunction isEqualityOptions<R>(value: unknown): value is UseGetterOptions<R> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'eq' in value &&\n\t\ttypeof (value as any).eq === 'function'\n\t)\n}\n\n/**\n * Adds derived getters to the store.\n *\n * @param builder Function returning new getter methods.\n * @param api Current store API to extend.\n * @param lib Underlying Zustand store.\n */\nexport function extendGetters<\n\tBuilder extends GettersBuilder<S, Getters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\tconst methods: any = builder({ get: api.get })\n\tconst getters: any = {}\n\n\tObject.keys(methods).forEach((key) => {\n\t\tgetters[key] = (...args: any[]) => {\n\t\t\t// Check if the last argument is an equality options object\n\t\t\tconst lastArg = args[args.length - 1]\n\t\t\tif (isEqualityOptions(lastArg)) {\n\t\t\t\tconst actualArgs = args.slice(0, -1)\n\t\t\t\treturn useStoreWithEqualityFn(lib, () => methods[key](...actualArgs), lastArg.eq)\n\t\t\t}\n\t\t\treturn useStoreWithEqualityFn(lib, () => methods[key](...args), shallow)\n\t\t}\n\t})\n\n\tapi.use = Object.assign(generateUseFnBase(lib), api.use, getters)\n\tapi.get = Object.assign(generateGetFnBase(lib), api.get, methods)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Generates getState function for store.get()\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFnBase<S extends State>(lib: StoreLib<S>) {\n\treturn () => lib.getState()\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { SettersBuilder, State, StoreApi } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\n\n/**\n * Adds custom setter methods to the store.\n *\n * @param builder Function returning new setter methods.\n * @param api Store API to extend.\n * @param lib Underlying Zustand store.\n * @param log Enables optional debug logging.\n */\nexport function extendSetters<\n\tBuilder extends SettersBuilder<S, Getters, Setters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>, log: boolean) {\n\tconst setters = generateSetFnBase(lib, log)\n\tconst baseSet = Object.entries(builder(api)).reduce(\n\t\t(acc, [name, func]) => {\n\t\t\tacc[name] = function _zustandLiteInferName_(...args: any[]) {\n\t\t\t\treturn func(...args)\n\t\t\t}\n\n\t\t\treturn acc\n\t\t},\n\t\t{} as Record<string, any>\n\t)\n\n\tapi.set = Object.assign(setters, api.set, baseSet)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Required to wrap original Zustand interface without getState and setState, which are handled\n * by get and set (we should allow only one way of doing certain things).\n *\n * @param lib Zustand api interface\n * @param key Zustand persist local storage key\n */\nexport function generateApiFn<S extends State>(lib: StoreLib<S>, key: string) {\n\treturn {\n\t\tgetInitialState: lib.getInitialState,\n\t\tgetState: lib.getState,\n\t\tpersist: augmentPersist(lib, key),\n\t\tsetState: lib.setState,\n\t\tsubscribe: lib.subscribe,\n\t}\n}\n\nfunction augmentPersist<S extends State>(lib: StoreLib<S>, key: string) {\n\tif ('persist' in lib) {\n\t\tconst augmented: any = lib.persist\n\t\taugmented.read = () => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(localStorage?.getItem(key) ?? '')?.state\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\n\t\treturn augmented\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\n\n/**\n * Generates getters for store.get. In the past getters were generated as functions, but I\n * came to the conclusion that it's better and simpler to return the whole state.\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFn<S extends State>(lib: StoreLib<S>) {\n\treturn generateGetFnBase(lib)\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GetRecord, SetRecord, State, StoreApi, UseRecord } from '../types'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Function that restrict access to the store and store api.\n *\n * @param privateState Property names to be made private like ['foo', 'bar']\n * @param mergedState Final state of the store\n * @param api Returned store API\n * @param lib Zustand api interface\n */\nexport function restrictState<\n\tS extends State,\n\tKey extends keyof S,\n\tGetters extends GetRecord<any>,\n\tSetters extends SetRecord<any>,\n>(privateState: Key[], mergedState: S, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\treturn {\n\t\tapi: api.api,\n\t\tset: api.set,\n\t\tuse: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getters = Object.keys(api.use).reduce(\n\t\t\t\t\t\t(acc, key) =>\n\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t: { ...acc, [key]: (api.use as UseRecord<any>)[key] },\n\t\t\t\t\t\t{}\n\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(generateUseFnBase(lib), getters)\n\t\t\t\t})()\n\t\t\t: api.use,\n\t\tget: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getFn = () =>\n\t\t\t\t\t\tObject.entries(api.get()).reduce(\n\t\t\t\t\t\t\t(acc, [key, val]) =>\n\t\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t\t: { ...acc, [key]: val },\n\t\t\t\t\t\t\t{}\n\t\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(getFn, api.get)\n\t\t\t\t})()\n\t\t\t: api.get,\n\t}\n}\n","import { definePlugin } from '../lib/definePlugin'\n\n/**\n * Basic plugin example, that extends store with custom setter.\n */\nexport const withReset = definePlugin((store) =>\n\tstore.extendSetters(({ api, set }) => ({\n\t\treset: () => {\n\t\t\tset(api.getInitialState?.() ?? {}, true)\n\t\t},\n\t}))\n)\n"],"mappings":"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","names":["index_exports","__export","createStore","definePlugin","setGlobalConfig","withReset","__toCommonJS","definePlugin","fn","import_middleware","import_vanilla","import_shallow","import_shallow","import_error_stack_parser","generateSetterName","stack","ErrorStackParser","index","entry","generateSetFnBase","lib","log","updater","replace","name","current","payload","generateSetterName","generateSetFn","lib","key","log","setters","generateSetFnBase","value","state","generateSetterName","identity","arg","pick","obj","keys","acc","k","import_shallow","import_traditional","generateUseFnStep","state","getters","path","lib","key","newPath","equalityFn","getFromPath","data","import_shallow","import_traditional","generateUseFnBase","lib","selector","identity","equality","s","pick","generateUseFn","lib","key","getters","generateUseFnBase","generateUseFnStep","pick","extendByState","builder","api","lib","log","newState","generateUseFn","generateSetFn","import_shallow","import_traditional","generateGetFnBase","lib","isEqualityOptions","value","extendGetters","builder","api","lib","methods","getters","key","args","lastArg","actualArgs","generateUseFnBase","generateGetFnBase","extendSetters","builder","api","lib","log","setters","generateSetFnBase","baseSet","acc","name","func","args","generateApiFn","lib","key","augmentPersist","augmented","generateGetFn","lib","generateGetFnBase","restrictState","privateState","mergedState","api","lib","getters","acc","key","generateUseFnBase","val","config","setGlobalConfig","newConfig","createStore","initialState","options","name","middlewares","initializer","persistId","shouldLog","storeLib","createVanillaStore","generateApiFn","generateGetFn","generateUseFn","generateSetFn","plugin","builder","extendGetters","extendSetters","extendByState","publicState","restrictState","withReset","store","api","set"]}
package/dist/index.d.cts CHANGED
@@ -14,7 +14,7 @@ type SetBase<S extends State> = StoreApi$1<S>['setState'];
14
14
  type UseBase<S extends State> = UseRecordBase<S>;
15
15
  type OverrideGet<T, U, S extends State> = Augments<T, U, GetBase<S>>;
16
16
  type OverrideSet<T, U, S extends State> = Augments<T, U, SetBase<S>>;
17
- type OverrideUse<T, U, S extends State> = Augments<T, U, UseBase<S>>;
17
+ type OverrideUse<T, U, S extends State> = Augments<T, GettersWithEquality<U>, UseBase<S>>;
18
18
  type GetRecord<S extends Record<string, unknown>> = GetBase<S>;
19
19
  type SetRecord<S extends Record<string, unknown>> = SetBase<S> & {
20
20
  [K in keyof S]-?: (value: S[K]) => any;
@@ -59,6 +59,29 @@ type UseRecordBase<S> = {
59
59
  };
60
60
  type UseRecord<S> = UseRecordDeep<S> & UseRecordBase<S>;
61
61
  type AnyFn = (...args: any[]) => any;
62
+ /**
63
+ * Options object for customizing getter hook behavior.
64
+ * Pass this as the last argument to a custom getter hook.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * store.use.getItemById(id, { eq: (a, b) => a?.id === b?.id })
69
+ * ```
70
+ */
71
+ type UseGetterOptions<R> = {
72
+ eq: EqualityChecker<R>;
73
+ };
74
+ /**
75
+ * Transforms a getter function type to accept an optional equality options argument.
76
+ * This allows passing `withEq(equalityFn)` as the last argument to custom getters.
77
+ */
78
+ type WithEqualityOption<F> = F extends (...args: infer A) => infer R ? (...args: [...A, options?: UseGetterOptions<R>]) => R : F;
79
+ /**
80
+ * Transforms all getters in a record to accept optional equality options.
81
+ */
82
+ type GettersWithEquality<G> = {
83
+ [K in keyof G]: WithEqualityOption<G[K]>;
84
+ };
62
85
  type UseRecordDeep<S> = {
63
86
  [K in keyof S]-?: S[K] extends Record<string, any> ? IsOptional<S, K> extends false ? ((equalityFn?: EqualityChecker<S[K]>) => S[K]) & UseRecordDeep<S[K]> : never : (equalityFn?: EqualityChecker<S[K]>) => S[K];
64
87
  };
@@ -105,4 +128,4 @@ declare const withReset: <S extends State, G, A, MW>(store: StoreApi<S, G, A, MW
105
128
  reset: () => void;
106
129
  }, {}>;
107
130
 
108
- export { createStore, definePlugin, setGlobalConfig, withReset };
131
+ export { type UseGetterOptions, createStore, definePlugin, setGlobalConfig, withReset };
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ type SetBase<S extends State> = StoreApi$1<S>['setState'];
14
14
  type UseBase<S extends State> = UseRecordBase<S>;
15
15
  type OverrideGet<T, U, S extends State> = Augments<T, U, GetBase<S>>;
16
16
  type OverrideSet<T, U, S extends State> = Augments<T, U, SetBase<S>>;
17
- type OverrideUse<T, U, S extends State> = Augments<T, U, UseBase<S>>;
17
+ type OverrideUse<T, U, S extends State> = Augments<T, GettersWithEquality<U>, UseBase<S>>;
18
18
  type GetRecord<S extends Record<string, unknown>> = GetBase<S>;
19
19
  type SetRecord<S extends Record<string, unknown>> = SetBase<S> & {
20
20
  [K in keyof S]-?: (value: S[K]) => any;
@@ -59,6 +59,29 @@ type UseRecordBase<S> = {
59
59
  };
60
60
  type UseRecord<S> = UseRecordDeep<S> & UseRecordBase<S>;
61
61
  type AnyFn = (...args: any[]) => any;
62
+ /**
63
+ * Options object for customizing getter hook behavior.
64
+ * Pass this as the last argument to a custom getter hook.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * store.use.getItemById(id, { eq: (a, b) => a?.id === b?.id })
69
+ * ```
70
+ */
71
+ type UseGetterOptions<R> = {
72
+ eq: EqualityChecker<R>;
73
+ };
74
+ /**
75
+ * Transforms a getter function type to accept an optional equality options argument.
76
+ * This allows passing `withEq(equalityFn)` as the last argument to custom getters.
77
+ */
78
+ type WithEqualityOption<F> = F extends (...args: infer A) => infer R ? (...args: [...A, options?: UseGetterOptions<R>]) => R : F;
79
+ /**
80
+ * Transforms all getters in a record to accept optional equality options.
81
+ */
82
+ type GettersWithEquality<G> = {
83
+ [K in keyof G]: WithEqualityOption<G[K]>;
84
+ };
62
85
  type UseRecordDeep<S> = {
63
86
  [K in keyof S]-?: S[K] extends Record<string, any> ? IsOptional<S, K> extends false ? ((equalityFn?: EqualityChecker<S[K]>) => S[K]) & UseRecordDeep<S[K]> : never : (equalityFn?: EqualityChecker<S[K]>) => S[K];
64
87
  };
@@ -105,4 +128,4 @@ declare const withReset: <S extends State, G, A, MW>(store: StoreApi<S, G, A, MW
105
128
  reset: () => void;
106
129
  }, {}>;
107
130
 
108
- export { createStore, definePlugin, setGlobalConfig, withReset };
131
+ export { type UseGetterOptions, createStore, definePlugin, setGlobalConfig, withReset };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- function O(e){return e}import{devtools as C,persist as z}from"zustand/middleware";import{createStore as _}from"zustand/vanilla";import{shallow as j}from"zustand/shallow";import{shallow as R}from"zustand/shallow";import w from"error-stack-parser";function p(){let e=w.parse(new Error),r=e.findIndex(t=>t.functionName?.includes("_zustandLiteInferName_"));return r-1>=0?e[r-1].functionName:null}function u(e,r){return(t,o,n)=>{let i=e.getState(),s=typeof t=="function"?t(i):t;R(i,s)||e.setState(s,o,r?{type:p()??n??"setState",payload:s}:void 0)}}function d(e,r,t){let o=u(e,t);return r.forEach(n=>{o[n]=i=>{j(e.getState()[n],i)||e.setState(s=>({...s,[n]:i}),!1,t?{type:p()??n,payload:{[n]:i}}:void 0)}}),o}var x=e=>e,c=(e,r)=>r.reduce((t,o)=>(o in e&&(t[o]=e[o]),t),{});import{shallow as N}from"zustand/shallow";import{useStoreWithEqualityFn as E}from"zustand/traditional";function y(e,r,t,o){typeof e=="object"&&e!==null&&Object.keys(e).forEach(n=>{let i=[...t,n];Object.defineProperty(r,n,{value:(s=N)=>E(o,a=>P(a,i),s),writable:!0,configurable:!0,enumerable:!0}),y(e[n],r[n],i,o)})}function P(e,r){let t=e;for(let o of r)if(t=t[o],!t)return t;return t}import{shallow as U}from"zustand/shallow";import{useStoreWithEqualityFn as W}from"zustand/traditional";function m(e){return(r=x,t=U)=>W(e,Array.isArray(r)?o=>c(o,r):r??x,t)}function g(e,r){let t=m(e);return y(c(e.getState(),r),t,[],e),t}function b(e,r,t,o){let n=typeof e=="function"?e(r):e;return t.setState(n),r.use={...r.use,...g(t,Object.keys(n))},r.set={...r.set,...d(t,Object.keys(n),o)},r}import{shallow as D}from"zustand/shallow";import{useStoreWithEqualityFn as I}from"zustand/traditional";function l(e){return()=>e.getState()}function G(e,r,t){let o=e({get:r.get}),n={};return Object.keys(o).forEach(i=>{n[i]=(...s)=>I(t,()=>o[i](...s),D)}),r.use=Object.assign(m(t),r.use,n),r.get=Object.assign(l(t),r.get,o),r}function A(e,r,t,o){let n=u(t,o),i=Object.entries(e(r)).reduce((s,[a,S])=>(s[a]=function(...h){return S(...h)},s),{});return r.set=Object.assign(n,r.set,i),r}function F(e,r){return{getInitialState:e.getInitialState,getState:e.getState,persist:M(e,r),setState:e.setState,subscribe:e.subscribe}}function M(e,r){if("persist"in e){let t=e.persist;return t.read=()=>{try{return JSON.parse(localStorage?.getItem(r)??"")?.state}catch{return}},t}}function B(e){return l(e)}function L(e,r,t,o){return{api:t.api,set:t.set,use:e?(()=>{let n=Object.keys(t.use).reduce((i,s)=>r[s]&&e.includes(s)?i:{...i,[s]:t.use[s]},{});return Object.assign(m(o),n)})():t.use,get:e?Object.assign(()=>Object.entries(t.get()).reduce((i,[s,a])=>r[s]&&e.includes(s)?i:{...i,[s]:a},{}),t.get):t.get}}var f={appName:"zustand-lite",logging:!1};function q(e){f={...f,...e}}function K(e,r){let{name:t="zustand-lite",middlewares:o={}}=r??{},n=()=>e,i=`${f.appName.replace(/\s/,"-")}.${t}}`,s=f.logging||!!o.devtools;s&&(n=C(n,{name:f.appName,store:t,...typeof o.devtools=="object"?o.devtools:{}})),o.persist&&(n=z(n,{name:i,...typeof o.persist=="object"?o.persist:{}}));let a=_(n);return{api:F(a,i),get:B(a),use:g(a,Object.keys(e)),set:d(a,Object.keys(e),s),composePlugin(S){return S(this)},extendGetters(S){return G(S,this,a)},extendSetters(S){return A(S,this,a,s)},extendByState(S){return b(S,this,a,s)},restrictState(S=[]){return L(S,e,this,a)}}}var $=e=>e.extendSetters(({api:r,set:t})=>({reset:()=>{t(r.getInitialState?.()??{},!0)}}));export{K as createStore,O as definePlugin,q as setGlobalConfig,$ as withReset};
1
+ function R(e){return e}import{devtools as C,persist as z}from"zustand/middleware";import{createStore as _}from"zustand/vanilla";import{shallow as N}from"zustand/shallow";import{shallow as j}from"zustand/shallow";import w from"error-stack-parser";function p(){let e=w.parse(new Error),r=e.findIndex(t=>t.functionName?.includes("_zustandLiteInferName_"));return r-1>=0?e[r-1].functionName:null}function u(e,r){return(t,o,n)=>{let i=e.getState(),s=typeof t=="function"?t(i):t;j(i,s)||e.setState(s,o,r?{type:p()??n??"setState",payload:s}:void 0)}}function c(e,r,t){let o=u(e,t);return r.forEach(n=>{o[n]=i=>{N(e.getState()[n],i)||e.setState(s=>({...s,[n]:i}),!1,t?{type:p()??n,payload:{[n]:i}}:void 0)}}),o}var x=e=>e,d=(e,r)=>r.reduce((t,o)=>(o in e&&(t[o]=e[o]),t),{});import{shallow as U}from"zustand/shallow";import{useStoreWithEqualityFn as E}from"zustand/traditional";function y(e,r,t,o){typeof e=="object"&&e!==null&&Object.keys(e).forEach(n=>{let i=[...t,n];Object.defineProperty(r,n,{value:(s=U)=>E(o,a=>P(a,i),s),writable:!0,configurable:!0,enumerable:!0}),y(e[n],r[n],i,o)})}function P(e,r){let t=e;for(let o of r)if(t=t[o],!t)return t;return t}import{shallow as W}from"zustand/shallow";import{useStoreWithEqualityFn as D}from"zustand/traditional";function m(e){return(r=x,t=W)=>D(e,Array.isArray(r)?o=>d(o,r):r??x,t)}function g(e,r){let t=m(e);return y(d(e.getState(),r),t,[],e),t}function b(e,r,t,o){let n=typeof e=="function"?e(r):e;return t.setState({...n,...t.getState()}),r.use={...r.use,...g(t,Object.keys(n))},r.set={...r.set,...c(t,Object.keys(n),o)},r}import{shallow as I}from"zustand/shallow";import{useStoreWithEqualityFn as G}from"zustand/traditional";function l(e){return()=>e.getState()}function M(e){return typeof e=="object"&&e!==null&&"eq"in e&&typeof e.eq=="function"}function A(e,r,t){let o=e({get:r.get}),n={};return Object.keys(o).forEach(i=>{n[i]=(...s)=>{let a=s[s.length-1];if(M(a)){let S=s.slice(0,-1);return G(t,()=>o[i](...S),a.eq)}return G(t,()=>o[i](...s),I)}}),r.use=Object.assign(m(t),r.use,n),r.get=Object.assign(l(t),r.get,o),r}function F(e,r,t,o){let n=u(t,o),i=Object.entries(e(r)).reduce((s,[a,S])=>(s[a]=function(...O){return S(...O)},s),{});return r.set=Object.assign(n,r.set,i),r}function B(e,r){return{getInitialState:e.getInitialState,getState:e.getState,persist:q(e,r),setState:e.setState,subscribe:e.subscribe}}function q(e,r){if("persist"in e){let t=e.persist;return t.read=()=>{try{return JSON.parse(localStorage?.getItem(r)??"")?.state}catch{return}},t}}function L(e){return l(e)}function h(e,r,t,o){return{api:t.api,set:t.set,use:e?(()=>{let n=Object.keys(t.use).reduce((i,s)=>r[s]&&e.includes(s)?i:{...i,[s]:t.use[s]},{});return Object.assign(m(o),n)})():t.use,get:e?Object.assign(()=>Object.entries(t.get()).reduce((i,[s,a])=>r[s]&&e.includes(s)?i:{...i,[s]:a},{}),t.get):t.get}}var f={appName:"zustand-lite",logging:!1};function K(e){f={...f,...e}}function $(e,r){let{name:t="zustand-lite",middlewares:o={}}=r??{},n=()=>e,i=`${f.appName.replace(/\s/,"-")}.${t}}`,s=f.logging||!!o.devtools;s&&(n=C(n,{name:f.appName,store:t,...typeof o.devtools=="object"?o.devtools:{}})),o.persist&&(n=z(n,{name:i,...typeof o.persist=="object"?o.persist:{}}));let a=_(n);return{api:B(a,i),get:L(a),use:g(a,Object.keys(e)),set:c(a,Object.keys(e),s),composePlugin(S){return S(this)},extendGetters(S){return A(S,this,a)},extendSetters(S){return F(S,this,a,s)},extendByState(S){return b(S,this,a,s)},restrictState(S=[]){return h(S,e,this,a)}}}var J=e=>e.extendSetters(({api:r,set:t})=>({reset:()=>{t(r.getInitialState?.()??{},!0)}}));export{$ as createStore,R as definePlugin,K as setGlobalConfig,J as withReset};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/definePlugin.ts","../src/lib/createStore.ts","../src/lib/generateSetFn.ts","../src/lib/generateSetFnBase.ts","../src/lib/generateSetterName.ts","../src/utils/utils.ts","../src/lib/generateUseFnStep.ts","../src/lib/generateUseFnBase.ts","../src/lib/generateUseFn.ts","../src/lib/extendByState.ts","../src/lib/extendGetters.ts","../src/lib/generateGetFnBase.ts","../src/lib/extendSetters.ts","../src/lib/generateApiFn.ts","../src/lib/generateGetFn.ts","../src/lib/restrictState.ts","../src/plugins/reset.ts"],"sourcesContent":["import { State, StoreApi } from '../types'\n\n/**\n * Identity helper that provides a typed `store` param and preserves the plugin's return type.\n */\nexport function definePlugin<F extends (store: StoreApi) => StoreApi>(fn: F) {\n\treturn fn as unknown as <S extends State, G, A, MW>(\n\t\tstore: StoreApi<S, G, A, MW>\n\t) => ReturnType<F>\n}\n","/**\n * Entire no-boilerplate functionality inspired by this recipe:\n * https://docs.pmnd.rs/zustand/guides/auto-generating-selectors.\n * It has few utilities described here: https://www.npmjs.com/package/zustand-lite\n * for:\n * 1) Generating getters for flat state (1-level deep selectors).\n * 2) Generating setters for flat state (1-level deep setters).\n * 3) Automatic devtools messaging.\n * 4) Annotating functions with proper TS types to avoid some bloating and TS frenzy.\n * 5) Extending getters and setters\n * 6) Extending state and restricting state\n * 7) Reuse plugins\n *\n * Idea is to support small store without complicated data reducing (it can be done as well,\n * but may indicate something is not right with the use case itself).\n **/\nimport { devtools, persist } from 'zustand/middleware'\nimport { createStore as createVanillaStore } from 'zustand/vanilla'\n\nimport {\n\tGetRecord,\n\tGlobalConfig,\n\tMWConfiguration,\n\tSetRecord,\n\tState,\n\tStoreApi,\n\tStorePersist,\n} from '../types'\n\nimport { extendByState } from './extendByState'\nimport { extendGetters } from './extendGetters'\nimport { extendSetters } from './extendSetters'\nimport { generateApiFn } from './generateApiFn'\nimport { generateGetFn } from './generateGetFn'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\nimport { restrictState } from './restrictState'\n\nlet config: GlobalConfig = { appName: 'zustand-lite', logging: false }\n\nexport function setGlobalConfig(newConfig: Partial<GlobalConfig>) {\n\tconfig = { ...config, ...newConfig }\n}\n\nexport function createStore<S extends State, ExtraMW extends MWConfiguration = {}>(\n\tinitialState: S,\n\toptions?: { name?: string; middlewares?: ExtraMW }\n): StoreApi<\n\tS,\n\tGetRecord<S>,\n\tSetRecord<S>,\n\tExtraMW extends { persist: any } ? StorePersist<S> : {}\n> {\n\tconst { name = 'zustand-lite', middlewares = {} as ExtraMW } = options ?? {}\n\n\t// Apply supported middlewares.\n\tlet initializer: any = () => initialState\n\n\tconst persistId = `${config.appName.replace(/\\s/, '-')}.${name}}`\n\tconst shouldLog = config.logging || !!middlewares.devtools\n\n\tif (shouldLog) {\n\t\tinitializer = devtools(initializer, {\n\t\t\tname: config.appName,\n\t\t\tstore: name,\n\t\t\t...(typeof middlewares.devtools === 'object' ? middlewares.devtools : {}),\n\t\t})\n\t}\n\n\tif (middlewares.persist) {\n\t\tinitializer = persist(initializer, {\n\t\t\tname: persistId,\n\t\t\t...(typeof middlewares.persist === 'object' ? middlewares.persist : {}),\n\t\t})\n\t}\n\n\t// Create a vanilla zustand store to wrap.\n\tconst storeLib: any = createVanillaStore(initializer)\n\n\t// Create zustand-lite wrapper.\n\treturn {\n\t\tapi: generateApiFn(storeLib, persistId),\n\t\tget: generateGetFn(storeLib),\n\t\tuse: generateUseFn(storeLib, Object.keys(initialState)),\n\t\tset: generateSetFn(storeLib, Object.keys(initialState), shouldLog),\n\t\tcomposePlugin(plugin) {\n\t\t\treturn plugin(this)\n\t\t},\n\t\textendGetters(builder) {\n\t\t\treturn extendGetters(builder, this, storeLib)\n\t\t},\n\t\textendSetters(builder) {\n\t\t\treturn extendSetters(builder, this, storeLib, shouldLog)\n\t\t},\n\t\textendByState(builder) {\n\t\t\treturn extendByState(builder, this, storeLib, shouldLog)\n\t\t},\n\t\trestrictState(publicState = []) {\n\t\t\treturn restrictState(publicState, initialState, this, storeLib)\n\t\t},\n\t} as any\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { SetRecord, State } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setters like store.set.foo(value)\n *\n * @param lib Zustand api interface\n * @param key Keys to generate setters for\n * @param log If devtools were activated for this store\n */\nexport function generateSetFn<S extends State>(lib: StoreLib<S>, key: string[], log: boolean) {\n\tconst setters: any = generateSetFnBase(lib, log)\n\n\tkey.forEach((key) => {\n\t\tsetters[key] = (value: any) => {\n\t\t\tif (shallow(lib.getState()[key], value)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlib.setState(\n\t\t\t\t(state) => ({ ...state, [key]: value }),\n\t\t\t\tfalse,\n\t\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\t\tlog ? { type: generateSetterName() ?? key, payload: { [key]: value } } : undefined\n\t\t\t)\n\t\t}\n\t})\n\n\treturn setters as SetRecord<S>\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setState function for store like store.set({ value })\n *\n * @param lib Zustand api interface\n * @param log If devtools were activated for this store\n */\nexport function generateSetFnBase<S extends State>(lib: StoreLib<S>, log: boolean) {\n\treturn (updater: S | ((state: S) => S), replace?: boolean, name?: string) => {\n\t\tconst current = lib.getState()\n\t\tconst payload = typeof updater === 'function' ? updater(current) : updater\n\n\t\tif (shallow(current, payload)) {\n\t\t\treturn\n\t\t}\n\n\t\tlib.setState(\n\t\t\tpayload,\n\t\t\treplace,\n\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\tlog ? { type: generateSetterName() ?? name ?? 'setState', payload } : undefined\n\t\t)\n\t}\n}\n","import ErrorStackParser from 'error-stack-parser'\n\n/**\n * Hacky, but working (and possibly only one there is) method of fetching proper caller\n * name of the extended function.\n */\nexport function generateSetterName() {\n\t// Proper setter name should hide at 2nd position in the normalized stack.\n\tconst stack = ErrorStackParser.parse(new Error())\n\tconst index = stack.findIndex((entry) => entry.functionName?.includes('_zustandLiteInferName_'))\n\treturn index - 1 >= 0 ? stack[index - 1].functionName : null\n}\n","export const identity = (arg: any) => arg\nexport const pick = (obj: Record<string, any>, keys: string[]) =>\n\tkeys.reduce<Record<string, any>>((acc, k) => (k in obj ? ((acc[k] = obj[k]), acc) : acc), {})\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\n/**\n * Generates automatic getters like store.use.foo() (recursive steps for each level).\n * Getters are created as side effects.\n *\n * @param state State at nth level\n * @param getters Getters at nth level\n * @param path Property access path at nth level like ['foo', 'bar']\n * @param lib Zustand api interface\n */\nexport function generateUseFnStep(state: any, getters: any, path: string[], lib: any) {\n\tif (typeof state === 'object' && state !== null) {\n\t\tObject.keys(state).forEach((key) => {\n\t\t\tconst newPath = [...path, key]\n\t\t\tObject.defineProperty(getters, key, {\n\t\t\t\tvalue: (equalityFn = shallow) => {\n\t\t\t\t\treturn useStoreWithEqualityFn(\n\t\t\t\t\t\tlib,\n\t\t\t\t\t\t(state) => getFromPath(state, newPath),\n\t\t\t\t\t\tequalityFn\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t})\n\n\t\t\tgenerateUseFnStep(state[key], getters[key], newPath, lib)\n\t\t})\n\t}\n}\n\nfunction getFromPath(state: any, path: string[]) {\n\tlet data = state\n\n\tfor (const key of path) {\n\t\tdata = data[key]\n\t\tif (!data) {\n\t\t\treturn data\n\t\t}\n\t}\n\n\treturn data\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\nimport { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { identity, pick } from '../utils/utils'\n\n/**\n * Generates automatic getters like store.use.foo()\n *\n * @param lib Zustand api interface\n */\nexport function generateUseFnBase<S extends State, U>(lib: StoreLib<S>) {\n\treturn (selector = identity, equality = shallow) => {\n\t\treturn useStoreWithEqualityFn(\n\t\t\tlib,\n\t\t\tArray.isArray(selector) ? (s) => pick(s, selector) : (selector ?? identity),\n\t\t\tequality\n\t\t)\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { pick } from '../utils/utils'\nimport { generateUseFnStep } from './generateUseFnStep'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Generates automatic store hook subscribe function store.use()\n *\n * @param lib Zustand api interface\n * @param key State keys to use\n */\nexport function generateUseFn<S extends State>(lib: StoreLib<S>, key: string[]) {\n\tconst getters = generateUseFnBase(lib)\n\tgenerateUseFnStep(pick(lib.getState(), key), getters, [], lib)\n\treturn getters\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { ByStateBuilder, State, StoreApi } from '../types'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\n\n/**\n * Extends the store by adding new state fields, either by:\n * - passing an object patch: `{ b: 'x' }`\n * - or using a builder: `({ get }) => ({ c: get().b + 'y' })`\n *\n * @param builder Object patch or function producing new state fields.\n * @param api The extended store API before widening.\n * @param lib The underlying Zustand vanilla store.\n * @param log Enables logging for generated setters.\n *\n * @returns The same API instance, but with widened state (via overloads).\n */\nexport function extendByState<\n\tNewData extends State,\n\tOldData extends State,\n\tGetters,\n\tSetters,\n\tBuilder extends ByStateBuilder<NewData, OldData, Getters>,\n>(\n\tbuilder: Builder | NewData,\n\tapi: StoreApi<OldData, Getters, Setters>,\n\tlib: StoreLib<OldData>,\n\tlog: boolean\n) {\n\t// Calculate new state to be added to the store.\n\tconst newState: NewData = typeof builder === 'function' ? builder(api) : builder\n\n\t// Merge the new keys into the zustand state.\n\tlib.setState(newState as unknown as OldData)\n\n\t// Generate basic getters and setters from the newly added record.\n\tapi.use = { ...api.use, ...generateUseFn(lib, Object.keys(newState)) }\n\tapi.set = { ...api.set, ...generateSetFn(lib, Object.keys(newState), log) }\n\n\t// Return the same object, but with widened state type (handled by overloads).\n\treturn api\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GettersBuilder, State, StoreApi } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Adds derived getters to the store.\n *\n * @param builder Function returning new getter methods.\n * @param api Current store API to extend.\n * @param lib Underlying Zustand store.\n */\nexport function extendGetters<\n\tBuilder extends GettersBuilder<S, Getters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\tconst methods: any = builder({ get: api.get })\n\tconst getters: any = {}\n\n\tObject.keys(methods).forEach((key) => {\n\t\tgetters[key] = (...args: any[]) =>\n\t\t\tuseStoreWithEqualityFn(lib, () => methods[key](...args), shallow)\n\t})\n\n\tapi.use = Object.assign(generateUseFnBase(lib), api.use, getters)\n\tapi.get = Object.assign(generateGetFnBase(lib), api.get, methods)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Generates getState function for store.get()\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFnBase<S extends State>(lib: StoreLib<S>) {\n\treturn () => lib.getState()\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { SettersBuilder, State, StoreApi } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\n\n/**\n * Adds custom setter methods to the store.\n *\n * @param builder Function returning new setter methods.\n * @param api Store API to extend.\n * @param lib Underlying Zustand store.\n * @param log Enables optional debug logging.\n */\nexport function extendSetters<\n\tBuilder extends SettersBuilder<S, Getters, Setters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>, log: boolean) {\n\tconst setters = generateSetFnBase(lib, log)\n\tconst baseSet = Object.entries(builder(api)).reduce(\n\t\t(acc, [name, func]) => {\n\t\t\tacc[name] = function _zustandLiteInferName_(...args: any[]) {\n\t\t\t\treturn func(...args)\n\t\t\t}\n\n\t\t\treturn acc\n\t\t},\n\t\t{} as Record<string, any>\n\t)\n\n\tapi.set = Object.assign(setters, api.set, baseSet)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Required to wrap original Zustand interface without getState and setState, which are handled\n * by get and set (we should allow only one way of doing certain things).\n *\n * @param lib Zustand api interface\n * @param key Zustand persist local storage key\n */\nexport function generateApiFn<S extends State>(lib: StoreLib<S>, key: string) {\n\treturn {\n\t\tgetInitialState: lib.getInitialState,\n\t\tgetState: lib.getState,\n\t\tpersist: augmentPersist(lib, key),\n\t\tsetState: lib.setState,\n\t\tsubscribe: lib.subscribe,\n\t}\n}\n\nfunction augmentPersist<S extends State>(lib: StoreLib<S>, key: string) {\n\tif ('persist' in lib) {\n\t\tconst augmented: any = lib.persist\n\t\taugmented.read = () => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(localStorage?.getItem(key) ?? '')?.state\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\n\t\treturn augmented\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\n\n/**\n * Generates getters for store.get. In the past getters were generated as functions, but I\n * came to the conclusion that it's better and simpler to return the whole state.\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFn<S extends State>(lib: StoreLib<S>) {\n\treturn generateGetFnBase(lib)\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GetRecord, SetRecord, State, StoreApi, UseRecord } from '../types'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Function that restrict access to the store and store api.\n *\n * @param privateState Property names to be made private like ['foo', 'bar']\n * @param mergedState Final state of the store\n * @param api Returned store API\n * @param lib Zustand api interface\n */\nexport function restrictState<\n\tS extends State,\n\tKey extends keyof S,\n\tGetters extends GetRecord<any>,\n\tSetters extends SetRecord<any>,\n>(privateState: Key[], mergedState: S, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\treturn {\n\t\tapi: api.api,\n\t\tset: api.set,\n\t\tuse: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getters = Object.keys(api.use).reduce(\n\t\t\t\t\t\t(acc, key) =>\n\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t: { ...acc, [key]: (api.use as UseRecord<any>)[key] },\n\t\t\t\t\t\t{}\n\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(generateUseFnBase(lib), getters)\n\t\t\t\t})()\n\t\t\t: api.use,\n\t\tget: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getFn = () =>\n\t\t\t\t\t\tObject.entries(api.get()).reduce(\n\t\t\t\t\t\t\t(acc, [key, val]) =>\n\t\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t\t: { ...acc, [key]: val },\n\t\t\t\t\t\t\t{}\n\t\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(getFn, api.get)\n\t\t\t\t})()\n\t\t\t: api.get,\n\t}\n}\n","import { definePlugin } from '../lib/definePlugin'\n\n/**\n * Basic plugin example, that extends store with custom setter.\n */\nexport const withReset = definePlugin((store) =>\n\tstore.extendSetters(({ api, set }) => ({\n\t\treset: () => {\n\t\t\tset(api.getInitialState?.() ?? {}, true)\n\t\t},\n\t}))\n)\n"],"mappings":"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","names":["definePlugin","fn","devtools","persist","createVanillaStore","shallow","shallow","ErrorStackParser","generateSetterName","stack","index","entry","generateSetFnBase","lib","log","updater","replace","name","current","payload","shallow","generateSetterName","generateSetFn","lib","key","log","setters","generateSetFnBase","value","shallow","state","generateSetterName","identity","arg","pick","obj","keys","acc","k","shallow","useStoreWithEqualityFn","generateUseFnStep","state","getters","path","lib","key","newPath","equalityFn","getFromPath","data","shallow","useStoreWithEqualityFn","generateUseFnBase","lib","selector","identity","equality","shallow","useStoreWithEqualityFn","s","pick","generateUseFn","lib","key","getters","generateUseFnBase","generateUseFnStep","pick","extendByState","builder","api","lib","log","newState","generateUseFn","generateSetFn","shallow","useStoreWithEqualityFn","generateGetFnBase","lib","extendGetters","builder","api","lib","methods","getters","key","args","useStoreWithEqualityFn","shallow","generateUseFnBase","generateGetFnBase","extendSetters","builder","api","lib","log","setters","generateSetFnBase","baseSet","acc","name","func","args","generateApiFn","lib","key","augmentPersist","augmented","generateGetFn","lib","generateGetFnBase","restrictState","privateState","mergedState","api","lib","getters","acc","key","generateUseFnBase","val","config","setGlobalConfig","newConfig","createStore","initialState","options","name","middlewares","initializer","persistId","shouldLog","devtools","persist","storeLib","createVanillaStore","generateApiFn","generateGetFn","generateUseFn","generateSetFn","plugin","builder","extendGetters","extendSetters","extendByState","publicState","restrictState","withReset","store","api","set"]}
1
+ {"version":3,"sources":["../src/lib/definePlugin.ts","../src/lib/createStore.ts","../src/lib/generateSetFn.ts","../src/lib/generateSetFnBase.ts","../src/lib/generateSetterName.ts","../src/utils/utils.ts","../src/lib/generateUseFnStep.ts","../src/lib/generateUseFnBase.ts","../src/lib/generateUseFn.ts","../src/lib/extendByState.ts","../src/lib/extendGetters.ts","../src/lib/generateGetFnBase.ts","../src/lib/extendSetters.ts","../src/lib/generateApiFn.ts","../src/lib/generateGetFn.ts","../src/lib/restrictState.ts","../src/plugins/reset.ts"],"sourcesContent":["import { State, StoreApi } from '../types'\n\n/**\n * Identity helper that provides a typed `store` param and preserves the plugin's return type.\n */\nexport function definePlugin<F extends (store: StoreApi) => StoreApi>(fn: F) {\n\treturn fn as unknown as <S extends State, G, A, MW>(\n\t\tstore: StoreApi<S, G, A, MW>\n\t) => ReturnType<F>\n}\n","/**\n * Entire no-boilerplate functionality inspired by this recipe:\n * https://docs.pmnd.rs/zustand/guides/auto-generating-selectors.\n * It has few utilities described here: https://www.npmjs.com/package/zustand-lite\n * for:\n * 1) Generating getters for flat state (1-level deep selectors).\n * 2) Generating setters for flat state (1-level deep setters).\n * 3) Automatic devtools messaging.\n * 4) Annotating functions with proper TS types to avoid some bloating and TS frenzy.\n * 5) Extending getters and setters\n * 6) Extending state and restricting state\n * 7) Reuse plugins\n *\n * Idea is to support small store without complicated data reducing (it can be done as well,\n * but may indicate something is not right with the use case itself).\n **/\nimport { devtools, persist } from 'zustand/middleware'\nimport { createStore as createVanillaStore } from 'zustand/vanilla'\n\nimport {\n\tGetRecord,\n\tGlobalConfig,\n\tMWConfiguration,\n\tSetRecord,\n\tState,\n\tStoreApi,\n\tStorePersist,\n} from '../types'\n\nimport { extendByState } from './extendByState'\nimport { extendGetters } from './extendGetters'\nimport { extendSetters } from './extendSetters'\nimport { generateApiFn } from './generateApiFn'\nimport { generateGetFn } from './generateGetFn'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\nimport { restrictState } from './restrictState'\n\nlet config: GlobalConfig = { appName: 'zustand-lite', logging: false }\n\nexport function setGlobalConfig(newConfig: Partial<GlobalConfig>) {\n\tconfig = { ...config, ...newConfig }\n}\n\nexport function createStore<S extends State, ExtraMW extends MWConfiguration = {}>(\n\tinitialState: S,\n\toptions?: { name?: string; middlewares?: ExtraMW }\n): StoreApi<\n\tS,\n\tGetRecord<S>,\n\tSetRecord<S>,\n\tExtraMW extends { persist: any } ? StorePersist<S> : {}\n> {\n\tconst { name = 'zustand-lite', middlewares = {} as ExtraMW } = options ?? {}\n\n\t// Apply supported middlewares.\n\tlet initializer: any = () => initialState\n\n\tconst persistId = `${config.appName.replace(/\\s/, '-')}.${name}}`\n\tconst shouldLog = config.logging || !!middlewares.devtools\n\n\tif (shouldLog) {\n\t\tinitializer = devtools(initializer, {\n\t\t\tname: config.appName,\n\t\t\tstore: name,\n\t\t\t...(typeof middlewares.devtools === 'object' ? middlewares.devtools : {}),\n\t\t})\n\t}\n\n\tif (middlewares.persist) {\n\t\tinitializer = persist(initializer, {\n\t\t\tname: persistId,\n\t\t\t...(typeof middlewares.persist === 'object' ? middlewares.persist : {}),\n\t\t})\n\t}\n\n\t// Create a vanilla zustand store to wrap.\n\tconst storeLib: any = createVanillaStore(initializer)\n\n\t// Create zustand-lite wrapper.\n\treturn {\n\t\tapi: generateApiFn(storeLib, persistId),\n\t\tget: generateGetFn(storeLib),\n\t\tuse: generateUseFn(storeLib, Object.keys(initialState)),\n\t\tset: generateSetFn(storeLib, Object.keys(initialState), shouldLog),\n\t\tcomposePlugin(plugin) {\n\t\t\treturn plugin(this)\n\t\t},\n\t\textendGetters(builder) {\n\t\t\treturn extendGetters(builder, this, storeLib)\n\t\t},\n\t\textendSetters(builder) {\n\t\t\treturn extendSetters(builder, this, storeLib, shouldLog)\n\t\t},\n\t\textendByState(builder) {\n\t\t\treturn extendByState(builder, this, storeLib, shouldLog)\n\t\t},\n\t\trestrictState(publicState = []) {\n\t\t\treturn restrictState(publicState, initialState, this, storeLib)\n\t\t},\n\t} as any\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { SetRecord, State } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setters like store.set.foo(value)\n *\n * @param lib Zustand api interface\n * @param key Keys to generate setters for\n * @param log If devtools were activated for this store\n */\nexport function generateSetFn<S extends State>(lib: StoreLib<S>, key: string[], log: boolean) {\n\tconst setters: any = generateSetFnBase(lib, log)\n\n\tkey.forEach((key) => {\n\t\tsetters[key] = (value: any) => {\n\t\t\tif (shallow(lib.getState()[key], value)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlib.setState(\n\t\t\t\t(state) => ({ ...state, [key]: value }),\n\t\t\t\tfalse,\n\t\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\t\tlog ? { type: generateSetterName() ?? key, payload: { [key]: value } } : undefined\n\t\t\t)\n\t\t}\n\t})\n\n\treturn setters as SetRecord<S>\n}\n","import { shallow } from 'zustand/shallow'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateSetterName } from './generateSetterName'\n\n/**\n * Generates automatic setState function for store like store.set({ value })\n *\n * @param lib Zustand api interface\n * @param log If devtools were activated for this store\n */\nexport function generateSetFnBase<S extends State>(lib: StoreLib<S>, log: boolean) {\n\treturn (updater: S | ((state: S) => S), replace?: boolean, name?: string) => {\n\t\tconst current = lib.getState()\n\t\tconst payload = typeof updater === 'function' ? updater(current) : updater\n\n\t\tif (shallow(current, payload)) {\n\t\t\treturn\n\t\t}\n\n\t\tlib.setState(\n\t\t\tpayload,\n\t\t\treplace,\n\t\t\t// @ts-ignore Additional parameter will have no effect even if logging is disabled.\n\t\t\tlog ? { type: generateSetterName() ?? name ?? 'setState', payload } : undefined\n\t\t)\n\t}\n}\n","import ErrorStackParser from 'error-stack-parser'\n\n/**\n * Hacky, but working (and possibly only one there is) method of fetching proper caller\n * name of the extended function.\n */\nexport function generateSetterName() {\n\t// Proper setter name should hide at 2nd position in the normalized stack.\n\tconst stack = ErrorStackParser.parse(new Error())\n\tconst index = stack.findIndex((entry) => entry.functionName?.includes('_zustandLiteInferName_'))\n\treturn index - 1 >= 0 ? stack[index - 1].functionName : null\n}\n","export const identity = (arg: any) => arg\nexport const pick = (obj: Record<string, any>, keys: string[]) =>\n\tkeys.reduce<Record<string, any>>((acc, k) => (k in obj ? ((acc[k] = obj[k]), acc) : acc), {})\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\n/**\n * Generates automatic getters like store.use.foo() (recursive steps for each level).\n * Getters are created as side effects.\n *\n * @param state State at nth level\n * @param getters Getters at nth level\n * @param path Property access path at nth level like ['foo', 'bar']\n * @param lib Zustand api interface\n */\nexport function generateUseFnStep(state: any, getters: any, path: string[], lib: any) {\n\tif (typeof state === 'object' && state !== null) {\n\t\tObject.keys(state).forEach((key) => {\n\t\t\tconst newPath = [...path, key]\n\t\t\tObject.defineProperty(getters, key, {\n\t\t\t\tvalue: (equalityFn = shallow) => {\n\t\t\t\t\treturn useStoreWithEqualityFn(\n\t\t\t\t\t\tlib,\n\t\t\t\t\t\t(state) => getFromPath(state, newPath),\n\t\t\t\t\t\tequalityFn\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t})\n\n\t\t\tgenerateUseFnStep(state[key], getters[key], newPath, lib)\n\t\t})\n\t}\n}\n\nfunction getFromPath(state: any, path: string[]) {\n\tlet data = state\n\n\tfor (const key of path) {\n\t\tdata = data[key]\n\t\tif (!data) {\n\t\t\treturn data\n\t\t}\n\t}\n\n\treturn data\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\n\nimport { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { identity, pick } from '../utils/utils'\n\n/**\n * Generates automatic getters like store.use.foo()\n *\n * @param lib Zustand api interface\n */\nexport function generateUseFnBase<S extends State, U>(lib: StoreLib<S>) {\n\treturn (selector = identity, equality = shallow) => {\n\t\treturn useStoreWithEqualityFn(\n\t\t\tlib,\n\t\t\tArray.isArray(selector) ? (s) => pick(s, selector) : (selector ?? identity),\n\t\t\tequality\n\t\t)\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand'\n\nimport { State } from '../types'\nimport { pick } from '../utils/utils'\nimport { generateUseFnStep } from './generateUseFnStep'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Generates automatic store hook subscribe function store.use()\n *\n * @param lib Zustand api interface\n * @param key State keys to use\n */\nexport function generateUseFn<S extends State>(lib: StoreLib<S>, key: string[]) {\n\tconst getters = generateUseFnBase(lib)\n\tgenerateUseFnStep(pick(lib.getState(), key), getters, [], lib)\n\treturn getters\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { ByStateBuilder, State, StoreApi } from '../types'\nimport { generateSetFn } from './generateSetFn'\nimport { generateUseFn } from './generateUseFn'\n\n/**\n * Extends the store by adding new state fields, either by:\n * - passing an object patch: `{ b: 'x' }`\n * - or using a builder: `({ get }) => ({ c: get().b + 'y' })`\n *\n * @param builder Object patch or function producing new state fields.\n * @param api The extended store API before widening.\n * @param lib The underlying Zustand vanilla store.\n * @param log Enables logging for generated setters.\n *\n * @returns The same API instance, but with widened state (via overloads).\n */\nexport function extendByState<\n\tNewData extends State,\n\tOldData extends State,\n\tGetters,\n\tSetters,\n\tBuilder extends ByStateBuilder<NewData, OldData, Getters>,\n>(\n\tbuilder: Builder | NewData,\n\tapi: StoreApi<OldData, Getters, Setters>,\n\tlib: StoreLib<OldData>,\n\tlog: boolean\n) {\n\t// Calculate new state to be added to the store.\n\tconst newState: NewData = typeof builder === 'function' ? builder(api) : builder\n\n\t// Merge the new keys into the zustand state in such a way that the old keys are preserved.\n\tlib.setState({ ...newState, ...lib.getState() })\n\n\t// Generate basic getters and setters from the newly added record.\n\tapi.use = { ...api.use, ...generateUseFn(lib, Object.keys(newState)) }\n\tapi.set = { ...api.set, ...generateSetFn(lib, Object.keys(newState), log) }\n\n\t// Return the same object, but with widened state type (handled by overloads).\n\treturn api\n}\n","import { shallow } from 'zustand/shallow'\nimport { useStoreWithEqualityFn } from 'zustand/traditional'\nimport { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GettersBuilder, State, StoreApi, UseGetterOptions } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Type guard to check if a value is an equality options object.\n * Detects plain objects with an `eq` property that is a function.\n */\nfunction isEqualityOptions<R>(value: unknown): value is UseGetterOptions<R> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t'eq' in value &&\n\t\ttypeof (value as any).eq === 'function'\n\t)\n}\n\n/**\n * Adds derived getters to the store.\n *\n * @param builder Function returning new getter methods.\n * @param api Current store API to extend.\n * @param lib Underlying Zustand store.\n */\nexport function extendGetters<\n\tBuilder extends GettersBuilder<S, Getters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\tconst methods: any = builder({ get: api.get })\n\tconst getters: any = {}\n\n\tObject.keys(methods).forEach((key) => {\n\t\tgetters[key] = (...args: any[]) => {\n\t\t\t// Check if the last argument is an equality options object\n\t\t\tconst lastArg = args[args.length - 1]\n\t\t\tif (isEqualityOptions(lastArg)) {\n\t\t\t\tconst actualArgs = args.slice(0, -1)\n\t\t\t\treturn useStoreWithEqualityFn(lib, () => methods[key](...actualArgs), lastArg.eq)\n\t\t\t}\n\t\t\treturn useStoreWithEqualityFn(lib, () => methods[key](...args), shallow)\n\t\t}\n\t})\n\n\tapi.use = Object.assign(generateUseFnBase(lib), api.use, getters)\n\tapi.get = Object.assign(generateGetFnBase(lib), api.get, methods)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Generates getState function for store.get()\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFnBase<S extends State>(lib: StoreLib<S>) {\n\treturn () => lib.getState()\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\nimport { SettersBuilder, State, StoreApi } from '../types'\nimport { generateSetFnBase } from './generateSetFnBase'\n\n/**\n * Adds custom setter methods to the store.\n *\n * @param builder Function returning new setter methods.\n * @param api Store API to extend.\n * @param lib Underlying Zustand store.\n * @param log Enables optional debug logging.\n */\nexport function extendSetters<\n\tBuilder extends SettersBuilder<S, Getters, Setters>,\n\tS extends State,\n\tGetters,\n\tSetters,\n>(builder: Builder, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>, log: boolean) {\n\tconst setters = generateSetFnBase(lib, log)\n\tconst baseSet = Object.entries(builder(api)).reduce(\n\t\t(acc, [name, func]) => {\n\t\t\tacc[name] = function _zustandLiteInferName_(...args: any[]) {\n\t\t\t\treturn func(...args)\n\t\t\t}\n\n\t\t\treturn acc\n\t\t},\n\t\t{} as Record<string, any>\n\t)\n\n\tapi.set = Object.assign(setters, api.set, baseSet)\n\treturn api\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\n\n/**\n * Required to wrap original Zustand interface without getState and setState, which are handled\n * by get and set (we should allow only one way of doing certain things).\n *\n * @param lib Zustand api interface\n * @param key Zustand persist local storage key\n */\nexport function generateApiFn<S extends State>(lib: StoreLib<S>, key: string) {\n\treturn {\n\t\tgetInitialState: lib.getInitialState,\n\t\tgetState: lib.getState,\n\t\tpersist: augmentPersist(lib, key),\n\t\tsetState: lib.setState,\n\t\tsubscribe: lib.subscribe,\n\t}\n}\n\nfunction augmentPersist<S extends State>(lib: StoreLib<S>, key: string) {\n\tif ('persist' in lib) {\n\t\tconst augmented: any = lib.persist\n\t\taugmented.read = () => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(localStorage?.getItem(key) ?? '')?.state\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\n\t\treturn augmented\n\t}\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { State } from '../types'\nimport { generateGetFnBase } from './generateGetFnBase'\n\n/**\n * Generates getters for store.get. In the past getters were generated as functions, but I\n * came to the conclusion that it's better and simpler to return the whole state.\n *\n * @param lib Zustand api interface\n */\nexport function generateGetFn<S extends State>(lib: StoreLib<S>) {\n\treturn generateGetFnBase(lib)\n}\n","import { StoreApi as StoreLib } from 'zustand/vanilla'\n\nimport { GetRecord, SetRecord, State, StoreApi, UseRecord } from '../types'\nimport { generateUseFnBase } from './generateUseFnBase'\n\n/**\n * Function that restrict access to the store and store api.\n *\n * @param privateState Property names to be made private like ['foo', 'bar']\n * @param mergedState Final state of the store\n * @param api Returned store API\n * @param lib Zustand api interface\n */\nexport function restrictState<\n\tS extends State,\n\tKey extends keyof S,\n\tGetters extends GetRecord<any>,\n\tSetters extends SetRecord<any>,\n>(privateState: Key[], mergedState: S, api: StoreApi<S, Getters, Setters>, lib: StoreLib<S>) {\n\treturn {\n\t\tapi: api.api,\n\t\tset: api.set,\n\t\tuse: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getters = Object.keys(api.use).reduce(\n\t\t\t\t\t\t(acc, key) =>\n\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t: { ...acc, [key]: (api.use as UseRecord<any>)[key] },\n\t\t\t\t\t\t{}\n\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(generateUseFnBase(lib), getters)\n\t\t\t\t})()\n\t\t\t: api.use,\n\t\tget: privateState\n\t\t\t? (() => {\n\t\t\t\t\tconst getFn = () =>\n\t\t\t\t\t\tObject.entries(api.get()).reduce(\n\t\t\t\t\t\t\t(acc, [key, val]) =>\n\t\t\t\t\t\t\t\tmergedState[key] && (privateState as string[]).includes(key)\n\t\t\t\t\t\t\t\t\t? acc\n\t\t\t\t\t\t\t\t\t: { ...acc, [key]: val },\n\t\t\t\t\t\t\t{}\n\t\t\t\t\t\t)\n\n\t\t\t\t\treturn Object.assign(getFn, api.get)\n\t\t\t\t})()\n\t\t\t: api.get,\n\t}\n}\n","import { definePlugin } from '../lib/definePlugin'\n\n/**\n * Basic plugin example, that extends store with custom setter.\n */\nexport const withReset = definePlugin((store) =>\n\tstore.extendSetters(({ api, set }) => ({\n\t\treset: () => {\n\t\t\tset(api.getInitialState?.() ?? {}, true)\n\t\t},\n\t}))\n)\n"],"mappings":"AAKO,SAASA,EAAsDC,EAAO,CAC5E,OAAOA,CAGR,CCOA,OAAS,YAAAC,EAAU,WAAAC,MAAe,qBAClC,OAAS,eAAeC,MAA0B,kBCjBlD,OAAS,WAAAC,MAAe,kBCAxB,OAAS,WAAAC,MAAe,kBCAxB,OAAOC,MAAsB,qBAMtB,SAASC,GAAqB,CAEpC,IAAMC,EAAQF,EAAiB,MAAM,IAAI,KAAO,EAC1CG,EAAQD,EAAM,UAAWE,GAAUA,EAAM,cAAc,SAAS,wBAAwB,CAAC,EAC/F,OAAOD,EAAQ,GAAK,EAAID,EAAMC,EAAQ,CAAC,EAAE,aAAe,IACzD,CDCO,SAASE,EAAmCC,EAAkBC,EAAc,CAClF,MAAO,CAACC,EAAgCC,EAAmBC,IAAkB,CAC5E,IAAMC,EAAUL,EAAI,SAAS,EACvBM,EAAU,OAAOJ,GAAY,WAAaA,EAAQG,CAAO,EAAIH,EAE/DK,EAAQF,EAASC,CAAO,GAI5BN,EAAI,SACHM,EACAH,EAEAF,EAAM,CAAE,KAAMO,EAAmB,GAAKJ,GAAQ,WAAY,QAAAE,CAAQ,EAAI,MACvE,CACD,CACD,CDdO,SAASG,EAA+BC,EAAkBC,EAAeC,EAAc,CAC7F,IAAMC,EAAeC,EAAkBJ,EAAKE,CAAG,EAE/C,OAAAD,EAAI,QAASA,GAAQ,CACpBE,EAAQF,CAAG,EAAKI,GAAe,CAC1BC,EAAQN,EAAI,SAAS,EAAEC,CAAG,EAAGI,CAAK,GAItCL,EAAI,SACFO,IAAW,CAAE,GAAGA,EAAO,CAACN,CAAG,EAAGI,CAAM,GACrC,GAEAH,EAAM,CAAE,KAAMM,EAAmB,GAAKP,EAAK,QAAS,CAAE,CAACA,CAAG,EAAGI,CAAM,CAAE,EAAI,MAC1E,CACD,CACD,CAAC,EAEMF,CACR,CGjCO,IAAMM,EAAYC,GAAaA,EACzBC,EAAO,CAACC,EAA0BC,IAC9CA,EAAK,OAA4B,CAACC,EAAKC,KAAOA,KAAKH,IAAQE,EAAIC,CAAC,EAAIH,EAAIG,CAAC,GAAID,GAAa,CAAC,CAAC,ECF7F,OAAS,WAAAE,MAAe,kBACxB,OAAS,0BAAAC,MAA8B,sBAWhC,SAASC,EAAkBC,EAAYC,EAAcC,EAAgBC,EAAU,CACjF,OAAOH,GAAU,UAAYA,IAAU,MAC1C,OAAO,KAAKA,CAAK,EAAE,QAASI,GAAQ,CACnC,IAAMC,EAAU,CAAC,GAAGH,EAAME,CAAG,EAC7B,OAAO,eAAeH,EAASG,EAAK,CACnC,MAAO,CAACE,EAAaT,IACbC,EACNK,EACCH,GAAUO,EAAYP,EAAOK,CAAO,EACrCC,CACD,EAED,SAAU,GACV,aAAc,GACd,WAAY,EACb,CAAC,EAEDP,EAAkBC,EAAMI,CAAG,EAAGH,EAAQG,CAAG,EAAGC,EAASF,CAAG,CACzD,CAAC,CAEH,CAEA,SAASI,EAAYP,EAAYE,EAAgB,CAChD,IAAIM,EAAOR,EAEX,QAAWI,KAAOF,EAEjB,GADAM,EAAOA,EAAKJ,CAAG,EACX,CAACI,EACJ,OAAOA,EAIT,OAAOA,CACR,CC7CA,OAAS,WAAAC,MAAe,kBACxB,OAAS,0BAAAC,MAA8B,sBAYhC,SAASC,EAAsCC,EAAkB,CACvE,MAAO,CAACC,EAAWC,EAAUC,EAAWC,IAChCC,EACNL,EACA,MAAM,QAAQC,CAAQ,EAAKK,GAAMC,EAAKD,EAAGL,CAAQ,EAAKA,GAAYC,EAClEC,CACD,CAEF,CCRO,SAASK,EAA+BC,EAAkBC,EAAe,CAC/E,IAAMC,EAAUC,EAAkBH,CAAG,EACrC,OAAAI,EAAkBC,EAAKL,EAAI,SAAS,EAAGC,CAAG,EAAGC,EAAS,CAAC,EAAGF,CAAG,EACtDE,CACR,CCAO,SAASI,EAOfC,EACAC,EACAC,EACAC,EACC,CAED,IAAMC,EAAoB,OAAOJ,GAAY,WAAaA,EAAQC,CAAG,EAAID,EAGzE,OAAAE,EAAI,SAAS,CAAE,GAAGE,EAAU,GAAGF,EAAI,SAAS,CAAE,CAAC,EAG/CD,EAAI,IAAM,CAAE,GAAGA,EAAI,IAAK,GAAGI,EAAcH,EAAK,OAAO,KAAKE,CAAQ,CAAC,CAAE,EACrEH,EAAI,IAAM,CAAE,GAAGA,EAAI,IAAK,GAAGK,EAAcJ,EAAK,OAAO,KAAKE,CAAQ,EAAGD,CAAG,CAAE,EAGnEF,CACR,CCzCA,OAAS,WAAAM,MAAe,kBACxB,OAAS,0BAAAC,MAA8B,sBCQhC,SAASC,EAAmCC,EAAkB,CACpE,MAAO,IAAMA,EAAI,SAAS,CAC3B,CDCA,SAASC,EAAqBC,EAA8C,CAC3E,OACC,OAAOA,GAAU,UACjBA,IAAU,MACV,OAAQA,GACR,OAAQA,EAAc,IAAO,UAE/B,CASO,SAASC,EAKdC,EAAkBC,EAAoCC,EAAkB,CACzE,IAAMC,EAAeH,EAAQ,CAAE,IAAKC,EAAI,GAAI,CAAC,EACvCG,EAAe,CAAC,EAEtB,cAAO,KAAKD,CAAO,EAAE,QAASE,GAAQ,CACrCD,EAAQC,CAAG,EAAI,IAAIC,IAAgB,CAElC,IAAMC,EAAUD,EAAKA,EAAK,OAAS,CAAC,EACpC,GAAIT,EAAkBU,CAAO,EAAG,CAC/B,IAAMC,EAAaF,EAAK,MAAM,EAAG,EAAE,EACnC,OAAOG,EAAuBP,EAAK,IAAMC,EAAQE,CAAG,EAAE,GAAGG,CAAU,EAAGD,EAAQ,EAAE,CACjF,CACA,OAAOE,EAAuBP,EAAK,IAAMC,EAAQE,CAAG,EAAE,GAAGC,CAAI,EAAGI,CAAO,CACxE,CACD,CAAC,EAEDT,EAAI,IAAM,OAAO,OAAOU,EAAkBT,CAAG,EAAGD,EAAI,IAAKG,CAAO,EAChEH,EAAI,IAAM,OAAO,OAAOW,EAAkBV,CAAG,EAAGD,EAAI,IAAKE,CAAO,EACzDF,CACR,CExCO,SAASY,EAKdC,EAAkBC,EAAoCC,EAAkBC,EAAc,CACvF,IAAMC,EAAUC,EAAkBH,EAAKC,CAAG,EACpCG,EAAU,OAAO,QAAQN,EAAQC,CAAG,CAAC,EAAE,OAC5C,CAACM,EAAK,CAACC,EAAMC,CAAI,KAChBF,EAAIC,CAAI,EAAI,YAAmCE,EAAa,CAC3D,OAAOD,EAAK,GAAGC,CAAI,CACpB,EAEOH,GAER,CAAC,CACF,EAEA,OAAAN,EAAI,IAAM,OAAO,OAAOG,EAASH,EAAI,IAAKK,CAAO,EAC1CL,CACR,CCrBO,SAASU,EAA+BC,EAAkBC,EAAa,CAC7E,MAAO,CACN,gBAAiBD,EAAI,gBACrB,SAAUA,EAAI,SACd,QAASE,EAAeF,EAAKC,CAAG,EAChC,SAAUD,EAAI,SACd,UAAWA,EAAI,SAChB,CACD,CAEA,SAASE,EAAgCF,EAAkBC,EAAa,CACvE,GAAI,YAAaD,EAAK,CACrB,IAAMG,EAAiBH,EAAI,QAC3B,OAAAG,EAAU,KAAO,IAAM,CACtB,GAAI,CACH,OAAO,KAAK,MAAM,cAAc,QAAQF,CAAG,GAAK,EAAE,GAAG,KACtD,MAAQ,CACP,MACD,CACD,EAEOE,CACR,CACD,CCvBO,SAASC,EAA+BC,EAAkB,CAChE,OAAOC,EAAkBD,CAAG,CAC7B,CCAO,SAASE,EAKdC,EAAqBC,EAAgBC,EAAoCC,EAAkB,CAC5F,MAAO,CACN,IAAKD,EAAI,IACT,IAAKA,EAAI,IACT,IAAKF,GACD,IAAM,CACP,IAAMI,EAAU,OAAO,KAAKF,EAAI,GAAG,EAAE,OACpC,CAACG,EAAKC,IACLL,EAAYK,CAAG,GAAMN,EAA0B,SAASM,CAAG,EACxDD,EACA,CAAE,GAAGA,EAAK,CAACC,CAAG,EAAIJ,EAAI,IAAuBI,CAAG,CAAE,EACtD,CAAC,CACF,EAEA,OAAO,OAAO,OAAOC,EAAkBJ,CAAG,EAAGC,CAAO,CACrD,GAAG,EACFF,EAAI,IACP,IAAKF,EAWK,OAAO,OATA,IACb,OAAO,QAAQE,EAAI,IAAI,CAAC,EAAE,OACzB,CAACG,EAAK,CAACC,EAAKE,CAAG,IACdP,EAAYK,CAAG,GAAMN,EAA0B,SAASM,CAAG,EACxDD,EACA,CAAE,GAAGA,EAAK,CAACC,CAAG,EAAGE,CAAI,EACzB,CAAC,CACF,EAE2BN,EAAI,GAAG,EAEnCA,EAAI,GACR,CACD,CdZA,IAAIO,EAAuB,CAAE,QAAS,eAAgB,QAAS,EAAM,EAE9D,SAASC,EAAgBC,EAAkC,CACjEF,EAAS,CAAE,GAAGA,EAAQ,GAAGE,CAAU,CACpC,CAEO,SAASC,EACfC,EACAC,EAMC,CACD,GAAM,CAAE,KAAAC,EAAO,eAAgB,YAAAC,EAAc,CAAC,CAAa,EAAIF,GAAW,CAAC,EAGvEG,EAAmB,IAAMJ,EAEvBK,EAAY,GAAGT,EAAO,QAAQ,QAAQ,KAAM,GAAG,CAAC,IAAIM,CAAI,IACxDI,EAAYV,EAAO,SAAW,CAAC,CAACO,EAAY,SAE9CG,IACHF,EAAcG,EAASH,EAAa,CACnC,KAAMR,EAAO,QACb,MAAOM,EACP,GAAI,OAAOC,EAAY,UAAa,SAAWA,EAAY,SAAW,CAAC,CACxE,CAAC,GAGEA,EAAY,UACfC,EAAcI,EAAQJ,EAAa,CAClC,KAAMC,EACN,GAAI,OAAOF,EAAY,SAAY,SAAWA,EAAY,QAAU,CAAC,CACtE,CAAC,GAIF,IAAMM,EAAgBC,EAAmBN,CAAW,EAGpD,MAAO,CACN,IAAKO,EAAcF,EAAUJ,CAAS,EACtC,IAAKO,EAAcH,CAAQ,EAC3B,IAAKI,EAAcJ,EAAU,OAAO,KAAKT,CAAY,CAAC,EACtD,IAAKc,EAAcL,EAAU,OAAO,KAAKT,CAAY,EAAGM,CAAS,EACjE,cAAcS,EAAQ,CACrB,OAAOA,EAAO,IAAI,CACnB,EACA,cAAcC,EAAS,CACtB,OAAOC,EAAcD,EAAS,KAAMP,CAAQ,CAC7C,EACA,cAAcO,EAAS,CACtB,OAAOE,EAAcF,EAAS,KAAMP,EAAUH,CAAS,CACxD,EACA,cAAcU,EAAS,CACtB,OAAOG,EAAcH,EAAS,KAAMP,EAAUH,CAAS,CACxD,EACA,cAAcc,EAAc,CAAC,EAAG,CAC/B,OAAOC,EAAcD,EAAapB,EAAc,KAAMS,CAAQ,CAC/D,CACD,CACD,CehGO,IAAMa,EAA0BC,GACtCA,EAAM,cAAc,CAAC,CAAE,IAAAC,EAAK,IAAAC,CAAI,KAAO,CACtC,MAAO,IAAM,CACZA,EAAID,EAAI,kBAAkB,GAAK,CAAC,EAAG,EAAI,CACxC,CACD,EAAE","names":["definePlugin","fn","devtools","persist","createVanillaStore","shallow","shallow","ErrorStackParser","generateSetterName","stack","index","entry","generateSetFnBase","lib","log","updater","replace","name","current","payload","shallow","generateSetterName","generateSetFn","lib","key","log","setters","generateSetFnBase","value","shallow","state","generateSetterName","identity","arg","pick","obj","keys","acc","k","shallow","useStoreWithEqualityFn","generateUseFnStep","state","getters","path","lib","key","newPath","equalityFn","getFromPath","data","shallow","useStoreWithEqualityFn","generateUseFnBase","lib","selector","identity","equality","shallow","useStoreWithEqualityFn","s","pick","generateUseFn","lib","key","getters","generateUseFnBase","generateUseFnStep","pick","extendByState","builder","api","lib","log","newState","generateUseFn","generateSetFn","shallow","useStoreWithEqualityFn","generateGetFnBase","lib","isEqualityOptions","value","extendGetters","builder","api","lib","methods","getters","key","args","lastArg","actualArgs","useStoreWithEqualityFn","shallow","generateUseFnBase","generateGetFnBase","extendSetters","builder","api","lib","log","setters","generateSetFnBase","baseSet","acc","name","func","args","generateApiFn","lib","key","augmentPersist","augmented","generateGetFn","lib","generateGetFnBase","restrictState","privateState","mergedState","api","lib","getters","acc","key","generateUseFnBase","val","config","setGlobalConfig","newConfig","createStore","initialState","options","name","middlewares","initializer","persistId","shouldLog","devtools","persist","storeLib","createVanillaStore","generateApiFn","generateGetFn","generateUseFn","generateSetFn","plugin","builder","extendGetters","extendSetters","extendByState","publicState","restrictState","withReset","store","api","set"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zustand-lite",
3
- "version": "0.7.2",
3
+ "version": "1.0.0",
4
4
  "description": "Zustand Lite builds upon zustand, by auto-generating selectors and simplifying API even more.",
5
5
  "author": "Piotr Siatkowski <p.siatkowski@gmail.com>",
6
6
  "license": "MIT",