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

110 lines (109 loc) 4.92 kB
import type { Span } from '@opentelemetry/api'; import type { ArvoContract, ArvoEvent, ArvoSemanticVersion, CreateArvoEvent, InferArvoEvent, OpenTelemetryHeaders, VersionedArvoContract } from 'arvo-core'; import type { z } from 'zod'; import type { ArvoEventHandlerOtelSpanOptions, NonEmptyArray } from '../types'; /** * Represents the input for an ArvoEvent handler function. */ export type ArvoEventHandlerFunctionInput<TContract extends VersionedArvoContract<any, any>> = { /** The ArvoEvent object. */ event: InferArvoEvent<ArvoEvent<z.infer<TContract['accepts']['schema']>, Record<string, any>, TContract['accepts']['type']>>; /** The source field data of the handler */ source: string; /** The domain information for handling the event */ domain: { self: string | null; event: string | null; }; /** The contract used in the processing */ contract: TContract; /** The OpenTelemetry span */ span: Span; /** The span headers */ spanHeaders: OpenTelemetryHeaders; }; /** * Represents the output of an ArvoEvent handler function. */ export type ArvoEventHandlerFunctionOutput<TContract extends VersionedArvoContract<any, any>> = { [K in keyof TContract['emits']]: Pick<CreateArvoEvent<z.infer<TContract['emits'][K]>, K & string>, 'id' | 'time' | 'type' | 'data' | 'to' | 'accesscontrol' | 'redirectto'> & { /** * An optional override for the execution units of this specific event. * * @remarks * Execution units represent the computational cost or resources required to process this event. * If not provided, the default value defined in the handler's constructor will be used. */ executionunits?: number; /** Optional extensions for the event. */ __extensions?: Record<string, string | number | boolean>; /** * Specifies which execution contexts should receive this event. Each domain value creates a separate routed event. * Defaults to the domain encoded in the triggering event's subject with fallback to ArvoDomain.LOCAL (null) to * maintain execution context continuity. * * @default [ArvoDomain.FROM_PARENT_SUBJECT] * * **Examples:** * - `['human.interaction', 'audit.reporting']` → Creates two routed events * - `[ArvoDomain.FROM_TRIGGERING_EVENT, 'human.review']` → Mirrors source domain and routes to review * - `[ArvoDomain.LOCAL]` → Stays in current execution context */ domain?: NonEmptyArray<string | null>; }; }[keyof TContract['emits']]; /** * Defines the structure of an ArvoEvent handler function. */ export type ArvoEventHandlerFunction<TContract extends ArvoContract> = { [V in ArvoSemanticVersion & keyof TContract['versions']]: (params: ArvoEventHandlerFunctionInput<VersionedArvoContract<TContract, V>>) => Promise<Array<ArvoEventHandlerFunctionOutput<VersionedArvoContract<TContract, V>>> | ArvoEventHandlerFunctionOutput<VersionedArvoContract<TContract, V>> | void>; }; /** * Interface for an ArvoEvent handler. */ export type ArvoEventHandlerParam<TContract extends ArvoContract> = { /** * The contract for the handler defining its input and outputs as well as the description. */ contract: TContract; /** * The default execution cost of the function. * This can represent a dollar value or some other number with a rate card. */ executionunits?: number; /** * The functional handler of the event which takes the input, performs an action, and returns the result. * @param params - The input parameters for the handler function. * @returns A promise of object containing the created ArvoEvent and optional extensions. */ handler: ArvoEventHandlerFunction<TContract>; /** * The OpenTelemetry span options */ spanOptions?: ArvoEventHandlerOtelSpanOptions; /** * Optional default domains for the events emitted * by the event handler. */ defaultEventEmissionDomains?: { /** * Default domains for system error events emitted by this handler. * * System errors are routed through these domains when the handler encounters * unhandled exceptions or critical failures. * * @default [ArvoDomain.ORCHESTRATION_CONTEXT] */ systemError?: NonEmptyArray<string | null>; /** * Default domains for response events emitted by this handler. * * Response events are routed through these domains when the handler successfully * processes an incoming event. Individual handler implementations can override * this default on a per-event basis. * * @default [ArvoDomain.ORCHESTRATION_CONTEXT] */ emits?: NonEmptyArray<string | null>; }; };