UNPKG

arvo-event-handler

Version:

Type-safe event handler system with versioning, telemetry, and contract validation for distributed Arvo event-driven architectures, featuring routing and multi-handler support.

133 lines (132 loc) 6.82 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MachineExecutionEngine = void 0; var api_1 = require("@opentelemetry/api"); var arvo_core_1 = require("arvo-core"); var xstate_1 = require("xstate"); /** * Handles state machine execution, event processing, and lifecycle management. */ var MachineExecutionEngine = /** @class */ (function () { function MachineExecutionEngine() { } /** * Executes a state machine and manages its lifecycle. * * @description * Handles machine initialization/resumption, event processing, and state transitions. * Manages event queues and volatile context during execution. * * @param params Configuration parameters: * - machine: State machine definition * - state: Optional existing state to resume from * - event: Event triggering the execution * @param opentelemetry Telemetry configuration for tracing * * @returns Object containing: * - state: Final machine state * - events: Generated events * - finalOutput: Machine output or null * * @throws Error on invalid initialization events or execution failures */ MachineExecutionEngine.prototype.execute = function (_a, opentelemetry) { var machine = _a.machine, state = _a.state, event = _a.event; if (opentelemetry === void 0) { opentelemetry = { inheritFrom: 'CONTEXT', }; } return arvo_core_1.ArvoOpenTelemetry.getInstance().startActiveSpan({ name: 'Execute Machine', spanOptions: { kind: api_1.SpanKind.INTERNAL, attributes: __assign({ 'arvo.machine.type': machine.source, 'arvo.machine.version': machine.version }, event.otelAttributes), }, context: opentelemetry.inheritFrom === 'EVENT' ? { inheritFrom: 'TRACE_HEADERS', traceHeaders: { traceparent: event.traceparent, tracestate: event.tracestate, }, } : { inheritFrom: 'CONTEXT', context: api_1.context.active(), }, fn: function () { var _a, _b, _c, _d, _e, _f, _g; var eventQueue = []; var errors = []; var actor; if (!state) { (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Starting new orchestration for machine '".concat(machine.source, "' with event type '").concat(event.type, "'"), }); if (event.type !== machine.source) { throw new Error("Invalid initialization event: Machine requires source event '".concat(machine.source, "' to start, but received event '").concat(event.type, "' instead. This likely indicates a mismatch between the expected workflow trigger and the actual event sent.")); } actor = (0, xstate_1.createActor)(machine.logic, { input: event.toJSON(), }); actor.on('*', function (event) { return eventQueue.push(event); }); actor.subscribe({ error: function (err) { return errors.push(err); } }); actor.start(); } else { (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Resuming orchestration for machine '".concat(machine.source, "' from existing state with event '").concat(event.type, "'"), }); actor = (0, xstate_1.createActor)(machine.logic, { snapshot: state, }); actor.on('*', function (event) { return eventQueue.push(event); }); actor.subscribe({ error: function (err) { return errors.push(err); } }); actor.start(); actor.send(event.toJSON()); } (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Machine '".concat(machine.source, "' execution completed successfully with ").concat(eventQueue.length, " queued events"), }); (0, arvo_core_1.logToSpan)({ level: 'INFO', message: "Extracting final state snapshot from machine '".concat(machine.source, "'"), }); var extractedSnapshot = actor.getPersistedSnapshot(); if ((_b = (_a = extractedSnapshot === null || extractedSnapshot === void 0 ? void 0 : extractedSnapshot.context) === null || _a === void 0 ? void 0 : _a.arvo$$) === null || _b === void 0 ? void 0 : _b.volatile$$) { // biome-ignore lint/complexity/noForEach: This is fine ((_e = (_d = (_c = extractedSnapshot === null || extractedSnapshot === void 0 ? void 0 : extractedSnapshot.context) === null || _c === void 0 ? void 0 : _c.arvo$$) === null || _d === void 0 ? void 0 : _d.volatile$$) === null || _e === void 0 ? void 0 : _e.eventQueue$$).forEach(function (item) { return eventQueue.push(item); }); extractedSnapshot.context.arvo$$.volatile$$ = undefined; } if (errors.length) { throw errors[0]; } var finalOutput = (_f = extractedSnapshot === null || extractedSnapshot === void 0 ? void 0 : extractedSnapshot.output) !== null && _f !== void 0 ? _f : null; var existingOutput = (_g = state === null || state === void 0 ? void 0 : state.output) !== null && _g !== void 0 ? _g : null; if (JSON.stringify(finalOutput !== null && finalOutput !== void 0 ? finalOutput : {}) === JSON.stringify(existingOutput !== null && existingOutput !== void 0 ? existingOutput : {})) { finalOutput = null; } return { state: extractedSnapshot, events: eventQueue, finalOutput: finalOutput, }; }, }); }; return MachineExecutionEngine; }()); exports.MachineExecutionEngine = MachineExecutionEngine;