+242
-1
@@ -1,1 +0,242 @@ | ||
| "use strict";var c=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var h=(t,s)=>{for(var i in s)c(t,i,{get:s[i],enumerable:!0})},l=(t,s,i,e)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of m(s))!g.call(t,r)&&r!==i&&c(t,r,{get:()=>s[r],enumerable:!(e=b(s,r))||e.enumerable});return t};var v=t=>l(c({},"__esModule",{value:!0}),t);var y={};h(y,{MemoryMessageProvider:()=>n,Qified:()=>a,QifiedEvents:()=>d});module.exports=v(y);var p=require("hookified");var P="@qified/memory",n=class{_subscriptions;_id;constructor(s){this._subscriptions=new Map,this._id=s?.id??P}get id(){return this._id}set id(s){this._id=s}get subscriptions(){return this._subscriptions}set subscriptions(s){this._subscriptions=s}async publish(s,i){let e={...i,providerId:this._id},r=this._subscriptions.get(s)??[];for(let u of r)await u.handler(e)}async subscribe(s,i){this._subscriptions.has(s)||this._subscriptions.set(s,[]),this._subscriptions.get(s)?.push(i)}async unsubscribe(s,i){if(i){let e=this._subscriptions.get(s);e&&this._subscriptions.set(s,e.filter(r=>r.id!==i))}else this._subscriptions.delete(s)}async disconnect(){this._subscriptions.clear()}};var d=(o=>(o.error="error",o.info="info",o.warn="warn",o.publish="publish",o.subscribe="subscribe",o.unsubscribe="unsubscribe",o.disconnect="disconnect",o))(d||{}),a=class extends p.Hookified{_messageProviders=[];constructor(s){super(s),s?.messageProviders&&(this._messageProviders=s.messageProviders)}get messageProviders(){return this._messageProviders}set messageProviders(s){this._messageProviders=s}async subscribe(s,i){try{let e=this._messageProviders.map(async r=>r.subscribe(s,i));await Promise.all(e),this.emit("subscribe",{topic:s,handler:i})}catch(e){this.emit("error",e)}}async publish(s,i){try{let e=this._messageProviders.map(async r=>r.publish(s,i));await Promise.all(e),this.emit("publish",{topic:s,message:i})}catch(e){this.emit("error",e)}}async unsubscribe(s,i){try{let e=this._messageProviders.map(async r=>r.unsubscribe(s,i));await Promise.all(e),this.emit("unsubscribe",{topic:s,id:i})}catch(e){this.emit("error",e)}}async disconnect(){try{let s=this._messageProviders.map(async i=>i.disconnect());await Promise.all(s),this._messageProviders=[],this.emit("disconnect")}catch(s){this.emit("error",s)}}};0&&(module.exports={MemoryMessageProvider,Qified,QifiedEvents}); | ||
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/index.ts | ||
| var index_exports = {}; | ||
| __export(index_exports, { | ||
| MemoryMessageProvider: () => MemoryMessageProvider, | ||
| Qified: () => Qified, | ||
| QifiedEvents: () => QifiedEvents | ||
| }); | ||
| module.exports = __toCommonJS(index_exports); | ||
| var import_hookified = require("hookified"); | ||
| // src/memory/message.ts | ||
| var defaultMemoryId = "@qified/memory"; | ||
| var MemoryMessageProvider = class { | ||
| _subscriptions; | ||
| _id; | ||
| /** | ||
| * Creates an instance of MemoryMessageProvider. | ||
| * @param {MemoryMessageProviderOptions} options - Optional configuration for the provider. | ||
| */ | ||
| constructor(options) { | ||
| this._subscriptions = /* @__PURE__ */ new Map(); | ||
| this._id = options?.id ?? defaultMemoryId; | ||
| } | ||
| /** | ||
| * Gets the provider ID for the memory message provider. | ||
| * @returns {string} The provider ID. | ||
| */ | ||
| get id() { | ||
| return this._id; | ||
| } | ||
| /** | ||
| * Sets the provider ID for the memory message provider. | ||
| * @param {string} id The new provider ID. | ||
| */ | ||
| set id(id) { | ||
| this._id = id; | ||
| } | ||
| /** | ||
| * Gets the subscriptions map for all topics. | ||
| * @returns {Map<string, TopicHandler[]>} The subscriptions map. | ||
| */ | ||
| get subscriptions() { | ||
| return this._subscriptions; | ||
| } | ||
| /** | ||
| * Sets the subscriptions map. | ||
| * @param {Map<string, TopicHandler[]>} value The new subscriptions map. | ||
| */ | ||
| set subscriptions(value) { | ||
| this._subscriptions = value; | ||
| } | ||
| /** | ||
| * Publishes a message to a specified topic. | ||
| * All handlers subscribed to the topic will be called synchronously in order. | ||
| * @param {string} topic The topic to publish the message to. | ||
| * @param {Message} message The message to publish. | ||
| * @returns {Promise<void>} A promise that resolves when all handlers have been called. | ||
| */ | ||
| async publish(topic, message) { | ||
| const messageWithProvider = { | ||
| ...message, | ||
| providerId: this._id | ||
| }; | ||
| const subscriptions = this._subscriptions.get(topic) ?? []; | ||
| for (const subscription of subscriptions) { | ||
| await subscription.handler(messageWithProvider); | ||
| } | ||
| } | ||
| /** | ||
| * Subscribes to a specified topic. | ||
| * @param {string} topic The topic to subscribe to. | ||
| * @param {TopicHandler} handler The handler to process incoming messages. | ||
| * @returns {Promise<void>} A promise that resolves when the subscription is complete. | ||
| */ | ||
| async subscribe(topic, handler) { | ||
| if (!this._subscriptions.has(topic)) { | ||
| this._subscriptions.set(topic, []); | ||
| } | ||
| this._subscriptions.get(topic)?.push(handler); | ||
| } | ||
| /** | ||
| * Unsubscribes from a specified topic. | ||
| * If an ID is provided, only the handler with that ID is removed. | ||
| * If no ID is provided, all handlers for the topic are removed. | ||
| * @param {string} topic The topic to unsubscribe from. | ||
| * @param {string} [id] Optional identifier for the subscription to remove. | ||
| * @returns {Promise<void>} A promise that resolves when the unsubscription is complete. | ||
| */ | ||
| async unsubscribe(topic, id) { | ||
| if (id) { | ||
| const subscriptions = this._subscriptions.get(topic); | ||
| if (subscriptions) { | ||
| this._subscriptions.set( | ||
| topic, | ||
| subscriptions.filter((sub) => sub.id !== id) | ||
| ); | ||
| } | ||
| } else { | ||
| this._subscriptions.delete(topic); | ||
| } | ||
| } | ||
| /** | ||
| * Disconnects and clears all subscriptions. | ||
| * @returns {Promise<void>} A promise that resolves when the disconnection is complete. | ||
| */ | ||
| async disconnect() { | ||
| this._subscriptions.clear(); | ||
| } | ||
| }; | ||
| // src/index.ts | ||
| var QifiedEvents = /* @__PURE__ */ ((QifiedEvents2) => { | ||
| QifiedEvents2["error"] = "error"; | ||
| QifiedEvents2["info"] = "info"; | ||
| QifiedEvents2["warn"] = "warn"; | ||
| QifiedEvents2["publish"] = "publish"; | ||
| QifiedEvents2["subscribe"] = "subscribe"; | ||
| QifiedEvents2["unsubscribe"] = "unsubscribe"; | ||
| QifiedEvents2["disconnect"] = "disconnect"; | ||
| return QifiedEvents2; | ||
| })(QifiedEvents || {}); | ||
| var Qified = class extends import_hookified.Hookified { | ||
| _messageProviders = []; | ||
| /** | ||
| * Creates an instance of Qified. | ||
| * @param {QifiedOptions} options - Optional configuration for Qified. | ||
| */ | ||
| constructor(options) { | ||
| super(options); | ||
| if (options?.messageProviders) { | ||
| if (Array.isArray(options?.messageProviders)) { | ||
| this._messageProviders = options.messageProviders; | ||
| } else { | ||
| this._messageProviders = [options?.messageProviders]; | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Gets or sets the message providers. | ||
| * @returns {MessageProvider[]} The array of message providers. | ||
| */ | ||
| get messageProviders() { | ||
| return this._messageProviders; | ||
| } | ||
| /** | ||
| * Sets the message providers. | ||
| * @param {MessageProvider[]} providers - The array of message providers to set. | ||
| */ | ||
| set messageProviders(providers) { | ||
| this._messageProviders = providers; | ||
| } | ||
| /** | ||
| * Subscribes to a topic. If you have multiple message providers, it will subscribe to the topic on all of them. | ||
| * @param {string} topic - The topic to subscribe to. | ||
| * @param {TopicHandler} handler - The handler to call when a message is published to the topic. | ||
| */ | ||
| async subscribe(topic, handler) { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.subscribe(topic, handler) | ||
| ); | ||
| await Promise.all(promises); | ||
| this.emit("subscribe" /* subscribe */, { topic, handler }); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| /** | ||
| * Publishes a message to a topic. If you have multiple message providers, it will publish the message to all of them. | ||
| * @param {string} topic - The topic to publish to. | ||
| * @param {Message} message - The message to publish. | ||
| */ | ||
| async publish(topic, message) { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.publish(topic, message) | ||
| ); | ||
| await Promise.all(promises); | ||
| this.emit("publish" /* publish */, { topic, message }); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| /** | ||
| * Unsubscribes from a topic. If you have multiple message providers, it will unsubscribe from the topic on all of them. | ||
| * If an ID is provided, it will unsubscribe only that handler. If no ID is provided, it will unsubscribe all handlers for the topic. | ||
| * @param topic - The topic to unsubscribe from. | ||
| * @param id - The optional ID of the handler to unsubscribe. If not provided, all handlers for the topic will be unsubscribed. | ||
| */ | ||
| async unsubscribe(topic, id) { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.unsubscribe(topic, id) | ||
| ); | ||
| await Promise.all(promises); | ||
| this.emit("unsubscribe" /* unsubscribe */, { topic, id }); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| /** | ||
| * Disconnects from all providers. | ||
| * This method will call the `disconnect` method on each message provider. | ||
| */ | ||
| async disconnect() { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.disconnect() | ||
| ); | ||
| await Promise.all(promises); | ||
| this._messageProviders = []; | ||
| this.emit("disconnect" /* disconnect */); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| }; | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| MemoryMessageProvider, | ||
| Qified, | ||
| QifiedEvents | ||
| }); |
+145
-27
@@ -16,3 +16,3 @@ import { HookifiedOptions, Hookified } from 'hookified'; | ||
| */ | ||
| providerId: string; | ||
| providerId?: string; | ||
| /** | ||
@@ -94,53 +94,171 @@ * The data of the message | ||
| /** | ||
| * Timestamp of when the task was created | ||
| * Timestamp of when the task was created (milliseconds since epoch) | ||
| * Set automatically by provider if not provided based on Date.now() | ||
| * @type {number} | ||
| */ | ||
| channel: string; | ||
| timestamp?: number; | ||
| /** | ||
| * Timestamp of when the task was created | ||
| * Scheduled time for delayed task execution (milliseconds since epoch) | ||
| * If set, task won't be processed until this time | ||
| * @type {number} | ||
| */ | ||
| scheduledAt?: number; | ||
| /** | ||
| * Headers for additional metadata | ||
| * @type {Record<string, string>} | ||
| */ | ||
| headers?: Record<string, string>; | ||
| /** | ||
| * Priority of the task (higher numbers = higher priority) | ||
| * @type {number} | ||
| * @default 0 | ||
| */ | ||
| priority?: number; | ||
| /** | ||
| * Timestamp of when the task was created | ||
| * Maximum number of retry attempts | ||
| * If undefined, uses provider default | ||
| * @type {number} | ||
| */ | ||
| retries?: number; | ||
| maxRetries?: number; | ||
| /** | ||
| * Maximum processing time in milliseconds before task times out | ||
| * If not set, uses provider default | ||
| * @type {number} | ||
| */ | ||
| timeout?: number; | ||
| }; | ||
| /** | ||
| * TaskProvider interface for the task provider | ||
| * Task type for enqueueing tasks | ||
| * Omits fields that are automatically generated by the provider | ||
| * The provider will assign the id and timestamp when the task is enqueued | ||
| */ | ||
| type TaskProvider = { | ||
| type EnqueueTask = Omit<Task, "id" | "timestamp">; | ||
| /** | ||
| * Context provided to task handlers for acknowledgment and task control | ||
| * Allows handlers to acknowledge, reject, or extend processing time for tasks | ||
| */ | ||
| type TaskContext = { | ||
| /** | ||
| * Array of handlers for task processing | ||
| * @type {Array<{taskName: string; handler: (payload: Task) => Promise<void>}>} | ||
| * Acknowledge successful task completion | ||
| * Removes the task from the queue and marks it as completed | ||
| * @returns {Promise<void>} | ||
| */ | ||
| taskHandlers: Array<{ | ||
| taskName: string; | ||
| handler: (payload: Task) => Promise<void>; | ||
| }>; | ||
| ack: () => Promise<void>; | ||
| /** | ||
| * Array of handlers for task processing | ||
| * @param config - Configuration object for the provider | ||
| * Reject the task with explicit requeue control | ||
| * @param requeue - If true, requeue for retry. If false, send to dead-letter queue. Defaults to true. | ||
| * @returns {Promise<void>} | ||
| */ | ||
| init(config: Record<string, any>): Promise<void>; | ||
| reject: (requeue?: boolean) => Promise<void>; | ||
| /** | ||
| * Publish a task to a queue. This is used to send tasks to subscribers. | ||
| * @param taskName - The name of the task to publish | ||
| * @param payload - The task to be published | ||
| * Extend the visibility timeout / processing deadline | ||
| * Prevents task from being redelivered to another consumer while still processing | ||
| * Useful for long-running tasks that need more time | ||
| * @param ttl - Additional time to live in milliseconds | ||
| * @returns {Promise<void>} | ||
| */ | ||
| enqueue(taskName: string, payload: Task): Promise<void>; | ||
| extend: (ttl: number) => Promise<void>; | ||
| /** | ||
| * Subscribe to a task. This is used to receive tasks from the provider. | ||
| * @param taskName - The name of the task to subscribe to | ||
| * @param handler - The handler function to process the task | ||
| * Metadata about the current task execution | ||
| * Provides context for retry logic and deadline management | ||
| */ | ||
| metadata: { | ||
| /** | ||
| * Current retry attempt (0 = first attempt) | ||
| * @type {number} | ||
| */ | ||
| attempt: number; | ||
| /** | ||
| * Maximum retries allowed for this task | ||
| * @type {number} | ||
| */ | ||
| maxRetries: number; | ||
| }; | ||
| }; | ||
| /** | ||
| * Handler configuration for processing tasks from a queue | ||
| * Defines how tasks should be processed and provides options for error handling | ||
| */ | ||
| type TaskHandler = { | ||
| /** | ||
| * Optional unique identifier for this handler | ||
| * Used to identify and unsubscribe specific handlers | ||
| * @type {string} | ||
| */ | ||
| id?: string; | ||
| /** | ||
| * The handler function to process tasks | ||
| * Called for each task dequeued from the queue | ||
| * @param task - The task to process | ||
| * @param context - Context for acknowledging, rejecting, or extending the task | ||
| * @returns {Promise<void>} | ||
| */ | ||
| dequeue(taskName: string, handler: (payload: Task) => Promise<void>): Promise<void>; | ||
| handler: (task: Task, context: TaskContext) => Promise<void>; | ||
| }; | ||
| /** | ||
| * TaskProvider interface for task queue management | ||
| * Handles enqueueing, dequeueing, and lifecycle management of tasks | ||
| * Implementations should provide reliable task delivery and acknowledgment | ||
| */ | ||
| type TaskProvider = { | ||
| /** | ||
| * Disconnect and clean up the provider. This is used to stop receiving tasks from the provider. | ||
| * Unique identifier for this provider instance | ||
| * Used to distinguish between multiple providers | ||
| * @type {string} | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Default timeout for task processing in milliseconds | ||
| * Can be overridden per task or per handler | ||
| * @type {number} | ||
| */ | ||
| timeout: number; | ||
| /** | ||
| * Default maximum number of retry attempts | ||
| * Can be overridden per task | ||
| * @type {number} | ||
| */ | ||
| retries: number; | ||
| /** | ||
| * Name of the dead-letter queue for failed tasks | ||
| * If not provided, dead-letter functionality is disabled | ||
| * @type {string} | ||
| */ | ||
| deadLetterQueue?: string; | ||
| /** | ||
| * Map of queue names to their registered handlers | ||
| * Tracks all active handlers for each queue | ||
| * @type {Map<string, TaskHandler[]>} | ||
| */ | ||
| taskHandlers: Map<string, TaskHandler[]>; | ||
| /** | ||
| * Enqueue a task to a specific queue for processing | ||
| * The task will be delivered to registered handlers for that queue | ||
| * @param queue - The queue name to enqueue the task to | ||
| * @param task - The task to be enqueued | ||
| * @returns {Promise<string>} - the id of the task being queued | ||
| */ | ||
| enqueue(queue: string, task: EnqueueTask): Promise<string>; | ||
| /** | ||
| * Register a handler to process tasks from a specific queue | ||
| * The handler will be called for each task dequeued from the queue | ||
| * @param queue - The queue name to dequeue tasks from | ||
| * @param handler - The handler configuration for processing tasks | ||
| * @returns {Promise<void>} | ||
| */ | ||
| dequeue(queue: string, handler: TaskHandler): Promise<void>; | ||
| /** | ||
| * Unsubscribe a handler from a queue | ||
| * Stops the handler from receiving new tasks | ||
| * @param queue - The queue name to unsubscribe from | ||
| * @param id - Optional handler ID. If not provided, removes all handlers for the queue | ||
| * @returns {Promise<void>} | ||
| */ | ||
| unsubscribe(queue: string, id?: string): Promise<void>; | ||
| /** | ||
| * Disconnect and clean up the provider | ||
| * Stops receiving tasks, closes connections, and releases resources | ||
| * Should be called before application shutdown | ||
| * @returns {Promise<void>} | ||
| */ | ||
| disconnect(): Promise<void>; | ||
@@ -238,3 +356,3 @@ }; | ||
| */ | ||
| messageProviders?: MessageProvider[]; | ||
| messageProviders?: MessageProvider | MessageProvider[]; | ||
| /** | ||
@@ -241,0 +359,0 @@ * The task providers to use. |
+145
-27
@@ -16,3 +16,3 @@ import { HookifiedOptions, Hookified } from 'hookified'; | ||
| */ | ||
| providerId: string; | ||
| providerId?: string; | ||
| /** | ||
@@ -94,53 +94,171 @@ * The data of the message | ||
| /** | ||
| * Timestamp of when the task was created | ||
| * Timestamp of when the task was created (milliseconds since epoch) | ||
| * Set automatically by provider if not provided based on Date.now() | ||
| * @type {number} | ||
| */ | ||
| channel: string; | ||
| timestamp?: number; | ||
| /** | ||
| * Timestamp of when the task was created | ||
| * Scheduled time for delayed task execution (milliseconds since epoch) | ||
| * If set, task won't be processed until this time | ||
| * @type {number} | ||
| */ | ||
| scheduledAt?: number; | ||
| /** | ||
| * Headers for additional metadata | ||
| * @type {Record<string, string>} | ||
| */ | ||
| headers?: Record<string, string>; | ||
| /** | ||
| * Priority of the task (higher numbers = higher priority) | ||
| * @type {number} | ||
| * @default 0 | ||
| */ | ||
| priority?: number; | ||
| /** | ||
| * Timestamp of when the task was created | ||
| * Maximum number of retry attempts | ||
| * If undefined, uses provider default | ||
| * @type {number} | ||
| */ | ||
| retries?: number; | ||
| maxRetries?: number; | ||
| /** | ||
| * Maximum processing time in milliseconds before task times out | ||
| * If not set, uses provider default | ||
| * @type {number} | ||
| */ | ||
| timeout?: number; | ||
| }; | ||
| /** | ||
| * TaskProvider interface for the task provider | ||
| * Task type for enqueueing tasks | ||
| * Omits fields that are automatically generated by the provider | ||
| * The provider will assign the id and timestamp when the task is enqueued | ||
| */ | ||
| type TaskProvider = { | ||
| type EnqueueTask = Omit<Task, "id" | "timestamp">; | ||
| /** | ||
| * Context provided to task handlers for acknowledgment and task control | ||
| * Allows handlers to acknowledge, reject, or extend processing time for tasks | ||
| */ | ||
| type TaskContext = { | ||
| /** | ||
| * Array of handlers for task processing | ||
| * @type {Array<{taskName: string; handler: (payload: Task) => Promise<void>}>} | ||
| * Acknowledge successful task completion | ||
| * Removes the task from the queue and marks it as completed | ||
| * @returns {Promise<void>} | ||
| */ | ||
| taskHandlers: Array<{ | ||
| taskName: string; | ||
| handler: (payload: Task) => Promise<void>; | ||
| }>; | ||
| ack: () => Promise<void>; | ||
| /** | ||
| * Array of handlers for task processing | ||
| * @param config - Configuration object for the provider | ||
| * Reject the task with explicit requeue control | ||
| * @param requeue - If true, requeue for retry. If false, send to dead-letter queue. Defaults to true. | ||
| * @returns {Promise<void>} | ||
| */ | ||
| init(config: Record<string, any>): Promise<void>; | ||
| reject: (requeue?: boolean) => Promise<void>; | ||
| /** | ||
| * Publish a task to a queue. This is used to send tasks to subscribers. | ||
| * @param taskName - The name of the task to publish | ||
| * @param payload - The task to be published | ||
| * Extend the visibility timeout / processing deadline | ||
| * Prevents task from being redelivered to another consumer while still processing | ||
| * Useful for long-running tasks that need more time | ||
| * @param ttl - Additional time to live in milliseconds | ||
| * @returns {Promise<void>} | ||
| */ | ||
| enqueue(taskName: string, payload: Task): Promise<void>; | ||
| extend: (ttl: number) => Promise<void>; | ||
| /** | ||
| * Subscribe to a task. This is used to receive tasks from the provider. | ||
| * @param taskName - The name of the task to subscribe to | ||
| * @param handler - The handler function to process the task | ||
| * Metadata about the current task execution | ||
| * Provides context for retry logic and deadline management | ||
| */ | ||
| metadata: { | ||
| /** | ||
| * Current retry attempt (0 = first attempt) | ||
| * @type {number} | ||
| */ | ||
| attempt: number; | ||
| /** | ||
| * Maximum retries allowed for this task | ||
| * @type {number} | ||
| */ | ||
| maxRetries: number; | ||
| }; | ||
| }; | ||
| /** | ||
| * Handler configuration for processing tasks from a queue | ||
| * Defines how tasks should be processed and provides options for error handling | ||
| */ | ||
| type TaskHandler = { | ||
| /** | ||
| * Optional unique identifier for this handler | ||
| * Used to identify and unsubscribe specific handlers | ||
| * @type {string} | ||
| */ | ||
| id?: string; | ||
| /** | ||
| * The handler function to process tasks | ||
| * Called for each task dequeued from the queue | ||
| * @param task - The task to process | ||
| * @param context - Context for acknowledging, rejecting, or extending the task | ||
| * @returns {Promise<void>} | ||
| */ | ||
| dequeue(taskName: string, handler: (payload: Task) => Promise<void>): Promise<void>; | ||
| handler: (task: Task, context: TaskContext) => Promise<void>; | ||
| }; | ||
| /** | ||
| * TaskProvider interface for task queue management | ||
| * Handles enqueueing, dequeueing, and lifecycle management of tasks | ||
| * Implementations should provide reliable task delivery and acknowledgment | ||
| */ | ||
| type TaskProvider = { | ||
| /** | ||
| * Disconnect and clean up the provider. This is used to stop receiving tasks from the provider. | ||
| * Unique identifier for this provider instance | ||
| * Used to distinguish between multiple providers | ||
| * @type {string} | ||
| */ | ||
| id: string; | ||
| /** | ||
| * Default timeout for task processing in milliseconds | ||
| * Can be overridden per task or per handler | ||
| * @type {number} | ||
| */ | ||
| timeout: number; | ||
| /** | ||
| * Default maximum number of retry attempts | ||
| * Can be overridden per task | ||
| * @type {number} | ||
| */ | ||
| retries: number; | ||
| /** | ||
| * Name of the dead-letter queue for failed tasks | ||
| * If not provided, dead-letter functionality is disabled | ||
| * @type {string} | ||
| */ | ||
| deadLetterQueue?: string; | ||
| /** | ||
| * Map of queue names to their registered handlers | ||
| * Tracks all active handlers for each queue | ||
| * @type {Map<string, TaskHandler[]>} | ||
| */ | ||
| taskHandlers: Map<string, TaskHandler[]>; | ||
| /** | ||
| * Enqueue a task to a specific queue for processing | ||
| * The task will be delivered to registered handlers for that queue | ||
| * @param queue - The queue name to enqueue the task to | ||
| * @param task - The task to be enqueued | ||
| * @returns {Promise<string>} - the id of the task being queued | ||
| */ | ||
| enqueue(queue: string, task: EnqueueTask): Promise<string>; | ||
| /** | ||
| * Register a handler to process tasks from a specific queue | ||
| * The handler will be called for each task dequeued from the queue | ||
| * @param queue - The queue name to dequeue tasks from | ||
| * @param handler - The handler configuration for processing tasks | ||
| * @returns {Promise<void>} | ||
| */ | ||
| dequeue(queue: string, handler: TaskHandler): Promise<void>; | ||
| /** | ||
| * Unsubscribe a handler from a queue | ||
| * Stops the handler from receiving new tasks | ||
| * @param queue - The queue name to unsubscribe from | ||
| * @param id - Optional handler ID. If not provided, removes all handlers for the queue | ||
| * @returns {Promise<void>} | ||
| */ | ||
| unsubscribe(queue: string, id?: string): Promise<void>; | ||
| /** | ||
| * Disconnect and clean up the provider | ||
| * Stops receiving tasks, closes connections, and releases resources | ||
| * Should be called before application shutdown | ||
| * @returns {Promise<void>} | ||
| */ | ||
| disconnect(): Promise<void>; | ||
@@ -238,3 +356,3 @@ }; | ||
| */ | ||
| messageProviders?: MessageProvider[]; | ||
| messageProviders?: MessageProvider | MessageProvider[]; | ||
| /** | ||
@@ -241,0 +359,0 @@ * The task providers to use. |
+215
-1
@@ -1,1 +0,215 @@ | ||
| import{Hookified as d}from"hookified";var p="@qified/memory",o=class{_subscriptions;_id;constructor(s){this._subscriptions=new Map,this._id=s?.id??p}get id(){return this._id}set id(s){this._id=s}get subscriptions(){return this._subscriptions}set subscriptions(s){this._subscriptions=s}async publish(s,i){let e={...i,providerId:this._id},r=this._subscriptions.get(s)??[];for(let a of r)await a.handler(e)}async subscribe(s,i){this._subscriptions.has(s)||this._subscriptions.set(s,[]),this._subscriptions.get(s)?.push(i)}async unsubscribe(s,i){if(i){let e=this._subscriptions.get(s);e&&this._subscriptions.set(s,e.filter(r=>r.id!==i))}else this._subscriptions.delete(s)}async disconnect(){this._subscriptions.clear()}};var u=(t=>(t.error="error",t.info="info",t.warn="warn",t.publish="publish",t.subscribe="subscribe",t.unsubscribe="unsubscribe",t.disconnect="disconnect",t))(u||{}),n=class extends d{_messageProviders=[];constructor(s){super(s),s?.messageProviders&&(this._messageProviders=s.messageProviders)}get messageProviders(){return this._messageProviders}set messageProviders(s){this._messageProviders=s}async subscribe(s,i){try{let e=this._messageProviders.map(async r=>r.subscribe(s,i));await Promise.all(e),this.emit("subscribe",{topic:s,handler:i})}catch(e){this.emit("error",e)}}async publish(s,i){try{let e=this._messageProviders.map(async r=>r.publish(s,i));await Promise.all(e),this.emit("publish",{topic:s,message:i})}catch(e){this.emit("error",e)}}async unsubscribe(s,i){try{let e=this._messageProviders.map(async r=>r.unsubscribe(s,i));await Promise.all(e),this.emit("unsubscribe",{topic:s,id:i})}catch(e){this.emit("error",e)}}async disconnect(){try{let s=this._messageProviders.map(async i=>i.disconnect());await Promise.all(s),this._messageProviders=[],this.emit("disconnect")}catch(s){this.emit("error",s)}}};export{o as MemoryMessageProvider,n as Qified,u as QifiedEvents}; | ||
| // src/index.ts | ||
| import { Hookified } from "hookified"; | ||
| // src/memory/message.ts | ||
| var defaultMemoryId = "@qified/memory"; | ||
| var MemoryMessageProvider = class { | ||
| _subscriptions; | ||
| _id; | ||
| /** | ||
| * Creates an instance of MemoryMessageProvider. | ||
| * @param {MemoryMessageProviderOptions} options - Optional configuration for the provider. | ||
| */ | ||
| constructor(options) { | ||
| this._subscriptions = /* @__PURE__ */ new Map(); | ||
| this._id = options?.id ?? defaultMemoryId; | ||
| } | ||
| /** | ||
| * Gets the provider ID for the memory message provider. | ||
| * @returns {string} The provider ID. | ||
| */ | ||
| get id() { | ||
| return this._id; | ||
| } | ||
| /** | ||
| * Sets the provider ID for the memory message provider. | ||
| * @param {string} id The new provider ID. | ||
| */ | ||
| set id(id) { | ||
| this._id = id; | ||
| } | ||
| /** | ||
| * Gets the subscriptions map for all topics. | ||
| * @returns {Map<string, TopicHandler[]>} The subscriptions map. | ||
| */ | ||
| get subscriptions() { | ||
| return this._subscriptions; | ||
| } | ||
| /** | ||
| * Sets the subscriptions map. | ||
| * @param {Map<string, TopicHandler[]>} value The new subscriptions map. | ||
| */ | ||
| set subscriptions(value) { | ||
| this._subscriptions = value; | ||
| } | ||
| /** | ||
| * Publishes a message to a specified topic. | ||
| * All handlers subscribed to the topic will be called synchronously in order. | ||
| * @param {string} topic The topic to publish the message to. | ||
| * @param {Message} message The message to publish. | ||
| * @returns {Promise<void>} A promise that resolves when all handlers have been called. | ||
| */ | ||
| async publish(topic, message) { | ||
| const messageWithProvider = { | ||
| ...message, | ||
| providerId: this._id | ||
| }; | ||
| const subscriptions = this._subscriptions.get(topic) ?? []; | ||
| for (const subscription of subscriptions) { | ||
| await subscription.handler(messageWithProvider); | ||
| } | ||
| } | ||
| /** | ||
| * Subscribes to a specified topic. | ||
| * @param {string} topic The topic to subscribe to. | ||
| * @param {TopicHandler} handler The handler to process incoming messages. | ||
| * @returns {Promise<void>} A promise that resolves when the subscription is complete. | ||
| */ | ||
| async subscribe(topic, handler) { | ||
| if (!this._subscriptions.has(topic)) { | ||
| this._subscriptions.set(topic, []); | ||
| } | ||
| this._subscriptions.get(topic)?.push(handler); | ||
| } | ||
| /** | ||
| * Unsubscribes from a specified topic. | ||
| * If an ID is provided, only the handler with that ID is removed. | ||
| * If no ID is provided, all handlers for the topic are removed. | ||
| * @param {string} topic The topic to unsubscribe from. | ||
| * @param {string} [id] Optional identifier for the subscription to remove. | ||
| * @returns {Promise<void>} A promise that resolves when the unsubscription is complete. | ||
| */ | ||
| async unsubscribe(topic, id) { | ||
| if (id) { | ||
| const subscriptions = this._subscriptions.get(topic); | ||
| if (subscriptions) { | ||
| this._subscriptions.set( | ||
| topic, | ||
| subscriptions.filter((sub) => sub.id !== id) | ||
| ); | ||
| } | ||
| } else { | ||
| this._subscriptions.delete(topic); | ||
| } | ||
| } | ||
| /** | ||
| * Disconnects and clears all subscriptions. | ||
| * @returns {Promise<void>} A promise that resolves when the disconnection is complete. | ||
| */ | ||
| async disconnect() { | ||
| this._subscriptions.clear(); | ||
| } | ||
| }; | ||
| // src/index.ts | ||
| var QifiedEvents = /* @__PURE__ */ ((QifiedEvents2) => { | ||
| QifiedEvents2["error"] = "error"; | ||
| QifiedEvents2["info"] = "info"; | ||
| QifiedEvents2["warn"] = "warn"; | ||
| QifiedEvents2["publish"] = "publish"; | ||
| QifiedEvents2["subscribe"] = "subscribe"; | ||
| QifiedEvents2["unsubscribe"] = "unsubscribe"; | ||
| QifiedEvents2["disconnect"] = "disconnect"; | ||
| return QifiedEvents2; | ||
| })(QifiedEvents || {}); | ||
| var Qified = class extends Hookified { | ||
| _messageProviders = []; | ||
| /** | ||
| * Creates an instance of Qified. | ||
| * @param {QifiedOptions} options - Optional configuration for Qified. | ||
| */ | ||
| constructor(options) { | ||
| super(options); | ||
| if (options?.messageProviders) { | ||
| if (Array.isArray(options?.messageProviders)) { | ||
| this._messageProviders = options.messageProviders; | ||
| } else { | ||
| this._messageProviders = [options?.messageProviders]; | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Gets or sets the message providers. | ||
| * @returns {MessageProvider[]} The array of message providers. | ||
| */ | ||
| get messageProviders() { | ||
| return this._messageProviders; | ||
| } | ||
| /** | ||
| * Sets the message providers. | ||
| * @param {MessageProvider[]} providers - The array of message providers to set. | ||
| */ | ||
| set messageProviders(providers) { | ||
| this._messageProviders = providers; | ||
| } | ||
| /** | ||
| * Subscribes to a topic. If you have multiple message providers, it will subscribe to the topic on all of them. | ||
| * @param {string} topic - The topic to subscribe to. | ||
| * @param {TopicHandler} handler - The handler to call when a message is published to the topic. | ||
| */ | ||
| async subscribe(topic, handler) { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.subscribe(topic, handler) | ||
| ); | ||
| await Promise.all(promises); | ||
| this.emit("subscribe" /* subscribe */, { topic, handler }); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| /** | ||
| * Publishes a message to a topic. If you have multiple message providers, it will publish the message to all of them. | ||
| * @param {string} topic - The topic to publish to. | ||
| * @param {Message} message - The message to publish. | ||
| */ | ||
| async publish(topic, message) { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.publish(topic, message) | ||
| ); | ||
| await Promise.all(promises); | ||
| this.emit("publish" /* publish */, { topic, message }); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| /** | ||
| * Unsubscribes from a topic. If you have multiple message providers, it will unsubscribe from the topic on all of them. | ||
| * If an ID is provided, it will unsubscribe only that handler. If no ID is provided, it will unsubscribe all handlers for the topic. | ||
| * @param topic - The topic to unsubscribe from. | ||
| * @param id - The optional ID of the handler to unsubscribe. If not provided, all handlers for the topic will be unsubscribed. | ||
| */ | ||
| async unsubscribe(topic, id) { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.unsubscribe(topic, id) | ||
| ); | ||
| await Promise.all(promises); | ||
| this.emit("unsubscribe" /* unsubscribe */, { topic, id }); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| /** | ||
| * Disconnects from all providers. | ||
| * This method will call the `disconnect` method on each message provider. | ||
| */ | ||
| async disconnect() { | ||
| try { | ||
| const promises = this._messageProviders.map( | ||
| async (provider) => provider.disconnect() | ||
| ); | ||
| await Promise.all(promises); | ||
| this._messageProviders = []; | ||
| this.emit("disconnect" /* disconnect */); | ||
| } catch (error) { | ||
| this.emit("error" /* error */, error); | ||
| } | ||
| } | ||
| }; | ||
| export { | ||
| MemoryMessageProvider, | ||
| Qified, | ||
| QifiedEvents | ||
| }; |
+4
-4
| { | ||
| "name": "qified", | ||
| "version": "0.5.0", | ||
| "version": "0.5.1", | ||
| "description": "Task and Message Queues with Multiple Providers", | ||
@@ -36,3 +36,3 @@ "type": "module", | ||
| "devDependencies": { | ||
| "@biomejs/biome": "^2.2.5", | ||
| "@biomejs/biome": "^2.2.6", | ||
| "@vitest/coverage-v8": "^3.2.4", | ||
@@ -49,3 +49,3 @@ "rimraf": "^6.0.1", | ||
| "dependencies": { | ||
| "hookified": "^1.12.1" | ||
| "hookified": "^1.12.2" | ||
| }, | ||
@@ -57,5 +57,5 @@ "scripts": { | ||
| "clean": "rimraf ./dist ./coverage ./site/dist", | ||
| "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean --minify", | ||
| "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean", | ||
| "build:publish": "pnpm build && pnpm publish --access public --no-git-checks" | ||
| } | ||
| } |
+6
-6
@@ -45,3 +45,3 @@ [](https://qified.org) | ||
| const qified = new Qified({ | ||
| messageProviders: [new MemoryMessageProvider()] | ||
| messageProviders: new MemoryMessageProvider() | ||
| }); | ||
@@ -74,3 +74,3 @@ | ||
| **Options:** | ||
| - `messageProviders?: MessageProvider[]` - Array of message providers to use | ||
| - `messageProviders?: MessageProvider | MessageProvider[]` - a provider or Array of message providers to use | ||
| - `taskProviders?: TaskProvider[]` - Array of task providers to use | ||
@@ -83,3 +83,3 @@ | ||
| const qified = new Qified({ | ||
| messageProviders: [new MemoryMessageProvider()] | ||
| messageProviders: new MemoryMessageProvider() | ||
| }); | ||
@@ -115,3 +115,3 @@ ``` | ||
| const qified = new Qified({ | ||
| messageProviders: [new MemoryMessageProvider()] | ||
| messageProviders: new MemoryMessageProvider() | ||
| }); | ||
@@ -238,3 +238,3 @@ | ||
| const qified = new Qified({ | ||
| messageProviders: [new MemoryMessageProvider()] | ||
| messageProviders: new MemoryMessageProvider() | ||
| }); | ||
@@ -298,3 +298,3 @@ | ||
| const qified = new Qified({ | ||
| messageProviders: [new NatsMessageProvider()] | ||
| messageProviders: new NatsMessageProvider() | ||
| }); | ||
@@ -301,0 +301,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
54914
52.79%851
184.62%1
-66.67%Updated