@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 CHANGED
@@ -11,8 +11,8 @@
11
11
  [![codecov](https://codecov.io/gh/camcima/finita/graph/badge.svg)](https://codecov.io/gh/camcima/finita)
12
12
  [![npm version](https://img.shields.io/npm/v/@camcima/finita)](https://www.npmjs.com/package/@camcima/finita)
13
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)
15
- [![Node.js](https://img.shields.io/badge/Node.js-18%20%7C%2020%20%7C%2022-green.svg)](https://nodejs.org/)
14
+ [![TypeScript](https://img.shields.io/badge/TypeScript-6.0-blue.svg)](https://www.typescriptlang.org/)
15
+ [![Node.js](https://img.shields.io/badge/Node.js-20%20%7C%2022%20%7C%2024-green.svg)](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
- - **Process Merging** -- combine state collections with optional name prefixing
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
- npm install @camcima/finita
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 { State, Transition, Process, Statemachine } from "@camcima/finita";
57
-
58
- // Define states
59
- const draft = new State("draft");
60
- const published = new State("published");
61
- const archived = new State("archived");
62
-
63
- // Define transitions
64
- draft.addTransition(new Transition(published, "publish"));
65
- published.addTransition(new Transition(archived, "archive"));
66
- archived.addTransition(new Transition(draft, "reopen"));
67
-
68
- // Create process and state machine
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
- State,
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 Process("order", pending);
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
- - **[Utilities](docs/utilities.md)** -- SetupHelper, StateCollectionMerger
159
- - **[Graph](docs/graph.md)** -- GraphBuilder
160
- - **[Errors](docs/errors.md)** -- WrongEventForStateError, LockCanNotBeAcquiredError, DuplicateStateError
161
- - **[Interfaces](docs/interfaces.md)** -- All TypeScript interfaces
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
- StateCollection.ts # Named collection of states
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
- util/ # SetupHelper, StateCollectionMerger
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
- npm run security:audit # npm dependency audit
208
- npm run security:secrets # Scan full repo for secrets (requires gitleaks)
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
- npm install
216
+ pnpm install
218
217
 
219
218
  # Run tests
220
- npm test
219
+ pnpm test
221
220
 
222
221
  # Run tests in watch mode
223
- npm run test:watch
222
+ pnpm run test:watch
224
223
 
225
224
  # Type check
226
- npm run lint
225
+ pnpm run lint
227
226
 
228
227
  # Build
229
- npm run build
228
+ pnpm run build
230
229
  ```
231
230
 
232
231
  ## License