dev-react-microstore 5.0.0 → 6.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,287 +1,254 @@
1
- # react-microstore
1
+ # dev-react-microstore
2
2
 
3
- A minimal global state manager for React with fine-grained subscriptions.
3
+ Probably the fastest store library ever created for React.
4
+
5
+ A minimal, zero-dependency global state manager with fine-grained subscriptions, full TypeScript inference, and a tiny footprint (< 2KB minified).
4
6
 
5
7
  ## Installation
6
8
 
7
9
  ```bash
8
- npm install react-microstore
10
+ npm install dev-react-microstore
9
11
  ```
10
12
 
11
- ## Basic Usage
13
+ ## Quick Start
12
14
 
13
15
  ```tsx
14
- import { createStoreState, useStoreSelector } from 'react-microstore';
16
+ import { createStoreState, createSelectorHook } from 'dev-react-microstore';
17
+
18
+ const store = createStoreState({
19
+ count: 0,
20
+ user: { name: 'Alice', age: 30 },
21
+ });
15
22
 
16
- const counterStore = createStoreState({ count: 0 });
23
+ export const useStore = createSelectorHook(store);
17
24
 
18
25
  function Counter() {
19
- const { count } = useStoreSelector(counterStore, ['count']);
20
-
21
- return (
22
- <div>
23
- <p>{count}</p>
24
- <button onClick={() => counterStore.set({ count: count + 1 })}>
25
- Increment
26
- </button>
27
- </div>
28
- );
26
+ const { count } = useStore(['count']);
27
+ return <button onClick={() => store.setKey('count', count + 1)}>{count}</button>;
29
28
  }
30
29
  ```
31
30
 
32
- ## Middleware Support
31
+ One line to create the hook, all types inferred from the store instance — no manual generics.
33
32
 
34
- Add Express-style middleware to intercept and control state updates:
33
+ ## API
35
34
 
36
- ```tsx
37
- const store = createStoreState({ count: 0, user: null });
35
+ ### `createStoreState(initialState)`
38
36
 
39
- // Validation middleware - can block updates
40
- store.addMiddleware(
41
- (currentState, update, next) => {
42
- if (update.count !== undefined && update.count < 0) {
43
- // Don't call next() to block the update
44
- console.log('Blocked negative count');
45
- return;
46
- }
47
- next(); // Allow the update
48
- },
49
- ['count'] // Only run for count updates
50
- );
37
+ Creates a reactive store. Returns:
51
38
 
52
- // Transform middleware - can modify updates
53
- store.addMiddleware(
54
- (currentState, update, next) => {
55
- if (update.user?.name) {
56
- const modifiedUpdate = {
57
- ...update,
58
- user: {
59
- ...update.user,
60
- name: update.user.name.trim().toLowerCase()
61
- }
62
- };
63
- next(modifiedUpdate); // Pass modified update
64
- } else {
65
- next(); // Pass original update
66
- }
67
- }
68
- );
39
+ | Method | Description |
40
+ |--------|-------------|
41
+ | `get()` | Returns the full state object |
42
+ | `getKey(key)` | Returns the value of a single key |
43
+ | `set(partial)` | Partially updates state. Middleware runs, listeners fire for changed keys only |
44
+ | `setKey(key, value)` | Sets a single key |
45
+ | `merge(key, partial)` | **Pure read** — returns `{ ...state[key], ...partial }` without writing. Type-safe: only works on object-valued keys |
46
+ | `mergeSet(key, partial)` | `merge` + `set` — shallow-merges and writes. Middleware & listeners fire as normal |
47
+ | `reset(keys?)` | Resets keys to their initial values. No args = full reset |
48
+ | `batch(fn)` | Groups multiple `set`/`setKey`/`mergeSet` calls — listeners fire once at the end |
49
+ | `subscribe(keys, listener)` | Fine-grained subscription. Returns unsubscribe function |
50
+ | `select(keys)` | Returns a `Pick<T, K>` snapshot of specific keys |
51
+ | `onChange(keys, callback)` | Non-React listener with `(newValues, prevValues)` — batched per microtask |
52
+ | `addMiddleware(fn, keys?)` | Express-style middleware to intercept, block, or transform updates |
53
+ | `skipSetWhen(key, fn)` | Skip updates for a key when `fn(prev, next)` returns `true`. Runs after `Object.is` |
54
+ | `removeSkipSetWhen(key)` | Remove the skip condition, restoring default `Object.is` behavior |
69
55
 
70
- // Logging middleware
71
- store.addMiddleware(
72
- (currentState, update, next) => {
73
- console.log('Processing update:', update);
74
- next(); // Continue
75
- }
76
- );
77
- ```
56
+ ### `createSelectorHook(store)`
78
57
 
