@camcima/finita 2.2.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 +50 -51
- package/dist/index.cjs +789 -520
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +314 -127
- package/dist/index.d.ts +314 -127
- package/dist/index.js +778 -516
- package/dist/index.js.map +1 -1
- package/package.json +16 -6
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
[](https://codecov.io/gh/camcima/finita)
|
|
12
12
|
[](https://www.npmjs.com/package/@camcima/finita)
|
|
13
13
|
[](https://opensource.org/licenses/MIT)
|
|
14
|
-
[](https://www.typescriptlang.org/)
|
|
15
|
+
[](https://nodejs.org/)
|
|
16
16
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
@@ -31,15 +31,14 @@ This library is a TypeScript port of [metabor/statemachine](https://github.com/M
|
|
|
31
31
|
- **Transition Selectors** -- pluggable strategies for resolving ambiguous transitions (score-based, weight-based)
|
|
32
32
|
- **Mutex/Locking** -- concurrency control with pluggable lock adapters
|
|
33
33
|
- **Factory Pattern** -- create pre-configured state machines from subject objects
|
|
34
|
-
- **
|
|
34
|
+
- **ProcessBuilder** -- fluent, validated API for building frozen, immutable state graphs
|
|
35
35
|
- **Graph Visualization** -- build graph data structures for rendering with GraphViz or other tools
|
|
36
|
-
- **Setup Helper** -- fluent API for building state machines from configuration
|
|
37
36
|
- **Zero Dependencies** -- no runtime dependencies
|
|
38
37
|
|
|
39
38
|
## Installation
|
|
40
39
|
|
|
41
40
|
```bash
|
|
42
|
-
|
|
41
|
+
pnpm add @camcima/finita
|
|
43
42
|
```
|
|
44
43
|
|
|
45
44
|
## Quick Start
|
|
@@ -53,20 +52,19 @@ stateDiagram-v2
|
|
|
53
52
|
```
|
|
54
53
|
|
|
55
54
|
```typescript
|
|
56
|
-
import {
|
|
57
|
-
|
|
58
|
-
// Define
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Create
|
|
69
|
-
const process = new Process("article-workflow", draft);
|
|
55
|
+
import { ProcessBuilder, Statemachine } from "@camcima/finita";
|
|
56
|
+
|
|
57
|
+
// Define the process
|
|
58
|
+
const process = new ProcessBuilder("article-workflow")
|
|
59
|
+
.addState("draft", { initial: true })
|
|
60
|
+
.addState("published")
|
|
61
|
+
.addState("archived")
|
|
62
|
+
.addTransition("draft", "published", { event: "publish" })
|
|
63
|
+
.addTransition("published", "archived", { event: "archive" })
|
|
64
|
+
.addTransition("archived", "draft", { event: "reopen" })
|
|
65
|
+
.build();
|
|
66
|
+
|
|
67
|
+
// Create the state machine
|
|
70
68
|
const article = { title: "Hello World" };
|
|
71
69
|
const sm = new Statemachine(article, process);
|
|
72
70
|
|
|
@@ -87,9 +85,7 @@ Use the `TSubject` generic parameter for type-safe access to your domain object
|
|
|
87
85
|
|
|
88
86
|
```typescript
|
|
89
87
|
import {
|
|
90
|
-
|
|
91
|
-
Transition,
|
|
92
|
-
Process,
|
|
88
|
+
ProcessBuilder,
|
|
93
89
|
Statemachine,
|
|
94
90
|
CallbackCondition,
|
|
95
91
|
} from "@camcima/finita";
|
|
@@ -99,17 +95,21 @@ interface Order {
|
|
|
99
95
|
total: number;
|
|
100
96
|
}
|
|
101
97
|
|
|
102
|
-
const pending = new State("pending");
|
|
103
|
-
const approved = new State("approved");
|
|
104
|
-
|
|
105
98
|
// subject is typed as Order -- no cast needed
|
|
106
99
|
const canApprove = new CallbackCondition<Order>(
|
|
107
100
|
"canApprove",
|
|
108
101
|
(order) => order.total <= 1000,
|
|
109
102
|
);
|
|
110
|
-
pending.addTransition(new Transition(approved, "review", canApprove));
|
|
111
103
|
|
|
112
|
-
const process = new
|
|
104
|
+
const process = new ProcessBuilder<Order>("order")
|
|
105
|
+
.addState("pending", { initial: true })
|
|
106
|
+
.addState("approved")
|
|
107
|
+
.addTransition("pending", "approved", {
|
|
108
|
+
event: "review",
|
|
109
|
+
condition: canApprove,
|
|
110
|
+
})
|
|
111
|
+
.build();
|
|
112
|
+
|
|
113
113
|
const sm = new Statemachine<Order>({ id: 1, total: 500 }, process);
|
|
114
114
|
|
|
115
115
|
const order = sm.getSubject(); // typed as Order
|
|
@@ -148,17 +148,17 @@ classDiagram
|
|
|
148
148
|
|
|
149
149
|
Detailed documentation for every component:
|
|
150
150
|
|
|
151
|
-
- **[Core](docs/core.md)** -- State, Transition, Event, Process, Statemachine, Dispatcher, StateCollection
|
|
152
|
-
- **[Conditions](docs/conditions.md)** -- Tautology, Contradiction, CallbackCondition, Timeout, AndComposite, OrComposite, Not
|
|
153
|
-
- **[Observers](docs/observers.md)** -- CallbackObserver, StatefulStatusChanger, OnEnterObserver, TransitionLogger
|
|
154
|
-
- **[Filters](docs/filters.md)** -- ActiveTransitionFilter, FilterStateByEvent, FilterStateByTransition, FilterStateByFinalState, FilterTransitionByEvent
|
|
155
|
-
- **[Selectors](docs/selectors.md)** -- OneOrNoneActiveTransition, ScoreTransition, WeightTransition
|
|
156
|
-
- **[Mutex](docs/mutex.md)** -- NullMutex, LockAdapterMutex, MutexFactory
|
|
157
|
-
- **[Factory](docs/factory.md)** -- Factory, SingleProcessDetector, AbstractNamedProcessDetector, StatefulStateNameDetector
|
|
158
|
-
- **[
|
|
159
|
-
- **[
|
|
160
|
-
- **[
|
|
161
|
-
- **[
|
|
151
|
+
- **[Core](https://github.com/camcima/finita/blob/main/docs/core.md)** -- State, Transition, Event, Process, Statemachine, Dispatcher, StateCollection
|
|
152
|
+
- **[Conditions](https://github.com/camcima/finita/blob/main/docs/conditions.md)** -- Tautology, Contradiction, CallbackCondition, Timeout, AndComposite, OrComposite, Not
|
|
153
|
+
- **[Observers](https://github.com/camcima/finita/blob/main/docs/observers.md)** -- CallbackObserver, StatefulStatusChanger, OnEnterObserver, TransitionLogger
|
|
154
|
+
- **[Filters](https://github.com/camcima/finita/blob/main/docs/filters.md)** -- ActiveTransitionFilter, FilterStateByEvent, FilterStateByTransition, FilterStateByFinalState, FilterTransitionByEvent
|
|
155
|
+
- **[Selectors](https://github.com/camcima/finita/blob/main/docs/selectors.md)** -- OneOrNoneActiveTransition, ScoreTransition, WeightTransition
|
|
156
|
+
- **[Mutex](https://github.com/camcima/finita/blob/main/docs/mutex.md)** -- NullMutex, LockAdapterMutex, MutexFactory
|
|
157
|
+
- **[Factory](https://github.com/camcima/finita/blob/main/docs/factory.md)** -- Factory, SingleProcessDetector, AbstractNamedProcessDetector, StatefulStateNameDetector
|
|
158
|
+
- **[Graph](https://github.com/camcima/finita/blob/main/docs/graph.md)** -- GraphBuilder
|
|
159
|
+
- **[Errors](https://github.com/camcima/finita/blob/main/docs/errors.md)** -- WrongEventForStateError, LockCanNotBeAcquiredError, DuplicateStateError, ProcessFinalizedError, GraphValidationError, DuplicateTransitionError
|
|
160
|
+
- **[Interfaces](https://github.com/camcima/finita/blob/main/docs/interfaces.md)** -- All TypeScript interfaces
|
|
161
|
+
- **[Migration Guide](https://github.com/camcima/finita/blob/main/docs/migration/v2-to-v3.md)** -- Upgrading from v2 to v3
|
|
162
162
|
|
|
163
163
|
## Examples
|
|
164
164
|
|
|
@@ -170,13 +170,12 @@ A complete working example (order processing with prepayment and postpayment wor
|
|
|
170
170
|
src/
|
|
171
171
|
index.ts # Barrel export
|
|
172
172
|
MaybePromise.ts # MaybePromise<T> = T | Promise<T> utility type
|
|
173
|
+
ProcessBuilder.ts # Fluent builder for frozen graph construction
|
|
173
174
|
Event.ts # Event implementation
|
|
174
|
-
State.ts # State implementation
|
|
175
|
-
Transition.ts # Transition implementation
|
|
176
|
-
|
|
177
|
-
Process.ts # Process (workflow definition)
|
|
175
|
+
State.ts # State implementation (frozen; use ProcessBuilder)
|
|
176
|
+
Transition.ts # Transition implementation (frozen; use ProcessBuilder)
|
|
177
|
+
Process.ts # Process (workflow definition; use ProcessBuilder)
|
|
178
178
|
Statemachine.ts # Runtime state machine
|
|
179
|
-
Dispatcher.ts # Deferred event dispatcher
|
|
180
179
|
interfaces/ # All TypeScript interfaces
|
|
181
180
|
condition/ # Condition (guard) implementations
|
|
182
181
|
observer/ # Observer implementations
|
|
@@ -184,7 +183,7 @@ src/
|
|
|
184
183
|
selector/ # Transition selection strategies
|
|
185
184
|
mutex/ # Locking implementations
|
|
186
185
|
factory/ # State machine factory pattern
|
|
187
|
-
|
|
186
|
+
internal/ # Internal helpers (OperationQueue, InternalConstruction)
|
|
188
187
|
graph/ # Graph visualization builder
|
|
189
188
|
error/ # Custom error classes
|
|
190
189
|
```
|
|
@@ -204,8 +203,8 @@ src/
|
|
|
204
203
|
### Manual checks
|
|
205
204
|
|
|
206
205
|
```bash
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
pnpm run security:audit # dependency audit
|
|
207
|
+
pnpm run security:secrets # Scan full repo for secrets (requires gitleaks)
|
|
209
208
|
```
|
|
210
209
|
|
|
211
210
|
Install Gitleaks: <https://github.com/gitleaks/gitleaks#installing>
|
|
@@ -214,19 +213,19 @@ Install Gitleaks: <https://github.com/gitleaks/gitleaks#installing>
|
|
|
214
213
|
|
|
215
214
|
```bash
|
|
216
215
|
# Install dependencies
|
|
217
|
-
|
|
216
|
+
pnpm install
|
|
218
217
|
|
|
219
218
|
# Run tests
|
|
220
|
-
|
|
219
|
+
pnpm test
|
|
221
220
|
|
|
222
221
|
# Run tests in watch mode
|
|
223
|
-
|
|
222
|
+
pnpm run test:watch
|
|
224
223
|
|
|
225
224
|
# Type check
|
|
226
|
-
|
|
225
|
+
pnpm run lint
|
|
227
226
|
|
|
228
227
|
# Build
|
|
229
|
-
|
|
228
|
+
pnpm run build
|
|
230
229
|
```
|
|
231
230
|
|
|
232
231
|
## License
|