coaction 1.5.0 → 2.1.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,17 +1,17 @@
1
1
  # coaction
2
2
 
3
- ![Node CI](https://github.com/unadlib/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)
6
4
 
7
5
  An efficient and flexible state management library for building high-performance, multithreading web applications.
8
6
 
7
+ 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.
8
+
9
9
  ## Installation
10
10
 
11
- You can install it via npm, yarn or pnpm.
11
+ Install it with pnpm:
12
12
 
13
13
  ```sh
14
- npm install coaction
14
+ pnpm add coaction
15
15
  ```
16
16
 
17
17
  ## Usage
@@ -19,14 +19,60 @@ npm install coaction
19
19
  ```jsx
20
20
  import { create } from 'coaction';
21
21
 
22
- const useStore = create((set) => ({
22
+ const store = create((set) => ({
23
23
  count: 0,
24
- increment: () => set((state) => state.count++)
24
+ get doubleCount() {
25
+ return this.count * 2;
26
+ },
27
+ increment() {
28
+ set(() => {
29
+ this.count += 1;
30
+ });
31
+ }
25
32
  }));
26
33
  ```
27
34
 
28
- Store methods using `this` are rebound to the latest state when invoked from
29
- `getState()`, so destructuring remains safe:
35
+ 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.
36
+
37
+ 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.
38
+
39
+ 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.
40
+
41
+ Accessor getters are cached automatically through the built-in signal runtime. Use `get(deps, selector)` when you want to declare dependencies manually:
42
+
43
+ ```ts
44
+ const store = create((set, get) => ({
45
+ count: 0,
46
+ doubleCount: get(
47
+ (state) => [state.count],
48
+ (count) => count * 2
49
+ ),
50
+ increment() {
51
+ set(() => {
52
+ this.count += 1;
53
+ });
54
+ }
55
+ }));
56
+ ```
57
+
58
+ Advanced integrations can import the native signal primitives and adapter helper directly from `coaction`:
59
+
60
+ ```ts
61
+ import { computed, defineExternalStoreAdapter, effect, signal } from 'coaction';
62
+ ```
63
+
64
+ ### Adapter and Middleware Utilities
65
+
66
+ `coaction` also 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:
67
+
68
+ - Mutable adapter helpers: `applyMutableAdapterPatches`, `replaceMutableAdapterState`, `toMutableAdapterSnapshot`, `snapshotMutableAdapterPureState`, `isEqualMutableAdapterSnapshot`, `getMutableAdapterOwnEnumerableKeys`, `isMutableAdapterUnsafeKey`.
69
+ - Root replacement helpers: `createRootReplacementPatches`, `applyRootReplacementWithPatches`.
70
+ - Patch safety helpers: `assertSafePatches`, `sanitizePatches`, `UnsafePatchPathError`.
71
+ - State shape helpers: `StateSchemaError`, `isStateSchemaError`, `sanitizeReplacementState`, `sanitizeInitialStateValue`, `replaceOwnEnumerable`.
72
+
73
+ 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.
74
+
75
+ Store methods using `this` are rebound to the latest state when invoked from `getState()`, so destructuring remains safe:
30
76
 
31
77
  ```ts
32
78
  const store = create((set) => ({
@@ -44,16 +90,12 @@ increment();
44
90
 
45
91
  ## API Reference
46
92
 
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)
93
+ - [Generated core API index](https://github.com/coactionjs/coaction/blob/main/docs/api/core/index.md)
94
+ - [Core API notes](https://github.com/coactionjs/coaction/blob/main/docs/api/core/documents/core-api-notes.md)
49
95
 
50
96
  ### Store Shape Mode (`sliceMode`)
51
97
 
52
- `create()` uses `sliceMode: 'auto'` by default. For backward compatibility,
53
- `auto` still treats a non-empty object whose enumerable values are all
54
- functions as slices. That shape is ambiguous with a plain store that only
55
- contains methods, so development builds warn and you should set `sliceMode`
56
- explicitly.
98
+ `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.
57
99
 
58
100
  You can force behavior explicitly:
59
101
 
@@ -67,4 +109,4 @@ create({ counter: (set) => ({ count: 0 }) }, { sliceMode: 'slices' });
67
109
 
68
110
  ## Documentation
69
111
 
70
- You can find the documentation [here](https://github.com/unadlib/coaction).
112
+ You can find the documentation [here](https://github.com/coactionjs/coaction).