UNPKG

@moleculer/channels

Version:
526 lines (468 loc) 13.6 kB
/* * @moleculer/channels * Copyright (c) 2025 MoleculerJS (https://github.com/moleculerjs/channels) * MIT Licensed */ declare module "@moleculer/channels" { import { ServiceBroker, Context, Service, Middleware, Logger, Serializers } from "moleculer"; // === Core Interfaces === /** * Dead-letter-queue options */ export interface DeadLetteringOptions { /** Enable dead-letter-queue */ enabled: boolean; /** Name of the dead-letter queue */ queueName?: string; /** Name of the dead-letter exchange (only for AMQP adapter) */ exchangeName?: string; /** Options for the dead-letter exchange (only for AMQP adapter) */ exchangeOptions?: Record<string, any>; /** Options for the dead-letter queue (only for AMQP adapter) */ queueOptions?: Record<string, any>; /** Custom function to convert Error object to header entries */ transformErrorToHeaders?: (error: Error) => Record<string, string>; /** Custom function to parse error info from headers back to data */ transformHeadersToErrorData?: (headers: Record<string, string>) => Record<string, any>; /** Time-to-live in seconds for error info storage (only for Redis adapter) */ errorInfoTTL?: number; } /** * Base consumer configuration */ export interface Channel<TThis = Service> { /** Consumer ID */ id?: string; /** Channel/Queue/Stream name */ name?: string; /** Consumer group name */ group?: string; /** Create Moleculer Context */ context?: boolean; /** Flag denoting if service is stopping */ unsubscribing?: boolean; /** Maximum number of messages that can be processed simultaneously */ maxInFlight?: number; /** Maximum number of retries before sending the message to dead-letter-queue */ maxRetries?: number; /** Dead-letter-queue options */ deadLettering?: DeadLetteringOptions; /** User defined handler */ handler?: (this: TThis, payload: any, raw?: any) => Promise<any> | any; /** Tracing options */ tracing?: boolean | TracingOptions; } /** * Channel registry entry */ export interface ChannelRegistryEntry { /** Service instance class */ svc: Service; /** Channel name */ name: string; /** Channel object */ chan: Channel; } /** * Adapter configuration object */ export interface AdapterConfig { /** Adapter name */ type: string; /** Adapter options */ options?: Record<string, any>; } /** * Middleware options */ export interface MiddlewareOptions { /** Adapter name, connection string, or configuration object */ adapter: string | AdapterConfig; /** Property name of channels definition in service schema */ schemaProperty?: string; /** Method name to send messages */ sendMethodName?: string; /** Property name of the adapter instance in broker instance */ adapterPropertyName?: string; /** Method name to add to service in order to trigger channel handlers */ channelHandlerTrigger?: string; /** Using Moleculer context in channel handlers by default */ context?: boolean; } /** * Tracing options */ export interface TracingOptions { /** Enable/disable tracing */ enabled?: boolean; /** Custom span name */ spanName?: string | ((ctx: Context<any, any>) => string); /** Tags for tracing */ tags?: Record<string, any> | ((ctx: Context<any, any>) => Record<string, any>); /** Enable safety tags */ safetyTags?: boolean; } /** * Send options for publishing messages */ export interface SendOptions { /** Headers to include with message */ headers?: Record<string, any>; /** Moleculer context to propagate */ ctx?: Context<any, any>; /** Additional adapter-specific options */ [key: string]: any; } // === Base Adapter === /** * Base adapter default options */ export interface BaseDefaultOptions { /** Adapter prefix */ prefix?: string; /** Name of the consumer */ consumerName?: string; /** Type of serializer to use in message exchange */ serializer?: string; /** Maximum number of retries before sending the message to dead-letter-queue or drop */ maxRetries?: number; /** Maximum number of messages that can be processed in parallel */ maxInFlight?: number; /** Dead-letter-queue options */ deadLettering?: DeadLetteringOptions; } /** * Base adapter class */ export class BaseAdapter { /** Adapter options */ opts: BaseDefaultOptions; /** Service broker instance */ broker: ServiceBroker; /** Logger instance */ logger: Logger; /** Promise constructor */ Promise: typeof Promise; /** Serializer instance */ serializer: Serializers.Base; /** Active messages tracking */ activeMessages: Map<string, Array<string | number>>; /** Connection status */ connected: boolean; /** Function to convert Error to header entries for dead-lettering */ transformErrorToHeaders: (error: Error) => Record<string, string> | null; /** Function to parse error info from headers */ transformHeadersToErrorData: (headers: Record<string, string>) => Record<string, any> | null; constructor(opts?: BaseDefaultOptions); /** * Initialize the adapter */ init(broker: ServiceBroker, logger: Logger): void; /** * Register adapter related metrics */ registerAdapterMetrics(broker: ServiceBroker): void; /** * Increment metrics */ metricsIncrement(metricName: string, chan: Channel): void; /** * Check client library version */ checkClientLibVersion(library: string, requiredVersions: string): boolean; /** * Initialize active messages tracking for a channel */ initChannelActiveMessages(channelID: string, toThrow?: boolean): void; /** * Stop active messages tracking for a channel */ stopChannelActiveMessages(channelID: string): void; /** * Add active message IDs */ addChannelActiveMessages(channelID: string, IDs: Array<string | number>): void; /** * Remove active message IDs */ removeChannelActiveMessages(channelID: string, IDs: Array<string | number>): void; /** * Get number of active messages for a channel */ getNumberOfChannelActiveMessages(channelID: string): number; /** * Get number of tracked channels */ getNumberOfTrackedChannels(): number; /** * Add prefix to topic name */ addPrefixTopic(topicName: string): string; /** * Connect to the adapter */ connect(): Promise<void>; /** * Disconnect from adapter */ disconnect(): Promise<void>; /** * Subscribe to a channel */ subscribe(chan: Channel, svc: Service): Promise<void>; /** * Unsubscribe from a channel */ unsubscribe(chan: Channel): Promise<void>; /** * Publish a payload to a channel */ publish(channelName: string, payload: any, opts?: SendOptions): Promise<void>; /** * Parse message headers from raw message */ parseMessageHeaders(raw: any): Record<string, any> | null; } // === Adapter-specific options === /** * Redis adapter options */ export interface RedisDefaultOptions extends BaseDefaultOptions { redis?: { /** Redis connection URL */ url?: string; /** Consumer options */ consumerOptions?: { /** Read timeout interval in milliseconds */ readTimeoutInterval?: number; /** Min idle time for claiming pending messages */ minIdleTime?: number; /** Claim interval in milliseconds */ claimInterval?: number; /** Starting ID for consumer group */ startID?: string; /** Processing attempts interval */ processingAttemptsInterval?: number; }; /** Additional Redis client options */ [key: string]: any; }; } /** * AMQP adapter options */ export interface AmqpDefaultOptions extends BaseDefaultOptions { amqp?: { /** AMQP connection URL(s) */ url?: string | string[]; /** Socket options */ socketOptions?: Record<string, any>; /** Queue options */ queueOptions?: Record<string, any>; /** Exchange options */ exchangeOptions?: Record<string, any>; /** Message options */ messageOptions?: Record<string, any>; /** Consumer options */ consumerOptions?: Record<string, any>; /** Publish assert exchange options */ publishAssertExchange?: { enabled?: boolean; exchangeOptions?: Record<string, any>; }; }; } /** * Kafka adapter options */ export interface KafkaDefaultOptions extends BaseDefaultOptions { kafka?: { /** Kafka brokers */ brokers?: string[]; /** Log creator function */ logCreator?: () => (logEntry: any) => void; /** Producer options */ producerOptions?: Record<string, any>; /** Consumer options */ consumerOptions?: Record<string, any>; /** Additional Kafka client config */ [key: string]: any; }; } /** * NATS adapter options */ export interface NatsDefaultOptions extends BaseDefaultOptions { /** NATS URL */ url?: string; nats?: { /** Connection options */ connectionOptions?: Record<string, any>; /** Stream configuration */ streamConfig?: Record<string, any>; /** Consumer options */ consumerOptions?: { mack?: boolean; config?: { deliver_policy?: string; ack_policy?: string; max_ack_pending?: number; }; }; }; } /** * Fake adapter options (for testing) */ export interface FakeOptions extends BaseDefaultOptions { /** Service prefix */ servicePrefix?: string; /** Event prefix */ eventPrefix?: string; } // === Adapter Classes === /** * Redis adapter */ export class RedisAdapter extends BaseAdapter { constructor(opts?: RedisDefaultOptions | string); } /** * AMQP adapter */ export class AmqpAdapter extends BaseAdapter { constructor(opts?: AmqpDefaultOptions | string); } /** * Kafka adapter */ export class KafkaAdapter extends BaseAdapter { constructor(opts?: KafkaDefaultOptions | string); } /** * NATS adapter */ export class NatsAdapter extends BaseAdapter { constructor(opts?: NatsDefaultOptions | string); } /** * Fake adapter (for testing) */ export class FakeAdapter extends BaseAdapter { constructor(opts?: FakeOptions | string); } // === Adapters Registry === export interface AdaptersRegistry { Base: typeof BaseAdapter; AMQP: typeof AmqpAdapter; Fake: typeof FakeAdapter; Kafka: typeof KafkaAdapter; NATS: typeof NatsAdapter; Redis: typeof RedisAdapter; resolve(opt: string | AdapterConfig | BaseAdapter): BaseAdapter; register(name: string, value: typeof BaseAdapter): void; } // === Constants === export interface Constants { /** Number of redelivery attempts */ HEADER_REDELIVERED_COUNT: string; /** Consumer group name */ HEADER_GROUP: string; /** Name of the channel where an error occurred while processing the message */ HEADER_ORIGINAL_CHANNEL: string; /** Name of consumer group that could not process the message properly */ HEADER_ORIGINAL_GROUP: string; /** Prefix for error-related headers */ HEADER_ERROR_PREFIX: string; /** Error message */ HEADER_ERROR_MESSAGE: string; /** Error code */ HEADER_ERROR_CODE: string; /** Error stack trace */ HEADER_ERROR_STACK: string; /** Error type */ HEADER_ERROR_TYPE: string; /** Error data */ HEADER_ERROR_DATA: string; /** Error name */ HEADER_ERROR_NAME: string; /** Error retryable flag */ HEADER_ERROR_RETRYABLE: string; /** Timestamp when the error happened */ HEADER_ERROR_TIMESTAMP: string; /** Metrics constants */ METRIC_CHANNELS_MESSAGES_SENT: string; METRIC_CHANNELS_MESSAGES_TOTAL: string; METRIC_CHANNELS_MESSAGES_ACTIVE: string; METRIC_CHANNELS_MESSAGES_TIME: string; METRIC_CHANNELS_MESSAGES_ERRORS_TOTAL: string; METRIC_CHANNELS_MESSAGES_RETRIES_TOTAL: string; METRIC_CHANNELS_MESSAGES_DEAD_LETTERING_TOTAL: string; /** Thrown when incoming messages cannot be deserialized */ INVALID_MESSAGE_SERIALIZATION_ERROR_CODE: string; } // === Enhanced ServiceBroker interface === export interface EnhancedServiceBroker extends ServiceBroker { /** * Send message to channel (added by channels middleware) */ sendToChannel(channelName: string, payload: any, opts?: SendOptions): Promise<void>; /** * Channel adapter instance (added by channels middleware) */ channelAdapter: BaseAdapter; } // === Enhanced Service interface === export interface EnhancedService extends Service { /** * Emit local channel handler (added by channels middleware for testing) */ emitLocalChannelHandler(channelName: string, payload: any, raw?: any): Promise<any>; } declare module "moleculer" { export interface ServiceBroker { sendToChannel(channelName: string, payload: any, opts?: SendOptions): Promise<void>; } export interface ServiceSchema<TSettings = ServiceSettingSchema, TMethods = Record<string, any>, TVars = Record<string, any>, TThis = Service<TSettings> & TVars & TMethods> { /** * Channel definitions for the service */ channels?: { [channelName: string]: | Channel<TThis> | ((this: TThis, payload: any, raw?: any) => Promise<any> | any); }; } } // === Main Module Exports === /** * Create Channels middleware */ declare function ChannelsMiddleware(opts: MiddlewareOptions): Middleware & { name: string; created(broker: ServiceBroker): void; serviceCreated(svc: Service): Promise<void>; serviceStopping(svc: Service): Promise<void>; starting(): Promise<void>; stopped(): Promise<void>; }; /** * Tracing middleware factory */ declare function TracingMiddleware(): Middleware; export { ChannelsMiddleware as Middleware, TracingMiddleware as Tracing, AdaptersRegistry as Adapters } }