rapid-mq
Version:
A simple and fast RabbitMQ client for Node.js
2 lines • 6.45 kB
JavaScript
import*as m from"amqplib";var u=class{async encode(n){let e=typeof n,t;return e==="object"&&n instanceof Date&&(e="date",n=n.getTime()),t=JSON.stringify([e,n]),Buffer.from(t,"utf-8")}async decode(n){let[e,t]=JSON.parse(n.toString("utf-8"));switch(e){case"date":return new Date(t);default:return t}}};var _=class{constructor(n){this.options=n;this._connection=null;this._isConnected=!1;if(!n.url)throw new Error("URL is required");if(!n.appId)throw new Error("App ID is required");this._url=n.url,this._appId=n.appId,this._encoder=n.encoder||new u}async connect(){if(!this._isConnected)try{this._connection=await m.connect(this._url),this._isConnected=!0}catch(n){throw this._isConnected=!1,n}}async disconnect(){if(!(!this._isConnected||!this._connection))try{await this._connection.close(),this._isConnected=!1,this._connection=null}catch(n){throw n}}get connection(){if(!this._isConnected||!this._connection)throw new Error("Connection is not established");return this._connection}get connected(){return this._isConnected}get appId(){return this._appId}get encoder(){return this._encoder}};var a=class{constructor(n,e,t,r){this._connector=n;this._exchangeName=e;this._durable=t;this._exclusive=r}get connector(){return this._connector}get exchangeName(){return this._exchangeName}};var g=class extends a{constructor(e){if(!e.connector)throw new Error("RapidConnector is required");if(!e.appGroup)throw new Error("App group is required");super(e.connector,e.exchangeName||"pubsub-exchange",e.durable??!0,e.exclusive??!1);this._channel=null;this._appGroup=e.appGroup}get appGroup(){return this._appGroup}async initialize(){if(this._connector.connected||await this._connector.connect(),this._channel=await this._connector.connection.createChannel(),!this._channel)throw new Error("Connection is not established");await this._channel.assertExchange(this._exchangeName,"topic",{durable:this._durable})}async publish(e,t,r){if(!this._channel)throw new Error("Channel is not initialized");let i=await this._connector.encoder.encode(t,this._exchangeName,e);return this._channel.publish(this._exchangeName,e,i,{expiration:r})}async subscribe(e,t){if(!this._channel)throw new Error("Channel is not initialized");let r=await this._channel.assertQueue(`${this._appGroup}.${e}`,{durable:this._durable,exclusive:this._exclusive});await this._channel.bindQueue(r.queue,this._exchangeName,e),await this._channel.bindQueue(r.queue,this._exchangeName,`${this._appGroup}.${e}`),this._channel.consume(r.queue,async i=>{try{if(i!==null){let o=await this._connector.encoder.decode(i.content,this._exchangeName,e);await t(o)}}catch(o){console.error("Error processing message:",o)}},{noAck:!0})}};import*as f from"crypto";import{EventEmitter as C}from"stream";var w=class extends a{constructor(e){if(!e.connector)throw new Error("RapidConnector is required");super(e.connector,e.exchangeName||"rpc-exchange",e.durable??!0,e.exclusive??!1);this._channel=null;this._responseQueue="amq.rabbitmq.reply-to";this._timeout=(e.timeoutInSec||5)*1e3,this._emitter=e.emitter||new C}async initialize(){if(this._connector.connected||await this._connector.connect(),this._channel=await this._connector.connection.createChannel(),!this._channel)throw new Error("Connection is not established");await this._channel.assertExchange(this._exchangeName,"direct",{durable:this._durable}),this._channel.consume(this._responseQueue,e=>{e&&e.properties.correlationId&&this._emitter.emit(`rpc:${e.properties.correlationId}`,e.content)},{noAck:!0})}async call(e,...t){if(!this._channel)throw new Error("Channel is not initialized");return new Promise(async(r,i)=>{let o=f.randomUUID(),l=await this._connector.encoder.encode(t,this._exchangeName,e),b=setTimeout(()=>{this._emitter.removeListener(`rpc:${o}`,p),i(new Error(`RPC call to ${e} timed out after ${this._timeout/1e3} seconds`))},this._timeout),p=async d=>{if(clearTimeout(b),d){let v=await this._connector.encoder.decode(d,this._exchangeName,e);r(v)}else i(new Error(`No response received for RPC call to ${e}`))};this._emitter.once(`rpc:${o}`,p),this._channel.publish(this._exchangeName,e,l,{replyTo:this._responseQueue,correlationId:o,expiration:this._timeout})})}async server(e,t){if(!this._channel)throw new Error("Channel is not initialized");let r=await this._channel.assertQueue(e,{durable:this._durable,exclusive:this._exclusive});await this._channel.bindQueue(r.queue,this._exchangeName,e),this._channel.consume(r.queue,async i=>{try{if(i!==null){let o=await this._connector.encoder.decode(i.content,this._exchangeName,e),l=await t(...o);i.properties.replyTo&&i.properties.correlationId&&this._channel.sendToQueue(i.properties.replyTo,await this._connector.encoder.encode(l,this._exchangeName,e),{correlationId:i.properties.correlationId})}}catch(o){console.error(`Error processing RPC call for method ${e}:`,o)}},{noAck:!0})}};var x=class extends a{constructor(e){if(!e.connector)throw new Error("RapidConnector is required");if(!e.consumerTag)throw new Error("Consumer tag is required");super(e.connector,e.exchangeName||"direct-exchange",e.durable??!0,e.exclusive??!1);this._channel=null;this._consumerTag=e.consumerTag}get consumerTag(){return this._consumerTag}async initialize(){if(this._connector.connected||await this._connector.connect(),this._channel=await this._connector.connection.createChannel(),!this._channel)throw new Error("Connection is not established");await this._channel.assertExchange(this._exchangeName,"direct",{durable:this._durable});let e=await this._channel.assertQueue(`${this._consumerTag}.queue`,{durable:this._durable,exclusive:this._exclusive});await this._channel.bindQueue(e.queue,this._exchangeName,e.queue),await this._channel.bindQueue(e.queue,this._exchangeName,this._consumerTag)}async send(e,t,r){if(!this._channel)throw new Error("Channel is not initialized");let i=await this._connector.encoder.encode(t,this._exchangeName,e);return this._channel.publish(this._exchangeName,e,i,{expiration:r})}async listen(e){if(!this._channel)throw new Error("Channel is not initialized");await this._channel.consume(`${this._consumerTag}.queue`,async t=>{try{if(t&&t.content){let r=await this._connector.encoder.decode(t.content,this._exchangeName,this._consumerTag);await e(r)}}catch(r){console.error("Error processing message:",r)}},{noAck:!0})}};export{u as DefaultRapidEncoder,x as DirectMessager,g as PubSubMessager,_ as RapidConnector,w as RpcMessager};
//# sourceMappingURL=index.mjs.map