@iota-big3/sdk-gateway
Version:
Universal API Gateway with protocol translation, intelligent routing, rate limiting, health checking, and caching
700 lines • 18.5 kB
TypeScript
/**
* 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