coaction 1.4.0 → 1.4.1

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
@@ -25,12 +25,35 @@ const useStore = create((set) => ({
25
25
  }));
26
26
  ```
27
27
 
28
+ Store methods using `this` are rebound to the latest state when invoked from
29
+ `getState()`, so destructuring remains safe:
30
+
31
+ ```ts
32
+ const store = create((set) => ({
33
+ count: 0,
34
+ increment() {
35
+ set(() => {
36
+ this.count += 1;
37
+ });
38
+ }
39
+ }));
40
+
41
+ const { increment } = store.getState();
42
+ increment();
43
+ ```
44
+
45
+ ## API Reference
46
+
47
+ - [Generated core API index](https://github.com/unadlib/coaction/blob/main/docs/api/core/index.md)
48
+ - [Core API notes](https://github.com/unadlib/coaction/blob/main/docs/api/core/documents/core-api-notes.md)
49
+
28
50
  ### Store Shape Mode (`sliceMode`)
29
51
 
30
52
  `create()` uses `sliceMode: 'auto'` by default. For backward compatibility,
31
53
  `auto` still treats a non-empty object whose enumerable values are all
32
54
  functions as slices. That shape is ambiguous with a plain store that only
33
- contains methods, so you should set `sliceMode` explicitly.
55
+ contains methods, so development builds warn and you should set `sliceMode`
56
+ explicitly.
34
57
 
35
58
  You can force behavior explicitly:
36
59
 
package/dist/index.d.mts CHANGED
@@ -1,15 +1,31 @@
1
1
  import { Transport } from 'data-transport';
2
2
  import { Draft, Patches } from 'mutative';
3
3
 
4
+ /**
5
+ * Generic object shape used by stores and slices.
6
+ */
4
7
  type ISlices<T = any> = Record<string, T>;
8
+ /**
9
+ * Recursive partial object accepted by {@link Store.setState} when merging a
10
+ * plain object payload into the current state tree.
11
+ */
5
12
  type DeepPartial<T> = {
6
13
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
7
14
  };
15
+ /**
16
+ * Subscription callback invoked after the store publishes a state change.
17
+ */
8
18
  type Listener = () => void;
19
+ /**
20
+ * Patch pair exposed to middleware compatibility hooks.
21
+ */
9
22
  interface PatchTransform {
10
23
  patches: Patches;
11
24
  inversePatches: Patches;
12
25
  }
26
+ /**
27
+ * Trace envelope emitted before and after a store method executes.
28
+ */
13
29
  interface StoreTraceEvent {
14
30
  /**
15
31
  * The id of the method.
@@ -32,57 +48,90 @@ interface StoreTraceEvent {
32
48
  */
33
49
  result?: any;
34
50
  }
51
+ /**
52
+ * Runtime store contract returned by {@link create} before framework-specific
53
+ * wrappers add selectors or reactivity helpers.
54
+ *
55
+ * @remarks
56
+ * `getState()` returns methods and getters alongside plain data. Methods
57
+ * extracted from the returned object keep the correct `this` binding when they
58
+ * are later invoked.
59
+ */
35
60
  interface Store<T extends ISlices = ISlices> {
36
61
  /**
37
62
  * The name of the store.
38
63
  */
39
64
  name: string;
40
65
  /**
41
- * Set the next state.
66
+ * Mutate the current state.
67
+ *
68
+ * @remarks
69
+ * Pass a deep-partial object to merge fields, or pass an updater to edit a
70
+ * Mutative draft. Client-side shared stores intentionally reject direct
71
+ * `setState()` calls; trigger a store method instead.
42
72
  */
43
73
  setState: (
44
74
  /**
45
- * The next state.
75
+ * The next partial state, or an updater that mutates a draft.
46
76
  */
47
77
  next: DeepPartial<T> | ((draft: Draft<T>) => any) | null,
48
78
  /**
49
- * The updater is used to update the state.
79
+ * Low-level updater hook used by transports and middleware integrations.
50
80
  */
51
81
  updater?: (next: DeepPartial<T> | ((draft: Draft<T>) => any) | null) => [] | [T, Patches, Patches]) => void;
52
82
  /**
53
- * Get the current state.
83
+ * Read the current state object.
84
+ *
85
+ * @remarks
86
+ * The returned object includes methods and getters. Methods destructured from
87
+ * this object continue to execute against the latest store state.
54
88
  */
55
89
  getState: () => T;
56
90
  /**
57
- * Subscribe to the state changes, and return the unsubscribe function.
91
+ * Subscribe to state changes.
92
+ *
93
+ * @returns A function that removes the listener.
58
94
  */
59
95
  subscribe: (listener: Listener) => () => void;
60
96
  /**
61
- * Unsubscribe all listeners and dispose the transport.
97
+ * Tear down the store.
98
+ *
99
+ * @remarks
100
+ * `destroy()` is idempotent. It clears subscriptions and disposes any
101
+ * attached transport.
62
102
  */
63
103
  destroy: () => void;
64
104
  /**
65
- * The store is shared in the web worker, shared worker, or other process.
105
+ * Indicates whether the store is local, the main shared store, or a client
106
+ * mirror of a shared store.
66
107
  */
67
108
  share?: 'main' | 'client' | false;
68
109
  /**
69
- * The transport is used to communicate between the main thread and the worker or shared worker.
110
+ * Transport used to synchronize a shared store between processes or threads.
70
111
  */
71
112
  transport?: Transport;
72
113
  /**
73
- * The store is a slices.
114
+ * Whether `createState` was interpreted as a slices object.
74
115
  */
75
116
  isSliceStore: boolean;
76
117
  /**
77
- * apply the patches to the state.
118
+ * Apply patches to the current state.
119
+ *
120
+ * @remarks
121
+ * This is a low-level hook used by transports and middleware. Application
122
+ * code should generally prefer store methods or `setState()`.
78
123
  */
79
124
  apply: (state?: T, patches?: Patches) => void;
80
125
  /**
81
- * the pure state is used to get the state without the methods and getters.
126
+ * Return the current state without methods or getters.
127
+ *
128
+ * @remarks
129
+ * Useful for serialization, inspection, or tests that only care about raw
130
+ * data.
82
131
  */
83
132
  getPureState: () => T;
84
133
  /**
85
- * Get the initial state.
134
+ * Return the state produced during initialization before later mutations.
86
135
  */
87
136
  getInitialState: () => T;
88
137
  /**
@@ -98,13 +147,31 @@ interface Store<T extends ISlices = ISlices> {
98
147
  }
99
148
  /**
100
149
  * Semantic alias for middleware-facing stores.
150
+ *
151
+ * @remarks
152
+ * Middleware implementations should type their `store` parameter as
153
+ * `MiddlewareStore` instead of relying on deprecated `patch` or `trace` hooks.
101
154
  */
102
155
  interface MiddlewareStore<T extends ISlices = ISlices> extends Store<T> {
103
156
  }
157
+ /**
158
+ * Helper passed into {@link Slice} and {@link Slices} factories.
159
+ *
160
+ * @remarks
161
+ * Call it with no arguments to read the current store state. Call it with a
162
+ * dependency selector pair to define a computed value.
163
+ */
104
164
  interface Getter<T extends ISlices> {
105
165
  <P extends any[], R>(getDeps: (store: T) => readonly [...P] | [...P], selector: (...args: P) => R): R;
106
166
  (): T;
107
167
  }
168
+ /**
169
+ * Factory for a single store object.
170
+ *
171
+ * @remarks
172
+ * Return a plain object containing state, getters, and methods. Methods and
173
+ * getters may use `this` to access the live store state.
174
+ */
108
175
  type Slice<T extends ISlices> = (
109
176
  /**
110
177
  * The setState is used to update the state.
@@ -118,6 +185,14 @@ get: Getter<T>,
118
185
  * The store is used to store the state.
119
186
  */
120
187
  store: Store<T>) => T;
188
+ /**
189
+ * Factory for a named slice inside a slices store.
190
+ *
191
+ * @remarks
192
+ * The returned object becomes the value stored under the slice key. When an
193
+ * object input only contains functions, prefer explicit `sliceMode` to avoid
194
+ * ambiguity between slices and a plain method-only store.
195
+ */
121
196
  type Slices<T extends ISlices, K extends keyof T> = (
122
197
  /**
123
198
  * The setState is used to update the state.
@@ -131,10 +206,24 @@ get: Getter<T>,
131
206
  * The store is used to store the state.
132
207
  */
133
208
  store: Store<T>) => T[K];
209
+ /**
210
+ * Store enhancer invoked during store creation.
211
+ *
212
+ * @remarks
213
+ * Middleware may mutate the received store in place or return a replacement
214
+ * store object, but it must preserve the {@link Store} contract.
215
+ */
134
216
  type Middleware<T extends CreateState> = (store: MiddlewareStore<T>) => MiddlewareStore<T>;
217
+ /**
218
+ * Derived state object produced by mapping slice factories to their return
219
+ * types.
220
+ */
135
221
  type SliceState<T extends Record<string, Slice<any>>> = {
136
222
  [K in keyof T]: ReturnType<T[K]>;
137
223
  };
224
+ /**
225
+ * Options for creating a local store or the main side of a shared store.
226
+ */
138
227
  type StoreOptions<T extends CreateState> = {
139
228
  /**
140
229
  * The name of the store.
@@ -149,13 +238,22 @@ type StoreOptions<T extends CreateState> = {
149
238
  * Inject a pre-built transport for advanced shared-store setups.
150
239
  */
151
240
  transport?: Transport;
241
+ /**
242
+ * Middleware chain applied before the initial state is finalized.
243
+ */
152
244
  middlewares?: Middleware<T>[];
153
245
  /**
154
- * enable patches
246
+ * Enable patch generation.
247
+ *
248
+ * @remarks
249
+ * Required for async client stores and useful for middleware or mutable
250
+ * integrations that depend on patch streams.
155
251
  */
156
252
  enablePatches?: boolean;
157
253
  /**
158
- * control how createState should be interpreted.
254
+ * Control how `createState` should be interpreted.
255
+ *
256
+ * @remarks
159
257
  * - auto: infer from createState shape. Object maps whose values are all
160
258
  * functions are ambiguous, so prefer setting `sliceMode` explicitly.
161
259
  * - slices: force slices mode.
@@ -163,14 +261,26 @@ type StoreOptions<T extends CreateState> = {
163
261
  */
164
262
  sliceMode?: 'auto' | 'slices' | 'single';
165
263
  };
264
+ /**
265
+ * Options for creating a client mirror of a shared store.
266
+ *
267
+ * @remarks
268
+ * Methods on the returned store become promise-returning methods because
269
+ * execution happens on the main/shared store.
270
+ */
166
271
  type ClientStoreOptions<T extends CreateState> = {
167
272
  /**
168
- * The name of the store.
273
+ * The name of the shared store to connect to.
169
274
  */
170
275
  name?: string;
276
+ /**
277
+ * Middleware chain applied to the client-side store wrapper.
278
+ */
171
279
  middlewares?: Middleware<T>[];
172
280
  /**
173
- * control how createState should be interpreted.
281
+ * Control how `createState` should be interpreted.
282
+ *
283
+ * @remarks
174
284
  * - auto: infer from createState shape. Object maps whose values are all
175
285
  * functions are ambiguous, so prefer setting `sliceMode` explicitly.
176
286
  * - slices: force slices mode.
@@ -178,6 +288,9 @@ type ClientStoreOptions<T extends CreateState> = {
178
288
  */
179
289
  sliceMode?: 'auto' | 'slices' | 'single';
180
290
  } & ClientTransportOptions;
291
+ /**
292
+ * Transport-related options for client/shared-store mirrors.
293
+ */
181
294
  interface ClientTransportOptions {
182
295
  /**
183
296
  * @deprecated Internal worker-mode override retained for compatibility.
@@ -203,14 +316,46 @@ interface ClientTransportOptions {
203
316
  */
204
317
  worker?: SharedWorker | Worker;
205
318
  }
319
+ /**
320
+ * Transform store methods into promise-returning methods for client stores.
321
+ */
206
322
  type Asyncify<T extends object, D extends true | false> = {
207
323
  [K in keyof T]: T[K] extends (...args: any[]) => any ? (...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>> : D extends false ? T[K] : {
208
324
  [P in keyof T[K]]: T[K][P] extends (...args: any[]) => any ? (...args: Parameters<T[K][P]>) => Promise<ReturnType<T[K][P]>> : T[K][P];
209
325
  };
210
326
  };
327
+ /**
328
+ * Store shape returned by {@link create} when acting as a client of a shared
329
+ * store.
330
+ *
331
+ * @remarks
332
+ * Methods return promises because they execute on the main/shared store.
333
+ */
211
334
  type StoreWithAsyncFunction<T extends object, D extends true | false = false> = Store<Asyncify<T, D>> & (() => Asyncify<T, D>);
335
+ /**
336
+ * Callable store returned by {@link create} in local or main/shared mode.
337
+ */
212
338
  type StoreReturn<T extends object> = Store<T> & ((...args: any[]) => T);
339
+ /**
340
+ * Accepted `create()` input shape.
341
+ *
342
+ * @remarks
343
+ * This can be either a single store factory/object or a map of slice
344
+ * factories.
345
+ */
213
346
  type CreateState = ISlices | Record<string, Slice<any>>;
347
+ /**
348
+ * Overload set for {@link create}.
349
+ *
350
+ * @remarks
351
+ * - `Slice` + `StoreOptions` returns a synchronous local or main/shared store.
352
+ * - slice map + `StoreOptions` returns a synchronous slices store.
353
+ * - `Slice` + `ClientStoreOptions` returns an async client store.
354
+ * - slice map + `ClientStoreOptions` returns an async client slices store.
355
+ *
356
+ * For object inputs whose enumerable values are all functions, prefer explicit
357
+ * `sliceMode` to avoid ambiguous inference.
358
+ */
214
359
  type Creator = {
215
360
  <T extends Record<string, Slice<any>>>(createState: T, options?: StoreOptions<T>): StoreReturn<SliceState<T>>;
216
361
  <T extends ISlices>(createState: Slice<T>, options?: StoreOptions<T>): StoreReturn<T>;
@@ -219,7 +364,17 @@ type Creator = {
219
364
  };
220
365
 
221
366
  /**
222
- * Create a simple store or a shared store. The shared store can be used in a worker or another thread.
367
+ * Create a local store, the main side of a shared store, or a client mirror of
368
+ * a shared store.
369
+ *
370
+ * @remarks
371
+ * - Pass a {@link Slice} function for a single store.
372
+ * - Pass an object of slice factories for a slices store.
373
+ * - When an object input only contains functions, prefer explicit `sliceMode`
374
+ * to avoid ambiguous inference.
375
+ * - When `clientTransport` or `worker` is provided, returned store methods
376
+ * become promise-returning methods because execution happens on the main
377
+ * shared store.
223
378
  */
224
379
  declare const create: Creator;
225
380
 
@@ -271,54 +426,69 @@ interface Internal<T extends CreateState = CreateState> {
271
426
  }
272
427
 
273
428
  /**
274
- * createBinder is a function to create a binder for the 3rd party store.
429
+ * Build an adapter helper for bridging an external store implementation into
430
+ * Coaction.
431
+ *
432
+ * @remarks
433
+ * Official bindings use this to integrate stores such as Redux, Jotai, Pinia,
434
+ * Zustand, MobX, and Valtio. Binder-backed integrations are whole-store
435
+ * adapters; they are not compatible with Coaction slices mode.
275
436
  */
276
437
  declare function createBinder<F = (...args: any[]) => any>({ handleState, handleStore }: {
277
438
  /**
278
- * handleState is a function to handle the state object.
439
+ * Normalize a third-party store instance into a raw state object plus the
440
+ * binding hook used during initialization.
279
441
  */
280
442
  handleState: <T extends object = object>(state: T) => {
281
443
  /**
282
- * copyState is a copy of the state object.
444
+ * Copy of the incoming state object that Coaction should consume.
283
445
  */
284
446
  copyState: T;
285
447
  /**
286
- * key is the key of the state object.
448
+ * Optional nested key when the adapter exposes a single child object from
449
+ * the third-party store.
287
450
  */
288
451
  key?: keyof T;
289
452
  /**
290
- * bind is a function to bind the state object.
453
+ * Convert the external state object into the raw state shape used by
454
+ * Coaction.
291
455
  */
292
456
  bind: (state: T) => T;
293
457
  };
294
458
  /**
295
- * handleStore is a function to handle the store object.
459
+ * Wire Coaction's store lifecycle to the external store implementation.
296
460
  */
297
461
  handleStore: (
298
462
  /**
299
- * Coaction store
463
+ * Coaction store wrapper.
300
464
  */
301
465
  store: Store<object>,
302
466
  /**
303
- * The raw state object from 3rd party library.
467
+ * Raw state object returned from `bind`.
304
468
  */
305
469
  rawState: object,
306
470
  /**
307
- * 3rd party library state object to Coaction state object.
471
+ * Original external store state object.
308
472
  */
309
473
  state: object,
310
474
  /**
311
- * internal Coaction API.
475
+ * Low-level Coaction adapter hooks used by official bindings.
312
476
  */
313
477
  internal: Internal<object>,
314
478
  /**
315
- * the key of the slice state object.
479
+ * Optional nested key returned by `handleState`.
316
480
  */
317
481
  key?: string) => void;
318
482
  }): F;
319
483
 
320
484
  /**
321
- * wrapStore is a function to wrap the store and return function to get the state with store.
485
+ * Convert a store object into Coaction's callable store shape.
486
+ *
487
+ * @remarks
488
+ * Framework bindings use this to attach selector-aware readers while
489
+ * preserving the underlying store API on the returned function object. Most
490
+ * applications should call {@link create} instead of using `wrapStore()`
491
+ * directly.
322
492
  */
323
493
  declare const wrapStore: <T extends object>(store: Store<T>, getState?: (...args: unknown[]) => T) => StoreReturn<T>;
324
494
 
package/dist/index.d.ts CHANGED
@@ -1,15 +1,31 @@
1
1
  import { Transport } from 'data-transport';
2
2
  import { Draft, Patches } from 'mutative';
3
3
 
4
+ /**
5
+ * Generic object shape used by stores and slices.
6
+ */
4
7
  type ISlices<T = any> = Record<string, T>;
8
+ /**
9
+ * Recursive partial object accepted by {@link Store.setState} when merging a
10
+ * plain object payload into the current state tree.
11
+ */
5
12
  type DeepPartial<T> = {
6
13
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
7
14
  };
15
+ /**
16
+ * Subscription callback invoked after the store publishes a state change.
17
+ */
8
18
  type Listener = () => void;
19
+ /**
20
+ * Patch pair exposed to middleware compatibility hooks.
21
+ */
9
22
  interface PatchTransform {
10
23
  patches: Patches;
11
24
  inversePatches: Patches;
12
25
  }
26
+ /**
27
+ * Trace envelope emitted before and after a store method executes.
28
+ */
13
29
  interface StoreTraceEvent {
14
30
  /**
15
31
  * The id of the method.
@@ -32,57 +48,90 @@ interface StoreTraceEvent {
32
48
  */
33
49
  result?: any;
34
50
  }
51
+ /**
52
+ * Runtime store contract returned by {@link create} before framework-specific
53
+ * wrappers add selectors or reactivity helpers.
54
+ *
55
+ * @remarks
56
+ * `getState()` returns methods and getters alongside plain data. Methods
57
+ * extracted from the returned object keep the correct `this` binding when they
58
+ * are later invoked.
59
+ */
35
60
  interface Store<T extends ISlices = ISlices> {
36
61
  /**
37
62
  * The name of the store.
38
63
  */
39
64
  name: string;
40
65
  /**
41
- * Set the next state.
66
+ * Mutate the current state.
67
+ *
68
+ * @remarks
69
+ * Pass a deep-partial object to merge fields, or pass an updater to edit a
70
+ * Mutative draft. Client-side shared stores intentionally reject direct
71
+ * `setState()` calls; trigger a store method instead.
42
72
  */
43
73
  setState: (
44
74
  /**
45
- * The next state.
75
+ * The next partial state, or an updater that mutates a draft.
46
76
  */
47
77
  next: DeepPartial<T> | ((draft: Draft<T>) => any) | null,
48
78
  /**
49
- * The updater is used to update the state.
79
+ * Low-level updater hook used by transports and middleware integrations.
50
80
  */
51
81
  updater?: (next: DeepPartial<T> | ((draft: Draft<T>) => any) | null) => [] | [T, Patches, Patches]) => void;
52
82
  /**
53
- * Get the current state.
83
+ * Read the current state object.
84
+ *
85
+ * @remarks
86
+ * The returned object includes methods and getters. Methods destructured from
87
+ * this object continue to execute against the latest store state.
54
88
  */
55
89
  getState: () => T;
56
90
  /**
57
- * Subscribe to the state changes, and return the unsubscribe function.
91
+ * Subscribe to state changes.
92
+ *
93
+ * @returns A function that removes the listener.
58
94
  */
59
95
  subscribe: (listener: Listener) => () => void;
60
96
  /**
61
- * Unsubscribe all listeners and dispose the transport.
97
+ * Tear down the store.
98
+ *
99
+ * @remarks
100
+ * `destroy()` is idempotent. It clears subscriptions and disposes any
101
+ * attached transport.
62
102
  */
63
103
  destroy: () => void;
64
104
  /**
65
- * The store is shared in the web worker, shared worker, or other process.
105
+ * Indicates whether the store is local, the main shared store, or a client
106
+ * mirror of a shared store.
66
107
  */
67
108
  share?: 'main' | 'client' | false;
68
109
  /**
69
- * The transport is used to communicate between the main thread and the worker or shared worker.
110
+ * Transport used to synchronize a shared store between processes or threads.
70
111
  */
71
112
  transport?: Transport;
72
113
  /**
73
- * The store is a slices.
114
+ * Whether `createState` was interpreted as a slices object.
74
115
  */
75
116
  isSliceStore: boolean;
76
117
  /**
77
- * apply the patches to the state.
118
+ * Apply patches to the current state.
119
+ *
120
+ * @remarks
121
+ * This is a low-level hook used by transports and middleware. Application
122
+ * code should generally prefer store methods or `setState()`.
78
123
  */
79
124
  apply: (state?: T, patches?: Patches) => void;
80
125
  /**
81
- * the pure state is used to get the state without the methods and getters.
126
+ * Return the current state without methods or getters.
127
+ *
128
+ * @remarks
129
+ * Useful for serialization, inspection, or tests that only care about raw
130
+ * data.
82
131
  */
83
132
  getPureState: () => T;
84
133
  /**
85
- * Get the initial state.
134
+ * Return the state produced during initialization before later mutations.
86
135
  */
87
136
  getInitialState: () => T;
88
137
  /**
@@ -98,13 +147,31 @@ interface Store<T extends ISlices = ISlices> {
98
147
  }
99
148
  /**
100
149
  * Semantic alias for middleware-facing stores.
150
+ *
151
+ * @remarks
152
+ * Middleware implementations should type their `store` parameter as
153
+ * `MiddlewareStore` instead of relying on deprecated `patch` or `trace` hooks.
101
154
  */
102
155
  interface MiddlewareStore<T extends ISlices = ISlices> extends Store<T> {
103
156
  }
157
+ /**
158
+ * Helper passed into {@link Slice} and {@link Slices} factories.
159
+ *
160
+ * @remarks
161
+ * Call it with no arguments to read the current store state. Call it with a
162
+ * dependency selector pair to define a computed value.
163
+ */
104
164
  interface Getter<T extends ISlices> {
105
165
  <P extends any[], R>(getDeps: (store: T) => readonly [...P] | [...P], selector: (...args: P) => R): R;
106
166
  (): T;
107
167
  }
168
+ /**
169
+ * Factory for a single store object.
170
+ *
171
+ * @remarks
172
+ * Return a plain object containing state, getters, and methods. Methods and
173
+ * getters may use `this` to access the live store state.
174
+ */
108
175
  type Slice<T extends ISlices> = (
109
176
  /**
110
177
  * The setState is used to update the state.
@@ -118,6 +185,14 @@ get: Getter<T>,
118
185
  * The store is used to store the state.
119
186
  */
120
187
  store: Store<T>) => T;
188
+ /**
189
+ * Factory for a named slice inside a slices store.
190
+ *
191
+ * @remarks
192
+ * The returned object becomes the value stored under the slice key. When an
193
+ * object input only contains functions, prefer explicit `sliceMode` to avoid
194
+ * ambiguity between slices and a plain method-only store.
195
+ */
121
196
  type Slices<T extends ISlices, K extends keyof T> = (
122
197
  /**
123
198
  * The setState is used to update the state.
@@ -131,10 +206,24 @@ get: Getter<T>,
131
206
  * The store is used to store the state.
132
207
  */
133
208
  store: Store<T>) => T[K];
209
+ /**
210
+ * Store enhancer invoked during store creation.
211
+ *
212
+ * @remarks
213
+ * Middleware may mutate the received store in place or return a replacement
214
+ * store object, but it must preserve the {@link Store} contract.
215
+ */
134
216
  type Middleware<T extends CreateState> = (store: MiddlewareStore<T>) => MiddlewareStore<T>;
217
+ /**
218
+ * Derived state object produced by mapping slice factories to their return
219
+ * types.
220
+ */
135
221
  type SliceState<T extends Record<string, Slice<any>>> = {
136
222
  [K in keyof T]: ReturnType<T[K]>;
137
223
  };
224
+ /**
225
+ * Options for creating a local store or the main side of a shared store.
226
+ */
138
227
  type StoreOptions<T extends CreateState> = {
139
228
  /**
140
229
  * The name of the store.
@@ -149,13 +238,22 @@ type StoreOptions<T extends CreateState> = {
149
238
  * Inject a pre-built transport for advanced shared-store setups.
150
239
  */
151
240
  transport?: Transport;
241
+ /**
242
+ * Middleware chain applied before the initial state is finalized.
243
+ */
152
244
  middlewares?: Middleware<T>[];
153
245
  /**
154
- * enable patches
246
+ * Enable patch generation.
247
+ *
248
+ * @remarks
249
+ * Required for async client stores and useful for middleware or mutable
250
+ * integrations that depend on patch streams.
155
251
  */
156
252
  enablePatches?: boolean;
157
253
  /**
158
- * control how createState should be interpreted.
254
+ * Control how `createState` should be interpreted.
255
+ *
256
+ * @remarks
159
257
  * - auto: infer from createState shape. Object maps whose values are all
160
258
  * functions are ambiguous, so prefer setting `sliceMode` explicitly.
161
259
  * - slices: force slices mode.
@@ -163,14 +261,26 @@ type StoreOptions<T extends CreateState> = {
163
261
  */
164
262
  sliceMode?: 'auto' | 'slices' | 'single';
165
263
  };
264
+ /**
265
+ * Options for creating a client mirror of a shared store.
266
+ *
267
+ * @remarks
268
+ * Methods on the returned store become promise-returning methods because
269
+ * execution happens on the main/shared store.
270
+ */
166
271
  type ClientStoreOptions<T extends CreateState> = {
167
272
  /**
168
- * The name of the store.
273
+ * The name of the shared store to connect to.
169
274
  */
170
275
  name?: string;
276
+ /**
277
+ * Middleware chain applied to the client-side store wrapper.
278
+ */
171
279
  middlewares?: Middleware<T>[];
172
280
  /**
173
- * control how createState should be interpreted.
281
+ * Control how `createState` should be interpreted.
282
+ *
283
+ * @remarks
174
284
  * - auto: infer from createState shape. Object maps whose values are all
175
285
  * functions are ambiguous, so prefer setting `sliceMode` explicitly.
176
286
  * - slices: force slices mode.
@@ -178,6 +288,9 @@ type ClientStoreOptions<T extends CreateState> = {
178
288
  */
179
289
  sliceMode?: 'auto' | 'slices' | 'single';
180
290
  } & ClientTransportOptions;
291
+ /**
292
+ * Transport-related options for client/shared-store mirrors.
293
+ */
181
294
  interface ClientTransportOptions {
182
295
  /**
183
296
  * @deprecated Internal worker-mode override retained for compatibility.
@@ -203,14 +316,46 @@ interface ClientTransportOptions {
203
316
  */
204
317
  worker?: SharedWorker | Worker;
205
318
  }
319
+ /**
320
+ * Transform store methods into promise-returning methods for client stores.
321
+ */
206
322
  type Asyncify<T extends object, D extends true | false> = {
207
323
  [K in keyof T]: T[K] extends (...args: any[]) => any ? (...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>> : D extends false ? T[K] : {
208
324
  [P in keyof T[K]]: T[K][P] extends (...args: any[]) => any ? (...args: Parameters<T[K][P]>) => Promise<ReturnType<T[K][P]>> : T[K][P];
209
325
  };
210
326
  };
327
+ /**
328
+ * Store shape returned by {@link create} when acting as a client of a shared
329
+ * store.
330
+ *
331
+ * @remarks
332
+ * Methods return promises because they execute on the main/shared store.
333
+ */
211
334
  type StoreWithAsyncFunction<T extends object, D extends true | false = false> = Store<Asyncify<T, D>> & (() => Asyncify<T, D>);
335
+ /**
336
+ * Callable store returned by {@link create} in local or main/shared mode.
337
+ */
212
338
  type StoreReturn<T extends object> = Store<T> & ((...args: any[]) => T);
339
+ /**
340
+ * Accepted `create()` input shape.
341
+ *
342
+ * @remarks
343
+ * This can be either a single store factory/object or a map of slice
344
+ * factories.
345
+ */
213
346
  type CreateState = ISlices | Record<string, Slice<any>>;
347
+ /**
348
+ * Overload set for {@link create}.
349
+ *
350
+ * @remarks
351
+ * - `Slice` + `StoreOptions` returns a synchronous local or main/shared store.
352
+ * - slice map + `StoreOptions` returns a synchronous slices store.
353
+ * - `Slice` + `ClientStoreOptions` returns an async client store.
354
+ * - slice map + `ClientStoreOptions` returns an async client slices store.
355
+ *
356
+ * For object inputs whose enumerable values are all functions, prefer explicit
357
+ * `sliceMode` to avoid ambiguous inference.
358
+ */
214
359
  type Creator = {
215
360
  <T extends Record<string, Slice<any>>>(createState: T, options?: StoreOptions<T>): StoreReturn<SliceState<T>>;
216
361
  <T extends ISlices>(createState: Slice<T>, options?: StoreOptions<T>): StoreReturn<T>;
@@ -219,7 +364,17 @@ type Creator = {
219
364
  };
220
365
 
221
366
  /**
222
- * Create a simple store or a shared store. The shared store can be used in a worker or another thread.
367
+ * Create a local store, the main side of a shared store, or a client mirror of
368
+ * a shared store.
369
+ *
370
+ * @remarks
371
+ * - Pass a {@link Slice} function for a single store.
372
+ * - Pass an object of slice factories for a slices store.
373
+ * - When an object input only contains functions, prefer explicit `sliceMode`
374
+ * to avoid ambiguous inference.
375
+ * - When `clientTransport` or `worker` is provided, returned store methods
376
+ * become promise-returning methods because execution happens on the main
377
+ * shared store.
223
378
  */
224
379
  declare const create: Creator;
225
380
 
@@ -271,54 +426,69 @@ interface Internal<T extends CreateState = CreateState> {
271
426
  }
272
427
 
273
428
  /**
274
- * createBinder is a function to create a binder for the 3rd party store.
429
+ * Build an adapter helper for bridging an external store implementation into
430
+ * Coaction.
431
+ *
432
+ * @remarks
433
+ * Official bindings use this to integrate stores such as Redux, Jotai, Pinia,
434
+ * Zustand, MobX, and Valtio. Binder-backed integrations are whole-store
435
+ * adapters; they are not compatible with Coaction slices mode.
275
436
  */
276
437
  declare function createBinder<F = (...args: any[]) => any>({ handleState, handleStore }: {
277
438
  /**
278
- * handleState is a function to handle the state object.
439
+ * Normalize a third-party store instance into a raw state object plus the
440
+ * binding hook used during initialization.
279
441
  */
280
442
  handleState: <T extends object = object>(state: T) => {
281
443
  /**
282
- * copyState is a copy of the state object.
444
+ * Copy of the incoming state object that Coaction should consume.
283
445
  */
284
446
  copyState: T;
285
447
  /**
286
- * key is the key of the state object.
448
+ * Optional nested key when the adapter exposes a single child object from
449
+ * the third-party store.
287
450
  */
288
451
  key?: keyof T;
289
452
  /**
290
- * bind is a function to bind the state object.
453
+ * Convert the external state object into the raw state shape used by
454
+ * Coaction.
291
455
  */
292
456
  bind: (state: T) => T;
293
457
  };
294
458
  /**
295
- * handleStore is a function to handle the store object.
459
+ * Wire Coaction's store lifecycle to the external store implementation.
296
460
  */
297
461
  handleStore: (
298
462
  /**
299
- * Coaction store
463
+ * Coaction store wrapper.
300
464
  */
301
465
  store: Store<object>,
302
466
  /**
303
- * The raw state object from 3rd party library.
467
+ * Raw state object returned from `bind`.
304
468
  */
305
469
  rawState: object,
306
470
  /**
307
- * 3rd party library state object to Coaction state object.
471
+ * Original external store state object.
308
472
  */
309
473
  state: object,
310
474
  /**
311
- * internal Coaction API.
475
+ * Low-level Coaction adapter hooks used by official bindings.
312
476
  */
313
477
  internal: Internal<object>,
314
478
  /**
315
- * the key of the slice state object.
479
+ * Optional nested key returned by `handleState`.
316
480
  */
317
481
  key?: string) => void;
318
482
  }): F;
319
483
 
320
484
  /**
321
- * wrapStore is a function to wrap the store and return function to get the state with store.
485
+ * Convert a store object into Coaction's callable store shape.
486
+ *
487
+ * @remarks
488
+ * Framework bindings use this to attach selector-aware readers while
489
+ * preserving the underlying store API on the returned function object. Most
490
+ * applications should call {@link create} instead of using `wrapStore()`
491
+ * directly.
322
492
  */
323
493
  declare const wrapStore: <T extends object>(store: Store<T>, getState?: (...args: unknown[]) => T) => StoreReturn<T>;
324
494
 
package/dist/index.js CHANGED
@@ -906,7 +906,12 @@ var warnAmbiguousFunctionMap = () => {
906
906
  }
907
907
  hasWarnedAmbiguousFunctionMap = true;
908
908
  console.warn(
909
- `sliceMode: 'auto' inferred slices from an object of functions. This shape is ambiguous with a single store that only contains methods. Set sliceMode to 'slices' or 'single' explicitly.`
909
+ [
910
+ `sliceMode: 'auto' inferred slices from an object of functions.`,
911
+ `This shape is ambiguous with a single store that only contains methods.`,
912
+ `Use create({ ping() {} }, { sliceMode: 'single' }) for a plain method store,`,
913
+ `or create({ counter: (set) => ({ count: 0 }) }, { sliceMode: 'slices' }) for slices.`
914
+ ].join(" ")
910
915
  );
911
916
  };
912
917
  var create = (createState, options = {}) => {
package/dist/index.mjs CHANGED
@@ -884,7 +884,12 @@ var warnAmbiguousFunctionMap = () => {
884
884
  }
885
885
  hasWarnedAmbiguousFunctionMap = true;
886
886
  console.warn(
887
- `sliceMode: 'auto' inferred slices from an object of functions. This shape is ambiguous with a single store that only contains methods. Set sliceMode to 'slices' or 'single' explicitly.`
887
+ [
888
+ `sliceMode: 'auto' inferred slices from an object of functions.`,
889
+ `This shape is ambiguous with a single store that only contains methods.`,
890
+ `Use create({ ping() {} }, { sliceMode: 'single' }) for a plain method store,`,
891
+ `or create({ counter: (set) => ({ count: 0 }) }, { sliceMode: 'slices' }) for slices.`
892
+ ].join(" ")
888
893
  );
889
894
  };
890
895
  var create = (createState, options = {}) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coaction",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "A sleek JavaScript library designed for high-performance and multithreading web apps.",
5
5
  "keywords": [
6
6
  "coaction"