@imqueue/core
Version:
Simple JSON-based messaging queue for inter service communication
380 lines (379 loc) • 10.7 kB
TypeScript
/*!
* Basic types and interfaces
*
* I'm Queue Software Project
* Copyright (C) 2025 imqueue.com <support@imqueue.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* If you want to use this code in a closed source (commercial) project, you can
* purchase a proprietary commercial license. Please contact us at
* <support@imqueue.com> to get commercial licensing options.
*/
import { EventEmitter } from 'events';
import { IMQMode } from './IMQMode';
import { ClusterManager } from './ClusterManager';
export { EventEmitter } from 'events';
/**
* Represents any JSON-serializable value
*/
export type AnyJson = boolean | number | string | null | undefined | JsonArray | JsonObject;
/**
* Represents JSON serializable object
*/
export interface JsonObject {
[key: string]: AnyJson;
}
/**
* Represents JSON-serializable array
*/
export interface JsonArray extends Array<AnyJson> {
}
/**
* Alias for JsonObject, legacy, outdated, deprecated, try to avoid using.
* Stands here for backward-compatibility only
*
* @deprecated
*/
export type IJson = JsonObject;
/**
* Logger interface
*/
export interface ILogger {
/**
* Log level function
*
* @param {...any[]} args
*/
log(...args: any[]): void;
/**
* Info level function
*
* @param {...any[]} args
*/
info(...args: any[]): void;
/**
* Warning level function
*
* @param {...any[]} args
*/
warn(...args: any[]): void;
/**
* Error level function
*
* @param {...any[]} args
*/
error(...args: any[]): void;
}
/**
* Defines message format.
*
* @type {IMessage}
*/
export interface IMessage {
/**
* Message unique identifier
*
* @type {string}
*/
id: string;
/**
* Message data. Any JSON-compatible data allowed
*
* @type {JsonObject}
*/
message: JsonObject;
/**
* Message source queue name
*
* @type {string}
*/
from: string;
/**
* Message delay in milliseconds (for delayed messages). Optional.
*
* @type {number}
*/
delay?: number;
}
export interface IServerInput {
/**
* Message queue network unique identifier, optional property
*
* @type {string | undefined}
*/
id?: string;
/**
* Message queue network host
*
* @type {string}
*/
host: string;
/**
* Message queue network port
*
* @type {number}
*/
port: number;
}
export interface IMessageQueueConnection extends IMessageQueueAuthConnection {
/**
* Message queue network unique identifier, optional property
*
* @type {string | undefined}
*/
id?: string;
/**
* Message queue network host
*
* @type {string}
*/
host: string;
/**
* Message queue network port
*
* @type {number}
*/
port: number;
}
export interface IMessageQueueAuthConnection {
/**
* Message queue username
*
* @type {string}
*/
username?: string;
/**
* Message queue password
*
* @type {string}
*/
password?: string;
}
/**
* Message queue options
*/
export interface IMQOptions extends Partial<IMessageQueueConnection> {
/**
* Turns on/off cleanup of the message queues
*
* @type {boolean}
*/
cleanup: boolean;
/**
* Defines cleanup pattern for the name of the queue
* which should be removed during cleanup processing
*
* @type {string}
*/
cleanupFilter: string;
/**
* Message queue vendor
*
* @type {string}
*/
vendor?: string;
/**
* Message queue global key prefix (namespace)
*
* @type {string}
*/
prefix?: string;
/**
* Logger defined to be used within message queue in runtime
*
* @type {ILogger}
*/
logger?: ILogger;
/**
* Watcher check delay period. This is used by a queue watcher
* agent to make sure at least one watcher is available for
* queue operations.
*
* @type {number}
*/
watcherCheckDelay?: number;
/**
* A way to serialize message using compression. Will increase
* load to worker process but can decrease network traffic between worker
* and queue host application
*
* @type {boolean}
*/
useGzip?: boolean;
/**
* Enables/disables safe message delivery. When safe message delivery
* is turned on it will use more complex algorithm for message handling
* by a worker process, guaranteeing that if worker fails the message will
* be delivered to another possible worker anyway. In most cases it
* is not required unless it is required by a system design.
*
* @type {boolean}
*/
safeDelivery?: boolean;
/**
* Time-to-live of worker queues (after this time messages are back to
* main queue for handling if worker died). Only works if safeDelivery
* option enabled.
*
* @type {number}
*/
safeDeliveryTtl?: number;
/**
* Queue cluster instances, if MQ should be clustered
*
* @type {IMessageQueueConnection[]}
*/
cluster?: IMessageQueueConnection[];
/**
* Array of cluster managers used to handle cluster operations.
* Any manager implements specific cluster server detection.
*
* @type {ClusterManager[]}
*/
clusterManagers?: ClusterManager[];
}
export interface EventMap {
message: [data: any, id: string, from: string];
error: [error: Error, eventName: string];
}
export type IMessageQueueConstructor = new (name: string, options?: Partial<IMQOptions>, mode?: IMQMode) => IMessageQueue;
/**
* Generic messaging queue implementation interface
*
* @example
* ~~~typescript
* import { IMessageQueue, EventEmitter, uuid } from '@imqueue/core';
*
* class SomeMQAdapter implements IMessageQueue extends EventEmitter {
* public async start(): Promise<SomeMQAdapter> {
* // ... implementation goes here
* return this;
* }
* public async stop(): Promise<SomeMQAdapter> {
* // ... implementation goes here
* return this;
* }
* public async send(
* toQueue: string,
* message: JsonObject,
* delay?: number
* ): Promise<string> {
* const messageId = uuid();
* // ... implementation goes here
* return messageId;
* }
* public async destroy(): Promise<void> {
* // ... implementation goes here
* }
* public async clear(): Promise<SomeMQAdapter> {
* // ... implementation goes here
* return this;
* }
* }
* ~~~
*/
export interface IMessageQueue extends EventEmitter<EventMap> {
/**
* Message event. Occurs every time queue got a message.
*
* @event IMessageQueue#message
* @type {JsonObject} message - message data
* @type {string} id - message identifier
* @type {string} from - source queue produced the message
*/
/**
* Error event. Occurs every time queue caught an error.
*
* @event IMessageQueue#error
* @type {Error} err - error caught by message queue
* @type {string} code - message queue error code
*/
/**
* Starts the messaging queue.
* Supposed to be an async function.
*
* @returns {Promise<IMessageQueue>}
*/
start(): Promise<IMessageQueue>;
/**
* Stops the queue (should stop handle queue messages).
* Supposed to be an async function.
*
* @returns {Promise<IMessageQueue>}
*/
stop(): Promise<IMessageQueue>;
/**
* Sends a message to given queue name with the given data.
* Supposed to be an async function.
*
* @param {string} toQueue - queue name to which message should be sent to
* @param {JsonObject} message - message data
* @param {number} [delay] - if specified, message will be handled in the
* target queue after specified period of time in milliseconds.
* @param {(err: Error) => void} [errorHandler] - callback called only when
* internal error occurs during message send execution.
* @returns {Promise<string>} - message identifier
*/
send(toQueue: string, message: JsonObject, delay?: number, errorHandler?: (err: Error) => void): Promise<string>;
/**
* Creates or uses subscription channel with the given name and sets
* message handler on data receive
*
* @param {string} channel - channel name
* @param {(data: JsonObject) => any} handler
*/
subscribe(channel: string, handler: (data: JsonObject) => any): Promise<void>;
/**
* Closes subscription channel
*
* @return {Promise<void>}
*/
unsubscribe(): Promise<void>;
/**
* Publishes data to current queue channel
*
* If toName specified will publish to pubsub with different name. This
* can be used to implement broadcasting some messages to other subscribers
* on other pubsub channels. Different name should be in the same namespace
* (same imq prefix)
*
* @param {JsonObject} data - data to publish as channel message
* @param {string} [toName] - different name of the pubsub to publish to
* @return {Promise<void>}
*/
publish(data: JsonObject, toName?: string): Promise<void>;
/**
* Safely destroys current queue, unregistered all set event
* listeners and connections.
* Supposed to be an async function.
*
* @returns {Promise<void>}
*/
destroy(): Promise<void>;
/**
* Clears queue data in queue host application.
* Supposed to be an async function.
*
* @returns {Promise<IMessageQueue>}
*/
clear(): Promise<IMessageQueue>;
/**
* Retrieves the current count of messages in the queue.
* Supposed to be an async function.
*
* @returns {Promise<number>}
*/
queueLength(): Promise<number>;
}