@nanobpm/bojtos-kit 0.1.0 → 0.2.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/dist/session.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type InitInput } from "@nanobpm/engine-wasm";
2
- import type { ActivatedJob, Snapshot, WasmEvent } from "./types.js";
2
+ import type { ActivatedJob, ActivateInstruction, Snapshot, WasmEvent } from "./types.js";
3
3
  /**
4
4
  * The source of the engine wasm binary. Under a bundler that understands
5
5
  * `new URL(..., import.meta.url)` (e.g. Vite) the default loader needs no
@@ -48,6 +48,63 @@ export interface BojtosSession {
48
48
  completeJob(jobKey: string, variablesJson: string): Snapshot;
49
49
  /** Fail a waiting job; with no retries left this raises an incident. */
50
50
  failJob(jobKey: string, retries: number, message: string): Snapshot;
51
+ /**
52
+ * Throw a BPMN business error from a waiting job: interrupts the activity via a
53
+ * matching error boundary/event-subprocess catch, or raises an incident if
54
+ * uncaught. The job is consumed either way.
55
+ */
56
+ throwError(jobKey: string, errorCode: string, errorMessage: string): Snapshot;
57
+ /**
58
+ * Set a job's remaining retries. Used to recover a job parked on a no-retries
59
+ * incident before resolving that incident; does not itself unblock the job.
60
+ */
61
+ updateRetries(jobKey: string, retries: number): Snapshot;
62
+ /**
63
+ * Resolve an open incident by key, retrying the work that failed (returns a
64
+ * parked job to the activatable pool / re-evaluates a gateway / re-creates a
65
+ * service-task job).
66
+ */
67
+ resolveIncident(incidentKey: string): Snapshot;
68
+ /**
69
+ * Merge variables into a scope (a process-instance or element-instance key).
70
+ * When `local` is true they are written strictly into the target scope,
71
+ * otherwise they propagate up to the nearest ancestor scope defining each name.
72
+ */
73
+ setVariables(scopeKey: string, variablesJson: string, local: boolean): Snapshot;
74
+ /**
75
+ * Broadcast a signal by name to every open subscription that matches, across
76
+ * all instances, merging `variablesJson` into each correlated instance.
77
+ */
78
+ broadcastSignal(signalName: string, variablesJson: string): Snapshot;
79
+ /** Cancel (terminate) a running process instance: every token is discarded. */
80
+ cancelInstance(instanceKey: string): Snapshot;
81
+ /**
82
+ * Modify a running process instance (Zeebe "modify process instance"): move
83
+ * tokens by terminating existing element instances and/or activating new
84
+ * ones. Each activate instruction places a token at `elementId` (in the
85
+ * process root scope), first merging its optional `variables` into the root
86
+ * scope; `terminateElementInstanceKeys` are the keys of active element
87
+ * instances (from `instances[].activeElements[].key`) to terminate. If the
88
+ * terminations drain the last token and nothing is activated, the instance is
89
+ * terminated.
90
+ */
91
+ modify(instanceKey: string, activateInstructions: ActivateInstruction[], terminateElementInstanceKeys: string[]): Snapshot;
92
+ /** Complete a waiting user task, merging `variablesJson` into the instance. */
93
+ completeUserTask(userTaskKey: string, variablesJson: string): Snapshot;
94
+ /**
95
+ * Assign a user task to `assignee`. With `allowOverride` false the command is
96
+ * rejected if the task already has an assignee (unassign it first).
97
+ */
98
+ assignUserTask(userTaskKey: string, assignee: string, allowOverride: boolean): Snapshot;
99
+ /** Clear a user task's assignee. */
100
+ unassignUserTask(userTaskKey: string): Snapshot;
101
+ /**
102
+ * Update a user task's attributes from a JSON changeset. Recognised keys (all
103
+ * optional): `candidateGroups` / `candidateUsers` (string arrays),
104
+ * `dueDate` / `followUpDate` (ISO-8601 string, or `null`/`""` to clear),
105
+ * `priority` (0..=100). Only present keys are changed.
106
+ */
107
+ updateUserTask(userTaskKey: string, changesetJson: string): Snapshot;
51
108
  /**
52
109
  * Correlate a message to any instance waiting on it: publishes `messageName`
53
110
  * with `correlationKey` (the value the waiting subscription's `correlationKey`
package/dist/session.js CHANGED
@@ -48,6 +48,39 @@ class WasmBojtosSession {
48
48
  failJob(jobKey, retries, message) {
49
49
  return parseSnapshot(this.engine.failJob(jobKey, retries, message));
50
50
  }
51
+ throwError(jobKey, errorCode, errorMessage) {
52
+ return parseSnapshot(this.engine.throwError(jobKey, errorCode, errorMessage));
53
+ }
54
+ updateRetries(jobKey, retries) {
55
+ return parseSnapshot(this.engine.updateRetries(jobKey, retries));
56
+ }
57
+ resolveIncident(incidentKey) {
58
+ return parseSnapshot(this.engine.resolveIncident(incidentKey));
59
+ }
60
+ setVariables(scopeKey, variablesJson, local) {
61
+ return parseSnapshot(this.engine.setVariables(scopeKey, variablesJson || "{}", local));
62
+ }
63
+ broadcastSignal(signalName, variablesJson) {
64
+ return parseSnapshot(this.engine.broadcastSignal(signalName, variablesJson || "{}"));
65
+ }
66
+ cancelInstance(instanceKey) {
67
+ return parseSnapshot(this.engine.cancelInstance(instanceKey));
68
+ }
69
+ modify(instanceKey, activateInstructions, terminateElementInstanceKeys) {
70
+ return parseSnapshot(this.engine.modify(instanceKey, JSON.stringify(activateInstructions ?? []), JSON.stringify(terminateElementInstanceKeys ?? [])));
71
+ }
72
+ completeUserTask(userTaskKey, variablesJson) {
73
+ return parseSnapshot(this.engine.completeUserTask(userTaskKey, variablesJson || "{}"));
74
+ }
75
+ assignUserTask(userTaskKey, assignee, allowOverride) {
76
+ return parseSnapshot(this.engine.assignUserTask(userTaskKey, assignee, allowOverride));
77
+ }
78
+ unassignUserTask(userTaskKey) {
79
+ return parseSnapshot(this.engine.unassignUserTask(userTaskKey));
80
+ }
81
+ updateUserTask(userTaskKey, changesetJson) {
82
+ return parseSnapshot(this.engine.updateUserTask(userTaskKey, changesetJson || "{}"));
83
+ }
51
84
  correlateMessage(messageName, correlationKey, variablesJson) {
52
85
  return parseSnapshot(this.engine.correlateMessage(messageName, correlationKey, variablesJson || "{}"));
53
86
  }
package/dist/types.d.ts CHANGED
@@ -51,10 +51,80 @@ export interface TimerDto {
51
51
  dueAt: number;
52
52
  dueInMs: number;
53
53
  }
54
+ /** A user task parked on a `userTask` element, awaiting a human. */
55
+ export interface UserTaskDto {
56
+ key: string;
57
+ instanceKey: string;
58
+ elementInstanceKey: string;
59
+ elementId: string;
60
+ /** `Created` (waiting), `Completed`, or `Canceled`. */
61
+ state: string;
62
+ assignee?: string;
63
+ candidateGroups: string[];
64
+ candidateUsers: string[];
65
+ dueDate?: string;
66
+ followUpDate?: string;
67
+ priority: number;
68
+ }
69
+ /** An open message subscription (a waiting message catch/boundary event). */
70
+ export interface MessageSubscriptionDto {
71
+ key: string;
72
+ instanceKey: string;
73
+ elementId: string;
74
+ messageName: string;
75
+ correlationKey: string;
76
+ /** What the subscription guards (intermediate/boundary, interrupting or not). */
77
+ kind: string;
78
+ }
79
+ /** An open signal subscription (a waiting signal catch/boundary event). */
80
+ export interface SignalSubscriptionDto {
81
+ key: string;
82
+ instanceKey: string;
83
+ elementId: string;
84
+ signalName: string;
85
+ kind: string;
86
+ }
87
+ /**
88
+ * Per-element token statistics for diagram overlays: `active` live tokens,
89
+ * cumulative `completed` element instances, and current `incidents`.
90
+ */
91
+ export interface ElementStatDto {
92
+ elementId: string;
93
+ active: number;
94
+ completed: number;
95
+ incidents: number;
96
+ }
97
+ /** A traversed connection, as source/target element ids. */
98
+ export interface SequenceFlowDto {
99
+ from: string;
100
+ to: string;
101
+ }
102
+ /** An evaluated decision instance (from a `businessRuleTask` / DMN). */
103
+ export interface DecisionInstanceDto {
104
+ instanceKey: string;
105
+ elementId: string;
106
+ decisionKey: string;
107
+ decisionId: string;
108
+ output: unknown;
109
+ evaluatedAt: number;
110
+ }
111
+ /**
112
+ * One activation instruction for {@link BojtosSession.modify}: place a new token
113
+ * at `elementId`, first merging `variables` into the instance's root scope.
114
+ * Mirrors Zeebe's process-instance-modification activate instruction (the token
115
+ * is activated in the process root scope).
116
+ */
117
+ export interface ActivateInstruction {
118
+ elementId: string;
119
+ variables?: Record<string, unknown>;
120
+ }
54
121
  /**
55
122
  * The full simulation state returned by every engine command. `activeElementIds`
56
123
  * / `incidentElementIds` drive the token/incident highlight (the visual
57
124
  * contract, ADR 0043 §4); `instances[].variables` is the live payload.
125
+ * `userTasks`, `messageSubscriptions`, `signalSubscriptions`, `elementStats`,
126
+ * `takenSequenceFlows` and `decisionInstances` back a Web-Modeler-Play-style UI
127
+ * (task panels, correlation/broadcast, overlays, DMN results).
58
128
  */
