amqplib 0.10.8 → 1.0.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.
Files changed (85) hide show
  1. package/.claude/commands/lint-disable.md +9 -0
  2. package/.claude/commands/lint-enable.md +12 -0
  3. package/.claude/settings.local.json +16 -0
  4. package/.github/workflows/publish.yml +1 -1
  5. package/.github/workflows/test.yml +1 -1
  6. package/CHANGELOG.md +34 -0
  7. package/CLAUDE.md +12 -0
  8. package/Makefile +5 -12
  9. package/bin/generate-defs.js +382 -369
  10. package/biome.json +51 -0
  11. package/callback_api.js +12 -8
  12. package/channel_api.js +5 -10
  13. package/examples/direct_reply_to_client.js +9 -5
  14. package/examples/direct_reply_to_server.js +8 -6
  15. package/examples/headers.js +13 -10
  16. package/examples/receive_generator.js +13 -20
  17. package/examples/send_generators.js +2 -9
  18. package/examples/ssl.js +2 -3
  19. package/examples/stream_queues/receive_stream.js +39 -36
  20. package/examples/stream_queues/send_stream.js +26 -29
  21. package/examples/tutorials/callback_api/emit_log.js +4 -3
  22. package/examples/tutorials/callback_api/emit_log_direct.js +5 -4
  23. package/examples/tutorials/callback_api/emit_log_topic.js +5 -4
  24. package/examples/tutorials/callback_api/new_task.js +5 -4
  25. package/examples/tutorials/callback_api/receive.js +16 -10
  26. package/examples/tutorials/callback_api/receive_logs.js +17 -11
  27. package/examples/tutorials/callback_api/receive_logs_direct.js +19 -13
  28. package/examples/tutorials/callback_api/receive_logs_topic.js +19 -14
  29. package/examples/tutorials/callback_api/rpc_client.js +20 -16
  30. package/examples/tutorials/callback_api/rpc_server.js +27 -21
  31. package/examples/tutorials/callback_api/send.js +4 -3
  32. package/examples/tutorials/callback_api/worker.js +18 -13
  33. package/examples/tutorials/emit_log.js +4 -6
  34. package/examples/tutorials/emit_log_direct.js +5 -7
  35. package/examples/tutorials/emit_log_topic.js +5 -7
  36. package/examples/tutorials/new_task.js +4 -6
  37. package/examples/tutorials/receive.js +8 -4
  38. package/examples/tutorials/receive_logs.js +10 -6
  39. package/examples/tutorials/receive_logs_direct.js +16 -10
  40. package/examples/tutorials/receive_logs_topic.js +16 -11
  41. package/examples/tutorials/rpc_client.js +17 -15
  42. package/examples/tutorials/rpc_server.js +9 -8
  43. package/examples/tutorials/send.js +4 -6
  44. package/examples/tutorials/worker.js +17 -14
  45. package/examples/waitForConfirms.js +2 -2
  46. package/lefthook.yml +14 -0
  47. package/lib/api_args.js +124 -149
  48. package/lib/bitset.js +28 -18
  49. package/lib/callback_model.js +134 -190
  50. package/lib/channel.js +175 -213
  51. package/lib/channel_model.js +41 -85
  52. package/lib/codec.js +257 -228
  53. package/lib/connect.js +74 -82
  54. package/lib/connection.js +204 -240
  55. package/lib/credentials.js +21 -29
  56. package/lib/defs.js +2559 -1927
  57. package/lib/error.js +5 -6
  58. package/lib/format.js +15 -33
  59. package/lib/frame.js +66 -66
  60. package/lib/heartbeat.js +17 -24
  61. package/lib/mux.js +32 -41
  62. package/package.json +8 -5
  63. package/test/bitset.test.js +65 -0
  64. package/test/callback_api.test.js +438 -0
  65. package/test/channel.test.js +592 -0
  66. package/test/channel_api.test.js +537 -0
  67. package/test/codec.test.js +172 -0
  68. package/test/connect.test.js +196 -0
  69. package/test/connection.test.js +330 -0
  70. package/test/data.test.js +33 -0
  71. package/test/frame.test.js +180 -0
  72. package/test/lib/data.js +249 -0
  73. package/test/lib/util.js +223 -0
  74. package/test/mux.test.js +215 -0
  75. package/test/bitset.js +0 -69
  76. package/test/callback_api.js +0 -379
  77. package/test/channel.js +0 -621
  78. package/test/channel_api.js +0 -606
  79. package/test/codec.js +0 -237
  80. package/test/connect.js +0 -197
  81. package/test/connection.js +0 -390
  82. package/test/data.js +0 -269
  83. package/test/frame.js +0 -191
  84. package/test/mux.js +0 -203
  85. package/test/util.js +0 -217