79
- ## Persistence
58
+ Returns a pre-bound React hook with full type inference:
59
+
60
+ ```tsx
61
+ const useStore = createSelectorHook(store);
80
62
 
81
- The store supports automatic state persistence using middleware with per-key storage:
63
+ // In a component types are inferred, no generics needed
64
+ const { user } = useStore(['user']);
65
+ // user is { name: string; age: number }
66
+ ```
82
67
 
83
- ```typescript
84
- import { createStoreState, createPersistenceMiddleware, loadPersistedState } from '@ohad/react-microstore'
68
+ ### `useStoreSelector(store, selector)`
85
69
 
86
- // Load persisted state during initialization
87
- const persistedState = loadPersistedState<AppState>(
88
- localStorage,
89
- 'my-app-state',
90
- ['theme', 'userName', 'isLoggedIn']
91
- );
70
+ Low-level React hook. Prefer `createSelectorHook` for cleaner usage.
92
71
 
93
- // Create store with merged initial + persisted state
94
- const store = createStoreState<AppState>({
95
- theme: 'light',
96
- userName: '',
97
- isLoggedIn: false,
98
- tempData: { cache: [] },
99
- ...persistedState // Apply persisted values
100
- });
72
+ ## merge vs mergeSet
101
73
 
102
- // Add persistence middleware - saves each key individually
103
- store.addMiddleware(
104
- createPersistenceMiddleware(localStorage, 'my-app-state', ['theme', 'userName', 'isLoggedIn'])
105
- );
74
+ `merge` is a pure read helper it returns the merged object without touching the store:
75
+
76
+ ```tsx
77
+ const updated = store.merge('user', { age: 31 });
78
+ // updated = { name: 'Alice', age: 31 }
79
+ // store is unchanged
106
80
  ```
107
81
 
108
- **Key benefits:**
82
+ `mergeSet` writes it:
109
83
 
110
- ✅ **Per-key storage** - Each key stored separately (e.g., `my-app-state:theme`, `my-app-state:userName`)
111
- **Efficient writes** - Only writes to storage when specified keys actually change
112
- **No state blobs** - Avoids serializing/storing entire state objects
113
- ✅ **Composable** - Uses the same middleware system as validation/logging
114
- ✅ **Flexible** - Easy to swap storage backends or add custom logic
84
+ ```tsx
85
+ store.mergeSet('user', { age: 31 });
86
+ // store.user is now { name: 'Alice', age: 31 }
87
+ ```
115
88
 
116
- ## Debouncing
89
+ Both are type-safe — calling on a primitive key (e.g. `merge('count', ...)`) is a compile error.
117
90
 
118
- Control when updates are applied:
91
+ ## Batching
92
+
93
+ Group multiple updates so listeners fire once:
119
94
 
120
95
  ```tsx
