arvo-event-handler 2.3.3 → 3.0.2
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/AbstractArvoEventHandler/index.d.ts +1 -1
- package/dist/ArvoEventHandler/helpers.d.ts +40 -6
- package/dist/ArvoEventHandler/helpers.js +40 -6
- package/dist/ArvoEventHandler/index.d.ts +78 -49
- package/dist/ArvoEventHandler/index.js +152 -83
- package/dist/ArvoEventHandler/types.d.ts +25 -2
- package/dist/ArvoMachine/createMachine.d.ts +208 -0
- package/dist/ArvoMachine/createMachine.js +283 -0
- package/dist/ArvoMachine/index.d.ts +93 -0
- package/dist/ArvoMachine/index.js +160 -0
- package/dist/ArvoMachine/types.d.ts +194 -0
- package/dist/ArvoMachine/utils.d.ts +40 -0
- package/dist/ArvoMachine/utils.js +70 -0
- package/dist/ArvoOrchestrator/error.d.ts +16 -0
- package/dist/ArvoOrchestrator/error.js +43 -0
- package/dist/ArvoOrchestrator/factory.d.ts +28 -0
- package/dist/ArvoOrchestrator/factory.js +56 -0
- package/dist/ArvoOrchestrator/index.d.ts +69 -0
- package/dist/ArvoOrchestrator/index.js +597 -0
- package/dist/ArvoOrchestrator/types.d.ts +98 -0
- package/dist/ArvoResumable/factory.d.ts +50 -0
- package/dist/ArvoResumable/factory.js +70 -0
- package/dist/ArvoResumable/index.d.ts +141 -0
- package/dist/ArvoResumable/index.js +694 -0
- package/dist/ArvoResumable/types.d.ts +147 -0
- package/dist/ArvoResumable/types.js +2 -0
- package/dist/MachineExecutionEngine/index.d.ts +29 -0
- package/dist/MachineExecutionEngine/index.js +132 -0
- package/dist/MachineExecutionEngine/interface.d.ts +14 -0
- package/dist/MachineExecutionEngine/interface.js +2 -0
- package/dist/MachineExecutionEngine/types.d.ts +14 -0
- package/dist/MachineExecutionEngine/types.js +2 -0
- package/dist/MachineMemory/Simple.d.ts +51 -0
- package/dist/MachineMemory/Simple.js +158 -0
- package/dist/MachineMemory/TelemetredSimple.d.ts +51 -0
- package/dist/MachineMemory/TelemetredSimple.js +230 -0
- package/dist/MachineMemory/interface.d.ts +57 -0
- package/dist/MachineMemory/interface.js +2 -0
- package/dist/MachineMemory/utils.d.ts +1 -0
- package/dist/MachineMemory/utils.js +18 -0
- package/dist/MachineRegistry/index.d.ts +37 -0
- package/dist/MachineRegistry/index.js +87 -0
- package/dist/MachineRegistry/interface.d.ts +21 -0
- package/dist/MachineRegistry/interface.js +2 -0
- package/dist/SyncEventResource/index.d.ts +110 -0
- package/dist/SyncEventResource/index.js +280 -0
- package/dist/SyncEventResource/types.d.ts +2 -0
- package/dist/SyncEventResource/types.js +2 -0
- package/dist/index.d.ts +26 -8
- package/dist/index.js +39 -16
- package/dist/utils/SimpleEventBroker/helper.d.ts +166 -0
- package/dist/utils/SimpleEventBroker/helper.js +276 -0
- package/dist/utils/SimpleEventBroker/index.d.ts +96 -0
- package/dist/utils/SimpleEventBroker/index.js +259 -0
- package/dist/utils/SimpleEventBroker/types.d.ts +6 -0
- package/dist/utils/SimpleEventBroker/types.js +2 -0
- package/dist/utils/SimpleEventBroker/utils.d.ts +1 -0
- package/dist/utils/SimpleEventBroker/utils.js +10 -0
- package/dist/{utils.d.ts → utils/index.d.ts} +3 -36
- package/dist/utils/index.js +91 -0
- package/dist/utils/object/index.d.ts +37 -0
- package/dist/utils/object/index.js +63 -0
- package/package.json +5 -3
- package/dist/ArvoEventRouter/helpers.d.ts +0 -19
- package/dist/ArvoEventRouter/helpers.js +0 -22
- package/dist/ArvoEventRouter/index.d.ts +0 -89
- package/dist/ArvoEventRouter/index.js +0 -268
- package/dist/ArvoEventRouter/types.d.ts +0 -36
- package/dist/ArvoEventRouter/utils.d.ts +0 -30
- package/dist/ArvoEventRouter/utils.js +0 -43
- package/dist/MultiArvoEventHandler/helpers.d.ts +0 -48
- package/dist/MultiArvoEventHandler/helpers.js +0 -56
- package/dist/MultiArvoEventHandler/index.d.ts +0 -68
- package/dist/MultiArvoEventHandler/index.js +0 -205
- package/dist/MultiArvoEventHandler/types.d.ts +0 -64
- package/dist/utils.js +0 -191
- /package/dist/{ArvoEventRouter → ArvoMachine}/types.js +0 -0
- /package/dist/{MultiArvoEventHandler → ArvoOrchestrator}/types.js +0 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.SyncEventResource = void 0;
|
|
40
|
+
var arvo_core_1 = require("arvo-core");
|
|
41
|
+
var error_1 = require("../ArvoOrchestrator/error");
|
|
42
|
+
var errors_1 = require("../errors");
|
|
43
|
+
/**
|
|
44
|
+
* A synchronous event resource that manages machine memory state based on event subjects.
|
|
45
|
+
*
|
|
46
|
+
* This class provides a distributed-system-safe mechanism for persisting and retrieving machine memory
|
|
47
|
+
* objects that are correlated with ArvoEvent subjects. It acts as a key-value store where
|
|
48
|
+
* the event subject serves as the key and the memory object serves as the value.
|
|
49
|
+
*
|
|
50
|
+
* Key features:
|
|
51
|
+
* - JSON serializable memory persistence
|
|
52
|
+
* - Optional resource locking for distributed concurrent access control
|
|
53
|
+
* - Subject-based memory correlation across multiple service instances
|
|
54
|
+
* - Transaction-safe operations with proper error handling
|
|
55
|
+
* - Optional OpenTelemetry span integration for observability
|
|
56
|
+
*
|
|
57
|
+
* @template T - The type of the memory object, must extend Record<string, any> and be JSON serializable
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* type MyMemory = {
|
|
62
|
+
* counter: number;
|
|
63
|
+
* status: string;
|
|
64
|
+
* }
|
|
65
|
+
*
|
|
66
|
+
* class MemoryImplementation implements IMachineMemory<MyMemory> { ... }
|
|
67
|
+
*
|
|
68
|
+
* const resource = new SyncEventResource<MyMemory>(
|
|
69
|
+
* new MemoryImplementation(),
|
|
70
|
+
* true // enable resource locking for distributed systems
|
|
71
|
+
* );
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
var SyncEventResource = /** @class */ (function () {
|
|
75
|
+
function SyncEventResource(memory, requiresResourceLocking) {
|
|
76
|
+
this.memory = memory;
|
|
77
|
+
this.requiresResourceLocking = requiresResourceLocking;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Acquires a lock on the event subject to prevent concurrent access across distributed services.
|
|
81
|
+
*
|
|
82
|
+
* This method ensures distributed-system-safe access to the memory resource by preventing
|
|
83
|
+
* multiple service instances from modifying the same event subject simultaneously. If resource
|
|
84
|
+
* locking is disabled, it will skip the lock acquisition process. The lock is subject-specific,
|
|
85
|
+
* meaning different event subjects can be processed concurrently across services.
|
|
86
|
+
*
|
|
87
|
+
* @returns A promise that resolves to the lock acquisition status:
|
|
88
|
+
* - 'ACQUIRED': Lock was successfully acquired
|
|
89
|
+
* - 'NOT_ACQUIRED': Lock acquisition failed (resource busy by another service)
|
|
90
|
+
* - 'NOOP': Lock acquisition was skipped (locking disabled)
|
|
91
|
+
*
|
|
92
|
+
* @throws {TransactionViolation} When lock acquisition fails due to system errors
|
|
93
|
+
*/
|
|
94
|
+
SyncEventResource.prototype.acquireLock = function (event, span) {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
96
|
+
var acquired, e_1;
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
switch (_a.label) {
|
|
99
|
+
case 0:
|
|
100
|
+
if (!this.requiresResourceLocking) {
|
|
101
|
+
(0, arvo_core_1.logToSpan)({
|
|
102
|
+
level: 'INFO',
|
|
103
|
+
message: "Skipping acquiring lock for event (subject=".concat(event.subject, ") as the resource does not required locking."),
|
|
104
|
+
}, span);
|
|
105
|
+
return [2 /*return*/, 'NOOP'];
|
|
106
|
+
}
|
|
107
|
+
_a.label = 1;
|
|
108
|
+
case 1:
|
|
109
|
+
_a.trys.push([1, 3, , 4]);
|
|
110
|
+
(0, arvo_core_1.logToSpan)({
|
|
111
|
+
level: 'INFO',
|
|
112
|
+
message: 'Acquiring lock for the event',
|
|
113
|
+
});
|
|
114
|
+
return [4 /*yield*/, this.memory.lock(event.subject)];
|
|
115
|
+
case 2:
|
|
116
|
+
acquired = _a.sent();
|
|
117
|
+
return [2 /*return*/, acquired ? 'ACQUIRED' : 'NOT_ACQUIRED'];
|
|
118
|
+
case 3:
|
|
119
|
+
e_1 = _a.sent();
|
|
120
|
+
throw new error_1.TransactionViolation({
|
|
121
|
+
cause: error_1.TransactionViolationCause.LOCK_FAILURE,
|
|
122
|
+
message: "Error acquiring lock for event (subject=".concat(event.subject, "): ").concat(e_1 === null || e_1 === void 0 ? void 0 : e_1.message),
|
|
123
|
+
initiatingEvent: event,
|
|
124
|
+
});
|
|
125
|
+
case 4: return [2 /*return*/];
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Retrieves the current state from memory for the given event subject.
|
|
132
|
+
*
|
|
133
|
+
* This method reads the persisted memory object associated with the event's subject
|
|
134
|
+
* from the distributed storage system. If no memory exists for the subject, it returns null.
|
|
135
|
+
* The operation is wrapped in proper error handling to ensure transaction safety across
|
|
136
|
+
* distributed service instances.
|
|
137
|
+
*
|
|
138
|
+
* @returns A promise that resolves to the memory object if found, or null if no memory exists
|
|
139
|
+
*
|
|
140
|
+
* @throws {TransactionViolation} When the read operation fails due to storage errors
|
|
141
|
+
*/
|
|
142
|
+
SyncEventResource.prototype.acquireState = function (event, span) {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
144
|
+
var e_2;
|
|
145
|
+
return __generator(this, function (_a) {
|
|
146
|
+
switch (_a.label) {
|
|
147
|
+
case 0:
|
|
148
|
+
_a.trys.push([0, 2, , 3]);
|
|
149
|
+
(0, arvo_core_1.logToSpan)({
|
|
150
|
+
level: 'INFO',
|
|
151
|
+
message: 'Reading machine state for the event',
|
|
152
|
+
}, span);
|
|
153
|
+
return [4 /*yield*/, this.memory.read(event.subject)];
|
|
154
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
155
|
+
case 2:
|
|
156
|
+
e_2 = _a.sent();
|
|
157
|
+
throw new error_1.TransactionViolation({
|
|
158
|
+
cause: error_1.TransactionViolationCause.READ_FAILURE,
|
|
159
|
+
message: "Error reading state for event (subject=".concat(event.subject, "): ").concat(e_2 === null || e_2 === void 0 ? void 0 : e_2.message),
|
|
160
|
+
initiatingEvent: event,
|
|
161
|
+
});
|
|
162
|
+
case 3: return [2 /*return*/];
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Persists the updated memory state to distributed storage.
|
|
169
|
+
*
|
|
170
|
+
* This method writes the new memory record to the distributed storage system, associating
|
|
171
|
+
* it with the event's subject. It provides both the new record and the previous record for
|
|
172
|
+
* implementations that need to perform atomic updates, maintain audit trails, or handle
|
|
173
|
+
* optimistic concurrency control in distributed environments.
|
|
174
|
+
*
|
|
175
|
+
* @throws {TransactionViolation} When the write operation fails due to storage errors
|
|
176
|
+
*/
|
|
177
|
+
SyncEventResource.prototype.persistState = function (event, record, prevRecord, span) {
|
|
178
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
179
|
+
var e_3;
|
|
180
|
+
return __generator(this, function (_a) {
|
|
181
|
+
switch (_a.label) {
|
|
182
|
+
case 0:
|
|
183
|
+
_a.trys.push([0, 2, , 3]);
|
|
184
|
+
(0, arvo_core_1.logToSpan)({
|
|
185
|
+
level: 'INFO',
|
|
186
|
+
message: 'Persisting machine state to the storage',
|
|
187
|
+
}, span);
|
|
188
|
+
return [4 /*yield*/, this.memory.write(event.subject, record, prevRecord)];
|
|
189
|
+
case 1:
|
|
190
|
+
_a.sent();
|
|
191
|
+
return [3 /*break*/, 3];
|
|
192
|
+
case 2:
|
|
193
|
+
e_3 = _a.sent();
|
|
194
|
+
throw new error_1.TransactionViolation({
|
|
195
|
+
cause: error_1.TransactionViolationCause.WRITE_FAILURE,
|
|
196
|
+
message: "Error writing state for event (subject=".concat(event.subject, "): ").concat(e_3 === null || e_3 === void 0 ? void 0 : e_3.message),
|
|
197
|
+
initiatingEvent: event,
|
|
198
|
+
});
|
|
199
|
+
case 3: return [2 /*return*/];
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Validates that the event subject conforms to the ArvoOrchestrationSubject format.
|
|
206
|
+
*
|
|
207
|
+
* This method ensures that the event subject follows the expected schema format
|
|
208
|
+
* required by the Arvo orchestration system. Invalid subjects will result in
|
|
209
|
+
* execution violations to prevent processing of malformed events across the
|
|
210
|
+
* distributed service architecture.
|
|
211
|
+
*
|
|
212
|
+
* @throws {ExecutionViolation} When the event subject format is invalid
|
|
213
|
+
*
|
|
214
|
+
* @protected
|
|
215
|
+
*/
|
|
216
|
+
SyncEventResource.prototype.validateEventSubject = function (event, span) {
|
|
217
|
+
(0, arvo_core_1.logToSpan)({
|
|
218
|
+
level: 'INFO',
|
|
219
|
+
message: 'Validating event subject',
|
|
220
|
+
}, span);
|
|
221
|
+
var isValid = arvo_core_1.ArvoOrchestrationSubject.isValid(event.subject);
|
|
222
|
+
if (!isValid) {
|
|
223
|
+
throw new errors_1.ExecutionViolation("Invalid event (id=".concat(event.id, ") subject format. Expected an ArvoOrchestrationSubject but received '").concat(event.subject, "'. The subject must follow the format specified by ArvoOrchestrationSubject schema"));
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Releases a previously acquired lock on the event subject.
|
|
228
|
+
*
|
|
229
|
+
* This method safely releases locks that were acquired during event processing to prevent
|
|
230
|
+
* resource leaks in distributed systems. It handles cases where no lock was acquired
|
|
231
|
+
* (NOOP operations) and provides proper error handling for unlock failures. Failed unlock
|
|
232
|
+
* operations are logged as potential resource leaks but do not throw exceptions to avoid
|
|
233
|
+
* disrupting the main processing flow as it assumes that the lock will have the lifedspan.
|
|
234
|
+
*
|
|
235
|
+
* @returns A promise that resolves to the lock release status:
|
|
236
|
+
* - 'NOOP': No lock was acquired, so no operation was performed
|
|
237
|
+
* - 'RELEASED': Lock was successfully released
|
|
238
|
+
* - 'ERROR': Lock release failed, potential resource leak
|
|
239
|
+
*
|
|
240
|
+
* @protected
|
|
241
|
+
*/
|
|
242
|
+
SyncEventResource.prototype.releaseLock = function (event, acquiredLock, span) {
|
|
243
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
244
|
+
var err_1;
|
|
245
|
+
return __generator(this, function (_a) {
|
|
246
|
+
switch (_a.label) {
|
|
247
|
+
case 0:
|
|
248
|
+
if (acquiredLock !== 'ACQUIRED') {
|
|
249
|
+
(0, arvo_core_1.logToSpan)({
|
|
250
|
+
level: 'INFO',
|
|
251
|
+
message: 'Lock was not acquired by the process so perfroming no operation',
|
|
252
|
+
}, span);
|
|
253
|
+
return [2 /*return*/, 'NOOP'];
|
|
254
|
+
}
|
|
255
|
+
_a.label = 1;
|
|
256
|
+
case 1:
|
|
257
|
+
_a.trys.push([1, 3, , 4]);
|
|
258
|
+
return [4 /*yield*/, this.memory.unlock(event.subject)];
|
|
259
|
+
case 2:
|
|
260
|
+
_a.sent();
|
|
261
|
+
(0, arvo_core_1.logToSpan)({
|
|
262
|
+
level: 'INFO',
|
|
263
|
+
message: 'Lock successfully released',
|
|
264
|
+
}, span);
|
|
265
|
+
return [2 /*return*/, 'RELEASED'];
|
|
266
|
+
case 3:
|
|
267
|
+
err_1 = _a.sent();
|
|
268
|
+
(0, arvo_core_1.logToSpan)({
|
|
269
|
+
level: 'ERROR',
|
|
270
|
+
message: "Memory unlock operation failed - Possible resource leak: ".concat(err_1.message),
|
|
271
|
+
}, span);
|
|
272
|
+
return [2 /*return*/, 'ERROR'];
|
|
273
|
+
case 4: return [2 /*return*/];
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
return SyncEventResource;
|
|
279
|
+
}());
|
|
280
|
+
exports.SyncEventResource = SyncEventResource;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,14 +2,32 @@ import AbstractArvoEventHandler from './AbstractArvoEventHandler';
|
|
|
2
2
|
import ArvoEventHandler from './ArvoEventHandler';
|
|
3
3
|
import { createArvoEventHandler } from './ArvoEventHandler/helpers';
|
|
4
4
|
import { ArvoEventHandlerFunction, ArvoEventHandlerFunctionInput, ArvoEventHandlerFunctionOutput, IArvoEventHandler } from './ArvoEventHandler/types';
|
|
5
|
-
import { ArvoEventRouter } from './ArvoEventRouter';
|
|
6
|
-
import { createArvoEventRouter } from './ArvoEventRouter/helpers';
|
|
7
|
-
import { IArvoEventRouter } from './ArvoEventRouter/types';
|
|
8
|
-
import { deleteOtelHeaders } from './ArvoEventRouter/utils';
|
|
9
|
-
import MultiArvoEventHandler from './MultiArvoEventHandler';
|
|
10
|
-
import { createMultiArvoEventHandler } from './MultiArvoEventHandler/helpers';
|
|
11
|
-
import { IMultiArvoEventHandler, MultiArvoEventHandlerFunction, MultiArvoEventHandlerFunctionInput, MultiArvoEventHandlerFunctionOutput } from './MultiArvoEventHandler/types';
|
|
12
5
|
import { ConfigViolation, ContractViolation, ExecutionViolation } from './errors';
|
|
13
6
|
import { ArvoEventHandlerOpenTelemetryOptions, EventHandlerFactory, PartialExcept } from './types';
|
|
14
7
|
import { coalesce, coalesceOrDefault, getValueOrDefault, isNullOrUndefined } from './utils';
|
|
15
|
-
|
|
8
|
+
import { assign, emit } from 'xstate';
|
|
9
|
+
import ArvoMachine from './ArvoMachine';
|
|
10
|
+
import { setupArvoMachine } from './ArvoMachine/createMachine';
|
|
11
|
+
import { ArvoMachineContext, EnqueueArvoEventActionParam } from './ArvoMachine/types';
|
|
12
|
+
import { ArvoOrchestrator } from './ArvoOrchestrator';
|
|
13
|
+
import { TransactionViolation, TransactionViolationCause } from './ArvoOrchestrator/error';
|
|
14
|
+
import { createArvoOrchestrator } from './ArvoOrchestrator/factory';
|
|
15
|
+
import { IArvoOrchestrator, MachineMemoryRecord } from './ArvoOrchestrator/types';
|
|
16
|
+
import { MachineExecutionEngine } from './MachineExecutionEngine';
|
|
17
|
+
import { IMachineExectionEngine } from './MachineExecutionEngine/interface';
|
|
18
|
+
import { ExecuteMachineInput, ExecuteMachineOutput } from './MachineExecutionEngine/types';
|
|
19
|
+
import { SimpleMachineMemory } from './MachineMemory/Simple';
|
|
20
|
+
import { TelemetredSimpleMachineMemory } from './MachineMemory/TelemetredSimple';
|
|
21
|
+
import { IMachineMemory } from './MachineMemory/interface';
|
|
22
|
+
import { MachineRegistry } from './MachineRegistry';
|
|
23
|
+
import { IMachineRegistry } from './MachineRegistry/interface';
|
|
24
|
+
import { SimpleEventBroker } from './utils/SimpleEventBroker';
|
|
25
|
+
import { createSimpleEventBroker } from './utils/SimpleEventBroker/helper';
|
|
26
|
+
import { ArvoResumable } from './ArvoResumable';
|
|
27
|
+
import { createArvoResumable } from './ArvoResumable/factory';
|
|
28
|
+
import { ArvoResumableHandler, ArvoResumableState } from './ArvoResumable/types';
|
|
29
|
+
declare const xstate: {
|
|
30
|
+
emit: typeof emit;
|
|
31
|
+
assign: typeof assign;
|
|
32
|
+
};
|
|
33
|
+
export { ArvoEventHandler, createArvoEventHandler, IArvoEventHandler, ArvoEventHandlerFunctionOutput, ArvoEventHandlerFunctionInput, ArvoEventHandlerFunction, PartialExcept, isNullOrUndefined, getValueOrDefault, coalesce, coalesceOrDefault, AbstractArvoEventHandler, ArvoEventHandlerOpenTelemetryOptions, EventHandlerFactory, ContractViolation, ConfigViolation, ExecutionViolation, ArvoMachine, setupArvoMachine, ArvoMachineContext, EnqueueArvoEventActionParam, IMachineRegistry, MachineRegistry, MachineExecutionEngine, IMachineExectionEngine, ExecuteMachineInput, ExecuteMachineOutput, IMachineMemory, SimpleMachineMemory, MachineMemoryRecord, IArvoOrchestrator, TransactionViolation, TransactionViolationCause, ArvoOrchestrator, createArvoOrchestrator, SimpleEventBroker, createSimpleEventBroker, TelemetredSimpleMachineMemory, xstate, ArvoResumable, createArvoResumable, ArvoResumableHandler, ArvoResumableState, };
|
package/dist/index.js
CHANGED
|
@@ -3,29 +3,52 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.createArvoResumable = exports.ArvoResumable = exports.xstate = exports.TelemetredSimpleMachineMemory = exports.createSimpleEventBroker = exports.SimpleEventBroker = exports.createArvoOrchestrator = exports.ArvoOrchestrator = exports.TransactionViolationCause = exports.TransactionViolation = exports.SimpleMachineMemory = exports.MachineExecutionEngine = exports.MachineRegistry = exports.setupArvoMachine = exports.ArvoMachine = exports.ExecutionViolation = exports.ConfigViolation = exports.ContractViolation = exports.AbstractArvoEventHandler = exports.coalesceOrDefault = exports.coalesce = exports.getValueOrDefault = exports.isNullOrUndefined = exports.createArvoEventHandler = exports.ArvoEventHandler = void 0;
|
|
7
7
|
var AbstractArvoEventHandler_1 = __importDefault(require("./AbstractArvoEventHandler"));
|
|
8
8
|
exports.AbstractArvoEventHandler = AbstractArvoEventHandler_1.default;
|
|
9
9
|
var ArvoEventHandler_1 = __importDefault(require("./ArvoEventHandler"));
|
|
10
10
|
exports.ArvoEventHandler = ArvoEventHandler_1.default;
|
|
11
11
|
var helpers_1 = require("./ArvoEventHandler/helpers");
|
|
12
12
|
Object.defineProperty(exports, "createArvoEventHandler", { enumerable: true, get: function () { return helpers_1.createArvoEventHandler; } });
|
|
13
|
-
var ArvoEventRouter_1 = require("./ArvoEventRouter");
|
|
14
|
-
Object.defineProperty(exports, "ArvoEventRouter", { enumerable: true, get: function () { return ArvoEventRouter_1.ArvoEventRouter; } });
|
|
15
|
-
var helpers_2 = require("./ArvoEventRouter/helpers");
|
|
16
|
-
Object.defineProperty(exports, "createArvoEventRouter", { enumerable: true, get: function () { return helpers_2.createArvoEventRouter; } });
|
|
17
|
-
var utils_1 = require("./ArvoEventRouter/utils");
|
|
18
|
-
Object.defineProperty(exports, "deleteOtelHeaders", { enumerable: true, get: function () { return utils_1.deleteOtelHeaders; } });
|
|
19
|
-
var MultiArvoEventHandler_1 = __importDefault(require("./MultiArvoEventHandler"));
|
|
20
|
-
exports.MultiArvoEventHandler = MultiArvoEventHandler_1.default;
|
|
21
|
-
var helpers_3 = require("./MultiArvoEventHandler/helpers");
|
|
22
|
-
Object.defineProperty(exports, "createMultiArvoEventHandler", { enumerable: true, get: function () { return helpers_3.createMultiArvoEventHandler; } });
|
|
23
13
|
var errors_1 = require("./errors");
|
|
24
14
|
Object.defineProperty(exports, "ConfigViolation", { enumerable: true, get: function () { return errors_1.ConfigViolation; } });
|
|
25
15
|
Object.defineProperty(exports, "ContractViolation", { enumerable: true, get: function () { return errors_1.ContractViolation; } });
|
|
26
16
|
Object.defineProperty(exports, "ExecutionViolation", { enumerable: true, get: function () { return errors_1.ExecutionViolation; } });
|
|
27
|
-
var
|
|
28
|
-
Object.defineProperty(exports, "coalesce", { enumerable: true, get: function () { return
|
|
29
|
-
Object.defineProperty(exports, "coalesceOrDefault", { enumerable: true, get: function () { return
|
|
30
|
-
Object.defineProperty(exports, "getValueOrDefault", { enumerable: true, get: function () { return
|
|
31
|
-
Object.defineProperty(exports, "isNullOrUndefined", { enumerable: true, get: function () { return
|
|
17
|
+
var utils_1 = require("./utils");
|
|
18
|
+
Object.defineProperty(exports, "coalesce", { enumerable: true, get: function () { return utils_1.coalesce; } });
|
|
19
|
+
Object.defineProperty(exports, "coalesceOrDefault", { enumerable: true, get: function () { return utils_1.coalesceOrDefault; } });
|
|
20
|
+
Object.defineProperty(exports, "getValueOrDefault", { enumerable: true, get: function () { return utils_1.getValueOrDefault; } });
|
|
21
|
+
Object.defineProperty(exports, "isNullOrUndefined", { enumerable: true, get: function () { return utils_1.isNullOrUndefined; } });
|
|
22
|
+
var xstate_1 = require("xstate");
|
|
23
|
+
var ArvoMachine_1 = __importDefault(require("./ArvoMachine"));
|
|
24
|
+
exports.ArvoMachine = ArvoMachine_1.default;
|
|
25
|
+
var createMachine_1 = require("./ArvoMachine/createMachine");
|
|
26
|
+
Object.defineProperty(exports, "setupArvoMachine", { enumerable: true, get: function () { return createMachine_1.setupArvoMachine; } });
|
|
27
|
+
var ArvoOrchestrator_1 = require("./ArvoOrchestrator");
|
|
28
|
+
Object.defineProperty(exports, "ArvoOrchestrator", { enumerable: true, get: function () { return ArvoOrchestrator_1.ArvoOrchestrator; } });
|
|
29
|
+
var error_1 = require("./ArvoOrchestrator/error");
|
|
30
|
+
Object.defineProperty(exports, "TransactionViolation", { enumerable: true, get: function () { return error_1.TransactionViolation; } });
|
|
31
|
+
Object.defineProperty(exports, "TransactionViolationCause", { enumerable: true, get: function () { return error_1.TransactionViolationCause; } });
|
|
32
|
+
var factory_1 = require("./ArvoOrchestrator/factory");
|
|
33
|
+
Object.defineProperty(exports, "createArvoOrchestrator", { enumerable: true, get: function () { return factory_1.createArvoOrchestrator; } });
|
|
34
|
+
var MachineExecutionEngine_1 = require("./MachineExecutionEngine");
|
|
35
|
+
Object.defineProperty(exports, "MachineExecutionEngine", { enumerable: true, get: function () { return MachineExecutionEngine_1.MachineExecutionEngine; } });
|
|
36
|
+
var Simple_1 = require("./MachineMemory/Simple");
|
|
37
|
+
Object.defineProperty(exports, "SimpleMachineMemory", { enumerable: true, get: function () { return Simple_1.SimpleMachineMemory; } });
|
|
38
|
+
var TelemetredSimple_1 = require("./MachineMemory/TelemetredSimple");
|
|
39
|
+
Object.defineProperty(exports, "TelemetredSimpleMachineMemory", { enumerable: true, get: function () { return TelemetredSimple_1.TelemetredSimpleMachineMemory; } });
|
|
40
|
+
var MachineRegistry_1 = require("./MachineRegistry");
|
|
41
|
+
Object.defineProperty(exports, "MachineRegistry", { enumerable: true, get: function () { return MachineRegistry_1.MachineRegistry; } });
|
|
42
|
+
var SimpleEventBroker_1 = require("./utils/SimpleEventBroker");
|
|
43
|
+
Object.defineProperty(exports, "SimpleEventBroker", { enumerable: true, get: function () { return SimpleEventBroker_1.SimpleEventBroker; } });
|
|
44
|
+
var helper_1 = require("./utils/SimpleEventBroker/helper");
|
|
45
|
+
Object.defineProperty(exports, "createSimpleEventBroker", { enumerable: true, get: function () { return helper_1.createSimpleEventBroker; } });
|
|
46
|
+
var ArvoResumable_1 = require("./ArvoResumable");
|
|
47
|
+
Object.defineProperty(exports, "ArvoResumable", { enumerable: true, get: function () { return ArvoResumable_1.ArvoResumable; } });
|
|
48
|
+
var factory_2 = require("./ArvoResumable/factory");
|
|
49
|
+
Object.defineProperty(exports, "createArvoResumable", { enumerable: true, get: function () { return factory_2.createArvoResumable; } });
|
|
50
|
+
var xstate = {
|
|
51
|
+
emit: xstate_1.emit,
|
|
52
|
+
assign: xstate_1.assign,
|
|
53
|
+
};
|
|
54
|
+
exports.xstate = xstate;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { ArvoEvent } from 'arvo-core';
|
|
2
|
+
import { SimpleEventBroker } from '.';
|
|
3
|
+
import type AbstractArvoEventHandler from '../../AbstractArvoEventHandler';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a local event broker configured with domain event handlers and provides event resolution capabilities
|
|
6
|
+
*
|
|
7
|
+
* This factory function establishes a comprehensive event-driven architecture within a single process,
|
|
8
|
+
* automatically wiring event handlers to their source topics and providing sophisticated event propagation
|
|
9
|
+
* with domain-specific routing capabilities. The broker implements sequential queue-based processing
|
|
10
|
+
* with built-in error handling and observability features.
|
|
11
|
+
*
|
|
12
|
+
* **Core Architecture:**
|
|
13
|
+
* The broker acts as an in-memory event bus that connects ArvoResumable orchestrators, ArvoOrchestrator
|
|
14
|
+
* state machines, and ArvoEventHandler services in a unified event-driven system. This enables
|
|
15
|
+
* local testing of distributed workflows and provides a foundation for event-driven microservices.
|
|
16
|
+
*
|
|
17
|
+
* **Event Processing Flow:**
|
|
18
|
+
* 1. Events are published to handler source topics
|
|
19
|
+
* 2. Handlers execute and produce response events
|
|
20
|
+
* 3. Domain-specific events are routed through onDomainedEvents callback
|
|
21
|
+
* 4. Default domain events are automatically propagated through the broker
|
|
22
|
+
* 5. Event chains continue until all handlers complete processing
|
|
23
|
+
*
|
|
24
|
+
* @param eventHandlers - Array of event handlers to register with the broker. Each handler is automatically
|
|
25
|
+
* subscribed to its source topic and executed when matching events are received.
|
|
26
|
+
* Supports ArvoResumable, ArvoOrchestrator, and ArvoEventHandler instances.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Optional configuration for customizing broker behavior and event processing
|
|
29
|
+
* @param options.onError - Custom error handler invoked when processing failures occur. Receives the error
|
|
30
|
+
* and triggering event for logging, monitoring, or recovery actions. Defaults to
|
|
31
|
+
* console.error with structured event information for debugging.
|
|
32
|
+
* @param options.onDomainedEvents - Callback for processing domain-specific events produced by handlers.
|
|
33
|
+
* Enables custom routing logic, external system integration, or
|
|
34
|
+
* domain-specific event processing patterns. Receives events grouped
|
|
35
|
+
* by domain (excluding 'all') and the broker instance for republishing.
|
|
36
|
+
*
|
|
37
|
+
* @returns Configuration object containing the broker instance and event resolution function
|
|
38
|
+
* @returns result.broker - Configured SimpleEventBroker with all handlers subscribed and ready for processing
|
|
39
|
+
* @returns result.resolve - Async function that executes complete event processing chains and returns
|
|
40
|
+
* the final resolved event. Returns null if resolution fails or handler is not found
|
|
41
|
+
* for an intermetiate event.
|
|
42
|
+
*
|
|
43
|
+
* @throws {Error} When event source conflicts with registered handler sources during resolution
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* **Basic Event-Driven Architecture Setup:**
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const userHandler = createArvoEventHandler({
|
|
49
|
+
* contract: userContract,
|
|
50
|
+
* handler: { '1.0.0': async ({ event }) => ({ type: 'user.processed', data: event.data }) }
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* const orderOrchestrator = createArvoResumable({
|
|
54
|
+
* contracts: { self: orderContract, services: { user: userContract } },
|
|
55
|
+
* handler: {
|
|
56
|
+
* '1.0.0': async ({ init, service }) => {
|
|
57
|
+
* if (init) return { services: [{ type: 'user.process', data: init.data }] };
|
|
58
|
+
* if (service) return { complete: { data: { orderId: 'order-123' } } };
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* const { broker, resolve } = createSimpleEventBroker([userHandler, orderOrchestrator]);
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* **Advanced Configuration with Domain Routing:**
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const { broker, resolve } = createSimpleEventBroker(
|
|
70
|
+
* [orchestrator, paymentHandler, notificationHandler],
|
|
71
|
+
* {
|
|
72
|
+
* onError: (error, event) => {
|
|
73
|
+
* logger.error('Event processing failed', {
|
|
74
|
+
* error: error.message,
|
|
75
|
+
* eventType: event.type,
|
|
76
|
+
* eventId: event.id,
|
|
77
|
+
* source: event.source,
|
|
78
|
+
* timestamp: new Date().toISOString()
|
|
79
|
+
* });
|
|
80
|
+
* // Could implement retry logic, dead letter queues, etc.
|
|
81
|
+
* },
|
|
82
|
+
* onDomainedEvents: ({ events, broker }) => {
|
|
83
|
+
* // Route payment events to external payment processor
|
|
84
|
+
* if (events.payment) {
|
|
85
|
+
* events.payment.forEach(event => paymentGateway.send(event));
|
|
86
|
+
* }
|
|
87
|
+
*
|
|
88
|
+
* // Route notification events to messaging service
|
|
89
|
+
* if (events.notifications) {
|
|
90
|
+
* events.notifications.forEach(event => messagingService.send(event));
|
|
91
|
+
* }
|
|
92
|
+
*
|
|
93
|
+
* // Republish other domain events through the broker
|
|
94
|
+
* Object.entries(events).forEach(([domain, domainEvents]) => {
|
|
95
|
+
* if (!['payment', 'notifications'].includes(domain)) {
|
|
96
|
+
* domainEvents.forEach(event => broker.publish(event));
|
|
97
|
+
* }
|
|
98
|
+
* });
|
|
99
|
+
* }
|
|
100
|
+
* }
|
|
101
|
+
* );
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* **Event Resolution for Integration Testing:**
|
|
106
|
+
* ```typescript
|
|
107
|
+
* // Test complete workflow execution
|
|
108
|
+
* const testEvent = createArvoEvent({
|
|
109
|
+
* type: 'order.create',
|
|
110
|
+
* source: 'test.client',
|
|
111
|
+
* to: 'order.orchestrator',
|
|
112
|
+
* data: { userId: '123', items: ['item1', 'item2'] }
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* const finalEvent = await resolve(testEvent);
|
|
116
|
+
*
|
|
117
|
+
* if (finalEvent) {
|
|
118
|
+
* // Verify the complete workflow executed successfully
|
|
119
|
+
* expect(finalEvent.type).toBe('order.completed');
|
|
120
|
+
* expect(finalEvent.data.orderId).toBeDefined();
|
|
121
|
+
* expect(finalEvent.source).toBe('test.client'); // Original source preserved
|
|
122
|
+
* } else {
|
|
123
|
+
* throw new Error('Order processing workflow failed');
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* **Direct Event Publishing:**
|
|
129
|
+
* ```typescript
|
|
130
|
+
* // Publish events directly to the broker for real-time processing
|
|
131
|
+
* await broker.publish(createArvoEvent({
|
|
132
|
+
* type: 'user.signup',
|
|
133
|
+
* source: 'web.app',
|
|
134
|
+
* to: 'user.service',
|
|
135
|
+
* data: { email: 'user@example.com', name: 'John Doe' }
|
|
136
|
+
* }));
|
|
137
|
+
*
|
|
138
|
+
* // The event will be routed to the user service handler automatically
|
|
139
|
+
* // Any resulting events will propagate through the broker
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @remarks
|
|
143
|
+
* **Event Source Conflict Prevention:**
|
|
144
|
+
* The resolve function validates that the input event's source doesn't conflict
|
|
145
|
+
* with registered handler sources to prevent infinite loops and routing ambiguity.
|
|
146
|
+
*
|
|
147
|
+
* **Sequential Processing Guarantee:**
|
|
148
|
+
* Events are processed sequentially within each topic to maintain ordering
|
|
149
|
+
* guarantees and prevent race conditions in workflow state management.
|
|
150
|
+
*
|
|
151
|
+
* **Integration Testing Benefits:**
|
|
152
|
+
* This pattern enables comprehensive integration testing of event-driven workflows
|
|
153
|
+
* without requiring external message brokers, making test suites faster and
|
|
154
|
+
* more reliable while maintaining production-like behavior patterns.
|
|
155
|
+
*/
|
|
156
|
+
export declare const createSimpleEventBroker: (eventHandlers: AbstractArvoEventHandler[], options?: {
|
|
157
|
+
onError?: (error: Error, event: ArvoEvent) => void;
|
|
158
|
+
onDomainedEvents?: (param: {
|
|
159
|
+
domain: string;
|
|
160
|
+
event: ArvoEvent;
|
|
161
|
+
broker: SimpleEventBroker;
|
|
162
|
+
}) => Promise<void>;
|
|
163
|
+
}) => {
|
|
164
|
+
broker: SimpleEventBroker;
|
|
165
|
+
resolve: (_event: ArvoEvent) => Promise<ArvoEvent | null>;
|
|
166
|
+
};
|