@@ -8,7 +8,7 @@ const queue = 'task_queue';
8
8
  (async () => {
9
9
  try {
10
10
  const connection = await amqp.connect('amqp://localhost');
11
- process.once('SIGINT', async () => {
11
+ process.once('SIGINT', async () => {
12
12
  await connection.close();
13
13
  });
14
14
 
@@ -16,19 +16,22 @@ const queue = 'task_queue';
16
16
  await channel.assertQueue(queue, { durable: true });
17
17
 
18
18
  channel.prefetch(1);
19
- await channel.consume(queue, (message) => {
20
- const text = message.content.toString();
21
- console.log(" [x] Received '%s'", text);
22
- const seconds = text.split('.').length - 1;
23
- setTimeout(() => {
24
- console.log(" [x] Done");
25
- channel.ack(message);
26
- }, seconds * 1000);
27
- }, { noAck: false });
28
-
29
- console.log(" [*] Waiting for messages. To exit press CTRL+C");
30
- }
31
- catch (err) {
19
+ await channel.consume(
20
+ queue,
21
+ (message) => {
22
+ const text = message.content.toString();
23
+ console.log(" [x] Received '%s'", text);
24
+ const seconds = text.split('.').length - 1;
25
+ setTimeout(() => {
26
+ console.log(' [x] Done');
27
+ channel.ack(message);
28
+ }, seconds * 1000);
29
+ },
30
+ { noAck: false },
31
+ );
32
+
33
+ console.log(' [*] Waiting for messages. To exit press CTRL+C');
34
+ } catch (err) {
32
35
  console.warn(err);
33
36
  }
34
37
  })();
@@ -6,9 +6,9 @@ const amqp = require('../');
6
6
  connection = await amqp.connect();
7
7
  const channel = await connection.createConfirmChannel();
8
8
 
9
- for (var i=0; i < 20; i++) {
9
+ for (let i = 0; i < 20; i++) {
10
10
  channel.publish('amq.topic', 'whatever', Buffer.from('blah'));
11
- };
11
+ }
12
12
 
13
13
  await channel.waitForConfirms();
14
14
  console.log('All messages done');
package/lefthook.yml ADDED
@@ -0,0 +1,14 @@
1
+ pre-commit:
2
+ commands:
3
+ format:
4
+ glob: "**/*.js"
5
+ exclude:
6
+ - "test/*.js"
7
+ run: npx biome format {staged_files} --write
8
+ stage_fixed: true
9
+ lint:
10
+ glob: "**/*.js"
11
+ run: npx biome lint {staged_files} --write
12
+ stage_fixed: true
13
+ test:
14
+ run: npm test
package/lib/api_args.js CHANGED
@@ -1,9 +1,3 @@
1
- //
2
- //
3
- //
4
-
5
- 'use strict';
6
-
7
1
  /*
8
2
  The channel (promise) and callback APIs have similar signatures, and
9
3
  in particular, both need AMQP fields prepared from the same arguments
@@ -38,24 +32,22 @@ fields for handing to the encoder.
38
32
  // NB the `arguments` field already has a default value of `{}`, so
39
33
  // there's no need to explicitly default it unless I'm setting values.
40
34
  function setIfDefined(obj, prop, value) {
41
- if (value != undefined) obj[prop] = value;
35
+ if (value !== undefined) obj[prop] = value;
42
36
  }
43
37
 
44
- var EMPTY_OPTIONS = Object.freeze({});
38
+ const EMPTY_OPTIONS = Object.freeze({});
45
39
 
46
- var Args = {};
40
+ const Args = {};
47
41
 
48
- Args.assertQueue = function(queue, options) {
42
+ Args.assertQueue = (queue, options) => {
49
43
  queue = queue || '';
50
44
  options = options || EMPTY_OPTIONS;
51
45
 
52
- var argt = Object.create(options.arguments || null);
46
+ const argt = Object.create(options.arguments || null);
53
47
  setIfDefined(argt, 'x-expires', options.expires);
54
48
  setIfDefined(argt, 'x-message-ttl', options.messageTtl);
55
- setIfDefined(argt, 'x-dead-letter-exchange',
56
- options.deadLetterExchange);
57
- setIfDefined(argt, 'x-dead-letter-routing-key',
58
- options.deadLetterRoutingKey);
49
+ setIfDefined(argt, 'x-dead-letter-exchange', options.deadLetterExchange);
50
+ setIfDefined(argt, 'x-dead-letter-routing-key', options.deadLetterRoutingKey);
59
51
  setIfDefined(argt, 'x-max-length', options.maxLength);
60
52
  setIfDefined(argt, 'x-max-priority', options.maxPriority);
61
53
  setIfDefined(argt, 'x-overflow', options.overflow);
@@ -64,126 +56,124 @@ Args.assertQueue = function(queue, options) {
64
56
  return {
65
57
  queue: queue,
66
58
  exclusive: !!options.exclusive,
67
- durable: (options.durable === undefined) ? true : options.durable,
59
+ durable: options.durable === undefined ? true : options.durable,
68
60
  autoDelete: !!options.autoDelete,
69
61
  arguments: argt,
70
62
  passive: false,
71
63
  // deprecated but we have to include it
72
64
  ticket: 0,
73
- nowait: false
74
- };
75
- };
76
-
77
- Args.checkQueue = function(queue) {
78
- return {
79
- queue: queue,
80
- passive: true, // switch to "completely different" mode
81
65
  nowait: false,
82
- durable: true, autoDelete: false, exclusive: false, // ignored
83
- ticket: 0,
84
66
  };
85
67
  };
86
68
 
87
- Args.deleteQueue = function(queue, options) {
69
+ Args.checkQueue = (queue) => ({
70
+ queue: queue,
71
+ passive: true, // switch to "completely different" mode
72
+ nowait: false,
73
+ durable: true,
74
+ autoDelete: false,
75
+ exclusive: false, // ignored
76
+ ticket: 0,
77
+ });
78
+
79
+ Args.deleteQueue = (queue, options) => {
88
80
  options = options || EMPTY_OPTIONS;
89
81
  return {
90
82
  queue: queue,
91
83
  ifUnused: !!options.ifUnused,
92
84
  ifEmpty: !!options.ifEmpty,
93
- ticket: 0, nowait: false
94
- };
95
- };
96
-
97
- Args.purgeQueue = function(queue) {
98
- return {
99
- queue: queue,
100
- ticket: 0, nowait: false
101
- };
102
- };
103
-
104
- Args.bindQueue = function(queue, source, pattern, argt) {
105
- return {
106
- queue: queue,
107
- exchange: source,
108
- routingKey: pattern,
109
- arguments: argt,
110
- ticket: 0, nowait: false
111
- };
112
- };
113
-
114
- Args.unbindQueue = function(queue, source, pattern, argt) {
115
- return {
116
- queue: queue,
117
- exchange: source,
118
- routingKey: pattern,
119
- arguments: argt,
120
- ticket: 0, nowait: false
85
+ ticket: 0,
86
+ nowait: false,
121
87
  };
122
88
  };
123
89
 
124
- Args.assertExchange = function(exchange, type, options) {
90
+ Args.purgeQueue = (queue) => ({
91
+ queue: queue,
92
+ ticket: 0,
93
+ nowait: false,
94
+ });
95
+
96
+ Args.bindQueue = (queue, source, pattern, argt) => ({
97
+ queue: queue,
98
+ exchange: source,
99
+ routingKey: pattern,
100
+ arguments: argt,
101
+ ticket: 0,
102
+ nowait: false,
103
+ });
104
+
105
+ Args.unbindQueue = (queue, source, pattern, argt) => ({
106
+ queue: queue,
107
+ exchange: source,
108
+ routingKey: pattern,
109
+ arguments: argt,
110
+ ticket: 0,
111
+ nowait: false,
112
+ });
113
+
114
+ Args.assertExchange = (exchange, type, options) => {
125
115
  options = options || EMPTY_OPTIONS;
126
- var argt = Object.create(options.arguments || null);
116
+ const argt = Object.create(options.arguments || null);
127
117
  setIfDefined(argt, 'alternate-exchange', options.alternateExchange);
128
118
  return {
129
119
  exchange: exchange,
130
120
  ticket: 0,
131
121
  type: type,
132
122
  passive: false,
133
- durable: (options.durable === undefined) ? true : options.durable,
123
+ durable: options.durable === undefined ? true : options.durable,
134
124
  autoDelete: !!options.autoDelete,
135
125
  internal: !!options.internal,
136
126
  nowait: false,
137
- arguments: argt
138
- };
139
- };
140
-
141
- Args.checkExchange = function(exchange) {
142
- return {
143
- exchange: exchange,
144
- passive: true, // switch to 'may as well be another method' mode
145
- nowait: false,
146
- // ff are ignored
147
- durable: true, internal: false, type: '', autoDelete: false,
148
- ticket: 0
127
+ arguments: argt,
149
128
  };
150
129
  };
151
130
 
152
- Args.deleteExchange = function(exchange, options) {
131
+ Args.checkExchange = (exchange) => ({
132
+ exchange: exchange,
133
+ passive: true, // switch to 'may as well be another method' mode
134
+ nowait: false,
135
+ // ff are ignored
136
+ durable: true,
137
+ internal: false,
138
+ type: '',
139
+ autoDelete: false,
140
+ ticket: 0,
141
+ });
142
+
143
+ Args.deleteExchange = (exchange, options) => {
153
144
  options = options || EMPTY_OPTIONS;
154
145
  return {
155
146
  exchange: exchange,
156
147
  ifUnused: !!options.ifUnused,
157
- ticket: 0, nowait: false
158
- };
159
- };
160
-
161
- Args.bindExchange = function(dest, source, pattern, argt) {
162
- return {
163
- source: source,
164
- destination: dest,
165
- routingKey: pattern,
166
- arguments: argt,
167
- ticket: 0, nowait: false
148
+ ticket: 0,
149
+ nowait: false,
168
150
  };
169
151
  };
170
152
 
171
- Args.unbindExchange = function(dest, source, pattern, argt) {
172
- return {
173
- source: source,
174
- destination: dest,
175
- routingKey: pattern,
176
- arguments: argt,
177
- ticket: 0, nowait: false
178
- };
179
- };
153
+ Args.bindExchange = (dest, source, pattern, argt) => ({
154
+ source: source,
155
+ destination: dest,
156
+ routingKey: pattern,
157
+ arguments: argt,
158
+ ticket: 0,
159
+ nowait: false,
160
+ });
161
+
162
+ Args.unbindExchange = (dest, source, pattern, argt) => ({
163
+ source: source,
164
+ destination: dest,
165
+ routingKey: pattern,
166
+ arguments: argt,
167
+ ticket: 0,
168
+ nowait: false,
169
+ });
180
170
 
181
171
  // It's convenient to construct the properties and the method fields
182
172
  // at the same time, since in the APIs, values for both can appear in
183
173
  // `options`. Since the property or mthod field names don't overlap, I
184
174
  // just return one big object that can be used for both purposes, and
185
175
  // the encoder will pick out what it wants.
186
- Args.publish = function(exchange, routingKey, options) {
176
+ Args.publish = (exchange, routingKey, options) => {
187
177
  options = options || EMPTY_OPTIONS;
188
178
 
189
179
  // The CC and BCC fields expect an array of "longstr", which would
@@ -193,31 +183,28 @@ Args.publish = function(exchange, routingKey, options) {
193
183
  function convertCC(cc) {
194
184
  if (cc === undefined) {
195
185
  return undefined;
196
- }
197
- else if (Array.isArray(cc)) {
186
+ } else if (Array.isArray(cc)) {
198
187
  return cc.map(String);
199
- }
200
- else return [String(cc)];
188
+ } else return [String(cc)];
201
189
  }
202
190
 
203
- var headers = Object.create(options.headers || null);
191
+ const headers = Object.create(options.headers || null);
204
192
  setIfDefined(headers, 'CC', convertCC(options.CC));
205
193
  setIfDefined(headers, 'BCC', convertCC(options.BCC));
206
194
 
207
- var deliveryMode; // undefined will default to 1 (non-persistent)
195
+ let deliveryMode; // undefined will default to 1 (non-persistent)
208
196
 
209
197
  // Previously I overloaded deliveryMode be a boolean meaning
210
198
  // 'persistent or not'; better is to name this option for what it
211
199
  // is, but I need to have backwards compatibility for applications
212
200
  // that either supply a numeric or boolean value.
213
- if (options.persistent !== undefined)
214
- deliveryMode = (options.persistent) ? 2 : 1;
215
- else if (typeof options.deliveryMode === 'number')
216
- deliveryMode = options.deliveryMode;
217
- else if (options.deliveryMode) // is supplied and truthy
201
+ if (options.persistent !== undefined) deliveryMode = options.persistent ? 2 : 1;
202
+ else if (typeof options.deliveryMode === 'number') deliveryMode = options.deliveryMode;
203
+ else if (options.deliveryMode)
204
+ // is supplied and truthy
218
205
  deliveryMode = 2;
219
206
 
220
- var expiration = options.expiration;
207
+ let expiration = options.expiration;
221
208
  if (expiration !== undefined) expiration = expiration.toString();
222
209
 
223
210
  return {
@@ -241,13 +228,13 @@ Args.publish = function(exchange, routingKey, options) {
241
228
  type: options.type,
242
229
  userId: options.userId,
243
230
  appId: options.appId,
244
- clusterId: undefined
231
+ clusterId: undefined,
245
232
  };
246
233
  };
247
234
 
248
- Args.consume = function(queue, options) {
235
+ Args.consume = (queue, options) => {
249
236
  options = options || EMPTY_OPTIONS;
250
- var argt = Object.create(options.arguments || null);
237
+ const argt = Object.create(options.arguments || null);
251
238
  setIfDefined(argt, 'x-priority', options.priority);
252
239
  return {
253
240
  ticket: 0,
@@ -257,58 +244,46 @@ Args.consume = function(queue, options) {
257
244
  noAck: !!options.noAck,
258
245
  exclusive: !!options.exclusive,
259
246
  nowait: false,
260
- arguments: argt
247
+ arguments: argt,
261
248
  };
262
249
  };
263
250
 
264
- Args.cancel = function(consumerTag) {
265
- return {
266
- consumerTag: consumerTag,
267
- nowait: false
268
- };
269
- };
251
+ Args.cancel = (consumerTag) => ({
252
+ consumerTag: consumerTag,
253
+ nowait: false,
254
+ });
270
255
 
271
- Args.get = function(queue, options) {
256
+ Args.get = (queue, options) => {
272
257
  options = options || EMPTY_OPTIONS;
273
258
  return {
274
259
  ticket: 0,
275
260
  queue: queue,
276
- noAck: !!options.noAck
277
- };
278
- };
279
-
280
- Args.ack = function(tag, allUpTo) {
281
- return {
282
- deliveryTag: tag,
283
- multiple: !!allUpTo
284
- };
285
- };
286
-
287
- Args.nack = function(tag, allUpTo, requeue) {
288
- return {
289
- deliveryTag: tag,
290
- multiple: !!allUpTo,
291
- requeue: (requeue === undefined) ? true : requeue
292
- };
293
- };
294
-
295
- Args.reject = function(tag, requeue) {
296
- return {
297
- deliveryTag: tag,
298
- requeue: (requeue === undefined) ? true : requeue
299
- };
300
- };
301
-
302
- Args.prefetch = function(count, global) {
303
- return {
304
- prefetchCount: count || 0,
305
- prefetchSize: 0,
306
- global: !!global
261
+ noAck: !!options.noAck,
307
262
  };
308
263
  };
309
264
 
310
- Args.recover = function() {
311
- return {requeue: true};
312
- };
265
+ Args.ack = (tag, allUpTo) => ({
266
+ deliveryTag: tag,
267
+ multiple: !!allUpTo,
268
+ });
269
+
270
+ Args.nack = (tag, allUpTo, requeue) => ({
271
+ deliveryTag: tag,
272
+ multiple: !!allUpTo,
273
+ requeue: requeue === undefined ? true : requeue,
274
+ });
275
+
276
+ Args.reject = (tag, requeue) => ({
277
+ deliveryTag: tag,
278
+ requeue: requeue === undefined ? true : requeue,
279
+ });
280
+
281
+ Args.prefetch = (count, global) => ({
282
+ prefetchCount: count || 0,
283
+ prefetchSize: 0,
284
+ global: !!global,
285
+ });
286
+
287
+ Args.recover = () => ({ requeue: true });
313
288
 
314
289
  module.exports = Object.freeze(Args);
package/lib/bitset.js CHANGED
@@ -1,9 +1,3 @@
1
- //
2
- //
3
- //
4
-
5
- 'use strict';
6
-
7
1
  /**
8
2
  * A bitset implementation, after that in java.util. Yes there
9
3
  * already exist such things, but none implement next{Clear|Set}Bit or
@@ -17,8 +11,7 @@ class BitSet {
17
11
  if (size) {
18
12
  const numWords = Math.ceil(size / 32);
19
13
  this.words = new Array(numWords);
20
- }
21
- else {
14
+ } else {
22
15
  this.words = [];
23
16
  }
24
17
  this.wordsInUse = 0; // = number, not index
@@ -80,7 +73,7 @@ class BitSet {
80
73
  // word that are > fromIndex
81
74
  let word = this.words[w] & (0xffffffff << fromIndex);
82
75
  while (true) {
83
- if (word) return (w * 32) + trailingZeros(word);
76
+ if (word) return w * 32 + trailingZeros(word);
84
77
  w++;
85
78
  if (w === this.wordsInUse) return -1;
86
79
  word = this.words[w];
@@ -94,12 +87,12 @@ class BitSet {
94
87
  let w = wordIndex(fromIndex);
95
88
  if (w >= this.wordsInUse) return fromIndex;
96
89
 
97
- let word = ~(this.words[w]) & (0xffffffff << fromIndex);
90
+ let word = ~this.words[w] & (0xffffffff << fromIndex);
98
91
  while (true) {
99
- if (word) return (w * 32) + trailingZeros(word);
92
+ if (word) return w * 32 + trailingZeros(word);
100
93
  w++;
101
- if (w == this.wordsInUse) return w * 32;
102
- word = ~(this.words[w]);
94
+ if (w === this.wordsInUse) return w * 32;
95
+ word = ~this.words[w];
103
96
  }
104
97
  }
105
98
  }
@@ -119,11 +112,28 @@ function trailingZeros(i) {
119
112
  // since bit ops are not necessarily the quick way to do things in
120
113
  // JS.
121
114
  if (i === 0) return 32;
122
- let y, n = 31;
123
- y = i << 16; if (y != 0) { n = n -16; i = y; }
124
- y = i << 8; if (y != 0) { n = n - 8; i = y; }
125
- y = i << 4; if (y != 0) { n = n - 4; i = y; }
126
- y = i << 2; if (y != 0) { n = n - 2; i = y; }
115
+ let y;
116
+ let n = 31;
117
+ y = i << 16;
118
+ if (y !== 0) {
119
+ n = n - 16;
120
+ i = y;
121
+ }
122
+ y = i << 8;
123
+ if (y !== 0) {
124
+ n = n - 8;
125
+ i = y;
126
+ }
127
+ y = i << 4;
128
+ if (y !== 0) {
129
+ n = n - 4;
130
+ i = y;
131
+ }
132
+ y = i << 2;
133
+ if (y !== 0) {
134
+ n = n - 2;
135
+ i = y;
136
+ }
127
137
  return n - ((i << 1) >>> 31);
128
138
  }
129
139