arnavmq 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,7 +16,7 @@ jobs:
16
16
 
17
17
  strategy:
18
18
  matrix:
19
- node-version: [12.x, 14.x, 16.x]
19
+ node-version: [14.x, 16.x, 18.x]
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v2
@@ -0,0 +1,19 @@
1
+ /bin/**
2
+ /build/**
3
+ /coverage/**
4
+ /docs/**
5
+ /jsdoc/**
6
+ /templates/**
7
+ /tests/bench/**
8
+ /tests/fixtures/**
9
+ /tests/performance/**
10
+ /tmp/**
11
+ /public/**
12
+ /node_modules/**
13
+ /lib-cov/**
14
+ /.grunt/**
15
+ /.sonar/**
16
+ /logs/**
17
+ /.idea/**
18
+ /.github/**
19
+ /samples/**
package/README.md CHANGED
@@ -62,12 +62,11 @@ arnavmq.subscribe('queue:name', function (msg) {
62
62
  You can create RPC requests easily by adding the `rpc: true` option to the `produce` call:
63
63
 
64
64
  ```javascript
65
- arnavmq.subscribe('queue:name', function() {
65
+ arnavmq.subscribe('queue:name', function () {
66
66
  return 'hello world!'; // you can also return a promise if you want to do async stuff
67
67
  });
68
68
 
69
- arnavmq.publish('queue:name', { message: 'content' }, { rpc: true, timeout: 1000 })
70
- .then(function(consumerResponse) {
69
+ arnavmq.publish('queue:name', { message: 'content' }, { rpc: true, timeout: 1000 }).then(function (consumerResponse) {
71
70
  console.log(consumerResponse); // prints hello world!
72
71
  });
73
72
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arnavmq",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "ArnavMQ is a RabbitMQ wrapper",
5
5
  "keywords": [
6
6
  "rabbitmq",
@@ -13,10 +13,15 @@
13
13
  ],
14
14
  "main": "src/index.js",
15
15
  "scripts": {
16
- "lint": "eslint .",
16
+ "lint": "eslint . && prettier -c .",
17
+ "format": "eslint --fix . && prettier --write .",
17
18
  "cover": "test -d .nyc_output && nyc report --reporter lcov",
18
19
  "test": "nyc mocha --recursive --timeout=30000 --exit"
19
20
  },
21
+ "prettier": {
22
+ "singleQuote": true,
23
+ "printWidth": 120
24
+ },
20
25
  "repository": {
21
26
  "type": "git",
22
27
  "url": "git+https://github.com/bringg/node-arnavmq.git"
@@ -37,12 +42,14 @@
37
42
  "child-process-promise": "^2.2.1",
38
43
  "eslint": "^8.25.0",
39
44
  "eslint-config-airbnb-base": "^15.0.0",
45
+ "eslint-config-prettier": "^8.6.0",
40
46
  "eslint-plugin-import": "^2.26.0",
41
47
  "mocha": "^10.0.0",
42
48
  "nyc": "^15.1.0",
49
+ "prettier": "^2.8.3",
43
50
  "sinon": "^14.0.1"
44
51
  },
45
52
  "engines": {
46
- "node": ">=12"
53
+ "node": ">=14"
47
54
  }
48
55
  }
package/src/index.js CHANGED
@@ -42,11 +42,14 @@ module.exports = (config) => {
42
42
  */
43
43
  logger: utils.emptyLogger,
44
44
 
45
- ...config
45
+ ...config,
46
46
  };
47
47
 
48
48
  if (configuration.transport !== utils.emptyLogger) {
49
- process.emitWarning("The 'transport' configuration option is deprecated. Please use the 'logger' option instead.", 'DeprecationWarning');
49
+ process.emitWarning(
50
+ "The 'transport' configuration option is deprecated. Please use the 'logger' option instead.",
51
+ 'DeprecationWarning'
52
+ );
50
53
  }
51
54
 
52
55
  configuration.prefetch = parseInt(configuration.prefetch, 10) || 0;
