Comparing version 8.2.2 to 8.2.3
@@ -89,3 +89,3 @@ "use strict"; | ||
if (exchange) { | ||
if (type && exchange.type !== type) throw new _Errors.SmqpError('Type doesn\'t match', _Errors.ERR_EXCHANGE_TYPE_MISMATCH); | ||
if (type && exchange.type !== type) throw new _Errors.SmqpError("Type doesn't match", _Errors.ERR_EXCHANGE_TYPE_MISMATCH); | ||
return exchange; | ||
@@ -298,3 +298,3 @@ } | ||
if (!queue) return this.createQueue(queueName, options); | ||
if (queue.options.durable !== options.durable) throw new _Errors.SmqpError('Durable doesn\'t match', _Errors.ERR_QUEUE_DURABLE_MISMATCH); | ||
if (queue.options.durable !== options.durable) throw new _Errors.SmqpError("Durable doesn't match", _Errors.ERR_QUEUE_DURABLE_MISMATCH); | ||
return queue; | ||
@@ -301,0 +301,0 @@ }; |
{ | ||
"name": "smqp", | ||
"version": "8.2.2", | ||
"version": "8.2.3", | ||
"type": "module", | ||
@@ -40,4 +40,4 @@ "description": "Synchronous message queueing package", | ||
"prepack": "npm run dist", | ||
"toc": "node ./scripts/generate-api-toc.cjs", | ||
"lint": "eslint . --cache" | ||
"toc": "node ./scripts/generate-api-toc.js", | ||
"lint": "eslint . --cache && prettier . -c --cache" | ||
}, | ||
@@ -62,13 +62,15 @@ "keywords": [ | ||
"devDependencies": { | ||
"@babel/cli": "^7.23.9", | ||
"@babel/core": "^7.23.9", | ||
"@babel/preset-env": "^7.23.9", | ||
"@babel/cli": "^7.24.1", | ||
"@babel/core": "^7.24.4", | ||
"@babel/preset-env": "^7.24.4", | ||
"c8": "^9.1.0", | ||
"chai": "^5.0.3", | ||
"chai": "^5.1.0", | ||
"chronokinesis": "^6.0.0", | ||
"eslint": "^8.56.0", | ||
"eslint-config-exp": "^0.6.2", | ||
"eslint": "^9.0.0", | ||
"markdown-toc": "^1.2.0", | ||
"mocha": "^10.2.0" | ||
"mocha": "^10.4.0" | ||
}, | ||
"dependencies": { | ||
"prettier": "^3.2.5" | ||
} | ||
} |
@@ -1,3 +0,2 @@ | ||
SMQP | ||
==== | ||
# SMQP | ||
@@ -11,2 +10,3 @@ [![Build](https://github.com/paed01/smqp/actions/workflows/build.yaml/badge.svg)](https://github.com/paed01/smqp/actions/workflows/build.yaml)[![Build status](https://ci.appveyor.com/api/projects/status/8dy3yrde5pe8mk6m/branch/default?svg=true)](https://ci.appveyor.com/project/paed01/smqp/branch/default)[![Coverage Status](https://coveralls.io/repos/github/paed01/smqp/badge.svg?branch=default)](https://coveralls.io/github/paed01/smqp?branch=default)[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) | ||
# Documentation | ||
- [API](/API.md) | ||
@@ -17,5 +17,5 @@ | ||
```javascript | ||
import {Broker} from 'smqp'; | ||
import { Broker } from 'smqp'; | ||
const owner = {name: 'me'}; | ||
const owner = { name: 'me' }; | ||
const broker = Broker(owner); | ||
@@ -25,3 +25,3 @@ | ||
broker.publish('events', 'start', {arg: 1}); | ||
broker.publish('events', 'start', { arg: 1 }); | ||
@@ -34,1 +34,2 @@ function onMessage(routingKey, message, brokerOwner) { | ||
} | ||
``` |
@@ -5,3 +5,11 @@ import { Exchange, EventExchange } from './Exchange.js'; | ||
import { generateId } from './shared.js'; | ||
import { SmqpError, ERR_EXCHANGE_TYPE_MISMATCH, ERR_QUEUE_DURABLE_MISMATCH, ERR_CONSUMER_TAG_CONFLICT, ERR_QUEUE_NAME_CONFLICT, ERR_SHOVEL_NAME_CONFLICT, ERR_QUEUE_NOT_FOUND } from './Errors.js'; | ||
import { | ||
SmqpError, | ||
ERR_EXCHANGE_TYPE_MISMATCH, | ||
ERR_QUEUE_DURABLE_MISMATCH, | ||
ERR_CONSUMER_TAG_CONFLICT, | ||
ERR_QUEUE_NAME_CONFLICT, | ||
ERR_SHOVEL_NAME_CONFLICT, | ||
ERR_QUEUE_NOT_FOUND, | ||
} from './Errors.js'; | ||
@@ -17,3 +25,3 @@ const kEntities = Symbol.for('entities'); | ||
this.events = new EventExchange('broker__events'); | ||
const entities = this[kEntities] = { | ||
const entities = (this[kEntities] = { | ||
exchanges: [], | ||
@@ -23,3 +31,3 @@ queues: [], | ||
shovels: [], | ||
}; | ||
}); | ||
this[kEventHandler] = new EventHandler(this, entities); | ||
@@ -47,3 +55,4 @@ } | ||
Broker.prototype.subscribe = function subscribe(exchangeName, pattern, queueName, onMessage, options = { durable: true }) { | ||
if (!exchangeName || !pattern || typeof onMessage !== 'function') throw new TypeError('exchange name, pattern, and message callback are required'); | ||
if (!exchangeName || !pattern || typeof onMessage !== 'function') | ||
throw new TypeError('exchange name, pattern, and message callback are required'); | ||
if (options && options.consumerTag) this.validateConsumerTag(options.consumerTag); | ||
@@ -90,3 +99,3 @@ | ||
if (exchange) { | ||
if (type && exchange.type !== type) throw new SmqpError('Type doesn\'t match', ERR_EXCHANGE_TYPE_MISMATCH); | ||
if (type && exchange.type !== type) throw new SmqpError("Type doesn't match", ERR_EXCHANGE_TYPE_MISMATCH); | ||
return exchange; | ||
@@ -207,3 +216,4 @@ } | ||
} | ||
if (state.exchanges) for (const eState of state.exchanges) this.assertExchange(eState.name, eState.type, eState.options).recover(eState, boundGetQueue); | ||
if (state.exchanges) | ||
for (const eState of state.exchanges) this.assertExchange(eState.name, eState.type, eState.options).recover(eState, boundGetQueue); | ||
} else { | ||
@@ -225,12 +235,17 @@ const { queues, exchanges } = this[kEntities]; | ||
const { priority } = args; | ||
const shovel = this.createShovel(name, { | ||
broker: this, | ||
exchange: source, | ||
pattern, | ||
priority, | ||
consumerTag: `smq.ctag-${name}`, | ||
}, { | ||
broker: this, | ||
exchange: destination, | ||
}, { ...args }); | ||
const shovel = this.createShovel( | ||
name, | ||
{ | ||
broker: this, | ||
exchange: source, | ||
pattern, | ||
priority, | ||
consumerTag: `smq.ctag-${name}`, | ||
}, | ||
{ | ||
broker: this, | ||
exchange: destination, | ||
}, | ||
{ ...args }, | ||
); | ||
@@ -313,3 +328,3 @@ return new Exchange2Exchange(shovel); | ||
if (queue.options.durable !== options.durable) throw new SmqpError('Durable doesn\'t match', ERR_QUEUE_DURABLE_MISMATCH); | ||
if (queue.options.durable !== options.durable) throw new SmqpError("Durable doesn't match", ERR_QUEUE_DURABLE_MISMATCH); | ||
return queue; | ||
@@ -316,0 +331,0 @@ }; |
@@ -10,3 +10,3 @@ import { Message } from './Message.js'; | ||
const exchangeTypes = [ 'topic', 'direct' ]; | ||
const exchangeTypes = ['topic', 'direct']; | ||
@@ -34,3 +34,3 @@ export function Exchange(name, type = 'topic', options) { | ||
const deliveryQueue = this[kDeliveryQueue] = new Queue('delivery-q', { autoDelete: false }); | ||
const deliveryQueue = (this[kDeliveryQueue] = new Queue('delivery-q', { autoDelete: false })); | ||
const onMessage = (type === 'topic' ? this._onTopicMessage : this._onDirectMessage).bind(this); | ||
@@ -72,6 +72,9 @@ deliveryQueue.consume(onMessage, { exclusive: true, consumerTag: '_exchange-tag' }); | ||
return this[kDeliveryQueue].queueMessage({ routingKey }, { | ||
content, | ||
properties, | ||
}); | ||
return this[kDeliveryQueue].queueMessage( | ||
{ routingKey }, | ||
{ | ||
content, | ||
properties, | ||
}, | ||
); | ||
}; | ||
@@ -155,3 +158,3 @@ | ||
const [ binding ] = bindings.splice(idx, 1); | ||
const [binding] = bindings.splice(idx, 1); | ||
binding.close(); | ||
@@ -158,0 +161,0 @@ |
@@ -7,3 +7,3 @@ import { generateId } from './shared.js'; | ||
export function Message(fields, content, properties, onConsumed) { | ||
this[kOnConsumed] = [ null, onConsumed ]; | ||
this[kOnConsumed] = [null, onConsumed]; | ||
this[kPending] = false; | ||
@@ -13,3 +13,3 @@ | ||
...properties, | ||
messageId: properties && properties.messageId || `smq.mid-${generateId()}`, | ||
messageId: (properties && properties.messageId) || `smq.mid-${generateId()}`, | ||
}; | ||
@@ -16,0 +16,0 @@ const timestamp = (mproperties.timestamp = mproperties.timestamp || Date.now()); |
@@ -117,4 +117,6 @@ import { generateId, sortByPriority } from './shared.js'; | ||
if (consumers.length) { | ||
if (this[kExclusive]) throw new SmqpError(`Queue ${this.name} is exclusively consumed by ${consumers[0].consumerTag}`, ERR_EXCLUSIVE_CONFLICT); | ||
if (consumeOptions.exclusive) throw new SmqpError(`Queue ${this.name} already has consumers and cannot be exclusively consumed`, ERR_EXCLUSIVE_NOT_ALLOWED); | ||
if (this[kExclusive]) | ||
throw new SmqpError(`Queue ${this.name} is exclusively consumed by ${consumers[0].consumerTag}`, ERR_EXCLUSIVE_CONFLICT); | ||
if (consumeOptions.exclusive) | ||
throw new SmqpError(`Queue ${this.name} already has consumers and cannot be exclusively consumed`, ERR_EXCLUSIVE_NOT_ALLOWED); | ||
} | ||
@@ -222,3 +224,7 @@ | ||
this[kAvailableCount]++; | ||
messages.splice(msgIdx, 0, new Message({ ...message.fields, redelivered: true }, message.content, message.properties, this._onMessageConsumed)); | ||
messages.splice( | ||
msgIdx, | ||
0, | ||
new Message({ ...message.fields, redelivered: true }, message.content, message.properties, this._onMessageConsumed), | ||
); | ||
} else { | ||
@@ -471,3 +477,3 @@ deadLetterExchange = this.options.deadLetterExchange; | ||
const { consumerTag } = this.options = { prefetch: 1, priority: 0, noAck: false, ...options }; | ||
const { consumerTag } = (this.options = { prefetch: 1, priority: 0, noAck: false, ...options }); | ||
if (!consumerTag) this.options.consumerTag = `smq.ctag-${generateId()}`; | ||
@@ -484,6 +490,10 @@ else if (typeof consumerTag !== 'string') throw new TypeError('consumerTag must be a string'); | ||
this[kInternalQueue] = new Queue(`${this.options.consumerTag}-q`, { | ||
autoDelete: false, | ||
maxLength: this.options.prefetch, | ||
}, new ConsumerQueueEvents(this)); | ||
this[kInternalQueue] = new Queue( | ||
`${this.options.consumerTag}-q`, | ||
{ | ||
autoDelete: false, | ||
maxLength: this.options.prefetch, | ||
}, | ||
new ConsumerQueueEvents(this), | ||
); | ||
} | ||
@@ -490,0 +500,0 @@ |
@@ -35,6 +35,3 @@ const allDots = /\./g; | ||
const rpattern = pattern | ||
.replace(allDots, '\\.') | ||
.replace(allAstx, '[^.]+?') | ||
.replace(allHashs, '.*?'); | ||
const rpattern = pattern.replace(allDots, '\\.').replace(allAstx, '[^.]+?').replace(allHashs, '.*?'); | ||
@@ -41,0 +38,0 @@ return new RegExp(`^${rpattern}$`); |
@@ -27,3 +27,6 @@ import { EventExchange } from './Exchange.js'; | ||
if (!destinationExchange) { | ||
throw new SmqpError(`shovel ${name} destination exchange <${destinationExchangeName}> not found`, ERR_SHOVEL_DESTINATION_EXCHANGE_NOT_FOUND); | ||
throw new SmqpError( | ||
`shovel ${name} destination exchange <${destinationExchangeName}> not found`, | ||
ERR_SHOVEL_DESTINATION_EXCHANGE_NOT_FOUND, | ||
); | ||
} | ||
@@ -43,3 +46,3 @@ | ||
const consumerTag = this[kConsumerTag] = source.consumerTag || `smq.shoveltag-${name}`; | ||
const consumerTag = (this[kConsumerTag] = source.consumerTag || `smq.shoveltag-${name}`); | ||
this[kClosed] = false; | ||
@@ -53,6 +56,3 @@ this[kSourceBroker] = sourceBroker; | ||
const eventHandlers = this[kEventHandlers] = [ | ||
sourceExchange.on('delete', boundClose), | ||
destinationExchange.on('delete', boundClose), | ||
]; | ||
const eventHandlers = (this[kEventHandlers] = [sourceExchange.on('delete', boundClose), destinationExchange.on('delete', boundClose)]); | ||
@@ -59,0 +59,0 @@ let consumer; |
@@ -1,26 +0,26 @@ | ||
import { Queue, Consumer, queueOptions, onMessage, consumeOptions, deleteQueueOptions, QueueState } from "./Queue.js"; | ||
import { Shovel, Exchange2Exchange, ShovelDestination, shovelOptions } from "./Shovel.js"; | ||
import { Message, MessageProperties } from "./Message.js"; | ||
import { Exchange, exchangeType, Binding, exchangeOptions, bindingOptions, ExchangeState } from "./Exchange.js"; | ||
import { Queue, Consumer, queueOptions, onMessage, consumeOptions, deleteQueueOptions, QueueState } from './Queue.js'; | ||
import { Shovel, Exchange2Exchange, ShovelDestination, shovelOptions } from './Shovel.js'; | ||
import { Message, MessageProperties } from './Message.js'; | ||
import { Exchange, exchangeType, Binding, exchangeOptions, bindingOptions, ExchangeState } from './Exchange.js'; | ||
type subscribeOptions = { | ||
/** defaults to true, exchange will be deleted when all bindings are removed; the queue will be removed when all consumers are down */ | ||
autoDelete?: boolean, | ||
autoDelete?: boolean; | ||
/** defaults to true, makes exchange and queue durable, i.e. will be returned when getting state */ | ||
durable?: boolean, | ||
durable?: boolean; | ||
/** unique consumer tag */ | ||
consumerTag?: string, | ||
consumerTag?: string; | ||
/** dead letter exchange */ | ||
deadLetterExchange?: string, | ||
deadLetterExchange?: string; | ||
/** publish dead letter with routing key */ | ||
deadLetterRoutingKey?: string; | ||
/** queue is exclusively consumed */ | ||
exclusive?: boolean, | ||
exclusive?: boolean; | ||
/** set to true if there is no need to acknowledge message */ | ||
noAck?: boolean, | ||
noAck?: boolean; | ||
/** defaults to 1, number of messages to consume at a time */ | ||
prefetch?: number, | ||
prefetch?: number; | ||
/** defaults to 0, higher value gets messages first */ | ||
priority?: number, | ||
[x: string]: any, | ||
priority?: number; | ||
[x: string]: any; | ||
}; | ||
@@ -74,8 +74,13 @@ | ||
createQueue(queueName: string, options: any): Queue; | ||
deleteExchange(exchangeName: string, { ifUnused }?: { | ||
ifUnused?: boolean; | ||
}): boolean; | ||
deleteExchange( | ||
exchangeName: string, | ||
{ | ||
ifUnused, | ||
}?: { | ||
ifUnused?: boolean; | ||
}, | ||
): boolean; | ||
purgeQueue(queueName: string): number; | ||
sendToQueue(queueName: string, content: any, options?: MessageProperties): number; | ||
deleteQueue(queueName: string, options?: deleteQueueOptions): { messageCount: number }; | ||
deleteQueue(queueName: string, options?: deleteQueueOptions): { messageCount: number }; | ||
bindExchange(source: string, destination: string, pattern?: string, options?: shovelOptions): Exchange2Exchange; | ||
@@ -102,5 +107,10 @@ unbindExchange(source: string, destination: string, pattern?: string): boolean; | ||
publish(exchangeName: string, routingKey: string, content?: any, options?: MessageProperties): number; | ||
get(queueName: string, { noAck }?: { | ||
noAck: boolean; | ||
}): Message | undefined; | ||
get( | ||
queueName: string, | ||
{ | ||
noAck, | ||
}?: { | ||
noAck: boolean; | ||
}, | ||
): Message | undefined; | ||
ack(message: Message, allUpTo?: boolean): void; | ||
@@ -107,0 +117,0 @@ ackAll(): void; |
@@ -37,3 +37,3 @@ export interface MessageFields { | ||
* @param [allUpTo=false] all outstanding messages prior to and including the given message shall be considered acknowledged. If false, or omitted, only the message supplied is acknowledged. | ||
*/ | ||
*/ | ||
ack(allUpTo?: boolean): void; | ||
@@ -44,3 +44,3 @@ /** | ||
* @param [requeue=true] put the message or messages back on the queue | ||
*/ | ||
*/ | ||
nack(allUpTo?: boolean, requeue?: boolean): void; | ||
@@ -50,6 +50,6 @@ /** | ||
* @param [requeue=true]: put the message back on the queue | ||
*/ | ||
*/ | ||
reject(requeue?: boolean): void; | ||
/** Message is pending ack */ | ||
get pending(): boolean | ||
get pending(): boolean; | ||
} |
import { Message, MessageFields, MessageProperties, MessageMessage } from './Message.js'; | ||
type onMessage = ( | ||
routingKey: string, | ||
message: Message, | ||
owner: any | ||
) => void | ||
type onMessage = (routingKey: string, message: Message, owner: any) => void; | ||
@@ -31,3 +27,3 @@ type queueOptions = { | ||
ifEmpty?: boolean; | ||
} | ||
}; | ||
@@ -34,0 +30,0 @@ export interface QueueState { |
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
9
3533
32
124324
1
28
1
+ Addedprettier@^3.2.5
+ Addedprettier@3.5.0(transitive)