anbaric-state-machine 1.0.0 → 1.0.1
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 +78 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# anbaric-state-machine
|
|
2
|
+
|
|
3
|
+
The public state machine library: the `StateMachine` itself, the concrete
|
|
4
|
+
actors, the auditor, and in-memory implementations of the
|
|
5
|
+
[`anbaric-tsapi`](https://npmjs.com/package/anbaric-tsapi) contracts. App
|
|
6
|
+
developers usually install [`anbaric`](https://npmjs.com/package/anbaric),
|
|
7
|
+
which re-exports this package.
|
|
8
|
+
|
|
9
|
+
## StateMachine
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
new StateMachine(workflowId, states, startState, dataSchema,
|
|
13
|
+
persistence = JobPersistenceFactory.instance(),
|
|
14
|
+
queue = QueueFactory.instance())
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Construction subscribes a consumer (`ConsumerFactory.instance(queue)`) to
|
|
18
|
+
the workflow, so jobs progress automatically whenever the queue delivers
|
|
19
|
+
them. `cleanUp()` releases the consumer.
|
|
20
|
+
|
|
21
|
+
**`startJob(properties?, actor?) : Promise<Job>`** — validates the
|
|
22
|
+
properties (every key must be in the schema and pass its validation;
|
|
23
|
+
`required` definitions must be present), persists the job and enqueues it.
|
|
24
|
+
`startedBy` is the actor's id, or the workflowId when no actor is given.
|
|
25
|
+
Throws `Invalid properties` / `Unauthorized`.
|
|
26
|
+
|
|
27
|
+
**`updateJob(jobId, properties, actor) : Promise<void>`** — explicit change
|
|
28
|
+
with a declared actor. Validates (required-ness is not re-checked on
|
|
29
|
+
update), merges via `updateProperties`, audits `Properties updated`,
|
|
30
|
+
re-enqueues.
|
|
31
|
+
|
|
32
|
+
**`executeAction(jobId, action) : Promise<void>`** — runs one action now,
|
|
33
|
+
its embedded actor as the responsible party. Refuses when the action's
|
|
34
|
+
predicate rejects the job (`Action predicate unmet`) or when the returned
|
|
35
|
+
properties fail the schema (`The action generated invalid properties`).
|
|
36
|
+
Persists the returned properties and re-enqueues.
|
|
37
|
+
|
|
38
|
+
**Progression** (internal, driven by the consumer): for the job's current
|
|
39
|
+
state, every action whose `predicate` accepts the job is run; each returned
|
|
40
|
+
property map is schema-validated (invalid output is discarded and audited,
|
|
41
|
+
not applied) and merged into the job. Then transitions are evaluated in
|
|
42
|
+
order — the first whose predicate accepts wins, at most one per progression,
|
|
43
|
+
and transitions to undefined states are skipped. The transition is recorded
|
|
44
|
+
in the job's history with the workflow as actor. Only when something
|
|
45
|
+
actually changed is the job saved and re-enqueued — so multi-state flows
|
|
46
|
+
chain automatically and an unchanged progression is a no-op. All changes are
|
|
47
|
+
audited through a transaction flushed at the end.
|
|
48
|
+
|
|
49
|
+
## Actors
|
|
50
|
+
|
|
51
|
+
`Code`, `Human` and `Agent` implement the `Actor` interface as pure identity
|
|
52
|
+
objects: `new Code(id, role = "code")`, `new Human(id, role)`,
|
|
53
|
+
`new Agent(id, role)`. Behaviour never lives on an actor — an `Action`'s
|
|
54
|
+
`run` field carries the code, the actor says who is responsible.
|
|
55
|
+
|
|
56
|
+
## Auditing
|
|
57
|
+
|
|
58
|
+
`Auditor.instance()` is a singleton logging
|
|
59
|
+
`[jobId] actorId description details`. `audit(jobId, actor, description, details)`
|
|
60
|
+
logs immediately; `transaction()` returns an `AuditorTransaction` that
|
|
61
|
+
collects entries and `flush()`es them in order, once.
|
|
62
|
+
|
|
63
|
+
## In-memory implementations and factories
|
|
64
|
+
|
|
65
|
+
`InMemoryJobPersistence`, `InMemoryQueue` (implements `Dequeue`, with
|
|
66
|
+
`schedule` releasing messages when due), `PullConsumer` (polls a `Dequeue`
|
|
67
|
+
on an interval, re-enqueues on failure or missing subscriber).
|
|
68
|
+
|
|
69
|
+
Factories switch on environment and default to in-memory:
|
|
70
|
+
|
|
71
|
+
| Factory | Env var | `cloud` gives |
|
|
72
|
+
| --- | --- | --- |
|
|
73
|
+
| `JobPersistenceFactory.instance()` | `ANBARIC_JOB_PERSISTENCE_TYPE` | `CloudJobPersistence` |
|
|
74
|
+
| `QueueFactory.instance()` | `ANBARIC_QUEUE_TYPE` | `CloudQueue` |
|
|
75
|
+
| `ConsumerFactory.instance(queue)` | — structural — | `PullConsumer` when the queue supports `dequeueSome`, else the push `CloudConsumer` |
|
|
76
|
+
|
|
77
|
+
An Anbaric platform injects the `cloud` values into deployed apps; never set
|
|
78
|
+
them manually in app code.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anbaric-state-machine",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "This is the state machine library that one can use to add state management to an application. It will, by default, be locally runnable but can deployed to the Anbaric Cloud via the CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "chris@anbaric.ai",
|