arvo-event-handler 2.3.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +151 -81
  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 +6 -12
  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 -267
  68. package/dist/ArvoEventRouter/types.d.ts +0 -36
  69. package/dist/ArvoEventRouter/utils.d.ts +0 -29
  70. package/dist/ArvoEventRouter/utils.js +0 -42
  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 -190
  77. /package/dist/{ArvoEventRouter → ArvoMachine}/types.js +0 -0
  78. /package/dist/{MultiArvoEventHandler → ArvoOrchestrator}/types.js +0 -0
@@ -0,0 +1,597 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __assign = (this && this.__assign) || function () {
18
+ __assign = Object.assign || function(t) {
19
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
20
+ s = arguments[i];
21
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
22
+ t[p] = s[p];
23
+ }
24
+ return t;
25
+ };
26
+ return __assign.apply(this, arguments);
27
+ };
28
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
+ return new (P || (P = Promise))(function (resolve, reject) {
31
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
35
+ });
36
+ };
37
+ var __generator = (this && this.__generator) || function (thisArg, body) {
38
+ 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);
39
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
+ function verb(n) { return function (v) { return step([n, v]); }; }
41
+ function step(op) {
42
+ if (f) throw new TypeError("Generator is already executing.");
43
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
44
+ 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;
45
+ if (y = 0, t) op = [op[0] & 2, t.value];
46
+ switch (op[0]) {
47
+ case 0: case 1: t = op; break;
48
+ case 4: _.label++; return { value: op[1], done: false };
49
+ case 5: _.label++; y = op[1]; op = [0]; continue;
50
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
51
+ default:
52
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
53
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
54
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
55
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
56
+ if (t[2]) _.ops.pop();
57
+ _.trys.pop(); continue;
58
+ }
59
+ op = body.call(thisArg, _);
60
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
61
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
+ }
63
+ };
64
+ var __importDefault = (this && this.__importDefault) || function (mod) {
65
+ return (mod && mod.__esModule) ? mod : { "default": mod };
66
+ };
67
+ Object.defineProperty(exports, "__esModule", { value: true });
68
+ exports.ArvoOrchestrator = void 0;
69
+ var api_1 = require("@opentelemetry/api");
70
+ var arvo_core_1 = require("arvo-core");
71
+ var utils_1 = require("../utils");
72
+ var error_1 = require("./error");
73
+ var SyncEventResource_1 = require("../SyncEventResource");
74
+ var AbstractArvoEventHandler_1 = __importDefault(require("../AbstractArvoEventHandler"));
75
+ var errors_1 = require("../errors");
76
+ /**
77
+ * Orchestrates state machine execution and lifecycle management.
78
+ * Handles machine resolution, state management, event processing and error handling.
79
+ */
80
+ var ArvoOrchestrator = /** @class */ (function (_super) {
81
+ __extends(ArvoOrchestrator, _super);
82
+ /**
83
+ * Creates a new orchestrator instance
84
+ * @param params - Configuration parameters
85
+ * @throws Error if machines in registry have different sources
86
+ */
87
+ function ArvoOrchestrator(_a) {
88
+ var executionunits = _a.executionunits, memory = _a.memory, registry = _a.registry, executionEngine = _a.executionEngine, requiresResourceLocking = _a.requiresResourceLocking;
89
+ var _this = _super.call(this) || this;
90
+ _this.executionunits = executionunits;
91
+ var representativeMachine = registry.machines[0];
92
+ var lastSeenVersions = [];
93
+ for (var _i = 0, _b = registry.machines; _i < _b.length; _i++) {
94
+ var machine = _b[_i];
95
+ if (representativeMachine.source !== machine.source) {
96
+ throw new Error("All the machines in the orchestrator must have type '".concat(representativeMachine.source, "'"));
97
+ }
98
+ if (lastSeenVersions.includes(machine.version)) {
99
+ throw new Error("An orchestrator must have unique machine versions. Machine ID:".concat(machine.id, " has duplicate version ").concat(machine.version, "."));
100
+ }
101
+ lastSeenVersions.push(machine.version);
102
+ }
103
+ _this.registry = registry;
104
+ _this.executionEngine = executionEngine;
105
+ _this.syncEventResource = new SyncEventResource_1.SyncEventResource(memory, requiresResourceLocking);
106
+ return _this;
107
+ }
108
+ Object.defineProperty(ArvoOrchestrator.prototype, "source", {
109
+ get: function () {
110
+ return this.registry.machines[0].source;
111
+ },
112
+ enumerable: false,
113
+ configurable: true
114
+ });
115
+ Object.defineProperty(ArvoOrchestrator.prototype, "requiresResourceLocking", {
116
+ get: function () {
117
+ return this.syncEventResource.requiresResourceLocking;
118
+ },
119
+ enumerable: false,
120
+ configurable: true
121
+ });
122
+ Object.defineProperty(ArvoOrchestrator.prototype, "memory", {
123
+ get: function () {
124
+ return this.syncEventResource.memory;
125
+ },
126
+ enumerable: false,
127
+ configurable: true
128
+ });
129
+ Object.defineProperty(ArvoOrchestrator.prototype, "domain", {
130
+ get: function () {
131
+ return this.registry.machines[0].contracts.self.domain;
132
+ },
133
+ enumerable: false,
134
+ configurable: true
135
+ });
136
+ /**
137
+ * Creates emittable event from execution result
138
+ * @param event - Source event to emit
139
+ * @param machine - Machine that generated event
140
+ * @param otelHeaders - OpenTelemetry headers
141
+ * @param orchestrationParentSubject - Parent orchestration subject
142
+ * @param sourceEvent - Original triggering event
143
+ * @param initEventId - The id of the event which initiated the orchestration in the first place
144
+ * @param _domain - The domain of the event.
145
+ *
146
+ * @throws {ContractViolation} On schema/contract mismatch
147
+ * @throws {ExecutionViolation} On invalid parentSubject$$ format
148
+ */
149
+ ArvoOrchestrator.prototype.createEmittableEvent = function (event, machine, otelHeaders, orchestrationParentSubject, sourceEvent, initEventId, _domain) {
150
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
151
+ (0, arvo_core_1.logToSpan)({
152
+ level: 'INFO',
153
+ message: "Creating emittable event: ".concat(event.type),
154
+ });
155
+ var selfContract = machine.contracts.self;
156
+ var serviceContract = Object.fromEntries(Object.values(machine.contracts.services).map(function (item) { return [item.accepts.type, item]; }));
157
+ var schema = null;
158
+ var contract = null;
159
+ var subject = sourceEvent.subject;
160
+ var parentId = sourceEvent.id;
161
+ var domain = _domain === undefined ? ((_b = (_a = sourceEvent.domain) !== null && _a !== void 0 ? _a : this.domain) !== null && _b !== void 0 ? _b : null) : _domain;
162
+ if (event.type === selfContract.metadata.completeEventType) {
163
+ (0, arvo_core_1.logToSpan)({
164
+ level: 'INFO',
165
+ message: "Creating event for machine workflow completion: ".concat(event.type),
166
+ });
167
+ contract = selfContract;
168
+ schema = selfContract.emits[selfContract.metadata.completeEventType];
169
+ subject = orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : sourceEvent.subject;
170
+ parentId = initEventId;
171
+ domain = _domain === undefined ? ((_e = (_d = (_c = selfContract.domain) !== null && _c !== void 0 ? _c : sourceEvent.domain) !== null && _d !== void 0 ? _d : this.domain) !== null && _e !== void 0 ? _e : null) : _domain;
172
+ }
173
+ else if (serviceContract[event.type]) {
174
+ (0, arvo_core_1.logToSpan)({
175
+ level: 'INFO',
176
+ message: "Creating service event for external system: ".concat(event.type),
177
+ });
178
+ contract = serviceContract[event.type];
179
+ schema = serviceContract[event.type].accepts.schema;
180
+ domain = _domain === undefined ? ((_h = (_g = (_f = contract === null || contract === void 0 ? void 0 : contract.domain) !== null && _f !== void 0 ? _f : sourceEvent.domain) !== null && _g !== void 0 ? _g : this.domain) !== null && _h !== void 0 ? _h : null) : _domain;
181
+ // If the event is to call another orchestrator then, extract the parent subject
182
+ // passed to it and then form an new subject. This allows for event chaining
183
+ // between orchestrators
184
+ if (contract.metadata.contractType === 'ArvoOrchestratorContract') {
185
+ if (event.data.parentSubject$$) {
186
+ try {
187
+ arvo_core_1.ArvoOrchestrationSubject.parse(event.data.parentSubject$$);
188
+ }
189
+ catch (e) {
190
+ throw new errors_1.ExecutionViolation("Invalid parentSubject$$ for the event(type='".concat(event.type, "', uri='").concat((_j = event.dataschema) !== null && _j !== void 0 ? _j : arvo_core_1.EventDataschemaUtil.create(contract), "').It must be follow the ArvoOrchestrationSubject schema. The easiest way is to use the current orchestration subject by storing the subject via the context block in the machine definition."));
191
+ }
192
+ }
193
+ try {
194
+ if (event.data.parentSubject$$) {
195
+ subject = arvo_core_1.ArvoOrchestrationSubject.from({
196
+ orchestator: contract.accepts.type,
197
+ version: contract.version,
198
+ subject: event.data.parentSubject$$,
199
+ domain: domain !== null && domain !== void 0 ? domain : null,
200
+ meta: {
201
+ redirectto: (_k = event.redirectto) !== null && _k !== void 0 ? _k : this.source,
202
+ },
203
+ });
204
+ }
205
+ else {
206
+ subject = arvo_core_1.ArvoOrchestrationSubject.new({
207
+ version: contract.version,
208
+ orchestator: contract.accepts.type,
209
+ initiator: this.source,
210
+ domain: domain !== null && domain !== void 0 ? domain : undefined,
211
+ meta: {
212
+ redirectto: (_l = event.redirectto) !== null && _l !== void 0 ? _l : this.source,
213
+ },
214
+ });
215
+ }
216
+ }
217
+ catch (error) {
218
+ // This is a execution violation because it indicates faulty parent subject
219
+ // or some fundamental error with subject creation which must be not be propagated
220
+ // any further and investigated manually.
221
+ throw new errors_1.ExecutionViolation("Orchestration subject creation failed due to invalid parameters - Event: ".concat(event.type, " - Check event emit parameters in the machine definition. ").concat(error === null || error === void 0 ? void 0 : error.message));
222
+ }
223
+ }
224
+ }
225
+ var finalDataschema = event.dataschema;
226
+ var finalData = event.data;
227
+ // finally if the contract and the schema are available
228
+ // then use them to validate the event. Otherwise just use
229
+ // the data from the incoming event which is raw and created
230
+ // by the machine
231
+ if (contract && schema) {
232
+ try {
233
+ finalData = schema.parse(event.data);
234
+ finalDataschema = arvo_core_1.EventDataschemaUtil.create(contract);
235
+ }
236
+ catch (error) {
237
+ throw new errors_1.ContractViolation("Invalid event data: Schema validation failed - Check emit parameters in machine definition.\nEvent type: ".concat(event.type, "\nDetails: ").concat(error.message));
238
+ }
239
+ }
240
+ // Create the event
241
+ var emittableEvent = (0, arvo_core_1.createArvoEvent)({
242
+ source: this.source,
243
+ type: event.type,
244
+ subject: subject,
245
+ dataschema: finalDataschema !== null && finalDataschema !== void 0 ? finalDataschema : undefined,
246
+ data: finalData,
247
+ to: (_m = event.to) !== null && _m !== void 0 ? _m : event.type,
248
+ accesscontrol: (_p = (_o = event.accesscontrol) !== null && _o !== void 0 ? _o : sourceEvent.accesscontrol) !== null && _p !== void 0 ? _p : undefined,
249
+ // The orchestrator does not respect redirectto from the source event
250
+ redirectto: (_q = event.redirectto) !== null && _q !== void 0 ? _q : this.source,
251
+ executionunits: (_r = event.executionunits) !== null && _r !== void 0 ? _r : this.executionunits,
252
+ traceparent: (_s = otelHeaders.traceparent) !== null && _s !== void 0 ? _s : undefined,
253
+ tracestate: (_t = otelHeaders.tracestate) !== null && _t !== void 0 ? _t : undefined,
254
+ parentid: parentId,
255
+ domain: domain !== null && domain !== void 0 ? domain : undefined,
256
+ }, (_u = event.__extensions) !== null && _u !== void 0 ? _u : {});
257
+ (0, arvo_core_1.logToSpan)({
258
+ level: 'INFO',
259
+ message: "Event created successfully: ".concat(emittableEvent.type),
260
+ });
261
+ return emittableEvent;
262
+ };
263
+ /**
264
+ * Core orchestration method that executes state machines in response to events.
265
+ * Manages the complete event lifecycle:
266
+ * 1. Acquires lock and state
267
+ * 2. Validates events and contracts
268
+ * 3. Executes state machine
269
+ * 4. Persists new state
270
+ * 5. Generates response events with domain-based segregation
271
+ *
272
+ * @param event - Event triggering the execution
273
+ * @param opentelemetry - OpenTelemetry configuration
274
+ * @returns Object containing domained events
275
+ *
276
+ * @throws {TransactionViolation} Lock/state operations failed
277
+ * @throws {ExecutionViolation} Invalid event structure/flow
278
+ * @throws {ContractViolation} Schema/contract mismatch
279
+ * @throws {ConfigViolation} Missing/invalid machine version
280
+ */
281
+ ArvoOrchestrator.prototype.execute = function (event_1) {
282
+ return __awaiter(this, arguments, void 0, function (event, opentelemetry) {
283
+ var _a;
284
+ var _this = this;
285
+ if (opentelemetry === void 0) { opentelemetry = {
286
+ inheritFrom: 'EVENT',
287
+ }; }
288
+ return __generator(this, function (_b) {
289
+ switch (_b.label) {
290
+ case 0: return [4 /*yield*/, arvo_core_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
291
+ name: "Orchestrator<".concat(this.registry.machines[0].contracts.self.uri, ">@<").concat(event.type, ">"),
292
+ spanOptions: {
293
+ kind: api_1.SpanKind.PRODUCER,
294
+ attributes: __assign((_a = {}, _a[arvo_core_1.ArvoExecution.ATTR_SPAN_KIND] = arvo_core_1.ArvoExecutionSpanKind.ORCHESTRATOR, _a[arvo_core_1.OpenInference.ATTR_SPAN_KIND] = arvo_core_1.OpenInferenceSpanKind.CHAIN, _a), Object.fromEntries(Object.entries(event.otelAttributes).map(function (_a) {
295
+ var key = _a[0], value = _a[1];
296
+ return ["to_process.0.".concat(key), value];
297
+ }))),
298
+ },
299
+ context: opentelemetry.inheritFrom === 'EVENT'
300
+ ? {
301
+ inheritFrom: 'TRACE_HEADERS',
302
+ traceHeaders: {
303
+ traceparent: event.traceparent,
304
+ tracestate: event.tracestate,
305
+ },
306
+ }
307
+ : {
308
+ inheritFrom: 'CONTEXT',
309
+ context: api_1.context.active(),
310
+ },
311
+ disableSpanManagement: true,
312
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
313
+ var otelHeaders, orchestrationParentSubject, initEventId, acquiredLock, parsedEventSubject, machine, _a, name_1, version, inputValidation, state, executionResult, rawMachineEmittedEvents, emittables, _i, rawMachineEmittedEvents_1, item, domains, _b, _c, _dom, evt, _d, _e, _f, key, value, error_2, e, parsedEventSubject, result, _g, _h, _dom, _j, _k, _l, key, value;
314
+ var _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
315
+ return __generator(this, function (_0) {
316
+ switch (_0.label) {
317
+ case 0:
318
+ (0, arvo_core_1.logToSpan)({
319
+ level: 'INFO',
320
+ message: "Orchestrator starting execution for ".concat(event.type, " on subject ").concat(event.subject),
321
+ });
322
+ otelHeaders = (0, arvo_core_1.currentOpenTelemetryHeaders)();
323
+ orchestrationParentSubject = null;
324
+ initEventId = null;
325
+ acquiredLock = null;
326
+ _0.label = 1;
327
+ case 1:
328
+ _0.trys.push([1, 5, 6, 8]);
329
+ ///////////////////////////////////////////////////////////////
330
+ // Subject resolution, machine resolution and input validation
331
+ ///////////////////////////////////////////////////////////////
332
+ this.syncEventResource.validateEventSubject(event, span);
333
+ parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
334
+ span.setAttributes({
335
+ 'arvo.parsed.subject.orchestrator.name': parsedEventSubject.orchestrator.name,
336
+ 'arvo.parsed.subject.orchestrator.version': parsedEventSubject.orchestrator.version,
337
+ });
338
+ // The wrong source is not a big violation. May be some routing went wrong. So just ignore
339
+ if (parsedEventSubject.orchestrator.name !== this.source) {
340
+ (0, arvo_core_1.logToSpan)({
341
+ level: 'WARNING',
342
+ message: "Event subject mismatch detected. Expected orchestrator '".concat(this.source, "' but subject indicates '").concat(parsedEventSubject.orchestrator.name, "'. This indicates either a routing error or a non-applicable event that can be safely ignored."),
343
+ });
344
+ (0, arvo_core_1.logToSpan)({
345
+ level: 'INFO',
346
+ message: 'Orchestration executed with issues and emitted 0 events',
347
+ });
348
+ return [2 /*return*/, {
349
+ events: [],
350
+ }];
351
+ }
352
+ (0, arvo_core_1.logToSpan)({
353
+ level: 'INFO',
354
+ message: "Resolving machine for event ".concat(event.type),
355
+ });
356
+ machine = this.registry.resolve(event, {
357
+ inheritFrom: 'CONTEXT',
358
+ });
359
+ // Unable to find a machine is a big configuration bug and violation
360
+ if (!machine) {
361
+ _a = parsedEventSubject.orchestrator, name_1 = _a.name, version = _a.version;
362
+ throw new errors_1.ConfigViolation("Machine resolution failed: No machine found matching orchestrator name='".concat(name_1, "' and version='").concat(version, "'."));
363
+ }
364
+ (0, arvo_core_1.logToSpan)({
365
+ level: 'INFO',
366
+ message: "Input validation started for event ".concat(event.type, " on machine ").concat(machine.source),
367
+ });
368
+ inputValidation = machine.validateInput(event);
369
+ if (inputValidation.type === 'CONTRACT_UNRESOLVED') {
370
+ // This is a configuration error because the contract was never
371
+ // configured in the machine. That is why it was unresolved. It
372
+ // signifies a problem in configration not the data or event flow
373
+ throw new errors_1.ConfigViolation('Contract validation failed - Event does not match any registered contract schemas in the machine');
374
+ }
375
+ if (inputValidation.type === 'INVALID_DATA' || inputValidation.type === 'INVALID') {
376
+ // This is a contract error becuase there is a configuration but
377
+ // the event data received was invalid due to conflicting data
378
+ // or event dataschema did not match the contract data schema. This
379
+ // signifies an issue with event flow because unexpected events
380
+ // are being received
381
+ throw new errors_1.ContractViolation("Input validation failed - Event data does not meet contract requirements: ".concat(inputValidation.error.message));
382
+ }
383
+ return [4 /*yield*/, this.syncEventResource.acquireLock(event, span)];
384
+ case 2:
385
+ ///////////////////////////////////////////////////////////////
386
+ // State locking, acquiry machine exection
387
+ ///////////////////////////////////////////////////////////////
388
+ acquiredLock = _0.sent();
389
+ if (acquiredLock === 'NOT_ACQUIRED') {
390
+ throw new error_1.TransactionViolation({
391
+ cause: error_1.TransactionViolationCause.LOCK_UNACQUIRED,
392
+ message: 'Lock acquisition denied - Unable to obtain exclusive access to event processing',
393
+ initiatingEvent: event,
394
+ });
395
+ }
396
+ if (acquiredLock === 'ACQUIRED') {
397
+ (0, arvo_core_1.logToSpan)({
398
+ level: 'INFO',
399
+ message: "This execution acquired lock at resource '".concat(event.subject, "'"),
400
+ });
401
+ }
402
+ return [4 /*yield*/, this.syncEventResource.acquireState(event, span)];
403
+ case 3:
404
+ state = _0.sent();
405
+ orchestrationParentSubject = (_m = state === null || state === void 0 ? void 0 : state.parentSubject) !== null && _m !== void 0 ? _m : null;
406
+ initEventId = (_o = state === null || state === void 0 ? void 0 : state.initEventId) !== null && _o !== void 0 ? _o : event.id;
407
+ if (!state) {
408
+ (0, arvo_core_1.logToSpan)({
409
+ level: 'INFO',
410
+ message: "Initializing new execution state for subject: ".concat(event.subject),
411
+ });
412
+ if (event.type !== this.source) {
413
+ (0, arvo_core_1.logToSpan)({
414
+ level: 'WARNING',
415
+ message: "Invalid initialization event detected. Expected type '".concat(this.source, "' but received '").concat(event.type, "'. This may indicate an incorrectly routed event or a non-initialization event that can be safely ignored."),
416
+ });
417
+ return [2 /*return*/, {
418
+ events: [],
419
+ }];
420
+ }
421
+ }
422
+ else {
423
+ (0, arvo_core_1.logToSpan)({
424
+ level: 'INFO',
425
+ message: "Resuming execution with existing state for subject: ".concat(event.subject),
426
+ });
427
+ }
428
+ // In case the event is the init event then
429
+ // extract the parent subject from it and assume
430
+ // it to be the orchestration parent subject
431
+ if (event.type === this.source) {
432
+ orchestrationParentSubject = (_q = (_p = event === null || event === void 0 ? void 0 : event.data) === null || _p === void 0 ? void 0 : _p.parentSubject$$) !== null && _q !== void 0 ? _q : null;
433
+ }
434
+ executionResult = this.executionEngine.execute({
435
+ state: (_r = state === null || state === void 0 ? void 0 : state.state) !== null && _r !== void 0 ? _r : null,
436
+ event: event,
437
+ machine: machine,
438
+ }, { inheritFrom: 'CONTEXT' });
439
+ span.setAttribute('arvo.orchestration.status', executionResult.state.status);
440
+ rawMachineEmittedEvents = executionResult.events;
441
+ // In case execution of the machine has finished
442
+ // and the final output has been created, then in
443
+ // that case, make the raw event as the final output
444
+ // is not even raw enough to be called an event yet
445
+ if (executionResult.finalOutput) {
446
+ rawMachineEmittedEvents.push({
447
+ type: machine.contracts.self
448
+ .metadata.completeEventType,
449
+ data: executionResult.finalOutput,
450
+ to: (_t = (_s = parsedEventSubject.meta) === null || _s === void 0 ? void 0 : _s.redirectto) !== null && _t !== void 0 ? _t : parsedEventSubject.execution.initiator,
451
+ domain: orchestrationParentSubject
452
+ ? [arvo_core_1.ArvoOrchestrationSubject.parse(orchestrationParentSubject).execution.domain]
453
+ : [undefined],
454
+ });
455
+ }
456
+ emittables = [];
457
+ for (_i = 0, rawMachineEmittedEvents_1 = rawMachineEmittedEvents; _i < rawMachineEmittedEvents_1.length; _i++) {
458
+ item = rawMachineEmittedEvents_1[_i];
459
+ domains = (_u = item.domain) !== null && _u !== void 0 ? _u : [null];
460
+ for (_b = 0, _c = Array.from(new Set(domains)); _b < _c.length; _b++) {
461
+ _dom = _c[_b];
462
+ evt = this.createEmittableEvent(item, machine, otelHeaders, orchestrationParentSubject, event, initEventId, _dom);
463
+ emittables.push(evt);
464
+ for (_d = 0, _e = Object.entries(emittables[emittables.length - 1].otelAttributes); _d < _e.length; _d++) {
465
+ _f = _e[_d], key = _f[0], value = _f[1];
466
+ span.setAttribute("to_emit.".concat(emittables.length - 1, ".").concat(key), value);
467
+ }
468
+ }
469
+ }
470
+ (0, arvo_core_1.logToSpan)({
471
+ level: 'INFO',
472
+ message: "Machine execution completed - Status: ".concat(executionResult.state.status, ", Generated events: ").concat(executionResult.events.length),
473
+ });
474
+ // Write to the memory
475
+ return [4 /*yield*/, this.syncEventResource.persistState(event, {
476
+ initEventId: initEventId,
477
+ subject: event.subject,
478
+ parentSubject: orchestrationParentSubject,
479
+ status: executionResult.state.status,
480
+ value: (_v = executionResult.state.value) !== null && _v !== void 0 ? _v : null,
481
+ state: executionResult.state,
482
+ events: {
483
+ consumed: event.toJSON(),
484
+ produced: emittables.map(function (item) { return item.toJSON(); }),
485
+ },
486
+ machineDefinition: JSON.stringify(machine.logic.config),
487
+ }, state, span)];
488
+ case 4:
489
+ // Write to the memory
490
+ _0.sent();
491
+ (0, arvo_core_1.logToSpan)({
492
+ level: 'INFO',
493
+ message: "State update persisted in memory for subject ".concat(event.subject),
494
+ });
495
+ (0, arvo_core_1.logToSpan)({
496
+ level: 'INFO',
497
+ message: "Orchestration successfully executed and emitted ".concat(emittables.length, " events"),
498
+ });
499
+ return [2 /*return*/, { events: emittables }];
500
+ case 5:
501
+ error_2 = _0.sent();
502
+ e = (0, utils_1.isError)(error_2)
503
+ ? error_2
504
+ : new errors_1.ExecutionViolation("Non-Error object thrown during machine execution: ".concat(typeof error_2, ". This indicates a serious implementation flaw."));
505
+ (0, arvo_core_1.exceptionToSpan)(e);
506
+ span.setStatus({
507
+ code: api_1.SpanStatusCode.ERROR,
508
+ message: e.message,
509
+ });
510
+ // For any violation errors bubble them up to the
511
+ // called of the function so that they can
512
+ // be handled gracefully
513
+ if (e.name.includes('ViolationError')) {
514
+ (0, arvo_core_1.logToSpan)({
515
+ level: 'CRITICAL',
516
+ message: "Orchestrator violation error: ".concat(e.message),
517
+ });
518
+ throw e;
519
+ }
520
+ (0, arvo_core_1.logToSpan)({
521
+ level: 'ERROR',
522
+ message: "Orchestrator execution failed: ".concat(e.message),
523
+ });
524
+ parsedEventSubject = null;
525
+ try {
526
+ parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
527
+ }
528
+ catch (e) {
529
+ (0, arvo_core_1.logToSpan)({
530
+ level: 'WARNING',
531
+ message: "Unable to parse event subject: ".concat(e.message),
532
+ });
533
+ }
534
+ result = [];
535
+ for (_g = 0, _h = Array.from(new Set([event.domain, this.domain, null])); _g < _h.length; _g++) {
536
+ _dom = _h[_g];
537
+ result.push((0, arvo_core_1.createArvoOrchestratorEventFactory)(this.registry.machines[0].contracts.self).systemError({
538
+ source: this.source,
539
+ // If the initiator of the workflow exist then match the
540
+ // subject so that it can incorporate it in its state. If
541
+ // parent does not exist then this is the root workflow so
542
+ // use its own subject
543
+ subject: orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : event.subject,
544
+ // The system error must always go back to
545
+ // the source which initiated it
546
+ to: (_w = parsedEventSubject === null || parsedEventSubject === void 0 ? void 0 : parsedEventSubject.execution.initiator) !== null && _w !== void 0 ? _w : event.source,
547
+ error: e,
548
+ traceparent: (_x = otelHeaders.traceparent) !== null && _x !== void 0 ? _x : undefined,
549
+ tracestate: (_y = otelHeaders.tracestate) !== null && _y !== void 0 ? _y : undefined,
550
+ accesscontrol: (_z = event.accesscontrol) !== null && _z !== void 0 ? _z : undefined,
551
+ executionunits: this.executionunits,
552
+ // If there is initEventID then use that.
553
+ // Otherwise, use event id. If the error is in init event
554
+ // then it will be the same as initEventId. Otherwise,
555
+ // we still would know what cause this error
556
+ parentid: initEventId ? initEventId : event.id,
557
+ domain: _dom,
558
+ }));
559
+ for (_j = 0, _k = Object.entries(result[result.length - 1].otelAttributes); _j < _k.length; _j++) {
560
+ _l = _k[_j], key = _l[0], value = _l[1];
561
+ span.setAttribute("to_emit.".concat(result.length - 1, ".").concat(key), value);
562
+ }
563
+ }
564
+ return [2 /*return*/, {
565
+ events: result,
566
+ }];
567
+ case 6: return [4 /*yield*/, this.syncEventResource.releaseLock(event, acquiredLock, span)];
568
+ case 7:
569
+ _0.sent();
570
+ span.end();
571
+ return [7 /*endfinally*/];
572
+ case 8: return [2 /*return*/];
573
+ }
574
+ });
575
+ }); },
576
+ })];
577
+ case 1: return [2 /*return*/, _b.sent()];
578
+ }
579
+ });
580
+ });
581
+ };
582
+ Object.defineProperty(ArvoOrchestrator.prototype, "systemErrorSchema", {
583
+ /**
584
+ * Gets the error schema for this orchestrator
585
+ */
586
+ get: function () {
587
+ return {
588
+ type: this.registry.machines[0].contracts.self.systemError.type,
589
+ schema: arvo_core_1.ArvoErrorSchema,
590
+ };
591
+ },
592
+ enumerable: false,
593
+ configurable: true
594
+ });
595
+ return ArvoOrchestrator;
596
+ }(AbstractArvoEventHandler_1.default));
597
+ exports.ArvoOrchestrator = ArvoOrchestrator;