@@ -51,12 +51,12 @@ module.exports = (connection) => {
51
51
 
52
52
  const consumer = {
53
53
  consume: instance.consume.bind(instance),
54
- subscribe: instance.subscribe.bind(instance)
54
+ subscribe: instance.subscribe.bind(instance),
55
55
  };
56
56
 
57
57
  const producer = {
58
58
  produce: instance.produce.bind(instance),
59
- publish: instance.publish.bind(instance)
59
+ publish: instance.publish.bind(instance),
60
60
  };
61
61
 
62
62
  return {
@@ -66,6 +66,6 @@ module.exports = (connection) => {
66
66
  produce: producer.produce,
67
67
  publish: producer.publish,
68
68
  consumer,
69
- producer
69
+ producer,
70
70
  };
71
71
  };
@@ -12,7 +12,7 @@ class Connection {
12
12
  /**
13
13
  * Connect to the broker. We keep only 1 connection for each connection string provided in config, as advised by RabbitMQ
14
14
  * @return {Promise} A promise that resolve with an amqp.node connection object
15
- */
15
+ */
16
16
  getConnection() {
17
17
  const url = this._config.host;
18
18
  const { hostname } = this._config;
@@ -25,28 +25,31 @@ class Connection {
25
25
  // prepare the connection internal object, and reset channel if connection has been closed
26
26
  this.connections[url] = {
27
27
  conn: null,
28
- channel: null
28
+ channel: null,
29
29
  };
30
30
  connection = this.connections[url];
31
- connection.conn = amqp.connect(url, {
32
- clientProperties: {
33
- hostname,
34
- arnavmq: packageVersion,
35
- startedAt: this.startedAt,
36
- connectedAt: new Date().toISOString()
37
- }
38
- }).then((conn) => {
39
- // on connection close, delete connection
40
- conn.on('close', () => {
41
- delete connection.conn;
31
+ connection.conn = amqp
32
+ .connect(url, {
33
+ clientProperties: {
34
+ hostname,
35
+ arnavmq: packageVersion,
36
+ startedAt: this.startedAt,
37
+ connectedAt: new Date().toISOString(),
38
+ },
39
+ })
40
+ .then((conn) => {
41
+ // on connection close, delete connection
42
+ conn.on('close', () => {
43
+ delete connection.conn;
44
+ });
45
+ conn.on('error', this._onError.bind(this));
46
+ connection.conn = conn;
47
+ return conn;
48
+ })
49
+ .catch((e) => {
50
+ connection.conn = null;
51
+ throw e;
42
52
  });
43
- conn.on('error', this._onError.bind(this));
44
- connection.conn = conn;
45
- return conn;
46
- }).catch((e) => {
47
- connection.conn = null;
48
- throw e;
49
- });
50
53
  return connection.conn;
51
54
  }
52
55
 
@@ -54,7 +57,7 @@ class Connection {
54
57
  * Create the channel on the broker, once connection is successfuly opened.
55
58
  * Since RabbitMQ advise to open one channel by process and node is mono-core, we keep only 1 channel for the whole connection.
56
59
  * @return {Promise} A promise that resolve with an amqp.node channel object
57
- */
60
+ */
58
61
  getChannel() {
59
62
  const url = this._config.host;
60
63
  const { prefetch } = this._config;
@@ -65,17 +68,18 @@ class Connection {
65
68
  return Promise.resolve(connection.chann);
66
69
  }
67
70
 
68
- connection.chann = connection.conn.createChannel()
69
- .then((channel) => {
70
- channel.prefetch(prefetch);
71
+ connection.chann = connection.conn.createChannel().then((channel) => {
72
+ channel.prefetch(prefetch);
71
73
 
72
- // on error we remove the channel so the next call will recreate it (auto-reconnect are handled by connection users)
73
- channel.on('close', () => { delete connection.chann; });
74
- channel.on('error', this._onError.bind(this));
75
-
76
- connection.chann = channel;
77
- return channel;
74
+ // on error we remove the channel so the next call will recreate it (auto-reconnect are handled by connection users)
75
+ channel.on('close', () => {
76
+ delete connection.chann;
78
77
  });
78
+ channel.on('error', this._onError.bind(this));
79
+
80
+ connection.chann = channel;
81
+ return channel;
82
+ });
79
83
  return connection.chann;
80
84
  }
81
85
 
@@ -87,7 +91,7 @@ class Connection {
87
91
  this._config.transport.error(error);
88
92
  this._config.logger.error({
89
93
  message: error.message,
90
- error
94
+ error,
91
95
  });
92
96
  }
93
97
 
@@ -35,7 +35,7 @@ class Consumer {
35
35
  this._connection.config.transport.debug(loggerAlias, `[${queue}][${msg.properties.replyTo}] >`, content);
36
36
  this._connection.config.logger.debug({
37
37
  message: `${loggerAlias} [${queue}][${msg.properties.replyTo}] > ${content}`,
38
- params: { content }
38
+ params: { content },
39
39
  });
40
40
  this.channel.sendToQueue(msg.properties.replyTo, parsers.out(content, options), options);
41
41
  }
@@ -68,55 +68,63 @@ class Consumer {
68
68
  // ex: service-something with suffix :ci becomes service-suffix:ci etc.
69
69
  const suffixedQueue = `${queue}${this._connection.config.consumerSuffix || ''}`;
70
70
 
71
- return this._connection.get().then((channel) => {
72
- this.channel = channel;
71
+ return this._connection
72
+ .get()
73
+ .then((channel) => {
74
+ this.channel = channel;
73
75
 
74
- // when channel is closed, we want to be sure we recreate the queue ASAP so we trigger a reconnect by recreating the consumer
75
- this.channel.addListener('close', () => {
76
- this.subscribe(queue, options, callback);
77
- });
78
-
79
- return this.channel.assertQueue(suffixedQueue, options).then((q) => {
80
- this._connection.config.transport.debug(loggerAlias, 'init', q.queue);
81
- this._connection.config.logger.debug({
82
- message: `${loggerAlias} init ${q.queue}`,
83
- params: { queue: q.queue }
76
+ // when channel is closed, we want to be sure we recreate the queue ASAP so we trigger a reconnect by recreating the consumer
77
+ this.channel.addListener('close', () => {
78
+ this.subscribe(queue, options, callback);
84
79
  });
85
80
 
86
- this.channel.consume(q.queue, (msg) => {
87
- const messageString = msg.content.toString();
88
- this._connection.config.transport.debug(loggerAlias, `[${q.queue}] < ${messageString}`);
81
+ return this.channel.assertQueue(suffixedQueue, options).then((q) => {
82
+ this._connection.config.transport.debug(loggerAlias, 'init', q.queue);
89
83
  this._connection.config.logger.debug({
90
- message: `${loggerAlias} [${q.queue}] < ${messageString}`,
91
- params: { queue: q.queue, message: messageString }
84
+ message: `${loggerAlias} init ${q.queue}`,
85
+ params: { queue: q.queue },
92
86
  });
93
87
 
94
- // main answer management chaining
95
- // receive message, parse it, execute callback, check if should answer, ack/reject message
96
- Promise.resolve(parsers.in(msg))
97
- .then((body) => callback(body, msg.properties))
98
- .then(this.checkRpc(msg, q.queue))
99
- .then(() => {
100
- this.channel.ack(msg);
101
- })
102
- .catch((error) => {
103
- // if something bad happened in the callback, reject the message so we can requeue it (or not)
104
- this._connection.config.transport.error(loggerAlias, error);
105
- this._connection.config.logger.error({
106
- message: `${loggerAlias} Failed processing message from queue ${q.queue}: ${error.message}`,
107
- error,
108
- params: { queue: q.queue, message: messageString }
88
+ this.channel.consume(
89
+ q.queue,
90
+ (msg) => {
91
+ const messageString = msg.content.toString();
92
+ this._connection.config.transport.debug(loggerAlias, `[${q.queue}] < ${messageString}`);
93
+ this._connection.config.logger.debug({
94
+ message: `${loggerAlias} [${q.queue}] < ${messageString}`,
95
+ params: { queue: q.queue, message: messageString },
109
96
  });
110
97
 
111
- this.channel.reject(msg, this._connection.config.requeue);
112
- });
113
- }, { noAck: false });
114
-
115
- return true;
116
- });
117
- // in case of any error creating the channel, wait for some time and then try to reconnect again (to avoid overflow)
118
- }).catch(() => utils.timeoutPromise(this._connection.config.timeout)
119
- .then(() => this.subscribe(queue, options, callback)));
98
+ // main answer management chaining
99
+ // receive message, parse it, execute callback, check if should answer, ack/reject message
100
+ Promise.resolve(parsers.in(msg))
101
+ .then((body) => callback(body, msg.properties))
102
+ .then(this.checkRpc(msg, q.queue))
103
+ .then(() => {
104
+ this.channel.ack(msg);
105
+ })
106
+ .catch((error) => {
107
+ // if something bad happened in the callback, reject the message so we can requeue it (or not)
108
+ this._connection.config.transport.error(loggerAlias, error);
109
+ this._connection.config.logger.error({
110
+ message: `${loggerAlias} Failed processing message from queue ${q.queue}: ${error.message}`,
111
+ error,
112
+ params: { queue: q.queue, message: messageString },
113
+ });
114
+
115
+ this.channel.reject(msg, this._connection.config.requeue);
116
+ });
117
+ },
118
+ { noAck: false }
119
+ );
120
+
121
+ return true;
122
+ });
123
+ // in case of any error creating the channel, wait for some time and then try to reconnect again (to avoid overflow)
124
+ })
125
+ .catch(() =>
126
+ utils.timeoutPromise(this._connection.config.timeout).then(() => this.subscribe(queue, options, callback))
127
+ );
120
128
  }
121
129
  }
122
130
 
@@ -50,27 +50,21 @@ class Producer {
50
50
 
51
51
  if (responsePromise === undefined) {
52
52
  const error = new Error(`Receiving RPC message from previous session: callback no more in memory. ${queue}`);
53
- this._connection.config.transport.warn(
54
- loggerAlias,
55
- error
56
- );
53
+ this._connection.config.transport.warn(loggerAlias, error);
57
54
  this._connection.config.logger.warn({
58
55
  message: `${loggerAlias} ${error.message}`,
59
56
  error,
60
- params: { queue, rpcQueue }
57
+ params: { queue, rpcQueue },
61
58
  });
62
59
 
63
60
  return;
64
61
  }
65
62
 
66
63
  // if we found one, we execute the callback and delete it because it will never be received again anyway
67
- this._connection.config.transport.info(
68
- loggerAlias,
69
- `[${queue}] < answer`
70
- );
64
+ this._connection.config.transport.info(loggerAlias, `[${queue}] < answer`);
71
65
  this._connection.config.logger.debug({
72
66
  message: `${loggerAlias} [${queue}] < answer`,
73
- params: { queue }
67
+ params: { queue },
74
68
  });
75
69
 
76
70
  try {
@@ -100,30 +94,30 @@ class Producer {
100
94
  const resQueue = `${queue}:${this._connection.config.hostname}:${process.pid}:res`;
101
95
  rpcQueue.queue = this._connection
102
96
  .get()
103
- .then((channel) => channel
104
- .assertQueue(resQueue, {
105
- durable: true,
106
- exclusive: true,
107
- })
108
- .then((q) => {
109
- rpcQueue.queue = q.queue;
110
-
111
- // if channel is closed, we want to make sure we cleanup the queue so future calls will recreate it
112
- this._connection.addListener('close', () => {
113
- delete rpcQueue.queue;
114
- this.createRpcQueue(queue);
115
- });
116
-
117
- return channel.consume(q.queue, this.maybeAnswer(queue), {
118
- noAck: true,
119
- });
120
- })
121
- .then(() => rpcQueue.queue))
97
+ .then((channel) =>
98
+ channel
99
+ .assertQueue(resQueue, {
100
+ durable: true,
101
+ exclusive: true,
102
+ })
103
+ .then((q) => {
104
+ rpcQueue.queue = q.queue;
105
+
106
+ // if channel is closed, we want to make sure we cleanup the queue so future calls will recreate it
107
+ this._connection.addListener('close', () => {
108
+ delete rpcQueue.queue;
109
+ this.createRpcQueue(queue);
110
+ });
111
+
112
+ return channel.consume(q.queue, this.maybeAnswer(queue), {
113
+ noAck: true,
114
+ });
115
+ })
116
+ .then(() => rpcQueue.queue)
117
+ )
122
118
  .catch(() => {
123
119
  delete rpcQueue.queue;
124
- return utils
125
- .timeoutPromise(this._connection.config.timeout)
126
- .then(() => this.createRpcQueue(queue));
120
+ return utils.timeoutPromise(this._connection.config.timeout).then(() => this.createRpcQueue(queue));
127
121
  });
128
122
 
129
123
  return rpcQueue.queue;
@@ -236,14 +230,10 @@ class Producer {
236
230
  // undefined can't be serialized/buffered :p
237
231
  if (!message) message = null;
238
232
 
239
- this._connection.config.transport.info(
240
- loggerAlias,
241
- `[${queue}] > `,
242
- message
243
- );
233
+ this._connection.config.transport.info(loggerAlias, `[${queue}] > `, message);
244
234
  this._connection.config.logger.debug({
245
235
  message: `${loggerAlias} [${queue}] > ${message}`,
246
- params: { queue, message }
236
+ params: { queue, message },
247
237
  });
248
238
 
249
239
  return this.checkRpc(queue, parsers.out(message, settings), settings);
@@ -258,7 +248,7 @@ class Producer {
258
248
  this._connection.config.logger.error({
259
249
  message: `${loggerAlias} Failed sending message to queue ${queue}: ${error.message}`,
260
250
  error,
261
- params: { queue, message }
251
+ params: { queue, message },
262
252
  });
263
253
  return utils
264
254
  .timeoutPromise(this._connection.config.timeout)
@@ -5,7 +5,7 @@ const emptyLogger = {
5
5
  debug: empty,
6
6
  warn: empty,
7
7
  error: empty,
8
- log: empty
8
+ log: empty,
9
9
  };
10
10
 
11
11
  module.exports = {
@@ -26,7 +26,8 @@ module.exports = {
26
26
  * @param {number} timer How much ws to wait
27
27
  * @return {Promise} A Promise that will resolve when timer is expired
28
28
  */
29
- timeoutPromise: (timer) => new Promise((resolve) => {
30
- setTimeout(resolve, timer);
31
- })
29
+ timeoutPromise: (timer) =>
30
+ new Promise((resolve) => {
31
+ setTimeout(resolve, timer);
32
+ }),
32
33
  };