UNPKG

@iota-big3/sdk-gateway

Version:

Universal API Gateway with protocol translation, intelligent routing, rate limiting, health checking, and caching

700 lines 18.5 kB
/** * Event-Driven Architecture Type Definitions * * @module event-architecture-types * @description Comprehensive types for event-driven systems including: * - Event definitions and schemas * - Event sourcing patterns * - Message queuing and streaming * - Pub/Sub patterns * - Event stores and projections * - CQRS (Command Query Responsibility Segregation) * - Saga/Orchestration patterns * - Dead letter queues and error handling * * Designed for type-safe event-driven architectures */ import type { Brand, Option, Result } from './index'; /** Unique event identifier */ export type EventId = Brand<string, 'EventId'>; /** Event stream/aggregate identifier */ export type StreamId = Brand<string, 'StreamId'>; /** Message identifier */ export type MessageId = Brand<string, 'MessageId'>; /** Correlation identifier for related events */ export type CorrelationId = Brand<string, 'CorrelationId'>; /** Causation identifier showing event relationships */ export type CausationId = Brand<string, 'CausationId'>; /** Saga/Process identifier */ export type SagaId = Brand<string, 'SagaId'>; /** Subscription identifier */ export type SubscriptionId = Brand<string, 'SubscriptionId'>; /** * Base event interface * All events in the system must implement this */ export interface DomainEvent<TPayload = unknown> { readonly eventId: EventId; readonly eventType: string; readonly eventVersion: string; readonly aggregateId: string; readonly aggregateType: string; readonly sequence: number; readonly timestamp: string; readonly payload: TPayload; readonly metadata: EventMetadata; } /** * Event metadata for tracking and debugging */ export interface EventMetadata { readonly correlationId: CorrelationId; readonly causationId?: CausationId; readonly userId?: string; readonly sessionId?: string; readonly ipAddress?: string; readonly userAgent?: string; readonly source: string; readonly tags?: Record<string, string>; readonly custom?: Record<string, unknown>; } /** * Event envelope for transport */ export interface EventEnvelope<T = unknown> { readonly event: DomainEvent<T>; readonly stream: StreamMetadata; readonly position: EventPosition; readonly checksum?: string; } /** * Stream metadata */ export interface StreamMetadata { readonly streamId: StreamId; readonly streamType: string; readonly version: number; readonly createdAt: string; readonly updatedAt: string; readonly metadata?: Record<string, unknown>; } /** * Event position in stream */ export interface EventPosition { readonly streamPosition: number; readonly globalPosition: number; readonly commitPosition?: number; } /** * Event schema definition */ export interface EventSchema { readonly eventType: string; readonly version: string; readonly description: string; readonly schema: JsonSchema; readonly examples?: EventExample[]; readonly deprecated?: boolean; readonly supersededBy?: string; } /** * JSON Schema for event validation */ export interface JsonSchema { readonly type: string; readonly properties?: Record<string, JsonSchema>; readonly required?: string[]; readonly additionalProperties?: boolean; readonly items?: JsonSchema; readonly enum?: unknown[]; readonly format?: string; readonly pattern?: string; readonly minimum?: number; readonly maximum?: number; } /** * Event example for documentation */ export interface EventExample { readonly name: string; readonly description: string; readonly event: Record<string, unknown>; readonly scenario?: string; } /** * Event store interface */ export interface EventStore { readonly append: (stream: StreamId, events: DomainEvent[], expectedVersion?: number) => Promise<Result<EventPosition, EventStoreError>>; readonly read: (stream: StreamId, fromPosition?: number) => AsyncIterable<EventEnvelope>; readonly readAll: (fromPosition?: number) => AsyncIterable<EventEnvelope>; readonly subscribe: (stream: StreamId | '*', fromPosition?: number) => EventSubscription; readonly createSnapshot: (stream: StreamId, snapshot: AggregateSnapshot) => Promise<Result<void, EventStoreError>>; readonly getSnapshot: (stream: StreamId) => Promise<Option<AggregateSnapshot>>; } /** * Event store errors */ export type EventStoreError = { type: 'CONCURRENCY_CONFLICT'; expectedVersion: number; actualVersion: number; } | { type: 'STREAM_NOT_FOUND'; stream: StreamId; } | { type: 'STREAM_DELETED'; stream: StreamId; } | { type: 'STORAGE_ERROR'; error: string; }; /** * Aggregate snapshot for performance */ export interface AggregateSnapshot { readonly aggregateId: string; readonly aggregateType: string; readonly data: unknown; readonly version: number; readonly timestamp: string; } /** * Event subscription */ export interface EventSubscription { readonly subscriptionId: SubscriptionId; readonly stream: StreamId | '*'; readonly position: number; readonly handlers: EventHandler[]; readonly options: SubscriptionOptions; readonly status: SubscriptionStatus; } /** * Subscription options */ export interface SubscriptionOptions { readonly fromPosition?: number; readonly resolveLinkTos?: boolean; readonly bufferSize?: number; readonly checkpointAfter?: number; readonly maxRetries?: number; readonly retryDelay?: number; } /** * Subscription status */ export declare enum SubscriptionStatus { Active = "ACTIVE", Paused = "PAUSED", Catching_Up = "CATCHING_UP", Disconnected = "DISCONNECTED", Error = "ERROR" } /** * Event handler function */ export type EventHandler<T = unknown> = (event: DomainEvent<T>, metadata: HandlerMetadata) => Promise<HandlerResult>; /** * Handler metadata */ export interface HandlerMetadata { readonly subscription: SubscriptionId; readonly position: EventPosition; readonly retryCount: number; readonly timestamp: string; } /** * Handler result */ export type HandlerResult = { type: 'SUCCESS'; } | { type: 'RETRY'; delay?: number; } | { type: 'SKIP'; reason: string; } | { type: 'ERROR'; error: string; retry: boolean; }; /** * Message for queuing systems */ export interface QueueMessage<T = unknown> { readonly messageId: MessageId; readonly queue: string; readonly payload: T; readonly headers: MessageHeaders; readonly attributes: MessageAttributes; } /** * Message headers */ export interface MessageHeaders { readonly contentType: string; readonly contentEncoding?: string; readonly correlationId?: CorrelationId; readonly replyTo?: string; readonly messageType?: string; readonly timestamp: string; readonly custom?: Record<string, string>; } /** * Message attributes */ export interface MessageAttributes { readonly priority?: number; readonly ttl?: number; readonly delaySeconds?: number; readonly maxRetries?: number; readonly deadLetterQueue?: string; } /** * Queue configuration */ export interface QueueConfig { readonly name: string; readonly type: QueueType; readonly durability: 'persistent' | 'transient'; readonly exclusive?: boolean; readonly autoDelete?: boolean; readonly maxLength?: number; readonly maxSizeBytes?: number; readonly messageTtl?: number; readonly deadLetterExchange?: string; readonly retryPolicy?: RetryPolicy; } /** * Queue types */ export declare enum QueueType { Standard = "STANDARD", FIFO = "FIFO",// First In First Out Priority = "PRIORITY", Delay = "DELAY", Topic = "TOPIC" } /** * Retry policy */ export interface RetryPolicy { readonly maxRetries: number; readonly backoffType: 'fixed' | 'linear' | 'exponential'; readonly initialDelay: number; readonly maxDelay?: number; readonly multiplier?: number; } /** * Message acknowledgment */ export interface MessageAck { readonly messageId: MessageId; readonly status: AckStatus; readonly timestamp: string; readonly error?: string; } /** * Acknowledgment status */ export declare enum AckStatus { Ack = "ACK",// Processed successfully Nack = "NACK",// Failed, retry Reject = "REJECT",// Failed, don't retry Requeue = "REQUEUE" } /** * Topic for pub/sub systems */ export interface Topic { readonly name: string; readonly partitions?: number; readonly replicationFactor?: number; readonly retentionMs?: number; readonly schema?: EventSchema; readonly config?: Record<string, string>; } /** * Publisher configuration */ export interface PublisherConfig { readonly clientId: string; readonly topics: string[]; readonly compression?: 'none' | 'gzip' | 'snappy' | 'lz4'; readonly batchSize?: number; readonly lingerMs?: number; readonly acks?: 'none' | 'leader' | 'all'; readonly retries?: number; } /** * Subscriber configuration */ export interface SubscriberConfig { readonly clientId: string; readonly groupId?: string; readonly topics: string[]; readonly fromBeginning?: boolean; readonly autoCommit?: boolean; readonly commitInterval?: number; readonly maxBatchSize?: number; readonly maxWaitMs?: number; } /** * Published message result */ export interface PublishResult { readonly messageId: MessageId; readonly topic: string; readonly partition?: number; readonly offset?: number; readonly timestamp: string; } /** * Subscription offset */ export interface ConsumerOffset { readonly topic: string; readonly partition: number; readonly offset: number; readonly metadata?: string; } /** * Command in CQRS pattern */ export interface Command<T = unknown> { readonly commandId: Brand<string, 'CommandId'>; readonly commandType: string; readonly aggregateId: string; readonly payload: T; readonly metadata: CommandMetadata; } /** * Command metadata */ export interface CommandMetadata { readonly correlationId: CorrelationId; readonly userId: string; readonly timestamp: string; readonly source: string; readonly expectedVersion?: number; } /** * Command handler */ export type CommandHandler<TCommand = unknown, TResult = unknown> = (command: Command<TCommand>) => Promise<Result<TResult, CommandError>>; /** * Command errors */ export type CommandError = { type: 'VALIDATION_ERROR'; errors: string[]; } | { type: 'NOT_FOUND'; aggregateId: string; } | { type: 'CONFLICT'; reason: string; } | { type: 'UNAUTHORIZED'; reason: string; } | { type: 'BUSINESS_RULE_VIOLATION'; rule: string; }; /** * Query in CQRS pattern */ export interface Query<T = unknown> { readonly queryId: Brand<string, 'QueryId'>; readonly queryType: string; readonly parameters: T; readonly metadata: QueryMetadata; } /** * Query metadata */ export interface QueryMetadata { readonly userId?: string; readonly timestamp: string; readonly source: string; readonly cacheKey?: string; readonly cacheTtl?: number; } /** * Query handler */ export type QueryHandler<TQuery = unknown, TResult = unknown> = (query: Query<TQuery>) => Promise<Result<TResult, QueryError>>; /** * Query errors */ export type QueryError = { type: 'NOT_FOUND'; message: string; } | { type: 'UNAUTHORIZED'; reason: string; } | { type: 'TIMEOUT'; duration: number; } | { type: 'INVALID_QUERY'; errors: string[]; }; /** * Read model/Projection */ export interface ReadModel { readonly modelId: string; readonly modelType: string; readonly version: number; readonly data: unknown; readonly lastEventPosition: EventPosition; readonly lastUpdated: string; } /** * Saga definition */ export interface Saga { readonly sagaId: SagaId; readonly sagaType: string; readonly state: SagaState; readonly data: unknown; readonly startedAt: string; readonly updatedAt: string; readonly completedAt?: string; readonly status: SagaStatus; } /** * Saga state */ export interface SagaState { readonly currentStep: string; readonly completedSteps: string[]; readonly pendingCommands: Command[]; readonly compensations: CompensationAction[]; readonly variables: Record<string, unknown>; } /** * Saga status */ export declare enum SagaStatus { Running = "RUNNING", Completed = "COMPLETED", Failed = "FAILED", Compensating = "COMPENSATING", Compensated = "COMPENSATED", Suspended = "SUSPENDED" } /** * Compensation action for saga rollback */ export interface CompensationAction { readonly step: string; readonly command: Command; readonly executed: boolean; readonly result?: Result<unknown, unknown>; } /** * Saga step definition */ export interface SagaStep { readonly name: string; readonly handler: (context: SagaContext) => Promise<StepResult>; readonly compensation?: (context: SagaContext) => Promise<void>; readonly retryPolicy?: RetryPolicy; readonly timeout?: number; } /** * Saga context */ export interface SagaContext { readonly sagaId: SagaId; readonly correlationId: CorrelationId; readonly data: Record<string, unknown>; readonly publish: (event: DomainEvent) => Promise<void>; readonly send: (command: Command) => Promise<Result<unknown, CommandError>>; } /** * Saga step result */ export type StepResult = { type: 'CONTINUE'; data?: Record<string, unknown>; } | { type: 'COMPLETE'; result?: unknown; } | { type: 'FAIL'; error: string; compensate: boolean; } | { type: 'WAIT'; until: string | DomainEvent; }; /** * Stream processor configuration */ export interface StreamProcessor { readonly processorId: string; readonly name: string; readonly inputStreams: string[]; readonly outputStream?: string; readonly processor: ProcessorFunction; readonly window?: WindowConfig; readonly state?: StateStoreConfig; } /** * Processor function */ export type ProcessorFunction = (events: DomainEvent[], context: ProcessorContext) => Promise<ProcessorResult>; /** * Processor context */ export interface ProcessorContext { readonly processorId: string; readonly window?: TimeWindow; readonly state: StateStore; readonly emit: (event: DomainEvent) => Promise<void>; } /** * Processor result */ export interface ProcessorResult { readonly processed: number; readonly emitted: number; readonly errors: ProcessorError[]; } /** * Processor error */ export interface ProcessorError { readonly eventId: EventId; readonly error: string; readonly retryable: boolean; } /** * Window configuration for stream processing */ export interface WindowConfig { readonly type: 'tumbling' | 'sliding' | 'session'; readonly size: number; readonly slide?: number; readonly grace?: number; } /** * Time window */ export interface TimeWindow { readonly start: string; readonly end: string; readonly key?: string; } /** * State store for stateful processing */ export interface StateStore { readonly get: <T>(key: string) => Promise<Option<T>>; readonly put: <T>(key: string, value: T) => Promise<void>; readonly delete: (key: string) => Promise<void>; readonly scan: <T>(prefix?: string) => AsyncIterable<[string, T]>; } /** * State store configuration */ export interface StateStoreConfig { readonly type: 'memory' | 'rocksdb' | 'redis'; readonly name: string; readonly ttl?: number; readonly maxSize?: number; } /** * Dead letter entry */ export interface DeadLetter<T = unknown> { readonly deadLetterId: Brand<string, 'DeadLetterId'>; readonly originalMessage: T; readonly source: string; readonly reason: string; readonly errorDetails?: unknown; readonly retryCount: number; readonly firstFailureAt: string; readonly lastFailureAt: string; readonly expiresAt?: string; } /** * Dead letter queue configuration */ export interface DeadLetterConfig { readonly queue: string; readonly maxRetries: number; readonly retentionPeriod: number; readonly alertThreshold?: number; readonly autoReplay?: boolean; readonly replayDelay?: number; } /** * Event bus for in-process events */ export interface EventBus { readonly publish: <T>(event: DomainEvent<T>) => Promise<void>; readonly subscribe: <T>(eventType: string, handler: EventHandler<T>) => SubscriptionHandle; readonly subscribeAll: (handler: EventHandler) => SubscriptionHandle; readonly unsubscribe: (handle: SubscriptionHandle) => void; } /** * Subscription handle */ export interface SubscriptionHandle { readonly id: string; readonly eventType: string | '*'; readonly unsubscribe: () => void; } /** * Event bus configuration */ export interface EventBusConfig { readonly async: boolean; readonly maxListeners?: number; readonly errorHandler?: (error: Error, event: DomainEvent) => void; readonly middleware?: EventMiddleware[]; } /** * Event middleware */ export type EventMiddleware = (event: DomainEvent, next: () => Promise<void>) => Promise<void>; /** * Validate event ordering in stream */ export declare function validateEventOrder(events: DomainEvent[]): Result<boolean, string>; /** * Calculate event stream statistics */ export declare function calculateStreamStats(events: DomainEvent[]): StreamStatistics; /** * Stream statistics */ export interface StreamStatistics { readonly eventCount: number; readonly firstEvent: string | null; readonly lastEvent: string | null; readonly duration: number; readonly eventsPerSecond: number; readonly eventTypes: Record<string, number>; } /** * Check if saga can be compensated */ export declare function canCompensateSaga(saga: Saga): boolean; export declare const eventArchitectureTypes: { SubscriptionStatus: typeof SubscriptionStatus; QueueType: typeof QueueType; AckStatus: typeof AckStatus; SagaStatus: typeof SagaStatus; validateEventOrder: typeof validateEventOrder; calculateStreamStats: typeof calculateStreamStats; canCompensateSaga: typeof canCompensateSaga; }; //# sourceMappingURL=event-architecture-types.d.ts.map