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
@@ -59,11 +59,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
59
59
  exports.ArvoResumable = void 0;
60
60
  var api_1 = require("@opentelemetry/api");
61
61
  var arvo_core_1 = require("arvo-core");
62
- var error_1 = require("../ArvoOrchestrator/error");
62
+ var createEmitableEvent_1 = require("../ArvoOrchestrationUtils/createEmitableEvent");
63
+ var orchestrationExecutionWrapper_1 = require("../ArvoOrchestrationUtils/orchestrationExecutionWrapper");
63
64
  var index_1 = require("../SyncEventResource/index");
64
- var index_2 = require("../utils/index");
65
65
  var errors_1 = require("../errors");
66
- var ArvoDomain_1 = require("../ArvoDomain");
67
66
  /**
68
67
  * ArvoResumable - A stateful orchestration handler for managing distributed workflows
69
68
  *
@@ -98,13 +97,15 @@ var ArvoDomain_1 = require("../ArvoDomain");
98
97
  var ArvoResumable = /** @class */ (function () {
99
98
  function ArvoResumable(param) {
100
99
  var _a;
100
+ var _b, _c, _d;
101
101
  this.systemErrorDomain = [];
102
102
  this.executionunits = param.executionunits;
103
103
  this.source = param.contracts.self.type;
104
- this.syncEventResource = new index_1.SyncEventResource(param.memory, (_a = param.requiresResourceLocking) !== null && _a !== void 0 ? _a : true);
104
+ this.syncEventResource = new index_1.SyncEventResource(param.memory, (_b = param.requiresResourceLocking) !== null && _b !== void 0 ? _b : true);
105
105
  this.contracts = param.contracts;
106
106
  this.handler = param.handler;
107
107
  this.systemErrorDomain = param.systemErrorDomain;
108
+ this.spanOptions = __assign(__assign({ kind: api_1.SpanKind.PRODUCER }, param.spanOptions), { attributes: __assign(__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), ((_d = (_c = param.spanOptions) === null || _c === void 0 ? void 0 : _c.attributes) !== null && _d !== void 0 ? _d : {})), { 'arvo.handler.source': this.source, 'arvo.contract.uri': this.contracts.self.uri }) });
108
109
  }
