UNPKG

arvo-xstate

Version:

This package allows you to use xstate Actors and State Machines to act as orchestrators in an Arvo Event Driven System

88 lines (87 loc) 4.47 kB
import { type Span } from '@opentelemetry/api'; import { type ArvoContractRecord, type ArvoEvent, type OpenTelemetryHeaders } from 'arvo-core'; import { AbstractArvoEventHandler, type ArvoEventHandlerOpenTelemetryOptions } from 'arvo-event-handler'; import type ArvoMachine from '../ArvoMachine'; import type { EnqueueArvoEventActionParam } from '../ArvoMachine/types'; import type { IMachineExectionEngine } from '../MachineExecutionEngine/interface'; import type { IMachineMemory } from '../MachineMemory/interface'; import type { IMachineRegistry } from '../MachineRegistry/interface'; import type { AcquiredLockStatusType, IArvoOrchestrator, MachineMemoryRecord } from './types'; /** * Orchestrates state machine execution and lifecycle management. * Handles machine resolution, state management, event processing and error handling. */ export declare class ArvoOrchestrator extends AbstractArvoEventHandler { readonly executionunits: number; readonly memory: IMachineMemory<MachineMemoryRecord>; readonly registry: IMachineRegistry; readonly executionEngine: IMachineExectionEngine; readonly requiresResourceLocking: boolean; /** * Gets the source identifier for this orchestrator */ get source(): any; /** * Creates a new orchestrator instance * @param params - Configuration parameters * @throws Error if machines in registry have different sources */ constructor({ executionunits, memory, registry, executionEngine, requiresResourceLocking }: IArvoOrchestrator); /** * Acquires a lock on the event subject. Skip if sequential processing is enabled. * @throws {TransactionViolation} If lock acquisition fails */ protected acquireLock(event: ArvoEvent): Promise<AcquiredLockStatusType>; protected acquireState(event: ArvoEvent): Promise<MachineMemoryRecord | null>; protected persistState(event: ArvoEvent, record: MachineMemoryRecord, prevRecord: MachineMemoryRecord | null): Promise<void>; protected validateConsumedEventSubject(event: ArvoEvent): void; /** * Creates emittable event from execution result * @param event - Source event to emit * @param machine - Machine that generated event * @param otelHeaders - OpenTelemetry headers * @param orchestrationParentSubject - Parent orchestration subject * @param sourceEvent - Original triggering event * * @throws {ContractViolation} On schema/contract mismatch * @throws {ExecutionViolation} On invalid parentSubject$$ format */ protected createEmittableEvent(event: EnqueueArvoEventActionParam, machine: ArvoMachine<any, any, any, any, any>, otelHeaders: OpenTelemetryHeaders, orchestrationParentSubject: string | null, sourceEvent: ArvoEvent): ArvoEvent; /** * If the machine execution session acquired the lock * release the lock before closing. Since the expectation from the * machine memory is that there is optimistic locking and the lock * has expiry time then swallowing is not an issue rather it * avoid unnecessary errors */ protected releaseLock(event: ArvoEvent, acquiredLock: AcquiredLockStatusType | null, span: Span): Promise<'NOOP' | 'RELEASED' | 'ERROR'>; /** * Core orchestration method that executes state machines in response to events. * Manages the complete event lifecycle: * 1. Acquires lock and state * 2. Validates events and contracts * 3. Executes state machine * 4. Persists new state * 5. Generates response events with domain-based segregation * * @param event - Event triggering the execution * @param opentelemetry - OpenTelemetry configuration * @returns Object containing default domained events, all event domains, and domain-segregated event buckets * * @throws {TransactionViolation} Lock/state operations failed * @throws {ExecutionViolation} Invalid event structure/flow * @throws {ContractViolation} Schema/contract mismatch * @throws {ConfigViolation} Missing/invalid machine version */ execute(event: ArvoEvent, opentelemetry?: ArvoEventHandlerOpenTelemetryOptions): Promise<{ events: ArvoEvent[]; allEventDomains: string[]; domainedEvents: { all: ArvoEvent[]; } & Partial<Record<string, ArvoEvent[]>>; }>; /** * Gets the error schema for this orchestrator */ get systemErrorSchema(): ArvoContractRecord; }