@camcima/finita 2.1.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
@@ -6,12 +6,13 @@
6
6
 
7
7
  <br>
8
8
 
9
- [![CI](https://github.com/camcima/finita/actions/workflows/ci.yml/badge.svg)](https://github.com/camcima/finita/actions/workflows/ci.yml)
9
+ [![CI](https://github.com/camcima/finita/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/camcima/finita/actions/workflows/ci.yml)
10
+ [![CodeQL](https://img.shields.io/badge/CodeQL-enabled-brightgreen)](https://github.com/camcima/finita/security/code-scanning)
10
11
  [![codecov](https://codecov.io/gh/camcima/finita/graph/badge.svg)](https://codecov.io/gh/camcima/finita)
11
12
  [![npm version](https://img.shields.io/npm/v/@camcima/finita)](https://www.npmjs.com/package/@camcima/finita)
12
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
13
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)
14
- [![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/)
15
16
 
16
17
  </div>
17
18
 
@@ -30,15 +31,14 @@ This library is a TypeScript port of [metabor/statemachine](https://github.com/M
30
31
  - **Transition Selectors** -- pluggable strategies for resolving ambiguous transitions (score-based, weight-based)
31
32
  - **Mutex/Locking** -- concurrency control with pluggable lock adapters
32
33
  - **Factory Pattern** -- create pre-configured state machines from subject objects
33
- - **Process Merging** -- combine state collections with optional name prefixing
34
+ - **ProcessBuilder** -- fluent, validated API for building frozen, immutable state graphs
34
35
  - **Graph Visualization** -- build graph data structures for rendering with GraphViz or other tools
35
- - **Setup Helper** -- fluent API for building state machines from configuration
36
36
  - **Zero Dependencies** -- no runtime dependencies
37
37
 
38
38
  ## Installation
39
39
 
40
40
  ```bash
41
- npm install @camcima/finita
41
+ pnpm add @camcima/finita
42
42
  ```
43
43
 
44
44
  ## Quick Start
@@ -52,20 +52,19 @@ stateDiagram-v2
52
52
  ```
53
53
 
54
54
  ```typescript
55
- import { State, Transition, Process, Statemachine } from "@camcima/finita";
56
-
57
- // Define states
58
- const draft = new State("draft");
59
- const published = new State("published");
60
- const archived = new State("archived");
61
-
62
- // Define transitions
63
- draft.addTransition(new Transition(published, "publish"));
64
- published.addTransition(new Transition(archived, "archive"));
65
- archived.addTransition(new Transition(draft, "reopen"));
66
-
67
- // Create process and state machine
68
- 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
69
68
  const article = { title: "Hello World" };
70
69
  const sm = new Statemachine(article, process);
71
70
 
@@ -86,9 +85,7 @@ Use the `TSubject` generic parameter for type-safe access to your domain object
86
85
 
87
86
  ```typescript
88
87
  import {
89
- State,
90
- Transition,
91
- Process,
88
+ ProcessBuilder,
92
89
  Statemachine,
93
90
  CallbackCondition,
94
91
  } from "@camcima/finita";
@@ -98,17 +95,21 @@ interface Order {
98
95
  total: number;
99
96
  }
100
97
 
101
- const pending = new State("pending");
102
- const approved = new State("approved");
103
-
104
98
  // subject is typed as Order -- no cast needed
105
99
  const canApprove = new CallbackCondition<Order>(
106
100
  "canApprove",
107
101
  (order) => order.total <= 1000,
108
102
  );
109
- pending.addTransition(new Transition(approved, "review", canApprove));
110
103
 
111
- 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
+
112
113
  const sm = new Statemachine<Order>({ id: 1, total: 500 }, process);
113
114
 
114
115
  const order = sm.getSubject(); // typed as Order
@@ -147,17 +148,17 @@ classDiagram
147
148
 
148
149
  Detailed documentation for every component:
149
150
 
150
- - **[Core](docs/core.md)** -- State, Transition, Event, Process, Statemachine, Dispatcher, StateCollection
151
- - **[Conditions](docs/conditions.md)** -- Tautology, Contradiction, CallbackCondition, Timeout, AndComposite, OrComposite, Not
152
- - **[Observers](docs/observers.md)** -- CallbackObserver, StatefulStatusChanger, OnEnterObserver, TransitionLogger
153
- - **[Filters](docs/filters.md)** -- ActiveTransitionFilter, FilterStateByEvent, FilterStateByTransition, FilterStateByFinalState, FilterTransitionByEvent
154
- - **[Selectors](docs/selectors.md)** -- OneOrNoneActiveTransition, ScoreTransition, WeightTransition
155
- - **[Mutex](docs/mutex.md)** -- NullMutex, LockAdapterMutex, MutexFactory
156
- - **[Factory](docs/factory.md)** -- Factory, SingleProcessDetector, AbstractNamedProcessDetector, StatefulStateNameDetector
157
- - **[Utilities](docs/utilities.md)** -- SetupHelper, StateCollectionMerger
158
- - **[Graph](docs/graph.md)** -- GraphBuilder
159
- - **[Errors](docs/errors.md)** -- WrongEventForStateError, LockCanNotBeAcquiredError, DuplicateStateError
160
- - **[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
161
162
 
162
163
  ## Examples
163
164
 
@@ -169,13 +170,12 @@ A complete working example (order processing with prepayment and postpayment wor
169
170
  src/
170
171
  index.ts # Barrel export
171
172
  MaybePromise.ts # MaybePromise<T> = T | Promise<T> utility type
173
+ ProcessBuilder.ts # Fluent builder for frozen graph construction
172
174
  Event.ts # Event implementation
173
- State.ts # State implementation
174
- Transition.ts # Transition implementation
175
- StateCollection.ts # Named collection of states
176
- 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)
177
178
  Statemachine.ts # Runtime state machine
178
- Dispatcher.ts # Deferred event dispatcher
179
179
  interfaces/ # All TypeScript interfaces
180
180
  condition/ # Condition (guard) implementations
181
181
  observer/ # Observer implementations
@@ -183,28 +183,49 @@ src/
183
183
  selector/ # Transition selection strategies
184
184
  mutex/ # Locking implementations
185
185
  factory/ # State machine factory pattern
186
- util/ # SetupHelper, StateCollectionMerger
186
+ internal/ # Internal helpers (OperationQueue, InternalConstruction)
187
187
  graph/ # Graph visualization builder
188
188
  error/ # Custom error classes
189
189
  ```
190
190
 
191
+ ## Security
192
+
193
+ ### CI
194
+
195
+ - **CodeQL** -- static analysis for security vulnerabilities (push, PR, weekly)
196
+ - **OSV-Scanner** -- dependency vulnerability scanning against the [OSV database](https://osv.dev/) (push, PR, weekly)
197
+ - **Dependabot** -- automated PRs for dependency and GitHub Actions updates (weekly)
198
+
199
+ ### Local (via Lefthook)
200
+
201
+ - **Gitleaks** -- scans staged files for secrets on every commit (auto-skipped if not installed)
202
+
203
+ ### Manual checks
204
+
205
+ ```bash
206
+ pnpm run security:audit # dependency audit
207
+ pnpm run security:secrets # Scan full repo for secrets (requires gitleaks)
208
+ ```
209
+
210
+ Install Gitleaks: <https://github.com/gitleaks/gitleaks#installing>
211
+
191
212
  ## Development
192
213
 
193
214
  ```bash
194
215
  # Install dependencies
195
- npm install
216
+ pnpm install
196
217
 
197
218
  # Run tests
198
- npm test
219
+ pnpm test
199
220
 
200
221
  # Run tests in watch mode
201
- npm run test:watch
222
+ pnpm run test:watch
202
223
 
203
224
  # Type check
204
- npm run lint
225
+ pnpm run lint
205
226
 
206
227
  # Build
207
- npm run build
228
+ pnpm run build
208
229
  ```
209
230
 
210
231
  ## License