coaction 2.0.0 → 3.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,27 +1,25 @@
1
1
  # coaction
2
2
 
3
- ![Node CI](https://github.com/coactionjs/coaction/workflows/Node%20CI/badge.svg)
4
- [![npm](https://img.shields.io/npm/v/coaction.svg)](https://www.npmjs.com/package/coaction)
5
- ![license](https://img.shields.io/npm/l/coaction)
3
+ ![Node CI](https://github.com/coactionjs/coaction/workflows/Node%20CI/badge.svg) [![npm](https://img.shields.io/npm/v/coaction.svg)](https://www.npmjs.com/package/coaction) ![license](https://img.shields.io/npm/l/coaction)
4
+
5
+ [English documentation](https://coactionjs.github.io/coaction/en/docs/) · [中文文档](https://coactionjs.github.io/coaction/zh/docs/)
6
6
 
7
7
  An efficient and flexible state management library for building high-performance, multithreading web applications.
8
8
 
9
- Coaction 2.0 uses `alien-signals` internally for cached getter/computed state,
10
- React selector reactivity, and adapter-facing subscriptions. The core package
11
- also re-exports the signal primitives for advanced integrations.
9
+ Coaction uses `alien-signals` internally for cached getter/computed state, React selector reactivity, and adapter-facing subscriptions. The core package also re-exports the signal primitives for advanced integrations.
12
10
 
13
11
  ## Installation
14
12
 
15
- You can install it via npm, yarn or pnpm.
13
+ Install it with pnpm:
16
14
 
17
15
  ```sh
18
- npm install coaction
16
+ pnpm add coaction
19
17
  ```
20
18
 
21
19
  ## Usage
22
20
 
23
21
  ```jsx
24
- import { create } from 'coaction';
22
+ import { create } from 'coaction/local';
25
23
 
26
24
  const store = create((set) => ({
27
25
  count: 0,
@@ -36,8 +34,13 @@ const store = create((set) => ({
36
34
  }));
37
35
  ```
38
36
 
39
- Accessor getters are cached automatically through the built-in signal runtime.
40
- Use `get(deps, selector)` when you want to declare dependencies manually:
37
+ Core stores are immutable by default. Getters and methods can read through `this`, but writes to Coaction-owned state must happen inside `set()` or `set((draft) => ...)`. Direct writes such as `this.count += 1` in a store method throw because they bypass the commit path that notifies subscribers, produces patches when enabled, and synchronizes worker/client mirrors in shared mode.
38
+
39
+ Coaction fixes the public state schema after initialization. A single store cannot add new top-level state keys later, and a slices store cannot add new slice keys or new top-level fields inside a slice. Replacement-style APIs such as `apply()` may omit a known single-store root key; the public getter remains present and reads as `undefined`, but no unknown key is promoted into the public module. Slice root keys are stricter and cannot be removed or replaced with non-object values. Keep dynamic data inside an existing object or array field.
40
+
41
+ Mutable adapters such as MobX, Pinia, and Valtio keep Coaction raw state, public state, and the external mutable runtime synchronized for known schema keys. Coaction still treats its raw/public schema as authoritative: out-of-band unknown properties written directly onto a third-party mutable runtime are not promoted into Coaction state, and adapter-specific docs define whether that external runtime property is pruned, restored, or left to the underlying library.
42
+
43
+ Accessor getters are cached automatically through the built-in signal runtime. Use `get(deps, selector)` when you want to declare dependencies manually:
41
44
 
42
45
  ```ts
43
46
  const store = create((set, get) => ({
@@ -54,15 +57,46 @@ const store = create((set, get) => ({
54
57
  }));
55
58
  ```
56
59
 
57
- Advanced integrations can import the native signal primitives and adapter helper
58
- directly from `coaction`:
60
+ Local stores can import signal primitives from `coaction/local`. Adapter
61
+ authors use the statically separate `coaction/adapter` entry:
59
62
 
60
63
  ```ts
61
- import { computed, defineExternalStoreAdapter, effect, signal } from 'coaction';
64
+ import { computed, effect, signal } from 'coaction/local';
65
+ import { defineExternalStoreAdapter } from 'coaction/adapter';
62
66
  ```
63
67
 
64
- Store methods using `this` are rebound to the latest state when invoked from
65
- `getState()`, so destructuring remains safe:
68
+ ### Adapter and Middleware Utilities
69
+
70
+ `coaction/adapter` exports utilities for adapter and middleware authors. These are not needed for normal application state updates, but they are part of the supported integration surface used by the official packages:
71
+
72
+ - Mutable adapter helpers: `applyMutableAdapterPatches`, `replaceMutableAdapterState`, `toMutableAdapterSnapshot`, `snapshotMutableAdapterPureState`, `isEqualMutableAdapterSnapshot`, `getMutableAdapterOwnEnumerableKeys`, `isMutableAdapterUnsafeKey`.
73
+ - Root replacement helpers: `createRootReplacementPatches`, `applyRootReplacementWithPatches`.
74
+ - Patch safety helpers: `assertSafePatches`, `sanitizePatches`, `UnsafePatchPathError`.
75
+ - State shape helpers: `StateSchemaError`, `isStateSchemaError`, `sanitizeReplacementState`, `sanitizeInitialStateValue`, `replaceOwnEnumerable`.
76
+
77
+ Runtime mutation paths reject unsafe patch paths before applying state changes. If a `store.patch()` hook returns a path containing `__proto__`, `prototype`, or `constructor`, Coaction throws `UnsafePatchPathError` instead of silently dropping that patch and applying the rest.
78
+
79
+ ### Shared JSON contract
80
+
81
+ Import `create` from `coaction/shared` when state crosses a Worker,
82
+ SharedWorker, or injected transport boundary:
83
+
84
+ ```ts
85
+ import { create } from 'coaction/shared';
86
+ ```
87
+
88
+ Shared state, action arguments, action results, patch values, and full-sync
89
+ snapshots must be JSON trees: finite numbers, strings, booleans, null, dense
90
+ arrays, and plain records. Coaction rejects values that JSON would normalize or
91
+ cannot represent losslessly, including `undefined`, `BigInt`, `NaN`, infinity,
92
+ negative zero, functions in data, symbols, accessors, platform objects, sparse
93
+ arrays, circular references, and repeated object references. Local stores do
94
+ not inherit this restriction.
95
+
96
+ An authority and every connected client must use the same Coaction major and
97
+ wire protocol. Mixed-major shared deployments are unsupported.
98
+
99
+ Store methods using `this` are rebound to the latest state when invoked from `getState()`, so destructuring remains safe:
66
100
 
67
101
  ```ts
68
102
  const store = create((set) => ({
@@ -85,11 +119,7 @@ increment();
85
119
 
86
120
  ### Store Shape Mode (`sliceMode`)
87
121
 
88
- `create()` uses `sliceMode: 'auto'` by default. For backward compatibility,
89
- `auto` still treats a non-empty object whose enumerable values are all
90
- functions as slices. That shape is ambiguous with a plain store that only
91
- contains methods, so development builds warn and you should set `sliceMode`
92
- explicitly.
122
+ `create()` uses `sliceMode: 'auto'` by default. For backward compatibility, `auto` still treats a non-empty object whose enumerable values are all functions as slices. That shape is ambiguous with a plain store that only contains methods, so development builds warn and you should set `sliceMode` explicitly.
93
123
 
94
124
  You can force behavior explicitly:
95
125
 
package/adapter.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './dist/adapter';
package/adapter.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./dist/adapter.js');
@@ -0,0 +1,468 @@
1
+ import { Transport } from "data-transport";
2
+ import { Draft, Patches } from "mutative";
3
+
4
+ //#region packages/core/src/interface.d.ts
5
+ /**
6
+ * Generic object shape used by stores and slices.
7
+ */
8
+ type ISlices<T = any> = Record<PropertyKey, T>;
9
+ /**
10
+ * Recursive partial object accepted by {@link Store.setState} when merging a
11
+ * plain object payload into the current state tree.
12
+ */
13
+ type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] };
14
+ /**
15
+ * Subscription callback invoked after the store publishes a state change.
16
+ */
17
+ type Listener = () => void;
18
+ /**
19
+ * Patch pair exposed to middleware compatibility hooks.
20
+ */
21
+ interface PatchTransform {
22
+ patches: Patches;
23
+ inversePatches: Patches;
24
+ }
25
+ /**
26
+ * Trace envelope emitted before and after a store method executes.
27
+ */
28
+ interface StoreTraceEvent {
29
+ /**
30
+ * The id of the method.
31
+ */
32
+ id: string;
33
+ /**
34
+ * The method name.
35
+ */
36
+ method: string;
37
+ /**
38
+ * The slice key.
39
+ */
40
+ sliceKey?: PropertyKey;
41
+ /**
42
+ * The parameters of the method.
43
+ */
44
+ parameters?: any[];
45
+ /**
46
+ * The result of the method.
47
+ */
48
+ result?: any;
49
+ }
50
+ /**
51
+ * Runtime store contract returned by {@link create} before framework-specific
52
+ * wrappers add selectors or reactivity helpers.
53
+ *
54
+ * @remarks
55
+ * `getState()` returns methods and getters alongside plain data. Methods
56
+ * extracted from the returned object keep the correct `this` binding when they
57
+ * are later invoked.
58
+ */
59
+ interface Store<T extends ISlices = ISlices> {
60
+ /**
61
+ * The name of the store.
62
+ */
63
+ name: string;
64
+ /**
65
+ * Mutate the current state.
66
+ *
67
+ * @remarks
68
+ * Pass a deep-partial object to merge fields, or pass an updater to edit a
69
+ * Mutative draft. Passing `null` is a no-op. Client-side shared stores intentionally reject direct
70
+ * `setState()` calls; trigger a store method instead.
71
+ */
72
+ setState: (
73
+ /**
74
+ * The next partial state, or an updater that mutates a draft.
75
+ */
76
+
77
+ next: DeepPartial<T> | ((draft: Draft<T>) => any) | null,
78
+ /**
79
+ * Low-level updater hook used by transports and middleware integrations.
80
+ */
81
+
82
+ updater?: (next: DeepPartial<T> | ((draft: Draft<T>) => any) | null) => [] | [T, Patches, Patches]) => void;
83
+ /**
84
+ * Read the current state object.
85
+ *
86
+ * @remarks
87
+ * The returned object includes methods and getters. Methods destructured from
88
+ * this object continue to execute against the latest store state.
89
+ */
90
+ getState: () => T;
91
+ /**
92
+ * Subscribe to state changes.
93
+ *
94
+ * @returns A function that removes the listener.
95
+ */
96
+ subscribe: (listener: Listener) => () => void;
97
+ /**
98
+ * Tear down the store.
99
+ *
100
+ * @remarks
101
+ * `destroy()` is idempotent. It clears subscriptions and disposes any
102
+ * attached transport.
103
+ */
104
+ destroy: () => void;
105
+ /**
106
+ * Indicates whether the store is local, the main shared store, or a client
107
+ * mirror of a shared store.
108
+ */
109
+ share?: 'main' | 'client' | false;
110
+ /**
111
+ * Transport used to synchronize a shared store between processes or threads.
112
+ */
113
+ transport?: Transport;
114
+ /**
115
+ * Whether `createState` was interpreted as a slices object.
116
+ */
117
+ isSliceStore: boolean;
118
+ /**
119
+ * Apply patches to the current state.
120
+ *
121
+ * @remarks
122
+ * This is a low-level hook used by transports and middleware. Application
123
+ * code should generally prefer store methods or `setState()`. Client-side
124
+ * shared-store mirrors reject direct `apply()` calls.
125
+ */
126
+ apply: (state?: T, patches?: Patches) => void;
127
+ /**
128
+ * Return the current state without methods or getters.
129
+ *
130
+ * @remarks
131
+ * Useful for serialization, inspection, or tests that only care about raw
132
+ * data.
133
+ */
134
+ getPureState: () => T;
135
+ /**
136
+ * Return the state produced during initialization before later mutations.
137
+ */
138
+ getInitialState: () => T;
139
+ /**
140
+ * @deprecated Middleware compatibility hook. Prefer typing middleware stores
141
+ * with `MiddlewareStore`.
142
+ */
143
+ patch?: (option: PatchTransform) => PatchTransform;
144
+ /**
145
+ * @deprecated Middleware compatibility hook. Prefer typing middleware stores
146
+ * with `MiddlewareStore`.
147
+ */
148
+ trace?: (options: StoreTraceEvent) => void;
149
+ }
150
+ /**
151
+ * Semantic alias for middleware-facing stores.
152
+ *
153
+ * @remarks
154
+ * Middleware implementations should type their `store` parameter as
155
+ * `MiddlewareStore` instead of relying on deprecated `patch` or `trace` hooks.
156
+ */
157
+ interface MiddlewareStore<T extends ISlices = ISlices> extends Store<T> {}
158
+ /**
159
+ * Helper passed into {@link Slice} and {@link Slices} factories.
160
+ *
161
+ * @remarks
162
+ * Call it with no arguments to read the current store state. Call it with a
163
+ * dependency selector pair to define a computed value.
164
+ */
165
+ interface Getter<T extends ISlices> {
166
+ <P extends any[], R>(getDeps: (store: T) => readonly [...P] | [...P], selector: (...args: P) => R): R;
167
+ (): T;
168
+ }
169
+ /**
170
+ * Factory for a single store object.
171
+ *
172
+ * @remarks
173
+ * Return a plain object containing state, getters, and methods. Methods and
174
+ * getters may use `this` to access the live store state.
175
+ */
176
+ type Slice<T extends ISlices> = (
177
+ /**
178
+ * The setState is used to update the state.
179
+ */
180
+ set: Store<T>['setState'],
181
+ /**
182
+ * The getState is used to get the state.
183
+ */
184
+ get: Getter<T>,
185
+ /**
186
+ * The store is used to store the state.
187
+ */
188
+ store: Store<T>) => T;
189
+ /**
190
+ * Store enhancer invoked during store creation.
191
+ *
192
+ * @remarks
193
+ * Middleware may mutate the received store in place or return a replacement
194
+ * store object, but it must preserve the {@link Store} contract.
195
+ */
196
+ type Middleware<T extends CreateState> = (store: MiddlewareStore<T>) => MiddlewareStore<T>;
197
+ /**
198
+ * Callable store returned by {@link create} in local or main/shared mode.
199
+ */
200
+ type StoreReturn<T extends object> = Store<T> & ((...args: any[]) => T);
201
+ /**
202
+ * Accepted `create()` input shape.
203
+ *
204
+ * @remarks
205
+ * This can be either a single store factory/object or a map of slice
206
+ * factories.
207
+ */
208
+ type CreateState = ISlices | Record<PropertyKey, Slice<any>>;
209
+ //#endregion
210
+ //#region packages/core/src/internal.d.ts
211
+ type MutationOperation = 'setState' | 'apply';
212
+ type StoreOperation = MutationOperation | 'subscribe' | 'store initialization' | `action ${string}`;
213
+ type SignalSlot = {
214
+ refresh: () => void;
215
+ };
216
+ type StateSchema = {
217
+ rootKeys: Set<PropertyKey>;
218
+ sliceKeys?: Map<PropertyKey, Set<PropertyKey>>;
219
+ };
220
+ interface Internal<T extends CreateState = CreateState> {
221
+ /**
222
+ * The store module.
223
+ */
224
+ module: T;
225
+ /**
226
+ * The root state.
227
+ */
228
+ rootState: T | Draft<T>;
229
+ /**
230
+ * The backup state.
231
+ */
232
+ backupState: T | Draft<T>;
233
+ /**
234
+ * Finalize the draft.
235
+ */
236
+ finalizeDraft: () => [T, Patches, Patches];
237
+ /**
238
+ * The mutable instance.
239
+ */
240
+ mutableInstance: any;
241
+ /**
242
+ * The sequence number.
243
+ */
244
+ sequence: number;
245
+ /** Identifies the lifetime of the current shared authority. */
246
+ transportEpoch?: string;
247
+ /** Action paths declared when the authoritative store was initialized. */
248
+ sharedActionPaths?: Set<string>;
249
+ /**
250
+ * Whether the batch is running.
251
+ */
252
+ isBatching: boolean;
253
+ /** Depth of a cached getter/computed evaluation over immutable state. */
254
+ computedReadDepth?: number;
255
+ /** Frozen snapshots keyed by immutable state object identity. */
256
+ computedSnapshotCache?: WeakMap<object, unknown>;
257
+ /** Immutable state sources keyed by frozen computed snapshot identity. */
258
+ computedSnapshotSources?: WeakMap<object, object>;
259
+ /** Whether a computed getter has returned a state snapshot object. */
260
+ computedIdentityRequired?: boolean;
261
+ /**
262
+ * The listeners.
263
+ */
264
+ listeners: Set<Listener>;
265
+ /** Cleanup callbacks owned by transport and integration layers. */
266
+ destroyCallbacks?: Set<() => void>;
267
+ /**
268
+ * Publish an externally-owned immutable state change to signal slots and
269
+ * store subscribers.
270
+ */
271
+ notifyStateChange: () => void;
272
+ /**
273
+ * Reactive state slots used by computed getters/selectors.
274
+ */
275
+ signalSlots?: Set<SignalSlot>;
276
+ /**
277
+ * State keys that are allowed after initialization.
278
+ */
279
+ stateSchema?: StateSchema;
280
+ /**
281
+ * The act is used to run the function in the action for mutable state.
282
+ */
283
+ actMutable?: <T extends () => any>(fn: T) => ReturnType<T>;
284
+ /**
285
+ * Get the mutable raw instance via the initial state.
286
+ */
287
+ toMutableRaw?: (key: any) => any;
288
+ /**
289
+ * The update immutable function.
290
+ */
291
+ updateImmutable?: (state: T) => void;
292
+ /**
293
+ * Adapter-level authority check for low-level mutations.
294
+ */
295
+ assertMutationAllowed?: (operation: MutationOperation) => void;
296
+ /**
297
+ * Store lifecycle guard.
298
+ */
299
+ assertAlive?: (operation: StoreOperation) => void;
300
+ /**
301
+ * Authorized client-mirror state application used by transports.
302
+ */
303
+ applyClientState?: (state?: T, patches?: Patches) => void;
304
+ /** Request an authoritative full sync for a client mirror. */
305
+ syncClientState?: (expectedEpoch?: string, minimumSequence?: number) => Promise<void>;
306
+ /** Cancel a transport promise when the client mirror is destroyed. */
307
+ awaitClientTransport?: <R>(value: PromiseLike<R> | R) => Promise<R>;
308
+ /** Validate committed state when a runtime capability requires it. */
309
+ validateState?: (state: unknown) => void;
310
+ /** Validate outbound patches before normalization or commit. */
311
+ validatePatches?: (patches: Patches) => void;
312
+ /** Validate an adapter replacement source before reading its values. */
313
+ validateReplacementSource?: (state: unknown) => void;
314
+ /** Commit patches already checked by the native updater. */
315
+ applyValidatedPatches?: (state: T, patches: Patches, skipFinalValidation: boolean) => boolean;
316
+ /** Publish patches when a shared authority transport is attached. */
317
+ emitPatches?: (patches: Patches) => void;
318
+ /** Return the plain state exposed at the JSON transport boundary. */
319
+ getTransportState?: () => unknown;
320
+ }
321
+ //#endregion
322
+ //#region packages/core/src/binder.d.ts
323
+ type ExternalStoreAdapterOptions<F = (...args: any[]) => any> = {
324
+ /**
325
+ * Normalize a third-party store instance into a raw state object plus the
326
+ * binding hook used during initialization.
327
+ */
328
+ handleState: <T extends object = object>(state: T) => {
329
+ /**
330
+ * Copy of the incoming state object that Coaction should consume.
331
+ */
332
+ copyState: T;
333
+ /**
334
+ * Optional nested key when the adapter exposes a single child object from
335
+ * the third-party store.
336
+ */
337
+ key?: keyof T;
338
+ /**
339
+ * Convert the external state object into the raw state shape used by
340
+ * Coaction.
341
+ */
342
+ bind: (state: T) => T;
343
+ };
344
+ /**
345
+ * Wire Coaction's store lifecycle to the external store implementation.
346
+ */
347
+ handleStore: (
348
+ /**
349
+ * Coaction store wrapper.
350
+ */
351
+
352
+ store: Store<object>,
353
+ /**
354
+ * Raw state object returned from `bind`.
355
+ */
356
+
357
+ rawState: object,
358
+ /**
359
+ * Original external store state object.
360
+ */
361
+
362
+ state: object,
363
+ /**
364
+ * Low-level Coaction adapter hooks used by official bindings.
365
+ */
366
+
367
+ internal: Internal<object>,
368
+ /**
369
+ * Optional nested key returned by `handleState`.
370
+ */
371
+
372
+ key?: PropertyKey) => void;
373
+ };
374
+ /**
375
+ * Build an adapter helper for bridging an external store implementation into
376
+ * Coaction.
377
+ *
378
+ * @remarks
379
+ * Import this compatibility helper from `coaction/adapter`.
380
+ *
381
+ * Official bindings use this to integrate stores such as Redux, Jotai, Pinia,
382
+ * Zustand, MobX, and Valtio. Binder-backed integrations are whole-store
383
+ * adapters; they are not compatible with Coaction slices mode.
384
+ */
385
+ declare function createBinder<F = (...args: any[]) => any>({
386
+ handleState,
387
+ handleStore
388
+ }: ExternalStoreAdapterOptions<F>): F;
389
+ /**
390
+ * Define a whole-store adapter for integrating an external state runtime with
391
+ * Coaction.
392
+ *
393
+ * @remarks
394
+ * Import this helper from `coaction/adapter`. `createBinder()` remains as a
395
+ * compatibility alias for existing official and community integrations.
396
+ */
397
+ declare function defineExternalStoreAdapter<F = (...args: any[]) => any>(options: ExternalStoreAdapterOptions<F>): F;
398
+ //#endregion
399
+ //#region packages/core/src/externalMutableAdapterUtils.d.ts
400
+ declare const getMutableAdapterOwnEnumerableKeys: (value: object) => (string | symbol)[];
401
+ declare const isMutableAdapterUnsafeKey: (key: PropertyKey) => key is "__proto__" | "prototype" | "constructor";
402
+ declare const replaceMutableAdapterState: (rawState: Record<PropertyKey, unknown>, mutableState: Record<PropertyKey, unknown>, publicState: Record<PropertyKey, unknown>, source: Record<PropertyKey, unknown>) => void;
403
+ declare const applyMutableAdapterPatches: (baseState: unknown, patches: Patches, rawState: Record<PropertyKey, unknown>, mutableState: Record<PropertyKey, unknown>, publicState: Record<PropertyKey, unknown>, validateState?: (state: unknown) => void) => void;
404
+ declare const toMutableAdapterSnapshot: (value: unknown, visited?: WeakMap<object, unknown>) => unknown;
405
+ declare const snapshotMutableAdapterPureState: (store: Store<object>) => Record<PropertyKey, unknown>;
406
+ declare const isEqualMutableAdapterSnapshot: (left: unknown, right: unknown, visited?: WeakMap<object, WeakSet<object>>) => boolean;
407
+ //#endregion
408
+ //#region packages/core/src/reactiveTracker.d.ts
409
+ type ReactiveTracker = {
410
+ getSnapshot: () => number;
411
+ subscribe: (listener: () => void) => () => void;
412
+ track: <T>(fn: () => T) => T;
413
+ dispose: () => void;
414
+ };
415
+ /**
416
+ * Create a low-level signal dependency tracker for framework adapters.
417
+ *
418
+ * @remarks
419
+ * Adapter and framework authors import this helper from `coaction/adapter`.
420
+ */
421
+ declare const createReactiveTracker: () => ReactiveTracker;
422
+ //#endregion
423
+ //#region packages/core/src/lifecycle.d.ts
424
+ declare const onStoreReady: <T extends CreateState>(store: Store<T>, callback: () => void) => () => void;
425
+ //#endregion
426
+ //#region packages/core/src/replaceExternalStoreState.d.ts
427
+ type ReplaceExternalStoreStateOptions = {
428
+ syncImmutable?: boolean;
429
+ };
430
+ declare const replaceExternalStoreState: <T extends CreateState>(store: MiddlewareStore<T>, internal: Internal<T>, source: Record<PropertyKey, unknown>, {
431
+ syncImmutable
432
+ }?: ReplaceExternalStoreStateOptions) => void;
433
+ //#endregion
434
+ //#region packages/core/src/utils.d.ts
435
+ declare class StateSchemaError extends Error {
436
+ name: string;
437
+ }
438
+ declare const isStateSchemaError: (error: unknown) => error is StateSchemaError;
439
+ type RootReplacementPatch = {
440
+ op: 'add' | 'remove' | 'replace';
441
+ path: PropertyKey[];
442
+ value?: unknown;
443
+ };
444
+ declare const createRootReplacementPatches: (currentState: Record<PropertyKey, unknown>, nextState: Record<PropertyKey, unknown>) => {
445
+ patches: RootReplacementPatch[];
446
+ inversePatches: RootReplacementPatch[];
447
+ };
448
+ declare const applyRootReplacementWithPatches: <T extends object>(store: MiddlewareStore<T>, nextState: Record<PropertyKey, unknown>, options?: {
449
+ applyExactReplacement?: (state: T) => void;
450
+ }) => [T, Patches, Patches];
451
+ declare const replaceOwnEnumerable: (target: Record<PropertyKey, unknown>, source: Record<PropertyKey, unknown>) => void;
452
+ declare const sanitizeReplacementState: <T>(source: T, seen?: WeakMap<object, unknown>) => T;
453
+ declare const sanitizeInitialStateValue: <T>(source: T, seen?: WeakMap<object, unknown>) => T;
454
+ //#endregion
455
+ //#region packages/core/src/wrapStore.d.ts
456
+ /**
457
+ * Convert a store object into Coaction's callable store shape.
458
+ *
459
+ * @remarks
460
+ * Framework bindings use this to attach selector-aware readers while
461
+ * preserving the underlying store API on the returned function object. Most
462
+ * applications should use a public `create` entry instead of calling
463
+ * `wrapStore()` directly. Framework authors import this helper from
464
+ * `coaction/local` or `coaction/adapter`.
465
+ */
466
+ declare const wrapStore: <T extends object>(store: Store<T>, getState?: (...args: unknown[]) => T) => StoreReturn<T>;
467
+ //#endregion
468
+ export { type CreateState, type ExternalStoreAdapterOptions, type Middleware, type MiddlewareStore, type PatchTransform, type ReactiveTracker, StateSchemaError, type Store, type StoreTraceEvent, applyMutableAdapterPatches, applyRootReplacementWithPatches, createBinder, createReactiveTracker, createRootReplacementPatches, defineExternalStoreAdapter, getMutableAdapterOwnEnumerableKeys, isEqualMutableAdapterSnapshot, isMutableAdapterUnsafeKey, isStateSchemaError, onStoreReady, replaceExternalStoreState, replaceMutableAdapterState, replaceOwnEnumerable, sanitizeInitialStateValue, sanitizeReplacementState, snapshotMutableAdapterPureState, toMutableAdapterSnapshot, wrapStore };