121
- // Debounce updates for 300ms
122
- store.set({ searchQuery: 'new value' }, 300);
96
+ store.batch(() => {
97
+ store.setKey('count', 10);
98
+ store.mergeSet('user', { age: 25 });
99
+ store.setKey('name', 'Bob');
100
+ });
101
+ // Listeners fire once with all changes
102
+ ```
103
+
104
+ ## reset
123
105
 
124
- // Or use boolean for default debounce (0ms)
125
- store.set({ count: count + 1 }, true);
106
+ ```tsx
107
+ store.reset(); // Full reset to initial state
108
+ store.reset(['count']); // Reset specific keys
126
109
  ```
127
110
 
128
- ## Custom Comparison Function
111
+ ## Middleware
112
+
113
+ Express-style middleware to intercept, block, or transform updates:
129
114
 
130
115
  ```tsx
131
- import { createStoreState, useStoreSelector } from 'react-microstore';
132
-
133
- const taskStore = createStoreState({
134
- tasks: [
135
- { id: 1, title: 'Learn React', completed: false, priority: 'high' },
136
- { id: 2, title: 'Build app', completed: false, priority: 'medium' }
137
- ],
138
- filters: {
139
- showCompleted: true,
140
- priorityFilter: null
116
+ // Validation block negative counts
117
+ store.addMiddleware(
118
+ (state, update, next) => {
119
+ if (update.count !== undefined && update.count < 0) return;
120
+ next();
121
+ },
122
+ ['count']
123
+ );
124
+
125
+ // Transform — normalize user input
126
+ store.addMiddleware((state, update, next) => {
127
+ if (update.user?.name) {
128
+ next({ ...update, user: { ...update.user, name: update.user.name.trim() } });
129
+ } else {
130
+ next();
141
131
  }
142
132
  });
143
133
 
144
- function TaskList() {
145
- // Only re-render when task completion status changes
146
- const { tasks } = useStoreSelector(taskStore, [
147
- {
148
- tasks: (prev, next) =>
149
- !prev.some((task, i) => task.id === next?.[i]?.id && task.completed !== next[i].completed)
150
- }
151
- ]);
152
-
153
- const toggleTask = (id) => {
154
- const currentTasks = taskStore.get().tasks;
155
- const updatedTasks = currentTasks.map(task =>
156
- task.id === id ? { ...task, completed: !task.completed } : task
157
- );
158
-
159
- taskStore.set({ tasks: updatedTasks });
160
- };
161
-
162
- return (
163
- <ul>
164
- {tasks.map(task => (
165
- <li key={task.id}>
166
- {task.title} - {task.completed ? 'Done' : 'Pending'}
167
- <button onClick={() => toggleTask(task.id)}>
168
- Toggle
169
- </button>
170
- </li>
171
- ))}
172
- </ul>
173
- );
174
- }
134
+ // Logging
135
+ store.addMiddleware((state, update, next) => {
136
+ console.log('Update:', update);
137
+ next();
138
+ });
175
139
  ```
176
140
 
177
- ## Example of setting store from outside components
141
+ No-middleware fast path: when no middleware is registered, `set()` skips the pipeline entirely.
142
+
143
+ ## Persistence
144
+
145
+ Built-in middleware for automatic state persistence. Supports both sync (`localStorage`) and async (`AsyncStorage`) backends:
178
146
 
179
147
  ```tsx
180
- import { createStoreState, useStoreSelector } from 'react-microstore';
148
+ import { createStoreState, createPersistenceMiddleware, loadPersistedState } from 'dev-react-microstore';
181
149
 
182
- // Create store
183
- const userStore = createStoreState({
184
- user: null,
185
- isLoading: false,
186
- error: null
187
- });
150
+ // Sync (localStorage / sessionStorage)
151
+ const persisted = loadPersistedState<AppState>(localStorage, 'app', ['theme', 'user']);
188
152
 
189
- // Function to update store from anywhere
190
- export async function fetchUserData(userId) {
191
- // Update loading state
192
- userStore.set({ isLoading: true, error: null });
193
-
194
- try {
195
- // API call
196
- const response = await fetch(`/api/users/${userId}`);
197
- const userData = await response.json();
198
-
199
- // Update store with fetched data
200
- userStore.set({
201
- user: userData,
202
- isLoading: false
203
- });
204
-
205
- return userData;
206
- } catch (error) {
207
- // Update store with error
208
- userStore.set({
209
- error: error.message,
210
- isLoading: false
211
- });
212
-
213
- throw error;
214
- }
215
- }
153
+ const store = createStoreState<AppState>({ theme: 'light', user: null, ...persisted });
154
+ store.addMiddleware(createPersistenceMiddleware(localStorage, 'app', ['theme', 'user']));
216
155
 
217
- // Components can use the store
218
- function UserProfile() {
219
- const { user, isLoading, error } = useStoreSelector(userStore, ['user', 'isLoading', 'error']);
220
-
221
- if (isLoading) return <div>Loading...</div>;
222
- if (error) return <div>Error: {error}</div>;
223
- if (!user) return <div>No user data</div>;
224
-
225
- return (
226
- <div>
227
- <h2>{user.name}</h2>
228
- <p>Email: {user.email}</p>
229
- </div>
230
- );
231
- }
156
+ // Async (React Native AsyncStorage)
157
+ const persisted = await loadPersistedState<AppState>(AsyncStorage, 'app', ['theme', 'user']);
232
158
 
233
- // Can call the function from anywhere
234
- // fetchUserData('123');
159
+ const store = createStoreState<AppState>({ theme: 'light', user: null, ...persisted });
160
+ store.addMiddleware(createPersistenceMiddleware(AsyncStorage, 'app', ['theme', 'user']));
235
161
  ```
236
162
 
237
- ## Features
163
+ Each key is stored individually (`app:theme`, `app:user`) — no serializing the entire state blob.
164
+
165
+ ## Change Listeners (outside React)
238
166
 
239
- - Extremely lightweight (less than 2KB minified)
240
- - Fine-grained subscriptions to minimize re-renders
241
- - Custom comparison functions for complex state updates
242
- - Simple middleware support with `addMiddleware()`
243
- - Automatic persistence to localStorage/sessionStorage
244
- - Debouncing support to control update frequency
245
- - Fully Type-safe with TypeScript
246
- - No dependencies other than React
247
- - Update store from anywhere in your application
167
+ Listen for value changes anywhere module scope, event handlers, async functions:
248
168
 
249
- ## Development Tools
169
+ ```tsx
170
+ const unsub = store.onChange(['theme', 'locale'], (values, prev) => {
171
+ document.body.className = values.theme;
172
+ console.log(`Theme: ${prev.theme} → ${values.theme}`);
173
+ });
250
174
 
251
- ### ESLint Plugin
175
+ // Multiple synchronous set() calls are batched into one notification
176
+ unsub();
177
+ ```
252
178
 
253
- [eslint-plugin-react-microstore](https://www.npmjs.com/package/eslint-plugin-react-microstore) provides ESLint rules to help you write with react-microstore.
179
+ ## Custom Comparison
254
180
 
255
- #### Installation
181
+ Control when re-renders happen with custom equality functions:
256
182
 
257
- ```bash
258
- npm install --save-dev eslint-plugin-react-microstore
183
+ ```tsx
184
+ const { tasks } = useStore([
185
+ {
186
+ tasks: (prev, next) =>
187
+ !prev.some((t, i) => t.completed !== next?.[i]?.completed)
188
+ }
189
+ ]);
259
190
  ```
260
191
 
261
- #### Usage
192
+ ## skipSetWhen
262
193
 
263
- ESLint configuration:
194
+ Skip updates for a key when a condition is met. `Object.is` always runs first as a fast path; `skipSetWhen` is an additional check when references differ. Return `true` = skip the update:
264
195
 
265
196
  ```tsx
266
- import reactMicrostore from 'eslint-plugin-react-microstore';
267
-
268
- const eslintConfig = [{
269
- "plugins": {
270
- "react-microstore": reactMicrostore
271
- },
272
- "rules": {
273
- "react-microstore/no-unused-selector-keys": "warn"
274
- }
275
- }]
197
+ const store = createStoreState({ user: { id: 1, name: 'Alice' }, tags: ['a', 'b'] });
198
+
199
+ // Skip update if id and name haven't changed
200
+ store.skipSetWhen('user', (prev, next) => prev.id === next.id && prev.name === next.name);
201
+
202
+ // Skip if array contents are the same
203
+ store.skipSetWhen('tags', (prev, next) => prev.length === next.length && prev.every((t, i) => t === next[i]));
204
+
205
+ // mergeSet with identical content is now a no-op — no listeners, no middleware
206
+ store.mergeSet('user', { name: 'Alice' }); // skipped
207
+
208
+ // Remove when no longer needed
209
+ store.removeSkipSetWhen('user');
276
210
  ```
277
211
 
278
- `react-microstore/no-unused-selector-keys`
279
- Warns when you select keys in `useStoreSelector` but don't destructure or use them.
212
+ Type-safe: `prev` and `next` types are inferred from the key.
213
+
214
+ ## Features
215
+
216
+ - Probably the fastest React store library ever created
217
+ - Extremely lightweight (< 2KB minified)
218
+ - Fine-grained subscriptions — components only re-render when their keys change
219
+ - `createSelectorHook` for one-line, fully-typed per-store hooks
220
+ - `merge` / `mergeSet` for ergonomic object updates
221
+ - `batch` to group updates and fire listeners once
222
+ - `reset` to restore initial state (full or per-key)
223
+ - `onChange` for non-React listeners with value tracking
224
+ - `skipSetWhen` to prevent unnecessary updates on object-valued keys
225
+ - Custom comparison functions for complex equality
226
+ - Express-style middleware (validation, transforms, logging)
227
+ - Automatic persistence to localStorage, sessionStorage, or AsyncStorage
228
+ - Fully type-safe — all types inferred from store instance
229
+ - Zero dependencies (peer: React >= 17)
230
+
231
+ ## ESLint Plugin
232
+
233
+ [eslint-plugin-dev-react-microstore](https://www.npmjs.com/package/eslint-plugin-dev-react-microstore) warns on unused selector keys:
234
+
235
+ ```bash
236
+ npm install --save-dev eslint-plugin-dev-react-microstore
237
+ ```
238
+
239
+ ```tsx
240
+ import reactMicrostore from 'eslint-plugin-dev-react-microstore';
241
+
242
+ export default [{
243
+ plugins: { 'dev-react-microstore': reactMicrostore },
244
+ rules: { 'dev-react-microstore/no-unused-selector-keys': 'warn' }
245
+ }];
246
+ ```
280
247
 
281
248
  ```tsx
282
- // ❌ This will trigger the rule
283
- const { a } = useStoreSelector(store, ['a', 'b']); // 'b' is unused
249
+ // ❌ Warns 'b' is selected but unused
250
+ const { a } = useStore(['a', 'b']);
284
251
 
285
- // ✅ This is fine
286
- const { a, b } = useStoreSelector(store, ['a', 'b']);
287
- ```
252
+ // ✅ Fine
253
+ const { a, b } = useStore(['a', 'b']);
254
+ ```
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ type MiddlewareFunction<T extends object> = (currentState: T, update: Partial<T>
4
4
  * Creates a new reactive store with fine-grained subscriptions and middleware support.
5
5
  *
6
6
  * @param initialState - The initial state object for the store
7
- * @returns Store object with methods: get, set, subscribe, select, addMiddleware
7
+ * @returns Store object with methods: get, set, subscribe, select, addMiddleware, onChange
8
8
  *
9
9
  * @example
10
10
  * ```ts
@@ -15,10 +15,20 @@ type MiddlewareFunction<T extends object> = (currentState: T, update: Partial<T>
15
15
  */
16
16
  declare function createStoreState<T extends object>(initialState: T): {
17
17
  get: () => T;
18
- set: (update: Partial<T>, debounceDelay?: number | boolean) => void;
18
+ getKey: <K extends keyof T>(key: K) => T[K];
19
+ set: (update: Partial<T>) => void;
20
+ setKey: <K extends keyof T>(key: K, value: T[K]) => void;
21
+ merge: <K extends keyof T>(key: K, value: T[K] extends object ? Partial<T[K]> : never) => T[K];
22
+ mergeSet: <K extends keyof T>(key: K, value: T[K] extends object ? Partial<T[K]> : never) => void;
23
+ reset: (keys?: (keyof T)[]) => void;
24
+ batch: (fn: () => void) => void;
19
25
  subscribe: (keys: (keyof T)[], listener: StoreListener) => (() => void);
20
26
  select: <K extends keyof T>(keys: K[]) => Pick<T, K>;
21
27
  addMiddleware: (callbackOrTuple: MiddlewareFunction<T> | [MiddlewareFunction<T>, (keyof T)[]], affectedKeys?: (keyof T)[] | null) => () => void;
28
+ onChange: <K extends keyof T>(keys: K[], callback: (values: Pick<T, K>, prev: Pick<T, K>) => void) => (() => void);
29
+ skipSetWhen: <K extends keyof T>(key: K, fn: (prev: T[K], next: T[K]) => boolean) => void;
30
+ removeSkipSetWhen: (key: keyof T) => void;
31
+ _eqReg: Record<string, ((prev: any, next: any) => boolean) | undefined>;
22
32
  };
23
33
  type StoreType<T extends object> = ReturnType<typeof createStoreState<T>>;
24
34
  type PrimitiveKey<T extends object> = keyof T;
@@ -53,18 +63,45 @@ type Picked<T extends object, S extends SelectorInput<T>> = ExtractSelectorKeys<
53
63
  */
54
64
  declare function useStoreSelector<T extends object, S extends SelectorInput<T>>(store: StoreType<T>, selector: S): Picked<T, S>;
55
65
  /**
56
- * Interface for storage objects compatible with persistence middleware.
57
- * Includes localStorage, sessionStorage, AsyncStorage, or any custom storage.
66
+ * Creates a pre-bound selector hook for a specific store instance.
67
+ * Infers the state type from the store — no manual generics needed.
68
+ *
69
+ * @param store - The store created with createStoreState
70
+ * @returns A React hook with the same API as useStoreSelector, but with the store already bound
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const useMyStore = createSelectorHook(myStore);
75
+ *
76
+ * // In a component:
77
+ * const { count, name } = useMyStore(['count', 'name']);
78
+ * ```
79
+ */
80
+ declare function createSelectorHook<T extends object>(store: StoreType<T>): <S extends SelectorInput<T>>(selector: S) => Picked<T, S>;
81
+ /**
82
+ * Interface for synchronous storage (localStorage, sessionStorage, etc.).
58
83
  */
59
84
  interface StorageSupportingInterface {
60
85
  getItem(key: string): string | null;
61
86
  setItem(key: string, value: string): void;
62
87
  }
88
+ /**
89
+ * Interface for asynchronous storage (React Native AsyncStorage, etc.).
90
+ */
91
+ interface AsyncStorageSupportingInterface {
92
+ getItem(key: string): Promise<string | null>;
93
+ setItem(key: string, value: string): Promise<void>;
94
+ }
95
+ type AnyStorage = Storage | StorageSupportingInterface | AsyncStorageSupportingInterface;
63
96
  /**
64
97
  * Creates a persistence middleware that saves individual keys to storage.
65
98
  * Only writes when the specified keys actually change, using per-key storage.
66
99
  * Storage format: `${persistKey}:${keyName}` for each persisted key.
67
100
  *
101
+ * Works with both synchronous storage (localStorage) and asynchronous storage
102
+ * (React Native AsyncStorage). Async writes are fire-and-forget — the state
103
+ * update is never blocked by a slow write.
104
+ *
68
105
  * @param storage - Storage interface (localStorage, sessionStorage, AsyncStorage, etc.)
69
106
  * @param persistKey - Base key prefix for storage (e.g., 'myapp' creates 'myapp:theme')
70
107
  * @param keys - Array of state keys to persist
@@ -72,34 +109,41 @@ interface StorageSupportingInterface {
72
109
  *
73
110
  * @example
74
111
  * ```ts
75
- * // Add persistence for theme and user settings
112
+ * // Sync localStorage
76
113
  * store.addMiddleware(
77
114
  * createPersistenceMiddleware(localStorage, 'myapp', ['theme', 'isLoggedIn'])
78
115
  * );
116
+ *
117
+ * // Async — React Native AsyncStorage
118
+ * store.addMiddleware(
119
+ * createPersistenceMiddleware(AsyncStorage, 'myapp', ['theme', 'isLoggedIn'])
120
+ * );
79
121
  * ```
80
122
  */
81
- declare function createPersistenceMiddleware<T extends object>(storage: Storage | StorageSupportingInterface, persistKey: string, keys: (keyof T)[]): [MiddlewareFunction<T>, (keyof T)[]];
123
+ declare function createPersistenceMiddleware<T extends object>(storage: AnyStorage, persistKey: string, keys: (keyof T)[]): [MiddlewareFunction<T>, (keyof T)[]];
82
124
  /**
83
125
  * Loads persisted state from individual key storage during store initialization.
84
126
  * Reads keys saved by createPersistenceMiddleware and returns them as partial state.
85
127
  *
128
+ * Returns synchronously for sync storage and a Promise for async storage.
129
+ *
86
130
  * @param storage - Storage interface to read from (same as used in middleware)
87
131
  * @param persistKey - Base key prefix used for storage (same as used in middleware)
88
132
  * @param keys - Array of keys to restore (should match middleware keys)
89
- * @returns Partial state object with persisted values, or empty object if loading fails
133
+ * @returns Partial state object (sync) or Promise of partial state (async)
90
134
  *
91
135
  * @example
92
136
  * ```ts
93
- * // Load persisted state before creating store
94
- * const persistedState = loadPersistedState(localStorage, 'myapp', ['theme', 'isLoggedIn']);
95
- *
96
- * const store = createStoreState({
97
- * theme: 'light',
98
- * isLoggedIn: false,
99
- * ...persistedState // Apply persisted values
100
- * });
137
+ * // Sync localStorage
138
+ * const persisted = loadPersistedState(localStorage, 'myapp', ['theme']);
139
+ * const store = createStoreState({ theme: 'light', ...persisted });
140
+ *
141
+ * // Async — React Native AsyncStorage
142
+ * const persisted = await loadPersistedState(AsyncStorage, 'myapp', ['theme']);
143
+ * const store = createStoreState({ theme: 'light', ...persisted });
101
144
  * ```
102
145
  */
103
146
  declare function loadPersistedState<T extends object>(storage: Storage | StorageSupportingInterface, persistKey: string, keys: (keyof T)[]): Partial<T>;
147
+ declare function loadPersistedState<T extends object>(storage: AsyncStorageSupportingInterface, persistKey: string, keys: (keyof T)[]): Promise<Partial<T>>;
104
148
 
105
- export { type StorageSupportingInterface, createPersistenceMiddleware, createStoreState, loadPersistedState, useStoreSelector };
149
+ export { type AsyncStorageSupportingInterface, type StorageSupportingInterface, createPersistenceMiddleware, createSelectorHook, createStoreState, loadPersistedState, useStoreSelector };