109
110
  Object.defineProperty(ArvoResumable.prototype, "requiresResourceLocking", {
110
111
  get: function () {
@@ -127,7 +128,7 @@ var ArvoResumable = /** @class */ (function () {
127
128
  enumerable: false,
128
129
  configurable: true
129
130
  });
130
- ArvoResumable.prototype.validateInput = function (event) {
131
+ ArvoResumable.prototype.validateInput = function (event, span) {
131
132
  var _a;
132
133
  var resolvedContract = null;
133
134
  var contractType;
@@ -161,7 +162,7 @@ var ArvoResumable = /** @class */ (function () {
161
162
  (0, arvo_core_1.logToSpan)({
162
163
  level: 'INFO',
163
164
  message: "Dataschema resolved: ".concat(event.dataschema, " matches contract(uri='").concat(resolvedContract.uri, "', version='").concat(resolvedContract.version, "')"),
164
- });
165
+ }, span);
165
166
  if (parsedEventDataSchema.uri !== resolvedContract.uri) {
166
167
  throw new Error("Contract URI mismatch: ".concat(contractType, " Contract(uri='").concat(resolvedContract.uri, "', type='").concat(resolvedContract.accepts.type, "') does not match Event(dataschema='").concat(event.dataschema, "', type='").concat(event.type, "')"));
167
168
  }
@@ -175,148 +176,6 @@ var ArvoResumable = /** @class */ (function () {
175
176
  validationSchema.parse(event.data);
176
177
  return { contractType: contractType };
177
178
  };
178
- /**
179
- * Creates emittable event from execution result
180
- * @param event - Source event to emit
181
- * @param otelHeaders - OpenTelemetry headers
182
- * @param orchestrationParentSubject - Parent orchestration subject
183
- * @param sourceEvent - Original triggering event
184
- * @param selfVersionedContract - The self versioned contract
185
- * @param initEventId - The id of the event which initiated the orchestration in the first place
186
- * @param _domain - The domain of the event.
187
- *
188
- * @throws {ContractViolation} On schema/contract mismatch
189
- * @throws {ExecutionViolation} On invalid parentSubject$$ format
190
- */
191
- ArvoResumable.prototype.createEmittableEvent = function (event, otelHeaders, orchestrationParentSubject, sourceEvent, selfVersionedContract, initEventId, _domain) {
192
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
193
- (0, arvo_core_1.logToSpan)({
194
- level: 'INFO',
195
- message: "Creating emittable event: ".concat(event.type),
196
- });
197
- var serviceContract = Object.fromEntries(Object.values(this.contracts.services).map(function (item) { return [item.accepts.type, item]; }));
198
- var schema = null;
199
- var contract = null;
200
- var subject = sourceEvent.subject;
201
- var parentId = sourceEvent.id;
202
- var domain = (0, ArvoDomain_1.resolveEventDomain)({
203
- domainToResolve: _domain,
204
- handlerSelfContract: selfVersionedContract,
205
- eventContract: null,
206
- triggeringEvent: sourceEvent,
207
- });
208
- if (event.type === selfVersionedContract.metadata.completeEventType) {
209
- (0, arvo_core_1.logToSpan)({
210
- level: 'INFO',
211
- message: "Creating event for machine workflow completion: ".concat(event.type),
212
- });
213
- contract = selfVersionedContract;
214
- schema = selfVersionedContract.emits[selfVersionedContract.metadata.completeEventType];
215
- subject = orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : sourceEvent.subject;
216
- parentId = initEventId;
217
- domain = (0, ArvoDomain_1.resolveEventDomain)({
218
- domainToResolve: _domain,
219
- handlerSelfContract: selfVersionedContract,
220
- eventContract: selfVersionedContract,
221
- triggeringEvent: sourceEvent,
222
- });
223
- }
224
- else if (serviceContract[event.type]) {
225
- (0, arvo_core_1.logToSpan)({
226
- level: 'INFO',
227
- message: "Creating service event for external system: ".concat(event.type),
228
- });
229
- contract = serviceContract[event.type];
230
- schema = serviceContract[event.type].accepts.schema;
231
- domain = (0, ArvoDomain_1.resolveEventDomain)({
232
- domainToResolve: _domain,
233
- handlerSelfContract: selfVersionedContract,
234
- eventContract: contract,
235
- triggeringEvent: sourceEvent,
236
- });
237
- // If the event is to call another orchestrator then, extract the parent subject
238
- // passed to it and then form an new subject. This allows for event chaining
239
- // between orchestrators
240
- if (contract.metadata.contractType === 'ArvoOrchestratorContract') {
241
- if (event.data.parentSubject$$) {
242
- try {
243
- arvo_core_1.ArvoOrchestrationSubject.parse(event.data.parentSubject$$);
244
- }
245
- catch (_m) {
246
- 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."));
247
- }
248
- }
249
- try {
250
- if (event.data.parentSubject$$) {
251
- subject = arvo_core_1.ArvoOrchestrationSubject.from({
252
- orchestator: contract.accepts.type,
253
- version: contract.version,
254
- subject: event.data.parentSubject$$,
255
- domain: domain !== null && domain !== void 0 ? domain : null,
256
- meta: {
257
- redirectto: (_b = event.redirectto) !== null && _b !== void 0 ? _b : this.source,
258
- },
259
- });
260
- }
261
- else {
262
- subject = arvo_core_1.ArvoOrchestrationSubject.new({
263
- version: contract.version,
264
- orchestator: contract.accepts.type,
265
- initiator: this.source,
266
- domain: domain !== null && domain !== void 0 ? domain : undefined,
267
- meta: {
268
- redirectto: (_c = event.redirectto) !== null && _c !== void 0 ? _c : this.source,
269
- },
270
- });
271
- }
272
- }
273
- catch (error) {
274
- // This is a execution violation because it indicates faulty parent subject
275
- // or some fundamental error with subject creation which must be not be propagated
276
- // any further and investigated manually.
277
- 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));
278
- }
279
- }
280
- }
281
- var finalDataschema = event.dataschema;
282
- var finalData = event.data;
283
- // finally if the contract and the schema are available
284
- // then use them to validate the event. Otherwise just use
285
- // the data from the incoming event which is raw and created
286
- // by the machine
287
- if (contract && schema) {
288
- try {
289
- finalData = schema.parse(event.data);
290
- finalDataschema = arvo_core_1.EventDataschemaUtil.create(contract);
291
- }
292
- catch (error) {
293
- 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));
294
- }
295
- }
296
- // Create the event
297
- var emittableEvent = (0, arvo_core_1.createArvoEvent)({
298
- id: event.id,
299
- source: this.source,
300
- type: event.type,
301
- subject: subject,
302
- dataschema: finalDataschema !== null && finalDataschema !== void 0 ? finalDataschema : undefined,
303
- data: finalData,
304
- to: (_d = event.to) !== null && _d !== void 0 ? _d : event.type,
305
- accesscontrol: (_f = (_e = event.accesscontrol) !== null && _e !== void 0 ? _e : sourceEvent.accesscontrol) !== null && _f !== void 0 ? _f : undefined,
306
- // The orchestrator/ resumable does not respect redirectto from the source event
307
- redirectto: (_g = event.redirectto) !== null && _g !== void 0 ? _g : this.source,
308
- executionunits: (_h = event.executionunits) !== null && _h !== void 0 ? _h : this.executionunits,
309
- traceparent: (_j = otelHeaders.traceparent) !== null && _j !== void 0 ? _j : undefined,
310
- tracestate: (_k = otelHeaders.tracestate) !== null && _k !== void 0 ? _k : undefined,
311
- parentid: parentId,
312
- domain: domain !== null && domain !== void 0 ? domain : undefined,
313
- }, (_l = event.__extensions) !== null && _l !== void 0 ? _l : {});
314
- (0, arvo_core_1.logToSpan)({
315
- level: 'INFO',
316
- message: "Event created successfully: ".concat(emittableEvent.type),
317
- });
318
- return emittableEvent;
319
- };
320
179
  /**
321
180
  * Executes the orchestration workflow for an incoming event
322
181
  *
@@ -332,82 +191,34 @@ var ArvoResumable = /** @class */ (function () {
332
191
  */
333
192
  ArvoResumable.prototype.execute = function (event, opentelemetry) {
334
193
  return __awaiter(this, void 0, void 0, function () {
335
- var _a;
336
194
  var _this = this;
337
- return __generator(this, function (_b) {
338
- return [2 /*return*/, arvo_core_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
339
- name: "Resumable<".concat(this.contracts.self.uri, ">@<").concat(event.type, ">"),
340
- spanOptions: {
341
- kind: api_1.SpanKind.PRODUCER,
342
- 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) {
343
- var key = _a[0], value = _a[1];
344
- return ["to_process.0.".concat(key), value];
345
- }))),
346
- },
347
- context: opentelemetry.inheritFrom === 'EVENT'
348
- ? {
349
- inheritFrom: 'TRACE_HEADERS',
350
- traceHeaders: {
351
- traceparent: event.traceparent,
352
- tracestate: event.tracestate,
353
- },
354
- }
355
- : {
356
- inheritFrom: 'CONTEXT',
357
- context: api_1.context.active(),
358
- },
359
- disableSpanManagement: true,
360
- fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
361
- var otelHeaders, orchestrationParentSubject, acquiredLock, initEventId, parsedEventSubject, contractType, state, eventTypeToExpectedEvent, _i, _a, _b, _, eventList, _c, eventList_1, _evt, handler, executionResult, emittables, _d, _e, item, createdDomain, _f, _g, _dom, evt, _h, _j, _k, key, value, eventTrackingState, error_2, e, parsedEventSubject, result, _l, _m, _dom, _o, _p, _q, key, value;
362
- var _this = this;
363
- var _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
364
- return __generator(this, function (_13) {
365
- switch (_13.label) {
195
+ return __generator(this, function (_a) {
196
+ switch (_a.label) {
197
+ case 0: return [4 /*yield*/, (0, orchestrationExecutionWrapper_1.executeWithOrchestrationWrapper)({
198
+ _handlerType: 'resumable',
199
+ event: event,
200
+ opentelemetry: opentelemetry !== null && opentelemetry !== void 0 ? opentelemetry : { inheritFrom: 'EVENT' },
201
+ spanOptions: __assign({ spanName: function (_a) {
202
+ var selfContractUri = _a.selfContractUri, consumedEvent = _a.consumedEvent;
203
+ return "Resumable<".concat(selfContractUri, ">@<").concat(consumedEvent.type, ">");
204
+ } }, this.spanOptions),
205
+ source: this.source,
206
+ syncEventResource: this.syncEventResource,
207
+ executionunits: this.executionunits,
208
+ systemErrorDomain: this.systemErrorDomain,
209
+ selfContract: this.contracts.self.version('latest'),
210
+ domain: this.domain,
211
+ }, function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
212
+ var contractType, eventTypeToExpectedEvent, _i, _c, _d, _, eventList, _e, eventList_1, _evt, handler, versionedSelfContract, executionResult, rawEvents, emittables, eventTrackingState, newState;
213
+ var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
214
+ var span = _b.span, otelHeaders = _b.otelHeaders, orchestrationParentSubject = _b.orchestrationParentSubject, initEventId = _b.initEventId, parsedEventSubject = _b.parsedEventSubject, state = _b.state;
215
+ return __generator(this, function (_v) {
216
+ switch (_v.label) {
366
217
  case 0:
367
218
  (0, arvo_core_1.logToSpan)({
368
219
  level: 'INFO',
369
- message: "Resumable function starting execution for ".concat(event.type, " on subject ").concat(event.subject),
370
- });
371
- otelHeaders = (0, arvo_core_1.currentOpenTelemetryHeaders)();
372
- orchestrationParentSubject = null;
373
- acquiredLock = null;
374
- initEventId = null;
375
- _13.label = 1;
376
- case 1:
377
- _13.trys.push([1, 6, 7, 9]);
378
- ///////////////////////////////////////////////////////////////
379
- // Subject resolution, handler resolution and input validation
380
- ///////////////
381
- // ////////////////////////////////////////////////
382
- this.syncEventResource.validateEventSubject(event);
383
- parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
384
- span.setAttributes({
385
- 'arvo.parsed.subject.orchestrator.name': parsedEventSubject.orchestrator.name,
386
- 'arvo.parsed.subject.orchestrator.version': parsedEventSubject.orchestrator.version,
387
- });
388
- // The wrong source is not a big violation. May be some routing went wrong. So just ignore the event
389
- if (parsedEventSubject.orchestrator.name !== this.source) {
390
- (0, arvo_core_1.logToSpan)({
391
- level: 'WARNING',
392
- 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."),
393
- });
394
- (0, arvo_core_1.logToSpan)({
395
- level: 'INFO',
396
- message: 'Orchestration executed with issues and emitted 0 events',
397
- });
398
- return [2 /*return*/, {
399
- events: [],
400
- allEventDomains: [],
401
- domainedEvents: {
402
- all: [],
403
- },
404
- }];
405
- }
406
- (0, arvo_core_1.logToSpan)({
407
- level: 'INFO',
408
- message: "Resolving machine for event ".concat(event.type),
409
- });
410
- // Handler not found means that the handler is not defined which is not allowed and a critical bug
220
+ message: "Resolving handler for event ".concat(event.type),
221
+ }, span);
411
222
  if (!this.handler[parsedEventSubject.orchestrator.version]) {
412
223
  throw new errors_1.ConfigViolation("Handler resolution failed: No handler found matching orchestrator name='".concat(parsedEventSubject.orchestrator.name, "' and version='").concat(parsedEventSubject.orchestrator.version, "'."));
413
224
  }
@@ -415,79 +226,28 @@ var ArvoResumable = /** @class */ (function () {
415
226
  level: 'INFO',
416
227
  message: "Input validation started for event ".concat(event.type),
417
228
  });
418
- contractType = this.validateInput(event).contractType;
419
- return [4 /*yield*/, this.syncEventResource.acquireLock(event)];
420
- case 2:
421
- ///////////////////////////////////////////////////////////////
422
- // State locking, acquiry and handler exection
423
- ///////////////////////////////////////////////////////////////
424
- acquiredLock = _13.sent();
425
- if (acquiredLock === 'NOT_ACQUIRED') {
426
- throw new error_1.TransactionViolation({
427
- cause: error_1.TransactionViolationCause.LOCK_UNACQUIRED,
428
- message: 'Lock acquisition denied - Unable to obtain exclusive access to event processing',
429
- initiatingEvent: event,
430
- });
431
- }
432
- if (acquiredLock === 'ACQUIRED') {
433
- (0, arvo_core_1.logToSpan)({
434
- level: 'INFO',
435
- message: "This execution acquired lock at resource '".concat(event.subject, "'"),
436
- });
437
- }
438
- return [4 /*yield*/, this.syncEventResource.acquireState(event)];
439
- case 3:
440
- state = _13.sent();
441
- orchestrationParentSubject = (_r = state === null || state === void 0 ? void 0 : state.parentSubject) !== null && _r !== void 0 ? _r : null;
442
- initEventId = (_s = state === null || state === void 0 ? void 0 : state.initEventId) !== null && _s !== void 0 ? _s : event.id;
229
+ contractType = this.validateInput(event, span).contractType;
443
230
  if ((state === null || state === void 0 ? void 0 : state.status) === 'done') {
444
231
  (0, arvo_core_1.logToSpan)({
445
232
  level: 'INFO',
446
233
  message: "The resumable has already reached the terminal state. Ignoring event(id=".concat(event.id, ")"),
447
234
  });
448
235
  return [2 /*return*/, {
449
- events: [],
236
+ emittables: [],
237
+ newState: state,
450
238
  }];
451
239
  }
452
- if (!state) {
453
- (0, arvo_core_1.logToSpan)({
454
- level: 'INFO',
455
- message: "Initializing new execution state for subject: ".concat(event.subject),
456
- });
457
- if (event.type !== this.source) {
458
- (0, arvo_core_1.logToSpan)({
459
- level: 'WARNING',
460
- 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."),
461
- });
462
- return [2 /*return*/, {
463
- events: [],
464
- }];
465
- }
466
- }
467
- else {
468
- (0, arvo_core_1.logToSpan)({
469
- level: 'INFO',
470
- message: "Resuming execution with existing state for subject: ".concat(event.subject),
471
- });
472
- }
473
- // In case the event is the init event then
474
- // extract the parent subject from it and assume
475
- // it to be the orchestration parent subject
476
- if (event.type === this.source) {
477
- orchestrationParentSubject = (_u = (_t = event === null || event === void 0 ? void 0 : event.data) === null || _t === void 0 ? void 0 : _t.parentSubject$$) !== null && _u !== void 0 ? _u : null;
478
- }
479
- // This is not persisted until handling. The reason is that if the event
480
- // is causing a fault then what is the point of persisting it
240
+ // Track expected events
481
241
  if (event.parentid &&
482
- ((_w = (_v = state === null || state === void 0 ? void 0 : state.events) === null || _v === void 0 ? void 0 : _v.expected) === null || _w === void 0 ? void 0 : _w[event.parentid]) &&
483
- Array.isArray((_y = (_x = state === null || state === void 0 ? void 0 : state.events) === null || _x === void 0 ? void 0 : _x.expected) === null || _y === void 0 ? void 0 : _y[event.parentid])) {
242
+ ((_g = (_f = state === null || state === void 0 ? void 0 : state.events) === null || _f === void 0 ? void 0 : _f.expected) === null || _g === void 0 ? void 0 : _g[event.parentid]) &&
243
+ Array.isArray((_j = (_h = state === null || state === void 0 ? void 0 : state.events) === null || _h === void 0 ? void 0 : _h.expected) === null || _j === void 0 ? void 0 : _j[event.parentid])) {
484
244
  state.events.expected[event.parentid].push(event.toJSON());
485
245
  }
486
246
  eventTypeToExpectedEvent = {};
487
- for (_i = 0, _a = Object.entries((_0 = (_z = state === null || state === void 0 ? void 0 : state.events) === null || _z === void 0 ? void 0 : _z.expected) !== null && _0 !== void 0 ? _0 : {}); _i < _a.length; _i++) {
488
- _b = _a[_i], _ = _b[0], eventList = _b[1];
489
- for (_c = 0, eventList_1 = eventList; _c < eventList_1.length; _c++) {
490
- _evt = eventList_1[_c];
247
+ for (_i = 0, _c = Object.entries((_l = (_k = state === null || state === void 0 ? void 0 : state.events) === null || _k === void 0 ? void 0 : _k.expected) !== null && _l !== void 0 ? _l : {}); _i < _c.length; _i++) {
248
+ _d = _c[_i], _ = _d[0], eventList = _d[1];
249
+ for (_e = 0, eventList_1 = eventList; _e < eventList_1.length; _e++) {
250
+ _evt = eventList_1[_e];
491
251
  if (!eventTypeToExpectedEvent[_evt.type]) {
492
252
  eventTypeToExpectedEvent[_evt.type] = [];
493
253
  }
@@ -495,9 +255,10 @@ var ArvoResumable = /** @class */ (function () {
495
255
  }
496
256
  }
497
257
  handler = this.handler[parsedEventSubject.orchestrator.version];
258
+ versionedSelfContract = this.contracts.self.version(parsedEventSubject.orchestrator.version);
498
259
  return [4 /*yield*/, handler({
499
260
  span: span,
500
- context: (_1 = state === null || state === void 0 ? void 0 : state.state$$) !== null && _1 !== void 0 ? _1 : null,
261
+ context: (_m = state === null || state === void 0 ? void 0 : state.state$$) !== null && _m !== void 0 ? _m : null,
501
262
  metadata: state !== null && state !== void 0 ? state : null,
502
263
  collectedEvents: eventTypeToExpectedEvent,
503
264
  domain: {
@@ -507,44 +268,35 @@ var ArvoResumable = /** @class */ (function () {
507
268
  input: contractType === 'self' ? event.toJSON() : null,
508
269
  service: contractType === 'service' ? event.toJSON() : null,
509
270
  contracts: {
510
- self: this.contracts.self.version(parsedEventSubject.orchestrator.version),
271
+ self: versionedSelfContract,
511
272
  services: this.contracts.services,
512
273
  },
513
274
  })];
514
- case 4:
515
- executionResult = _13.sent();
516
- emittables = [];
517
- for (_d = 0, _e = __spreadArray(__spreadArray([], ((executionResult === null || executionResult === void 0 ? void 0 : executionResult.output)
518
- ? [
519
- {
520
- id: executionResult.output.__id,
521
- data: executionResult.output,
522
- type: this.contracts.self.metadata.completeEventType,
523
- to: (_3 = (_2 = parsedEventSubject.meta) === null || _2 === void 0 ? void 0 : _2.redirectto) !== null && _3 !== void 0 ? _3 : parsedEventSubject.execution.initiator,
524
- domain: orchestrationParentSubject
525
- ? [arvo_core_1.ArvoOrchestrationSubject.parse(orchestrationParentSubject).execution.domain]
526
- : [null],
527
- },
528
- ]
529
- : []), true), ((_4 = executionResult === null || executionResult === void 0 ? void 0 : executionResult.services) !== null && _4 !== void 0 ? _4 : []), true); _d < _e.length; _d++) {
530
- item = _e[_d];
531
- createdDomain = new Set(null);
532
- for (_f = 0, _g = Array.from(new Set((_5 = item.domain) !== null && _5 !== void 0 ? _5 : [null])); _f < _g.length; _f++) {
533
- _dom = _g[_f];
534
- evt = this.createEmittableEvent(item, otelHeaders, orchestrationParentSubject, event, this.contracts.self.version(parsedEventSubject.orchestrator.version), initEventId, _dom);
535
- // Making sure the raw event broadcast is actually unique as the
536
- // domain resolution (especially for symbolic) can only happen
537
- // in the createEmittableEvent
538
- if (createdDomain.has(evt.domain))
539
- continue;
540
- createdDomain.add(evt.domain);
541
- emittables.push(evt);
542
- for (_h = 0, _j = Object.entries(emittables[emittables.length - 1].otelAttributes); _h < _j.length; _h++) {
543
- _k = _j[_h], key = _k[0], value = _k[1];
544
- span.setAttribute("to_emit.".concat(emittables.length - 1, ".").concat(key), value);
545
- }
546
- }
275
+ case 1:
276
+ executionResult = _v.sent();
277
+ rawEvents = (_o = executionResult === null || executionResult === void 0 ? void 0 : executionResult.services) !== null && _o !== void 0 ? _o : [];
278
+ if (executionResult === null || executionResult === void 0 ? void 0 : executionResult.output) {
279
+ rawEvents.push({
280
+ id: executionResult.output.__id,
281
+ data: executionResult.output,
282
+ type: this.contracts.self.metadata.completeEventType,
283
+ to: (_q = (_p = parsedEventSubject.meta) === null || _p === void 0 ? void 0 : _p.redirectto) !== null && _q !== void 0 ? _q : parsedEventSubject.execution.initiator,
284
+ domain: orchestrationParentSubject
285
+ ? [arvo_core_1.ArvoOrchestrationSubject.parse(orchestrationParentSubject).execution.domain]
286
+ : [null],
287
+ });
547
288
  }
289
+ emittables = (0, createEmitableEvent_1.processRawEventsIntoEmittables)({
290
+ rawEvents: rawEvents,
291
+ otelHeaders: otelHeaders,
292
+ orchestrationParentSubject: orchestrationParentSubject,
293
+ sourceEvent: event,
294
+ selfContract: versionedSelfContract,
295
+ serviceContracts: this.contracts.services,
296
+ initEventId: initEventId,
297
+ executionunits: this.executionunits,
298
+ source: this.source,
299
+ }, span);
548
300
  (0, arvo_core_1.logToSpan)({
549
301
  level: 'INFO',
550
302
  message: "Resumable execution completed. Generated events: ".concat(emittables.length),
@@ -553,116 +305,24 @@ var ArvoResumable = /** @class */ (function () {
553
305
  consumed: event.toJSON(),
554
306
  expected: emittables.length
555
307
  ? Object.fromEntries(emittables.map(function (item) { return [item.id, []]; }))
556
- : ((_6 = state === null || state === void 0 ? void 0 : state.events.expected) !== null && _6 !== void 0 ? _6 : null),
308
+ : ((_s = (_r = state === null || state === void 0 ? void 0 : state.events) === null || _r === void 0 ? void 0 : _r.expected) !== null && _s !== void 0 ? _s : null),
557
309
  produced: emittables.map(function (item) { return item.toJSON(); }),
558
310
  };
559
- // Write to the memory
560
- return [4 /*yield*/, this.syncEventResource.persistState(event, {
561
- status: (executionResult === null || executionResult === void 0 ? void 0 : executionResult.output) ? 'done' : 'active',
562
- initEventId: initEventId,
563
- parentSubject: orchestrationParentSubject,
564
- subject: event.subject,
565
- events: eventTrackingState,
566
- state$$: (_8 = (_7 = executionResult === null || executionResult === void 0 ? void 0 : executionResult.context) !== null && _7 !== void 0 ? _7 : state === null || state === void 0 ? void 0 : state.state$$) !== null && _8 !== void 0 ? _8 : null,
567
- }, state, span)];
568
- case 5:
569
- // Write to the memory
570
- _13.sent();
571
- (0, arvo_core_1.logToSpan)({
572
- level: 'INFO',
573
- message: "State update persisted in memory for subject ".concat(event.subject),
574
- });
575
- (0, arvo_core_1.logToSpan)({
576
- level: 'INFO',
577
- message: "Resumable successfully executed and emitted ".concat(emittables.length, " events"),
578
- });
579
- return [2 /*return*/, { events: emittables }];
580
- case 6:
581
- error_2 = _13.sent();
582
- e = (0, index_2.isError)(error_2)
583
- ? error_2
584
- : new errors_1.ExecutionViolation("Non-Error object thrown during machine execution: ".concat(typeof error_2, ". This indicates a serious implementation flaw."));
585
- (0, arvo_core_1.exceptionToSpan)(e);
586
- span.setStatus({
587
- code: api_1.SpanStatusCode.ERROR,
588
- message: e.message,
589
- });
590
- // For any violation errors bubble them up to the
591
- // called of the function so that they can
592
- // be handled gracefully
593
- if (e.name.includes('ViolationError')) {
594
- (0, arvo_core_1.logToSpan)({
595
- level: 'CRITICAL',
596
- message: "Resumable violation error: ".concat(e.message),
597
- });
598
- throw e;
599
- }
600
- (0, arvo_core_1.logToSpan)({
601
- level: 'ERROR',
602
- message: "Resumable execution failed: ".concat(e.message),
603
- });
604
- parsedEventSubject = null;
605
- try {
606
- parsedEventSubject = arvo_core_1.ArvoOrchestrationSubject.parse(event.subject);
607
- }
608
- catch (e) {
609
- (0, arvo_core_1.logToSpan)({
610
- level: 'WARNING',
611
- message: "Unable to parse event subject: ".concat(e.message),
612
- });
613
- }
614
- result = [];
615
- for (_l = 0, _m = Array.from(new Set(this.systemErrorDomain
616
- ? this.systemErrorDomain.map(function (item) {
617
- return (0, ArvoDomain_1.resolveEventDomain)({
618
- domainToResolve: item,
619
- handlerSelfContract: _this.contracts.self.version('latest'),
620
- eventContract: _this.contracts.self.version('latest'),
621
- triggeringEvent: event,
622
- });
623
- })
624
- : [event.domain, this.domain, null])); _l < _m.length; _l++) {
625
- _dom = _m[_l];
626
- result.push((0, arvo_core_1.createArvoOrchestratorEventFactory)(this.contracts.self.version('latest')).systemError({
627
- source: this.source,
628
- // If the initiator of the workflow exist then match the
629
- // subject so that it can incorporate it in its state. If
630
- // parent does not exist then this is the root workflow so
631
- // use its own subject
632
- subject: orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : event.subject,
633
- // The system error must always go back to
634
- // the source which initiated it
635
- to: (_9 = parsedEventSubject === null || parsedEventSubject === void 0 ? void 0 : parsedEventSubject.execution.initiator) !== null && _9 !== void 0 ? _9 : event.source,
636
- error: e,
637
- traceparent: (_10 = otelHeaders.traceparent) !== null && _10 !== void 0 ? _10 : undefined,
638
- tracestate: (_11 = otelHeaders.tracestate) !== null && _11 !== void 0 ? _11 : undefined,
639
- accesscontrol: (_12 = event.accesscontrol) !== null && _12 !== void 0 ? _12 : undefined,
640
- executionunits: this.executionunits,
641
- // If there is initEventID then use that.
642
- // Otherwise, use event id. If the error is in init event
643
- // then it will be the same as initEventId. Otherwise,
644
- // we still would know what cause this error
645
- parentid: initEventId !== null && initEventId !== void 0 ? initEventId : event.id,
646
- domain: _dom,
647
- }));
648
- for (_o = 0, _p = Object.entries(result[result.length - 1].otelAttributes); _o < _p.length; _o++) {
649
- _q = _p[_o], key = _q[0], value = _q[1];
650
- span.setAttribute("to_emit.".concat(result.length - 1, ".").concat(key), value);
651
- }
652
- }
653
- return [2 /*return*/, {
654
- events: result,
655
- }];
656
- case 7: return [4 /*yield*/, this.syncEventResource.releaseLock(event, acquiredLock, span)];
657
- case 8:
658
- _13.sent();
659
- span.end();
660
- return [7 /*endfinally*/];
661
- case 9: return [2 /*return*/];
311
+ newState = {
312
+ executionStatus: 'normal',
313
+ status: (executionResult === null || executionResult === void 0 ? void 0 : executionResult.output) ? 'done' : 'active',
314
+ initEventId: initEventId,
315
+ parentSubject: orchestrationParentSubject,
316
+ subject: event.subject,
317
+ events: eventTrackingState,
318
+ state$$: (_u = (_t = executionResult === null || executionResult === void 0 ? void 0 : executionResult.context) !== null && _t !== void 0 ? _t : state === null || state === void 0 ? void 0 : state.state$$) !== null && _u !== void 0 ? _u : null,
319
+ };
320
+ return [2 /*return*/, { emittables: emittables, newState: newState }];
662
321
  }
663
322
  });
664
- }); },
665
- })];
323
+ }); })];
324
+ case 1: return [2 /*return*/, _a.sent()];
325
+ }
666
326
  });
667
327
  });
668
328
  };