59
129
  export interface Snapshot {
60
130
  now: number;
@@ -67,6 +137,12 @@ export interface Snapshot {
67
137
  jobs: JobDto[];
68
138
  incidents: IncidentDto[];
69
139
  timers: TimerDto[];
140
+ userTasks: UserTaskDto[];
141
+ messageSubscriptions: MessageSubscriptionDto[];
142
+ signalSubscriptions: SignalSubscriptionDto[];
143
+ elementStats: ElementStatDto[];
144
+ takenSequenceFlows: SequenceFlowDto[];
145
+ decisionInstances: DecisionInstanceDto[];
70
146
  activeElementIds: string[];
71
147
  incidentElementIds: string[];
72
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanobpm/bojtos-kit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Framework-agnostic core of the Bojtos in-browser BPMN demo framework (ADR 0043): a single scenario runner over the @nanobpm/engine-wasm engine (deploy, start instances, complete/fail jobs, advance the clock, read snapshots and the event log), plus the engine's snapshot/event contract types. Consumed by @nanobpm/bojtos-react and the console test-run panel.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -32,7 +32,7 @@
32
32
  "prepack": "npm run build"
33
33
  },
34
34
  "dependencies": {
35
- "@nanobpm/engine-wasm": "^0.1.0"
35
+ "@nanobpm/engine-wasm": "^0.2.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "typescript": "^5.6.3"
package/src/session.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import init, { type InitInput, TestEngine } from "@nanobpm/engine-wasm";
2
- import type { ActivatedJob, Snapshot, WasmEvent } from "./types.js";
2
+ import type { ActivatedJob, ActivateInstruction, Snapshot, WasmEvent } from "./types.js";
3
3
 
4
4
  // Lazily initialise the wasm module exactly once per page, no matter how many
5
5
  // sessions are created. Mirrors the console's original `ensureWasm`.
@@ -70,6 +70,75 @@ export interface BojtosSession {
70
70
  completeJob(jobKey: string, variablesJson: string): Snapshot;
71
71
  /** Fail a waiting job; with no retries left this raises an incident. */
72
72
  failJob(jobKey: string, retries: number, message: string): Snapshot;
73
+ /**
74
+ * Throw a BPMN business error from a waiting job: interrupts the activity via a
75
+ * matching error boundary/event-subprocess catch, or raises an incident if
76
+ * uncaught. The job is consumed either way.
77
+ */
78
+ throwError(jobKey: string, errorCode: string, errorMessage: string): Snapshot;
79
+ /**
80
+ * Set a job's remaining retries. Used to recover a job parked on a no-retries
81
+ * incident before resolving that incident; does not itself unblock the job.
82
+ */
83
+ updateRetries(jobKey: string, retries: number): Snapshot;
84
+ /**
85
+ * Resolve an open incident by key, retrying the work that failed (returns a
86
+ * parked job to the activatable pool / re-evaluates a gateway / re-creates a
87
+ * service-task job).
88
+ */
89
+ resolveIncident(incidentKey: string): Snapshot;
90
+ /**
91
+ * Merge variables into a scope (a process-instance or element-instance key).
92
+ * When `local` is true they are written strictly into the target scope,
93
+ * otherwise they propagate up to the nearest ancestor scope defining each name.
94
+ */
95
+ setVariables(
96
+ scopeKey: string,
97
+ variablesJson: string,
98
+ local: boolean,
99
+ ): Snapshot;
100
+ /**
101
+ * Broadcast a signal by name to every open subscription that matches, across
102
+ * all instances, merging `variablesJson` into each correlated instance.
103
+ */
104
+ broadcastSignal(signalName: string, variablesJson: string): Snapshot;
105
+ /** Cancel (terminate) a running process instance: every token is discarded. */
106
+ cancelInstance(instanceKey: string): Snapshot;
107
+ /**
108
+ * Modify a running process instance (Zeebe "modify process instance"): move
109
+ * tokens by terminating existing element instances and/or activating new
110
+ * ones. Each activate instruction places a token at `elementId` (in the
111
+ * process root scope), first merging its optional `variables` into the root
112
+ * scope; `terminateElementInstanceKeys` are the keys of active element
113
+ * instances (from `instances[].activeElements[].key`) to terminate. If the
114
+ * terminations drain the last token and nothing is activated, the instance is
115
+ * terminated.
116
+ */
117
+ modify(
118
+ instanceKey: string,
119
+ activateInstructions: ActivateInstruction[],
120
+ terminateElementInstanceKeys: string[],
121
+ ): Snapshot;
122
+ /** Complete a waiting user task, merging `variablesJson` into the instance. */
123
+ completeUserTask(userTaskKey: string, variablesJson: string): Snapshot;
124
+ /**
125
+ * Assign a user task to `assignee`. With `allowOverride` false the command is
126
+ * rejected if the task already has an assignee (unassign it first).
127
+ */
128
+ assignUserTask(
129
+ userTaskKey: string,
130
+ assignee: string,
131
+ allowOverride: boolean,
132
+ ): Snapshot;
133
+ /** Clear a user task's assignee. */
134
+ unassignUserTask(userTaskKey: string): Snapshot;
135
+ /**
136
+ * Update a user task's attributes from a JSON changeset. Recognised keys (all
137
+ * optional): `candidateGroups` / `candidateUsers` (string arrays),
138
+ * `dueDate` / `followUpDate` (ISO-8601 string, or `null`/`""` to clear),
139
+ * `priority` (0..=100). Only present keys are changed.
140
+ */
141
+ updateUserTask(userTaskKey: string, changesetJson: string): Snapshot;
73
142
  /**
74
143
  * Correlate a message to any instance waiting on it: publishes `messageName`
75
144
  * with `correlationKey` (the value the waiting subscription's `correlationKey`
@@ -141,6 +210,84 @@ class WasmBojtosSession implements BojtosSession {
141
210
  return parseSnapshot(this.engine.failJob(jobKey, retries, message));
142
211
  }
143
212
 
213
+ throwError(
214
+ jobKey: string,
215
+ errorCode: string,
216
+ errorMessage: string,
217
+ ): Snapshot {
218
+ return parseSnapshot(
219
+ this.engine.throwError(jobKey, errorCode, errorMessage),
220
+ );
221
+ }
222
+
223
+ updateRetries(jobKey: string, retries: number): Snapshot {
224
+ return parseSnapshot(this.engine.updateRetries(jobKey, retries));
225
+ }
226
+
227
+ resolveIncident(incidentKey: string): Snapshot {
228
+ return parseSnapshot(this.engine.resolveIncident(incidentKey));
229
+ }
230
+
231
+ setVariables(
232
+ scopeKey: string,
233
+ variablesJson: string,
234
+ local: boolean,
235
+ ): Snapshot {
236
+ return parseSnapshot(
237
+ this.engine.setVariables(scopeKey, variablesJson || "{}", local),
238
+ );
239
+ }
240
+
241
+ broadcastSignal(signalName: string, variablesJson: string): Snapshot {
242
+ return parseSnapshot(
243
+ this.engine.broadcastSignal(signalName, variablesJson || "{}"),
244
+ );
245
+ }
246
+
247
+ cancelInstance(instanceKey: string): Snapshot {
248
+ return parseSnapshot(this.engine.cancelInstance(instanceKey));
249
+ }
250
+
251
+ modify(
252
+ instanceKey: string,
253
+ activateInstructions: ActivateInstruction[],
254
+ terminateElementInstanceKeys: string[],
255
+ ): Snapshot {
256
+ return parseSnapshot(
257
+ this.engine.modify(
258
+ instanceKey,
259
+ JSON.stringify(activateInstructions ?? []),
260
+ JSON.stringify(terminateElementInstanceKeys ?? []),
261
+ ),
262
+ );
263
+ }
264
+
265
+ completeUserTask(userTaskKey: string, variablesJson: string): Snapshot {
266
+ return parseSnapshot(
267
+ this.engine.completeUserTask(userTaskKey, variablesJson || "{}"),
268
+ );
269
+ }
270
+
271
+ assignUserTask(
272
+ userTaskKey: string,
273
+ assignee: string,
274
+ allowOverride: boolean,
275
+ ): Snapshot {
276
+ return parseSnapshot(
277
+ this.engine.assignUserTask(userTaskKey, assignee, allowOverride),
278
+ );
279
+ }
280
+
281
+ unassignUserTask(userTaskKey: string): Snapshot {
282
+ return parseSnapshot(this.engine.unassignUserTask(userTaskKey));
283
+ }
284
+
285
+ updateUserTask(userTaskKey: string, changesetJson: string): Snapshot {
286
+ return parseSnapshot(
287
+ this.engine.updateUserTask(userTaskKey, changesetJson || "{}"),
288
+ );
289
+ }
290
+
144
291
  correlateMessage(
145
292
  messageName: string,
146
293
  correlationKey: string,
package/src/types.ts CHANGED
@@ -63,10 +63,87 @@ export interface TimerDto {
63
63
  dueInMs: number;
64
64
  }
65
65
 
66
+ /** A user task parked on a `userTask` element, awaiting a human. */
67
+ export interface UserTaskDto {
68
+ key: string;
69
+ instanceKey: string;
70
+ elementInstanceKey: string;
71
+ elementId: string;
72
+ /** `Created` (waiting), `Completed`, or `Canceled`. */
73
+ state: string;
74
+ assignee?: string;
75
+ candidateGroups: string[];
76
+ candidateUsers: string[];
77
+ dueDate?: string;
78
+ followUpDate?: string;
79
+ priority: number;
80
+ }
81
+
82
+ /** An open message subscription (a waiting message catch/boundary event). */
83
+ export interface MessageSubscriptionDto {
84
+ key: string;
85
+ instanceKey: string;
86
+ elementId: string;
87
+ messageName: string;
88
+ correlationKey: string;
89
+ /** What the subscription guards (intermediate/boundary, interrupting or not). */
90
+ kind: string;
91
+ }
92
+
93
+ /** An open signal subscription (a waiting signal catch/boundary event). */
94
+ export interface SignalSubscriptionDto {
95
+ key: string;
96
+ instanceKey: string;
97
+ elementId: string;
98
+ signalName: string;
99
+ kind: string;
100
+ }
101
+
102
+ /**
103
+ * Per-element token statistics for diagram overlays: `active` live tokens,
104
+ * cumulative `completed` element instances, and current `incidents`.
105
+ */
106
+ export interface ElementStatDto {
107
+ elementId: string;
108
+ active: number;
109
+ completed: number;
110
+ incidents: number;
111
+ }
112
+
113
+ /** A traversed connection, as source/target element ids. */
114
+ export interface SequenceFlowDto {
115
+ from: string;
116
+ to: string;
117
+ }
118
+
119
+ /** An evaluated decision instance (from a `businessRuleTask` / DMN). */
120
+ export interface DecisionInstanceDto {
121
+ instanceKey: string;
122
+ elementId: string;
123
+ decisionKey: string;
124
+ decisionId: string;
125
+ output: unknown;
126
+ evaluatedAt: number;
127
+ }
128
+
129
+ /**
130
+ * One activation instruction for {@link BojtosSession.modify}: place a new token
131
+ * at `elementId`, first merging `variables` into the instance's root scope.
132
+ * Mirrors Zeebe's process-instance-modification activate instruction (the token
133
+ * is activated in the process root scope).
134
+ */
135
+ export interface ActivateInstruction {
136
+ elementId: string;
137
+ variables?: Record<string, unknown>;
138
+ }
139
+
66
140
  /**
67
141
  * The full simulation state returned by every engine command. `activeElementIds`
68
142
  * / `incidentElementIds` drive the token/incident highlight (the visual
69
143
  * contract, ADR 0043 §4); `instances[].variables` is the live payload.
144
+ * `userTasks`, `messageSubscriptions`, `signalSubscriptions`, `elementStats`,
145
+ * `takenSequenceFlows` and `decisionInstances` back a Web-Modeler-Play-style UI
146
+ * (task panels, correlation/broadcast, overlays, DMN results).
70
147
  */
71
148
  export interface Snapshot {
72
149
  now: number;
@@ -79,6 +156,12 @@ export interface Snapshot {
79
156
  jobs: JobDto[];
80
157
  incidents: IncidentDto[];
81
158
  timers: TimerDto[];
159
+ userTasks: UserTaskDto[];
160
+ messageSubscriptions: MessageSubscriptionDto[];
161
+ signalSubscriptions: SignalSubscriptionDto[];
162
+ elementStats: ElementStatDto[];
163
+ takenSequenceFlows: SequenceFlowDto[];
164
+ decisionInstances: DecisionInstanceDto[];
82
165
  activeElementIds: string[];
83
166
  incidentElementIds: string[];
84
167
  }