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.
Files changed (78) hide show
  1. package/dist/AbstractArvoEventHandler/index.d.ts +1 -1
  2. package/dist/ArvoEventHandler/helpers.d.ts +40 -6
  3. package/dist/ArvoEventHandler/helpers.js +40 -6
  4. package/dist/ArvoEventHandler/index.d.ts +78 -49
  5. package/dist/ArvoEventHandler/index.js +152 -83
  6. package/dist/ArvoEventHandler/types.d.ts +25 -2
  7. package/dist/ArvoMachine/createMachine.d.ts +208 -0
  8. package/dist/ArvoMachine/createMachine.js +283 -0
  9. package/dist/ArvoMachine/index.d.ts +93 -0
  10. package/dist/ArvoMachine/index.js +160 -0
  11. package/dist/ArvoMachine/types.d.ts +194 -0
  12. package/dist/ArvoMachine/utils.d.ts +40 -0
  13. package/dist/ArvoMachine/utils.js +70 -0
  14. package/dist/ArvoOrchestrator/error.d.ts +16 -0
  15. package/dist/ArvoOrchestrator/error.js +43 -0
  16. package/dist/ArvoOrchestrator/factory.d.ts +28 -0
  17. package/dist/ArvoOrchestrator/factory.js +56 -0
  18. package/dist/ArvoOrchestrator/index.d.ts +69 -0
  19. package/dist/ArvoOrchestrator/index.js +597 -0
  20. package/dist/ArvoOrchestrator/types.d.ts +98 -0
  21. package/dist/ArvoResumable/factory.d.ts +50 -0
  22. package/dist/ArvoResumable/factory.js +70 -0
  23. package/dist/ArvoResumable/index.d.ts +141 -0
  24. package/dist/ArvoResumable/index.js +694 -0
  25. package/dist/ArvoResumable/types.d.ts +147 -0
  26. package/dist/ArvoResumable/types.js +2 -0
  27. package/dist/MachineExecutionEngine/index.d.ts +29 -0
  28. package/dist/MachineExecutionEngine/index.js +132 -0
  29. package/dist/MachineExecutionEngine/interface.d.ts +14 -0
  30. package/dist/MachineExecutionEngine/interface.js +2 -0
  31. package/dist/MachineExecutionEngine/types.d.ts +14 -0
  32. package/dist/MachineExecutionEngine/types.js +2 -0
  33. package/dist/MachineMemory/Simple.d.ts +51 -0
  34. package/dist/MachineMemory/Simple.js +158 -0
  35. package/dist/MachineMemory/TelemetredSimple.d.ts +51 -0
  36. package/dist/MachineMemory/TelemetredSimple.js +230 -0
  37. package/dist/MachineMemory/interface.d.ts +57 -0
  38. package/dist/MachineMemory/interface.js +2 -0
  39. package/dist/MachineMemory/utils.d.ts +1 -0
  40. package/dist/MachineMemory/utils.js +18 -0
  41. package/dist/MachineRegistry/index.d.ts +37 -0
  42. package/dist/MachineRegistry/index.js +87 -0
  43. package/dist/MachineRegistry/interface.d.ts +21 -0
  44. package/dist/MachineRegistry/interface.js +2 -0
  45. package/dist/SyncEventResource/index.d.ts +110 -0
  46. package/dist/SyncEventResource/index.js +280 -0
  47. package/dist/SyncEventResource/types.d.ts +2 -0
  48. package/dist/SyncEventResource/types.js +2 -0
  49. package/dist/index.d.ts +26 -8
  50. package/dist/index.js +39 -16
  51. package/dist/utils/SimpleEventBroker/helper.d.ts +166 -0
  52. package/dist/utils/SimpleEventBroker/helper.js +276 -0
  53. package/dist/utils/SimpleEventBroker/index.d.ts +96 -0
  54. package/dist/utils/SimpleEventBroker/index.js +259 -0
  55. package/dist/utils/SimpleEventBroker/types.d.ts +6 -0
  56. package/dist/utils/SimpleEventBroker/types.js +2 -0
  57. package/dist/utils/SimpleEventBroker/utils.d.ts +1 -0
  58. package/dist/utils/SimpleEventBroker/utils.js +10 -0
  59. package/dist/{utils.d.ts → utils/index.d.ts} +3 -36
  60. package/dist/utils/index.js +91 -0
  61. package/dist/utils/object/index.d.ts +37 -0
  62. package/dist/utils/object/index.js +63 -0
  63. package/package.json +5 -3
  64. package/dist/ArvoEventRouter/helpers.d.ts +0 -19
  65. package/dist/ArvoEventRouter/helpers.js +0 -22
  66. package/dist/ArvoEventRouter/index.d.ts +0 -89
  67. package/dist/ArvoEventRouter/index.js +0 -268
  68. package/dist/ArvoEventRouter/types.d.ts +0 -36
  69. package/dist/ArvoEventRouter/utils.d.ts +0 -30
  70. package/dist/ArvoEventRouter/utils.js +0 -43
  71. package/dist/MultiArvoEventHandler/helpers.d.ts +0 -48
  72. package/dist/MultiArvoEventHandler/helpers.js +0 -56
  73. package/dist/MultiArvoEventHandler/index.d.ts +0 -68
  74. package/dist/MultiArvoEventHandler/index.js +0 -205
  75. package/dist/MultiArvoEventHandler/types.d.ts +0 -64
  76. package/dist/utils.js +0 -191
  77. /package/dist/{ArvoEventRouter → ArvoMachine}/types.js +0 -0
  78. /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;
