rascal 13.1.1 → 14.0.1

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 (66) hide show
  1. package/.husky/pre-commit +1 -1
  2. package/.prettierrc.json +4 -0
  3. package/CHANGELOG.md +213 -1
  4. package/README.md +597 -381
  5. package/examples/advanced/cluster.js +8 -8
  6. package/examples/advanced/config.js +121 -123
  7. package/examples/advanced/handlers/deleteUser.js +16 -17
  8. package/examples/advanced/handlers/saveUser.js +32 -33
  9. package/examples/advanced/index.js +85 -80
  10. package/examples/busy-publisher/config.js +19 -22
  11. package/examples/busy-publisher/index.js +11 -12
  12. package/examples/default-exchange/config.js +13 -13
  13. package/examples/default-exchange/index.js +22 -18
  14. package/examples/mocha/config.js +13 -15
  15. package/examples/mocha/test.js +34 -35
  16. package/examples/promises/config.js +15 -17
  17. package/examples/promises/index.js +14 -12
  18. package/examples/simple/config.js +21 -23
  19. package/examples/simple/index.js +20 -22
  20. package/index.js +1 -1
  21. package/lib/amqp/Broker.js +105 -82
  22. package/lib/amqp/BrokerAsPromised.js +40 -28
  23. package/lib/amqp/Publication.js +15 -14
  24. package/lib/amqp/PublicationSession.js +6 -7
  25. package/lib/amqp/SubscriberError.js +159 -124
  26. package/lib/amqp/SubscriberSession.js +87 -68
  27. package/lib/amqp/SubscriberSessionAsPromised.js +1 -3
  28. package/lib/amqp/Subscription.js +25 -24
  29. package/lib/amqp/Vhost.js +93 -67
  30. package/lib/amqp/tasks/applyBindings.js +9 -6
  31. package/lib/amqp/tasks/assertExchanges.js +9 -5
  32. package/lib/amqp/tasks/assertQueues.js +9 -5
  33. package/lib/amqp/tasks/assertVhost.js +17 -13
  34. package/lib/amqp/tasks/bounceVhost.js +1 -1
  35. package/lib/amqp/tasks/checkExchanges.js +9 -5
  36. package/lib/amqp/tasks/checkQueues.js +9 -5
  37. package/lib/amqp/tasks/checkVhost.js +17 -13
  38. package/lib/amqp/tasks/closeChannel.js +0 -1
  39. package/lib/amqp/tasks/createChannel.js +0 -1
  40. package/lib/amqp/tasks/createConnection.js +18 -15
  41. package/lib/amqp/tasks/deleteExchanges.js +9 -5
  42. package/lib/amqp/tasks/deleteQueues.js +9 -5
  43. package/lib/amqp/tasks/deleteVhost.js +17 -13
  44. package/lib/amqp/tasks/forewarnVhost.js +1 -1
  45. package/lib/amqp/tasks/initCounters.js +12 -8
  46. package/lib/amqp/tasks/initPublications.js +13 -9
  47. package/lib/amqp/tasks/initShovels.js +9 -5
  48. package/lib/amqp/tasks/initSubscriptions.js +12 -8
  49. package/lib/amqp/tasks/initVhosts.js +16 -12
  50. package/lib/amqp/tasks/nukeVhost.js +1 -1
  51. package/lib/amqp/tasks/purgeQueues.js +9 -5
  52. package/lib/amqp/tasks/purgeVhost.js +1 -1
  53. package/lib/amqp/tasks/shutdownVhost.js +1 -1
  54. package/lib/backoff/exponential.js +1 -2
  55. package/lib/backoff/index.js +1 -1
  56. package/lib/backoff/linear.js +2 -4
  57. package/lib/config/baseline.js +12 -23
  58. package/lib/config/configure.js +89 -41
  59. package/lib/config/tests.js +30 -27
  60. package/lib/config/validate.js +22 -3
  61. package/lib/counters/inMemoryCluster.js +33 -22
  62. package/lib/counters/index.js +1 -1
  63. package/lib/counters/stub.js +2 -3
  64. package/lib/management/client.js +3 -9
  65. package/lib/utils/setTimeoutUnref.js +1 -1
  66. package/package.json +12 -4
