@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 +71 -50
- 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 +21 -7
package/dist/index.d.ts
CHANGED
|
@@ -65,110 +65,205 @@ interface TransitionInterface<TSubject = unknown> extends Weighted {
|
|
|
65
65
|
|
|
66
66
|
interface StateInterface extends Named, Metadata {
|
|
67
67
|
getTransitions(): Iterable<TransitionInterface>;
|
|
68
|
-
addTransition(transition: TransitionInterface): void;
|
|
69
68
|
getEventNames(): string[];
|
|
70
69
|
hasEvent(name: string): boolean;
|
|
71
70
|
getEvent(name: string): EventInterface;
|
|
72
71
|
getMetadataValue(key: string): unknown;
|
|
73
|
-
setMetadataValue(key: string, value: unknown): void;
|
|
74
72
|
hasMetadataValue(key: string): boolean;
|
|
75
|
-
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface StateCollectionInterface {
|
|
76
|
+
getStates(): Iterable<StateInterface>;
|
|
77
|
+
getState(name: string): StateInterface;
|
|
78
|
+
hasState(name: string): boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface ProcessInterface extends Named, StateCollectionInterface {
|
|
82
|
+
getInitialState(): StateInterface;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Symbol-based construction guard for State / Transition / Process.
|
|
87
|
+
*
|
|
88
|
+
* These classes' constructors require this symbol as the first argument.
|
|
89
|
+
* Only ProcessBuilder imports it, ensuring only the builder can instantiate
|
|
90
|
+
* the graph. User code receives an opaque type error if it tries to call
|
|
91
|
+
* `new State(...)` directly.
|
|
92
|
+
*/
|
|
93
|
+
declare const INTERNAL_CONSTRUCTION_KEY: unique symbol;
|
|
94
|
+
type InternalConstructionKey = typeof INTERNAL_CONSTRUCTION_KEY;
|
|
95
|
+
|
|
96
|
+
declare class Process implements ProcessInterface {
|
|
97
|
+
private readonly name;
|
|
98
|
+
private readonly initialState;
|
|
99
|
+
private readonly states;
|
|
100
|
+
constructor(key: InternalConstructionKey, name: string, initialState: StateInterface, states: Iterable<StateInterface>);
|
|
101
|
+
getName(): string;
|
|
102
|
+
getInitialState(): StateInterface;
|
|
103
|
+
getStates(): Iterable<StateInterface>;
|
|
104
|
+
getState(name: string): StateInterface;
|
|
105
|
+
hasState(name: string): boolean;
|
|
76
106
|
}
|
|
77
107
|
|
|
78
108
|
declare class State implements StateInterface {
|
|
79
109
|
private readonly name;
|
|
80
|
-
private
|
|
110
|
+
private _transitions;
|
|
81
111
|
private readonly events;
|
|
82
112
|
private readonly metadata;
|
|
83
|
-
constructor(name: string);
|
|
113
|
+
constructor(key: InternalConstructionKey, name: string, eventNames: Iterable<string>, metadata: ReadonlyMap<string, unknown>);
|
|
114
|
+
/**
|
|
115
|
+
* Internal: populate transitions after State construction.
|
|
116
|
+
* May only be called once and only with the construction key.
|
|
117
|
+
* Used by ProcessBuilder to break the cycle: State must exist before
|
|
118
|
+
* Transitions can target it, but State needs its transitions to be useful.
|
|
119
|
+
*/
|
|
120
|
+
_initTransitions(key: InternalConstructionKey, transitions: Iterable<TransitionInterface>): void;
|
|
84
121
|
getName(): string;
|
|
85
122
|
getTransitions(): Iterable<TransitionInterface>;
|
|
86
|
-
addTransition(transition: TransitionInterface): void;
|
|
87
123
|
getEventNames(): string[];
|
|
88
124
|
hasEvent(name: string): boolean;
|
|
89
125
|
getEvent(name: string): EventInterface;
|
|
90
126
|
getMetadata(): Record<string, unknown>;
|
|
91
127
|
getMetadataValue(key: string): unknown;
|
|
92
|
-
setMetadataValue(key: string, value: unknown): void;
|
|
93
128
|
hasMetadataValue(key: string): boolean;
|
|
94
|
-
deleteMetadataValue(key: string): void;
|
|
95
129
|
}
|
|
96
130
|
|
|
97
131
|
declare class Transition<TSubject = unknown> implements TransitionInterface<TSubject> {
|
|
98
132
|
private readonly targetState;
|
|
99
133
|
private readonly eventName;
|
|
100
134
|
private readonly condition;
|
|
101
|
-
private weight;
|
|
102
|
-
constructor(targetState: StateInterface, eventName
|
|
135
|
+
private readonly weight;
|
|
136
|
+
constructor(key: InternalConstructionKey, targetState: StateInterface, eventName: string | null, condition: ConditionInterface<TSubject> | null, weight: number);
|
|
103
137
|
getTargetState(): StateInterface;
|
|
104
138
|
getEventName(): string | null;
|
|
105
139
|
getConditionName(): string | null;
|
|
106
140
|
getCondition(): ConditionInterface<TSubject> | null;
|
|
107
141
|
isActive(subject: TSubject, context: Map<string, unknown>, event?: EventInterface): Promise<boolean>;
|
|
108
142
|
getWeight(): number;
|
|
109
|
-
setWeight(weight: number): void;
|
|
110
143
|
}
|
|
111
144
|
|
|
112
|
-
interface
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
145
|
+
interface AddStateOptions {
|
|
146
|
+
initial?: boolean;
|
|
147
|
+
metadata?: Record<string, unknown>;
|
|
148
|
+
}
|
|
149
|
+
interface AddTransitionOptions<TSubject = unknown> {
|
|
150
|
+
event?: string;
|
|
151
|
+
condition?: ConditionInterface<TSubject>;
|
|
152
|
+
weight?: number;
|
|
153
|
+
}
|
|
154
|
+
interface BuildOptions {
|
|
155
|
+
/**
|
|
156
|
+
* When true, orphan/unreachable states cause GraphValidationError.
|
|
157
|
+
* When false (default), orphan states are silently allowed.
|
|
158
|
+
*/
|
|
159
|
+
strictOrphans?: boolean;
|
|
160
|
+
}
|
|
161
|
+
declare class ProcessBuilder<TSubject = unknown> {
|
|
162
|
+
private readonly processName;
|
|
163
|
+
private readonly stateSpecs;
|
|
164
|
+
private readonly transitionSpecs;
|
|
165
|
+
private built;
|
|
166
|
+
constructor(processName: string);
|
|
167
|
+
addState(name: string, options?: AddStateOptions): this;
|
|
168
|
+
addTransition(fromState: string, toState: string, options?: AddTransitionOptions<TSubject>): this;
|
|
169
|
+
build(options?: BuildOptions): Process;
|
|
170
|
+
private validateInitialState;
|
|
171
|
+
private findInitialStateName;
|
|
172
|
+
private validateTransitionEndpoints;
|
|
173
|
+
private validateNoConflictingDuplicates;
|
|
174
|
+
private collectEventNamesByState;
|
|
175
|
+
/**
|
|
176
|
+
* Two-phase construction:
|
|
177
|
+
* Phase 1 — create all final State instances with no transitions.
|
|
178
|
+
* Phase 2 — build Transitions targeting the Phase-1 States, then attach
|
|
179
|
+
* them via State._initTransitions.
|
|
180
|
+
*
|
|
181
|
+
* Because every Transition is created after every State exists, target
|
|
182
|
+
* identity holds by construction for any graph topology (acyclic, cyclic,
|
|
183
|
+
* self-loop).
|
|
184
|
+
*/
|
|
185
|
+
private buildAllStates;
|
|
186
|
+
private validateOrphans;
|
|
116
187
|
}
|
|
117
188
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
merge(source: StateCollectionInterface): void;
|
|
189
|
+
/**
|
|
190
|
+
* Immutable snapshot passed to AfterTransitionObserver.notify().
|
|
191
|
+
*
|
|
192
|
+
* Captures the post-commit transition: state has already moved from
|
|
193
|
+
* fromState to toState. Reading any field is safe and stable for the
|
|
194
|
+
* duration of the observer call (and beyond — the frame is frozen).
|
|
195
|
+
*/
|
|
196
|
+
interface TransitionFrame<TSubject = unknown> {
|
|
197
|
+
readonly fromState: StateInterface;
|
|
198
|
+
readonly toState: StateInterface;
|
|
199
|
+
readonly transition: TransitionInterface<TSubject>;
|
|
200
|
+
readonly event: EventInterface | null;
|
|
201
|
+
readonly condition: ConditionInterface<TSubject> | null;
|
|
202
|
+
readonly context: ReadonlyMap<string, unknown>;
|
|
203
|
+
readonly timestamp: number;
|
|
204
|
+
readonly machineName: string | null;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Immutable snapshot passed to BeforeTransitionObserver.notify().
|
|
208
|
+
*
|
|
209
|
+
* Same shape as TransitionFrame but represents a *proposed* transition
|
|
210
|
+
* — fromState is still the current state at notification time. Throwing
|
|
211
|
+
* from a before-observer aborts the transition; otherwise commit proceeds.
|
|
212
|
+
*/
|
|
213
|
+
interface ProposedTransitionFrame<TSubject = unknown> extends TransitionFrame<TSubject> {
|
|
144
214
|
}
|
|
145
215
|
|
|
146
|
-
|
|
147
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Runs before a transition commits. Throwing aborts the transition —
|
|
218
|
+
* state is not mutated and the original caller's promise rejects with
|
|
219
|
+
* the thrown error.
|
|
220
|
+
*
|
|
221
|
+
* Implementations must be pure relative to the FSM: they MUST NOT call
|
|
222
|
+
* triggerEvent / checkTransitions on the same Statemachine. There is no
|
|
223
|
+
* enqueue handle in the before phase by design — vetoes and validations
|
|
224
|
+
* complete synchronously per observer; chained behaviour belongs in
|
|
225
|
+
* AfterTransitionObserver.
|
|
226
|
+
*/
|
|
227
|
+
interface BeforeTransitionObserver<TSubject = unknown> {
|
|
228
|
+
notify(frame: ProposedTransitionFrame<TSubject>): MaybePromise<void>;
|
|
148
229
|
}
|
|
149
230
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Handle passed to AfterTransitionObserver.notify so observers can
|
|
233
|
+
* append events to the FSM's queue without reentering it.
|
|
234
|
+
*
|
|
235
|
+
* enqueue() never runs the event inline — it returns immediately. The
|
|
236
|
+
* event runs as its own top-level operation after the current operation
|
|
237
|
+
* (and any auto-follow-on transitions) completes.
|
|
238
|
+
*/
|
|
239
|
+
interface EnqueueContext {
|
|
240
|
+
enqueue(event: string, context?: Map<string, unknown>): void;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Runs after a transition has committed. State has already moved.
|
|
244
|
+
*
|
|
245
|
+
* Errors thrown by an after-observer do NOT roll back the transition.
|
|
246
|
+
* All after-observers are still invoked (no early bail). After all have
|
|
247
|
+
* run, the caller's promise rejects: with the thrown error if exactly
|
|
248
|
+
* one observer threw, or with a standard AggregateError if multiple did.
|
|
249
|
+
*/
|
|
250
|
+
interface AfterTransitionObserver<TSubject = unknown> {
|
|
251
|
+
notify(frame: TransitionFrame<TSubject>, ctx: EnqueueContext): MaybePromise<void>;
|
|
161
252
|
}
|
|
162
253
|
|
|
163
|
-
interface StatemachineInterface<TSubject = unknown>
|
|
254
|
+
interface StatemachineInterface<TSubject = unknown> {
|
|
164
255
|
getCurrentState(): StateInterface;
|
|
256
|
+
getLastState(): StateInterface | null;
|
|
165
257
|
getSubject(): TSubject;
|
|
166
258
|
getProcess(): ProcessInterface;
|
|
167
259
|
triggerEvent(name: string, context?: Map<string, unknown>): Promise<void>;
|
|
168
260
|
checkTransitions(context?: Map<string, unknown>): Promise<void>;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
261
|
+
attachBefore(observer: BeforeTransitionObserver<TSubject>): void;
|
|
262
|
+
detachBefore(observer: BeforeTransitionObserver<TSubject>): void;
|
|
263
|
+
getBeforeObservers(): Iterable<BeforeTransitionObserver<TSubject>>;
|
|
264
|
+
attachAfter(observer: AfterTransitionObserver<TSubject>): void;
|
|
265
|
+
detachAfter(observer: AfterTransitionObserver<TSubject>): void;
|
|
266
|
+
getAfterObservers(): Iterable<AfterTransitionObserver<TSubject>>;
|
|
172
267
|
acquireLock(): Promise<boolean>;
|
|
173
268
|
releaseLock(): Promise<void>;
|
|
174
269
|
isLockAcquired(): boolean;
|
|
@@ -187,59 +282,57 @@ interface TransitionSelectorInterface<TSubject = unknown> {
|
|
|
187
282
|
selectTransition(transitions: Iterable<TransitionInterface<TSubject>>): TransitionInterface<TSubject> | null;
|
|
188
283
|
}
|
|
189
284
|
|
|
190
|
-
interface
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
285
|
+
interface StatemachineOptions<TSubject = unknown> {
|
|
286
|
+
/** Override the process's initial state. Defaults to process.getInitialState(). */
|
|
287
|
+
initialStateName?: string;
|
|
288
|
+
/** Defaults to OneOrNoneActiveTransition. */
|
|
289
|
+
transitionSelector?: TransitionSelectorInterface<TSubject>;
|
|
290
|
+
/** Defaults to NullMutex (no cross-process serialization). */
|
|
291
|
+
mutex?: MutexInterface;
|
|
292
|
+
/** When true, the engine releases the mutex at the end of each top-level operation. Defaults to true. */
|
|
293
|
+
autoreleaseLock?: boolean;
|
|
197
294
|
}
|
|
198
295
|
|
|
199
296
|
declare class Statemachine<TSubject = unknown> implements StatemachineInterface<TSubject> {
|
|
200
297
|
private readonly subject;
|
|
201
|
-
private currentState;
|
|
202
|
-
private lastState;
|
|
203
|
-
private readonly transitionSelector;
|
|
204
|
-
private selectedTransition;
|
|
205
298
|
private readonly process;
|
|
299
|
+
private readonly transitionSelector;
|
|
206
300
|
private readonly mutex;
|
|
301
|
+
private currentState;
|
|
302
|
+
private lastState;
|
|
207
303
|
private autoreleaseLock;
|
|
208
|
-
private
|
|
209
|
-
private
|
|
210
|
-
private
|
|
211
|
-
private readonly
|
|
212
|
-
constructor(subject: TSubject, process: ProcessInterface,
|
|
213
|
-
getProcess(): ProcessInterface;
|
|
304
|
+
private readonly queue;
|
|
305
|
+
private running;
|
|
306
|
+
private readonly beforeObservers;
|
|
307
|
+
private readonly afterObservers;
|
|
308
|
+
constructor(subject: TSubject, process: ProcessInterface, options?: StatemachineOptions<TSubject>);
|
|
214
309
|
getCurrentState(): StateInterface;
|
|
215
310
|
getLastState(): StateInterface | null;
|
|
216
311
|
getSubject(): TSubject;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
private acquireLockOrThrowException;
|
|
225
|
-
isAutoreleaseLock(): boolean;
|
|
226
|
-
setAutoreleaseLock(autorelease: boolean): void;
|
|
312
|
+
getProcess(): ProcessInterface;
|
|
313
|
+
attachBefore(observer: BeforeTransitionObserver<TSubject>): void;
|
|
314
|
+
detachBefore(observer: BeforeTransitionObserver<TSubject>): void;
|
|
315
|
+
getBeforeObservers(): Iterable<BeforeTransitionObserver<TSubject>>;
|
|
316
|
+
attachAfter(observer: AfterTransitionObserver<TSubject>): void;
|
|
317
|
+
detachAfter(observer: AfterTransitionObserver<TSubject>): void;
|
|
318
|
+
getAfterObservers(): Iterable<AfterTransitionObserver<TSubject>>;
|
|
227
319
|
acquireLock(): Promise<boolean>;
|
|
228
320
|
releaseLock(): Promise<void>;
|
|
229
321
|
isLockAcquired(): boolean;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
322
|
+
isAutoreleaseLock(): boolean;
|
|
323
|
+
setAutoreleaseLock(autorelease: boolean): void;
|
|
324
|
+
triggerEvent(name: string, context?: Map<string, unknown>): Promise<void>;
|
|
325
|
+
checkTransitions(context?: Map<string, unknown>): Promise<void>;
|
|
326
|
+
private runIfIdle;
|
|
327
|
+
private runOperation;
|
|
328
|
+
private resolveEvent;
|
|
329
|
+
/**
|
|
330
|
+
* Drive transitions starting from the current state, following automatic
|
|
331
|
+
* transitions until quiescent. The first iteration may use the supplied
|
|
332
|
+
* event; subsequent iterations are automatic.
|
|
333
|
+
*/
|
|
334
|
+
private processOperation;
|
|
335
|
+
private readonlyContext;
|
|
243
336
|
}
|
|
244
337
|
|
|
245
338
|
interface MutexFactoryInterface<TSubject = unknown> {
|
|
@@ -261,12 +354,13 @@ interface StateNameDetectorInterface<TSubject = unknown> {
|
|
|
261
354
|
}
|
|
262
355
|
|
|
263
356
|
interface FactoryInterface<TSubject = unknown> {
|
|
264
|
-
createStatemachine(subject: TSubject): Promise<StatemachineInterface<TSubject>>;
|
|
265
357
|
setMutexFactory(factory: MutexFactoryInterface<TSubject> | null): void;
|
|
266
358
|
setTransitionSelector(selector: TransitionSelectorInterface<TSubject>): void;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
359
|
+
attachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void;
|
|
360
|
+
detachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void;
|
|
361
|
+
attachAfterObserver(observer: AfterTransitionObserver<TSubject>): void;
|
|
362
|
+
detachAfterObserver(observer: AfterTransitionObserver<TSubject>): void;
|
|
363
|
+
createStatemachine(subject: TSubject): Promise<StatemachineInterface<TSubject>>;
|
|
270
364
|
}
|
|
271
365
|
|
|
272
366
|
interface StatefulInterface {
|
|
@@ -278,6 +372,14 @@ interface LastStateHasChangedDateInterface {
|
|
|
278
372
|
getLastStateHasChangedDate(): Date;
|
|
279
373
|
}
|
|
280
374
|
|
|
375
|
+
interface CallbackInterface {
|
|
376
|
+
invoke(): MaybePromise<void>;
|
|
377
|
+
}
|
|
378
|
+
interface DispatcherInterface extends CallbackInterface {
|
|
379
|
+
dispatch(event: EventInterface, args?: unknown[]): void;
|
|
380
|
+
invoke(): Promise<void>;
|
|
381
|
+
}
|
|
382
|
+
|
|
281
383
|
interface LoggerInterface {
|
|
282
384
|
log(level: string, message: string, context?: Record<string, unknown>): void;
|
|
283
385
|
}
|
|
@@ -337,28 +439,46 @@ declare class Not<TSubject = unknown> implements ConditionInterface<TSubject> {
|
|
|
337
439
|
checkCondition(subject: TSubject, context: Map<string, unknown>): Promise<boolean>;
|
|
338
440
|
}
|
|
339
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Legacy Observer for Event observers (commands attached to specific events).
|
|
444
|
+
*
|
|
445
|
+
* In v3 this is no longer used as a Statemachine observer. To run a
|
|
446
|
+
* callback after every transition, implement AfterTransitionObserver
|
|
447
|
+
* directly or compose a small wrapper.
|
|
448
|
+
*/
|
|
340
449
|
declare class CallbackObserver implements Observer {
|
|
341
450
|
private readonly callback;
|
|
342
451
|
constructor(callback: (...args: unknown[]) => MaybePromise<void>);
|
|
343
452
|
update(subject: ObservableSubject): MaybePromise<void>;
|
|
344
453
|
}
|
|
345
454
|
|
|
346
|
-
declare class StatefulStatusChanger implements
|
|
347
|
-
|
|
455
|
+
declare class StatefulStatusChanger<TSubject extends StatefulInterface> implements AfterTransitionObserver<TSubject> {
|
|
456
|
+
private readonly subject;
|
|
457
|
+
constructor(subject: TSubject);
|
|
458
|
+
notify(frame: TransitionFrame<TSubject>): void;
|
|
348
459
|
}
|
|
349
460
|
|
|
350
|
-
|
|
461
|
+
/**
|
|
462
|
+
* After-transition observer that fires an event named DEFAULT_EVENT_NAME
|
|
463
|
+
* (or a custom name) when entering any state that has that event declared.
|
|
464
|
+
*
|
|
465
|
+
* The chained event is *enqueued*, not invoked inline: it runs as its own
|
|
466
|
+
* top-level operation after the current operation completes. Other
|
|
467
|
+
* after-observers registered after OnEnterObserver still see the original
|
|
468
|
+
* frame, not the chained one.
|
|
469
|
+
*/
|
|
470
|
+
declare class OnEnterObserver<TSubject = unknown> implements AfterTransitionObserver<TSubject> {
|
|
351
471
|
static readonly DEFAULT_EVENT_NAME = "onEnter";
|
|
352
472
|
private readonly eventName;
|
|
353
473
|
constructor(eventName?: string);
|
|
354
|
-
|
|
474
|
+
notify(frame: TransitionFrame<TSubject>, ctx: EnqueueContext): void;
|
|
355
475
|
}
|
|
356
476
|
|
|
357
|
-
declare class TransitionLogger implements
|
|
477
|
+
declare class TransitionLogger<TSubject = unknown> implements AfterTransitionObserver<TSubject> {
|
|
358
478
|
private readonly logger;
|
|
359
479
|
private readonly loggerLevel;
|
|
360
480
|
constructor(logger: LoggerInterface, loggerLevel?: string);
|
|
361
|
-
|
|
481
|
+
notify(frame: TransitionFrame<TSubject>): void;
|
|
362
482
|
}
|
|
363
483
|
|
|
364
484
|
declare class ActiveTransitionFilter {
|
|
@@ -432,15 +552,17 @@ declare class MutexFactory<TSubject = unknown> implements MutexFactoryInterface<
|
|
|
432
552
|
declare class Factory<TSubject = unknown> implements FactoryInterface<TSubject> {
|
|
433
553
|
private readonly processDetector;
|
|
434
554
|
private readonly stateNameDetector;
|
|
435
|
-
private readonly
|
|
555
|
+
private readonly beforeObservers;
|
|
556
|
+
private readonly afterObservers;
|
|
436
557
|
private transitionSelector;
|
|
437
558
|
private mutexFactory;
|
|
438
559
|
constructor(processDetector: ProcessDetectorInterface<TSubject>, stateNameDetector?: StateNameDetectorInterface<TSubject> | null);
|
|
439
560
|
setMutexFactory(factory: MutexFactoryInterface<TSubject> | null): void;
|
|
440
561
|
setTransitionSelector(selector: TransitionSelectorInterface<TSubject>): void;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
562
|
+
attachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void;
|
|
563
|
+
detachBeforeObserver(observer: BeforeTransitionObserver<TSubject>): void;
|
|
564
|
+
attachAfterObserver(observer: AfterTransitionObserver<TSubject>): void;
|
|
565
|
+
detachAfterObserver(observer: AfterTransitionObserver<TSubject>): void;
|
|
444
566
|
createStatemachine(subject: TSubject): Promise<StatemachineInterface<TSubject>>;
|
|
445
567
|
}
|
|
446
568
|
|
|
@@ -462,17 +584,6 @@ declare class StatefulStateNameDetector implements StateNameDetectorInterface<St
|
|
|
462
584
|
detectCurrentStateName(subject: StatefulInterface): string | null;
|
|
463
585
|
}
|
|
464
586
|
|
|
465
|
-
declare class SetupHelper {
|
|
466
|
-
protected readonly stateCollection: StateCollection;
|
|
467
|
-
constructor(stateCollection: StateCollection);
|
|
468
|
-
findOrCreateState(name: string): StateInterface;
|
|
469
|
-
protected findTransition(sourceState: StateInterface, targetState: StateInterface, eventName?: string | null, condition?: ConditionInterface | null): TransitionInterface | null;
|
|
470
|
-
findOrCreateTransition(sourceStateName: string, targetStateName: string, eventName?: string | null, condition?: ConditionInterface | null): TransitionInterface;
|
|
471
|
-
findOrCreateEvent(sourceStateName: string, eventName: string): EventInterface;
|
|
472
|
-
addCommand(sourceStateName: string, eventName: string, command: Observer): void;
|
|
473
|
-
addCommandAndSelfTransition(sourceStateName: string, eventName: string, command: Observer): void;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
587
|
interface GraphNode {
|
|
477
588
|
id: string;
|
|
478
589
|
label: string;
|
|
@@ -497,6 +608,7 @@ interface MermaidOptions {
|
|
|
497
608
|
declare class GraphBuilder {
|
|
498
609
|
private readonly nodes;
|
|
499
610
|
private readonly edges;
|
|
611
|
+
private readonly statesWithEdges;
|
|
500
612
|
private getOrCreateNode;
|
|
501
613
|
protected getTransitionLabel(state: StateInterface, transition: TransitionInterface): string;
|
|
502
614
|
addState(state: StateInterface): void;
|
|
@@ -507,19 +619,94 @@ declare class GraphBuilder {
|
|
|
507
619
|
toMermaid(options?: MermaidOptions): string;
|
|
508
620
|
}
|
|
509
621
|
|
|
510
|
-
declare class
|
|
622
|
+
declare abstract class FinitaError extends Error {
|
|
623
|
+
abstract readonly code: string;
|
|
624
|
+
constructor(message?: string);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
declare class WrongEventForStateError extends FinitaError {
|
|
628
|
+
readonly code = "wrongEventForState";
|
|
511
629
|
readonly stateName: string;
|
|
512
630
|
readonly eventName: string;
|
|
513
631
|
constructor(stateName: string, eventName: string);
|
|
514
632
|
}
|
|
515
633
|
|
|
516
|
-
declare class LockCanNotBeAcquiredError extends
|
|
634
|
+
declare class LockCanNotBeAcquiredError extends FinitaError {
|
|
635
|
+
readonly code = "lockCanNotBeAcquired";
|
|
517
636
|
constructor(message?: string);
|
|
518
637
|
}
|
|
519
638
|
|
|
520
|
-
declare class DuplicateStateError extends
|
|
639
|
+
declare class DuplicateStateError extends FinitaError {
|
|
640
|
+
readonly code = "duplicateState";
|
|
521
641
|
readonly stateName: string;
|
|
522
642
|
constructor(stateName: string);
|
|
523
643
|
}
|
|
524
644
|
|
|
525
|
-
|
|
645
|
+
declare class ProcessFinalizedError extends FinitaError {
|
|
646
|
+
readonly code = "processFinalized";
|
|
647
|
+
readonly processName: string;
|
|
648
|
+
constructor(processName: string);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
type GraphValidationCode = "unknownTarget" | "unknownSource" | "missingInitialState" | "multipleInitialStates" | "invalidEventName" | "invalidConditionName" | "orphanState";
|
|
652
|
+
declare class GraphValidationError extends FinitaError {
|
|
653
|
+
readonly code: GraphValidationCode;
|
|
654
|
+
readonly details: Readonly<Record<string, unknown>>;
|
|
655
|
+
constructor(code: GraphValidationCode, message: string, details?: Record<string, unknown>);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
interface DuplicateTransitionConflict {
|
|
659
|
+
fromState: string;
|
|
660
|
+
toState: string;
|
|
661
|
+
eventName: string | null;
|
|
662
|
+
existingConditionName: string | null;
|
|
663
|
+
newConditionName: string | null;
|
|
664
|
+
}
|
|
665
|
+
declare class DuplicateTransitionError extends FinitaError {
|
|
666
|
+
readonly code = "duplicateTransition";
|
|
667
|
+
readonly conflict: Readonly<DuplicateTransitionConflict>;
|
|
668
|
+
constructor(conflict: DuplicateTransitionConflict);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
declare class StateNotFoundError extends FinitaError {
|
|
672
|
+
readonly code = "stateNotFound";
|
|
673
|
+
readonly stateName: string;
|
|
674
|
+
readonly availableStates: readonly string[];
|
|
675
|
+
constructor(stateName: string, availableStates: Iterable<string>);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
declare class StateEventNotFoundError extends FinitaError {
|
|
679
|
+
readonly code = "stateEventNotFound";
|
|
680
|
+
readonly stateName: string;
|
|
681
|
+
readonly eventName: string;
|
|
682
|
+
constructor(stateName: string, eventName: string);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
declare class ProcessNotFoundError extends FinitaError {
|
|
686
|
+
readonly code = "processNotFound";
|
|
687
|
+
readonly processName: string;
|
|
688
|
+
readonly availableProcesses: readonly string[];
|
|
689
|
+
constructor(processName: string, availableProcesses: Iterable<string>);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
declare class InvalidSubjectError extends FinitaError {
|
|
693
|
+
readonly code = "invalidSubject";
|
|
694
|
+
readonly expectedInterface: string;
|
|
695
|
+
readonly missingMembers: readonly string[];
|
|
696
|
+
constructor(expectedInterface: string, missingMembers: Iterable<string>);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
declare class AmbiguousTransitionError extends FinitaError {
|
|
700
|
+
readonly code = "ambiguousTransition";
|
|
701
|
+
readonly activeCount: number;
|
|
702
|
+
constructor(activeCount: number);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
declare class AutomaticTransitionCycleError extends FinitaError {
|
|
706
|
+
readonly code = "automaticTransitionCycle";
|
|
707
|
+
readonly targetStateName: string;
|
|
708
|
+
readonly visitedStateNames: readonly string[];
|
|
709
|
+
constructor(targetStateName: string, visitedStateNames: Iterable<string>);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
export { AbstractNamedProcessDetector, ActiveTransitionFilter, type AddStateOptions, type AddTransitionOptions, type AfterTransitionObserver, AmbiguousTransitionError, AndComposite, AutomaticTransitionCycleError, type BeforeTransitionObserver, type BuildOptions, CallbackCondition, type CallbackInterface, CallbackObserver, type ConditionCallbackFn, type ConditionInterface, Contradiction, type DispatcherInterface, type DotOptions, DuplicateStateError, type DuplicateTransitionConflict, DuplicateTransitionError, type EnqueueContext, Event, type EventInterface, Factory, type FactoryInterface, FilterStateByEvent, FilterStateByFinalState, FilterStateByTransition, FilterTransitionByEvent, FinitaError, type Graph, GraphBuilder, type GraphEdge, type GraphNode, type GraphValidationCode, GraphValidationError, InvalidSubjectError, type LastStateHasChangedDateInterface, type LockAdapterInterface, LockAdapterMutex, LockCanNotBeAcquiredError, type LoggerInterface, type MaybePromise, type MermaidOptions, type Metadata, MutexFactory, type MutexFactoryInterface, type MutexInterface, type Named, Not, NullMutex, type ObservableSubject, type Observer, OnEnterObserver, OneOrNoneActiveTransition, OrComposite, Process, ProcessBuilder, type ProcessDetectorInterface, ProcessFinalizedError, type ProcessInterface, ProcessNotFoundError, type ProposedTransitionFrame, ScoreTransition, SingleProcessDetector, State, type StateCollectionInterface, StateEventNotFoundError, type StateInterface, type StateNameDetectorInterface, StateNotFoundError, type StatefulInterface, StatefulStateNameDetector, StatefulStatusChanger, Statemachine, type StatemachineInterface, type StatemachineOptions, type StringConverter, Tautology, Timeout, Transition, type TransitionFrame, type TransitionInterface, TransitionLogger, type TransitionSelectorInterface, WeightTransition, type Weighted, WrongEventForStateError };
|