arvo-event-handler 3.0.7 → 3.0.10

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