@@ -1,41 +1,44 @@
1
1
  const _ = require('lodash').runInContext();
2
2
  const defaultConfig = require('./defaults');
3
3
 
4
- module.exports = _.defaultsDeep({
5
- defaults: {
6
- vhosts: {
7
- connection: {
8
- options: {
9
- heartbeat: 50,
4
+ module.exports = _.defaultsDeep(
5
+ {
6
+ defaults: {
7
+ vhosts: {
8
+ connection: {
9
+ options: {
10
+ heartbeat: 50,
11
+ },
10
12
  },
11
- },
12
- namespace: true,
13
- exchanges: {
14
- options: {
15
- durable: false,
13
+ namespace: true,
14
+ exchanges: {
15
+ options: {
16
+ durable: false,
17
+ },
18
+ },
19
+ queues: {
20
+ purge: true,
21
+ options: {
22
+ durable: false,
23
+ },
16
24
  },
17
25
  },
18
- queues: {
19
- purge: true,
26
+ publications: {
20
27
  options: {
21
- durable: false,
28
+ persistent: false,
22
29
  },
23
30
  },
24
- },
25
- publications: {
26
- options: {
27
- persistent: false,
31
+ subscriptions: {
32
+ closeTimeout: 500,
28
33
  },
29
34
  },
30
- subscriptions: {
31
- deferCloseChannel: 100,
32
- },
33
- },
34
- redeliveries: {
35
- "counters": {
36
- "inMemory": {
37
- "size": 1000,
35
+ redeliveries: {
36
+ counters: {
37
+ inMemory: {
38
+ size: 1000,
39
+ },
38
40
  },
39
41
  },
40
42
  },
41
- }, defaultConfig);
43
+ defaultConfig
44
+ );
@@ -59,7 +59,6 @@ module.exports = _.curry((config, next) => {
59
59
  if (invalid.length) throw new Error(format('%s: %s in vhost: %s refers to an unsupported attribute: %s', type, childName, vhostName, invalid[0]));
60
60
  }
61
61
 
62
-
63
62
  function validateExchanges(vhost, vhostName, exchanges) {
64
63
  _.each(exchanges, validateExchange.bind(null, vhost, vhostName));
65
64
  }
@@ -104,7 +103,7 @@ module.exports = _.curry((config, next) => {
104
103
  validateAttributes('Publication', publication, publicationName, ['name', 'vhost', 'exchange', 'queue', 'routingKey', 'confirm', 'options', 'destination', 'autoCreated', 'deprecated', 'encryption', 'timeout']);
105
104
  if (!publication.vhost) throw new Error(format('Publication: %s is missing a vhost', publicationName));
106
105
  if (!(Object.prototype.hasOwnProperty.call(publication, 'exchange') || publication.queue)) throw new Error(format('Publication: %s is missing an exchange or a queue', publicationName));
107
- if ((Object.prototype.hasOwnProperty.call(publication, 'exchange') && publication.queue)) throw new Error(format('Publication: %s has an exchange and a queue', publicationName));
106
+ if (Object.prototype.hasOwnProperty.call(publication, 'exchange') && publication.queue) throw new Error(format('Publication: %s has an exchange and a queue', publicationName));
108
107
 
109
108
  if (!config.vhosts) throw new Error(format('Publication: %s refers to an unknown vhost: %s', publicationName, publication.vhost));
110
109
  if (!config.vhosts[publication.vhost]) throw new Error(format('Publication: %s refers to an unknown vhost: %s', publicationName, publication.vhost));
@@ -125,7 +124,27 @@ module.exports = _.curry((config, next) => {
125
124
  }
126
125
 
127
126
  function validateSubscription(subscription, subscriptionName) {
128
- validateAttributes('Subscription', subscription, subscriptionName, ['name', 'vhost', 'queue', 'contentType', 'options', 'prefetch', 'retry', 'source', 'recovery', 'workflow', 'handler', 'workflows', 'handlers', 'redeliveries', 'autoCreated', 'deprecated', 'deferCloseChannel', 'encryption', 'promisifyAckOrNack']);
127
+ validateAttributes('Subscription', subscription, subscriptionName, [
128
+ 'name',
129
+ 'vhost',
130
+ 'queue',
131
+ 'contentType',
132
+ 'options',
133
+ 'prefetch',
134
+ 'retry',
135
+ 'source',
136
+ 'recovery',
137
+ 'workflow',
138
+ 'handler',
139
+ 'workflows',
140
+ 'handlers',
141
+ 'redeliveries',
142
+ 'autoCreated',
143
+ 'deprecated',
144
+ 'closeTimeout',
145
+ 'encryption',
146
+ 'promisifyAckOrNack',
147
+ ]);
129
148
 
130
149
  if (!subscription.vhost) throw new Error(format('Subscription: %s is missing a vhost', subscriptionName));
131
150
  if (!subscription.queue) throw new Error(format('Subscription: %s is missing a queue', subscriptionName));
@@ -12,23 +12,30 @@ module.exports = {
12
12
  function handleMessage(worker, message) {
13
13
  if (message.sender !== 'rascal-in-memory-cluster-counter' || message.cmd !== 'incrementAndGet') return;
14
14
  counter.incrementAndGet(message.key, (err, value) => {
15
- worker.send({ sender: 'rascal-in-memory-cluster-counter', correlationId: message.correlationId, value: err ? 1 : value });
15
+ worker.send({
16
+ sender: 'rascal-in-memory-cluster-counter',
17
+ correlationId: message.correlationId,
18
+ value: err ? 1 : value,
19
+ });
16
20
  });
17
21
  }
18
22
 
19
- cluster.on('fork', (worker) => {
20
- workers[worker.id] = worker;
21
- worker.on('message', (message) => {
22
- handleMessage(worker, message);
23
+ cluster
24
+ .on('fork', (worker) => {
25
+ workers[worker.id] = worker;
26
+ worker.on('message', (message) => {
27
+ handleMessage(worker, message);
28
+ });
29
+ })
30
+ .on('disconnect', (worker) => {
31
+ delete workers[worker.id];
32
+ })
33
+ .on('exit', (worker) => {
34
+ delete workers[worker.id];
23
35
  });
24
- }).on('disconnect', (worker) => {
25
- delete workers[worker.id];
26
- }).on('exit', (worker) => {
27
- delete workers[worker.id];
28
- });
29
36
  },
30
37
  worker: function worker(options) {
31
- if (!cluster.isWorker) throw new Error('You cannot use Rascal\'s in memmory cluster counter outside of a cluster');
38
+ if (!cluster.isWorker) throw new Error("You cannot use Rascal's in memmory cluster counter outside of a cluster");
32
39
  if (!options) return worker({});
33
40
  const timeout = options.timeout || 100;
34
41
  const stashback = Stashback({ timeout });
@@ -41,18 +48,22 @@ module.exports = {
41
48
  });
42
49
 
43
50
  return {
44
- incrementAndGet (key, cb) {
51
+ incrementAndGet(key, cb) {
45
52
  const correlationId = uuid();
46
- stashback.stash(correlationId, (err, value) => {
47
- err ? cb(null, 1) : cb(null, value);
48
- }, (err) => {
49
- if (err) return cb(null, 1);
50
- process.send({
51
- sender: 'rascal-in-memory-cluster-counter',
52
- correlationId,
53
- cmd: 'incrementAndGet',
54
- });
55
- });
53
+ stashback.stash(
54
+ correlationId,
55
+ (err, value) => {
56
+ err ? cb(null, 1) : cb(null, value);
57
+ },
58
+ (err) => {
59
+ if (err) return cb(null, 1);
60
+ process.send({
61
+ sender: 'rascal-in-memory-cluster-counter',
62
+ correlationId,
63
+ cmd: 'incrementAndGet',
64
+ });
65
+ }
66
+ );
56
67
  },
57
68
  };
58
69
  },
@@ -2,4 +2,4 @@ module.exports = {
2
2
  stub: require('./stub'),
3
3
  inMemory: require('./inMemory'),
4
4
  inMemoryCluster: require('./inMemoryCluster'),
5
- };
5
+ };
@@ -1,8 +1,7 @@
1
- module.exports = function() {
2
-
1
+ module.exports = function () {
3
2
  return {
4
3
  incrementAndGet(key, next) {
5
4
  next(null, 0);
6
5
  },
7
6
  };
8
- };
7
+ };
@@ -8,9 +8,7 @@ function assertVhost(name, config, next) {
8
8
  const options = getVhostOptions(name, config);
9
9
  request('put', options.url, options.timeout, (err) => {
10
10
  if (!err) return next();
11
- const message = err.status
12
- ? format('Failed to assert vhost: %s. %s returned status %d', name, config.loggableUrl, err.status)
13
- : format('Failed to assert vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
11
+ const message = err.status ? format('Failed to assert vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to assert vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
14
12
  return next(new Error(message));
15
13
  });
16
14
  }
@@ -20,9 +18,7 @@ function checkVhost(name, config, next) {
20
18
  const options = getVhostOptions(name, config);
21
19
  request('get', options.url, options.timeout, (err) => {
22
20
  if (!err) return next();
23
- const message = err.status
24
- ? format('Failed to check vhost: %s. %s returned status %d', name, config.loggableUrl, err.status)
25
- : format('Failed to check vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
21
+ const message = err.status ? format('Failed to check vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to check vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
26
22
  return next(new Error(message));
27
23
  });
28
24
  }
@@ -32,9 +28,7 @@ function deleteVhost(name, config, next) {
32
28
  const options = getVhostOptions(name, config);
33
29
  request('delete', options.url, options.timeout, (err) => {
34
30
  if (!err) return next();
35
- const message = err.status
36
- ? format('Failed to delete vhost: %s. %s returned status %d', name, config.loggableUrl, err.status)
37
- : format('Failed to delete vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
31
+ const message = err.status ? format('Failed to delete vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to delete vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
38
32
  return next(new Error(message));
39
33
  });
40
34
  }
@@ -1,5 +1,5 @@
1
1
  // See https://github.com/guidesmiths/rascal/issues/89
2
- module.exports = function(fn, millis) {
2
+ module.exports = function (fn, millis) {
3
3
  const t = setTimeout(fn, millis);
4
4
  return t.unref ? t.unref() : t;
5
5
  };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "rascal",
3
- "version": "13.1.1",
3
+ "version": "14.0.1",
4
4
  "description": "A config driven wrapper for amqplib supporting multi-host connections, automatic error recovery, redelivery flood protection, transparent encryption / decryption, channel pooling and publication timeouts",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
- "async": "^3.2.0",
7
+ "async": "^3.2.1",
8
8
  "debug": "^4.1.1",
9
9
  "deep-freeze": "0.0.1",
10
10
  "forward-emitter": "^0.1.1",
@@ -21,10 +21,13 @@
21
21
  "amqplib": "^0.8.0",
22
22
  "chalk": "^4.0.0",
23
23
  "chance": "^1.1.4",
24
- "eslint": "^6.8.0",
25
- "eslint-config-esnext": "^4.1.0",
24
+ "eslint": "^7.32.0",
25
+ "eslint-config-prettier": "^8.3.0",
26
+ "eslint-plugin-prettier": "^4.0.0",
26
27
  "husky": "^6.0.0",
28
+ "lint-staged": "^11.2.4",
27
29
  "nyc": "^15.1.0",
30
+ "prettier": "2.4.1",
28
31
  "random-readable": "^1.0.1",
29
32
  "zunit": "^3.0.8"
30
33
  },
@@ -36,11 +39,16 @@
36
39
  },
37
40
  "scripts": {
38
41
  "test": "zUnit",
42
+ "prettier": "prettier --check .",
39
43
  "lint": "eslint .",
44
+ "lint-staged": "lint-staged",
40
45
  "coverage": "nyc --report html --reporter lcov --reporter text-summary zUnit",
41
46
  "docker": "docker run -d --name rascal-rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management",
42
47
  "prepare": "husky install"
43
48
  },
49
+ "lint-staged": {
50
+ "**/*": "prettier --write --ignore-unknown"
51
+ },
44
52
  "keywords": [
45
53
  "amqplib",
46
54
  "amqp",