UNPKG

arvo-event-handler

Version:

A complete set of orthogonal event handler and orchestration primitives for Arvo based applications, featuring declarative state machines (XState), imperative resumables for agentic workflows, contract-based routing, OpenTelemetry observability, and in-me

185 lines (184 loc) 9.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processRawEventsIntoEmittables = exports.createEmittableEvent = void 0; var arvo_core_1 = require("arvo-core"); var ArvoDomain_1 = require("../ArvoDomain"); var errors_1 = require("../errors"); /** * Creates a fully-formed emittable event from raw event parameters. * * Transforms machine-emitted event data into valid Arvo events by: * - Validating against appropriate contracts (self or service) * - Resolving domains for routing * - Generating proper subjects for orchestration events * - Adding tracing context and metadata * * Handles three event types differently: * 1. Completion events - routed to workflow initiator with parent subject * 2. Service orchestrator events - creates/extends orchestration subjects * 3. Regular service events - standard external service calls * * @returns Fully-formed Arvo event ready for emission * @throws {ContractViolation} When event data fails schema validation * @throws {ExecutionViolation} When orchestration subject creation fails */ var createEmittableEvent = function (_a, span) { var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; var event = _a.event, otelHeaders = _a.otelHeaders, orchestrationParentSubject = _a.orchestrationParentSubject, sourceEvent = _a.sourceEvent, selfContract = _a.selfContract, serviceContracts = _a.serviceContracts, initEventId = _a.initEventId, _domain = _a.domain, executionunits = _a.executionunits, source = _a.source; (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Creating emittable event: ".concat(event.type), }, span); var serviceContractMap = Object.fromEntries(Object.values(serviceContracts).map(function (item) { return [ item.accepts.type, item, ]; })); var schema = null; var contract = null; var subject = sourceEvent.subject; var parentId = sourceEvent.id; var domain = (0, ArvoDomain_1.resolveEventDomain)({ domainToResolve: _domain, parentSubject: orchestrationParentSubject, currentSubject: sourceEvent.subject, handlerSelfContract: selfContract, eventContract: null, triggeringEvent: sourceEvent, }); if (event.type === selfContract.metadata.completeEventType) { (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Creating event for workflow completion: ".concat(event.type), }, span); contract = selfContract; schema = selfContract.emits[selfContract.metadata.completeEventType]; subject = orchestrationParentSubject !== null && orchestrationParentSubject !== void 0 ? orchestrationParentSubject : sourceEvent.subject; parentId = initEventId; domain = (0, ArvoDomain_1.resolveEventDomain)({ domainToResolve: _domain, parentSubject: orchestrationParentSubject, currentSubject: sourceEvent.subject, handlerSelfContract: selfContract, eventContract: selfContract, triggeringEvent: sourceEvent, }); } else if (serviceContractMap[event.type]) { (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Creating service event for external system: ".concat(event.type), }, span); contract = serviceContractMap[event.type]; schema = serviceContractMap[event.type].accepts.schema; domain = (0, ArvoDomain_1.resolveEventDomain)({ domainToResolve: _domain, parentSubject: orchestrationParentSubject, currentSubject: sourceEvent.subject, handlerSelfContract: selfContract, eventContract: contract, triggeringEvent: sourceEvent, }); if (contract.metadata.contractType === 'ArvoOrchestratorContract') { if (event.data.parentSubject$$) { try { arvo_core_1.ArvoOrchestrationSubject.parse(event.data.parentSubject$$); } catch (_o) { throw new errors_1.ExecutionViolation("[Emittable Event Creation] Invalid parentSubject$$ for the event(type='".concat(event.type, "', uri='").concat((_b = event.dataschema) !== null && _b !== void 0 ? _b : 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.")); } } try { if (event.data.parentSubject$$) { subject = arvo_core_1.ArvoOrchestrationSubject.from({ orchestator: contract.accepts.type, version: contract.version, subject: event.data.parentSubject$$, domain: domain !== null && domain !== void 0 ? domain : null, meta: { redirectto: (_c = event.redirectto) !== null && _c !== void 0 ? _c : source, }, }); } else { subject = arvo_core_1.ArvoOrchestrationSubject.new({ version: contract.version, orchestator: contract.accepts.type, initiator: source, domain: domain !== null && domain !== void 0 ? domain : undefined, meta: { redirectto: (_d = event.redirectto) !== null && _d !== void 0 ? _d : source, }, }); } } catch (error) { throw new errors_1.ExecutionViolation("[Emittable Event Creation] Orchestration subject creation failed due to invalid parameters - Event: ".concat(event.type, " - ").concat(error === null || error === void 0 ? void 0 : error.message)); } } } var finalDataschema = event.dataschema; var finalData = event.data; if (contract && schema) { try { finalData = schema.parse(event.data); finalDataschema = arvo_core_1.EventDataschemaUtil.create(contract); } catch (error) { throw new errors_1.ContractViolation("[Emittable Event Creation] Invalid event data: Schema validation failed.\nEvent type: ".concat(event.type, "\nDetails: ").concat(error.message)); } } var emittableEvent = (0, arvo_core_1.createArvoEvent)({ id: event.id, source: source, type: event.type, subject: subject, dataschema: finalDataschema !== null && finalDataschema !== void 0 ? finalDataschema : undefined, data: finalData, to: (_e = event.to) !== null && _e !== void 0 ? _e : event.type, accesscontrol: (_g = (_f = event.accesscontrol) !== null && _f !== void 0 ? _f : sourceEvent.accesscontrol) !== null && _g !== void 0 ? _g : undefined, redirectto: (_h = event.redirectto) !== null && _h !== void 0 ? _h : source, executionunits: (_j = event.executionunits) !== null && _j !== void 0 ? _j : executionunits, traceparent: (_k = otelHeaders.traceparent) !== null && _k !== void 0 ? _k : undefined, tracestate: (_l = otelHeaders.tracestate) !== null && _l !== void 0 ? _l : undefined, parentid: parentId, domain: domain !== null && domain !== void 0 ? domain : undefined, }, (_m = event.__extensions) !== null && _m !== void 0 ? _m : {}); (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Event created successfully: ".concat(emittableEvent.type), }, span); return emittableEvent; }; exports.createEmittableEvent = createEmittableEvent; /** * Processes raw events into emittable events with domain resolution */ var processRawEventsIntoEmittables = function (params, span) { var _a; var emittables = []; for (var _i = 0, _b = params.rawEvents; _i < _b.length; _i++) { var item = _b[_i]; for (var _c = 0, _d = Array.from(new Set((_a = item.domain) !== null && _a !== void 0 ? _a : [ArvoDomain_1.ArvoDomain.LOCAL])); _c < _d.length; _c++) { var _dom = _d[_c]; var evt = (0, exports.createEmittableEvent)({ event: item, otelHeaders: params.otelHeaders, orchestrationParentSubject: params.orchestrationParentSubject, sourceEvent: params.sourceEvent, selfContract: params.selfContract, serviceContracts: params.serviceContracts, initEventId: params.initEventId, domain: _dom, executionunits: params.executionunits, source: params.source, }, span); emittables.push(evt); for (var _e = 0, _f = Object.entries(emittables[emittables.length - 1].otelAttributes); _e < _f.length; _e++) { var _g = _f[_e], key = _g[0], value = _g[1]; span.setAttribute("emittables.".concat(emittables.length - 1, ".").concat(key), value); } } } return emittables; }; exports.processRawEventsIntoEmittables = processRawEventsIntoEmittables;