@@ -0,0 +1,2 @@
1
+ export type AcquiredLockStatusType = 'NOOP' | 'ACQUIRED' | 'NOT_ACQUIRED';
2
+ export type ReleasedLockStatusType = 'NOOP' | 'RELEASED' | 'ERROR';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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
- export { ArvoEventHandler, createArvoEventHandler, IArvoEventHandler, ArvoEventHandlerFunctionOutput, ArvoEventHandlerFunctionInput, ArvoEventHandlerFunction, PartialExcept, MultiArvoEventHandler, MultiArvoEventHandlerFunctionInput, MultiArvoEventHandlerFunctionOutput, MultiArvoEventHandlerFunction, IMultiArvoEventHandler, createMultiArvoEventHandler, isNullOrUndefined, getValueOrDefault, coalesce, coalesceOrDefault, IArvoEventRouter, ArvoEventRouter, createArvoEventRouter, AbstractArvoEventHandler, deleteOtelHeaders, ArvoEventHandlerOpenTelemetryOptions, EventHandlerFactory, ContractViolation, ConfigViolation, ExecutionViolation, };
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.ExecutionViolation = exports.ConfigViolation = exports.ContractViolation = exports.deleteOtelHeaders = exports.AbstractArvoEventHandler = exports.createArvoEventRouter = exports.ArvoEventRouter = exports.coalesceOrDefault = exports.coalesce = exports.getValueOrDefault = exports.isNullOrUndefined = exports.createMultiArvoEventHandler = exports.MultiArvoEventHandler = exports.createArvoEventHandler = exports.ArvoEventHandler = void 0;
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 utils_2 = require("./utils");
28
- Object.defineProperty(exports, "coalesce", { enumerable: true, get: function () { return utils_2.coalesce; } });
29
- Object.defineProperty(exports, "coalesceOrDefault", { enumerable: true, get: function () { return utils_2.coalesceOrDefault; } });
30
- Object.defineProperty(exports, "getValueOrDefault", { enumerable: true, get: function () { return utils_2.getValueOrDefault; } });
31
- Object.defineProperty(exports, "isNullOrUndefined", { enumerable: true, get: function () { return utils_2.isNullOrUndefined; } });
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
+ };