redis-smq 7.0.7 → 7.1.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 (54) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +16 -11
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.js +9 -1
  5. package/dist/misc/health-check/combined-run.js +6 -6
  6. package/dist/src/common/redis-keys/redis-keys.d.ts +19 -9
  7. package/dist/src/common/redis-keys/redis-keys.js +16 -9
  8. package/dist/src/lib/consumer/consumer-message-handler/acknowledge-message.js +1 -1
  9. package/dist/src/lib/consumer/consumer-message-handler/dead-letter-message.js +2 -2
  10. package/dist/src/lib/consumer/consumer-message-handler/delay-message.js +2 -2
  11. package/dist/src/lib/consumer/consumer-message-handler/requeue-message.js +1 -1
  12. package/dist/src/lib/exchange/direct-exchange.d.ts +10 -0
  13. package/dist/src/lib/exchange/direct-exchange.js +34 -0
  14. package/dist/src/lib/exchange/errors/destination-queue-required.error.d.ts +4 -0
  15. package/dist/src/lib/exchange/errors/destination-queue-required.error.js +11 -0
  16. package/dist/src/lib/exchange/errors/exchange.error.d.ts +3 -0
  17. package/dist/src/lib/exchange/errors/exchange.error.js +8 -0
  18. package/dist/src/lib/exchange/errors/invalid-exchange-data.error.d.ts +4 -0
  19. package/dist/src/lib/exchange/errors/invalid-exchange-data.error.js +11 -0
  20. package/dist/src/lib/exchange/exchange.d.ts +19 -0
  21. package/dist/src/lib/exchange/exchange.js +51 -0
  22. package/dist/src/lib/exchange/fan-out-exchange-manager.d.ts +21 -0
  23. package/dist/src/lib/exchange/fan-out-exchange-manager.js +160 -0
  24. package/dist/src/lib/exchange/fan-out-exchange.d.ts +10 -0
  25. package/dist/src/lib/exchange/fan-out-exchange.js +28 -0
  26. package/dist/src/lib/exchange/topic-exchange.d.ts +12 -0
  27. package/dist/src/lib/exchange/topic-exchange.js +58 -0
  28. package/dist/src/lib/message/errors/message-exchange-required.error.d.ts +4 -0
  29. package/dist/src/lib/message/errors/message-exchange-required.error.js +11 -0
  30. package/dist/src/lib/message/errors/message.error.d.ts +3 -0
  31. package/dist/src/lib/message/errors/message.error.js +8 -0
  32. package/dist/src/lib/message/{message-metadata.d.ts → message-state.d.ts} +12 -12
  33. package/dist/src/lib/message/{message-metadata.js → message-state.js} +4 -4
  34. package/dist/src/lib/message/message.d.ts +19 -10
  35. package/dist/src/lib/message/message.js +135 -77
  36. package/dist/src/lib/message-manager/message-storage/list.js +6 -5
  37. package/dist/src/lib/producer/errors/message-already-published.error.js +1 -1
  38. package/dist/src/lib/producer/producer.d.ts +4 -2
  39. package/dist/src/lib/producer/producer.js +61 -37
  40. package/dist/src/lib/producer/schedule-message.js +6 -5
  41. package/dist/src/lib/queue-manager/delete-queue-transaction.js +11 -3
  42. package/dist/src/lib/queue-manager/queue-manager.d.ts +3 -2
  43. package/dist/src/lib/queue-manager/queue-manager.js +3 -3
  44. package/dist/src/lib/queue-manager/queue-rate-limit.js +7 -6
  45. package/dist/src/lib/queue-manager/queue.d.ts +4 -1
  46. package/dist/src/lib/queue-manager/queue.js +24 -8
  47. package/dist/src/workers/delay.worker.js +2 -2
  48. package/dist/src/workers/requeue.worker.js +2 -2
  49. package/dist/src/workers/schedule.worker.js +5 -4
  50. package/dist/types/index.d.ts +37 -4
  51. package/dist/types/index.js +13 -1
  52. package/package.json +3 -3
  53. package/dist/src/lib/producer/errors/message-queue-required.error.d.ts +0 -4
  54. package/dist/src/lib/producer/errors/message-queue-required.error.js +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 7.1.0 (2022-10-06)
4
+
5
+ * docs: update README.md (8734e49)
6
+ * build: update npm dependencies (4225c50)
7
+ * test(FanOutExchangeManager): increase code coverage (df4c693)
8
+ * refactor(FanOutExchangeManager): improve unbindQueue() logic (c1440a5)
9
+ * docs: update docs (508430f)
10
+ * fix: fix typing error (05c1575)
11
+ * test: increase code coverage (c4ba4f3)
12
+ * refactor: rename saveExchange() to createExchange() (995ca03)
13
+ * refactor: improve TQueueSettings typing (413f4d3)
14
+ * refactor: bump up redis keys version (3389216)
15
+ * refactor: add EQueueSettingType, remove KEY_QUEUE_SETTINGS_* keys (600199c)
16
+ * refactor(queue-manager): update queue.create() reply payload (f3a12d1)
17
+ * feat(FanOutExchangeManager): add saveExchange(), deleteExchange() (1ce22cc)
18
+ * refactor(redis-keys): clean up validateRedisKey() (e921540)
19
+ * fix(FanOutExchange): fix bindingParams validation (327d045)
20
+ * test(exchange): increase code coverage (f5f5d95)
21
+ * feat(exchange): allow retrieving fanout exchange list (8a96b17)
22
+ * refactor(exchange): improve exchange tag naming (a089738)
23
+ * refactor(message): improve message.exchange typing (9ce281a)
24
+ * refactor(queue-manager): clean up (ce5ab8e)
25
+ * docs(message): update MessageMetadata references (5041a85)
26
+ * test(message): update MessageMetadata references (9888918)
27
+ * refactor(message): rename MessageMetadata to MessageState, clean up (2de18b4)
28
+ * docs(exchange): improve documentation (718a80a)
29
+ * docs(producer): update docs (1965a75)
30
+ * docs(exchange): fix typos (93b4c8e)
31
+ * test(exchange): test exchanges with unmatched queues (d836eab)
32
+ * fix(exchange): return an error for exchanges with unmatched queues (e89ce06)
33
+ * docs(message): add missing method references (c723ec2)
34
+ * docs(exchange): update docs (1dc02a4)
35
+ * refactor(exchange): rename FanOutExchangeManager methods (f981241)
36
+ * docs(exchange): add FanOutExchangeManager reference (9cecc89)
37
+ * test(exchange): update fanout-exchange tests (be75519)
38
+ * feat(exchange): add FanOutExchangeManager (f8168a4)
39
+ * refactor(exchange): rename files (fd9d906)
40
+ * build: update workflow names (7b1b545)
41
+ * docs(readme): display the status of codeql.yml workflow (94eb97a)
42
+ * perf(redis-keys): fix inefficient regex complexity (dcb4f1f)
43
+ * build: set up code scanning (be0dd02)
44
+ * docs(exchange): update message-exchanges.md (49436af)
45
+ * test(exchange): fix test errors (f3aa786)
46
+ * docs(exchange): fix typos (a62a732)
47
+ * fix(redis-keys): enforce a redis key to start with a letter (a-z) (ecb7493)
48
+ * docs(exchange): update docs (wip) (6d3eaee)
49
+ * fix(exchange): export DirectExchange/TopicExchange/FanOutExchange classes (c070f3c)
50
+ * test(exchange): increase code coverage (063582c)
51
+ * refactor(exchange): add and use InvalidExchangeDataError (482e093)
52
+ * docs(readme): add reference to current release documentation (747e4e3)
53
+ * docs(producer): update producer.produce() parameters (938976e)
54
+ * fix: fix various typings issues (9c51445)
55
+ * chore: update examples (3628813)
56
+ * refactor: update tests (1456c5a)
57
+ * test(exchange): test fanout and topic exchanges (54c081b)
58
+ * feat(queue-manager): allow to bind/unbind a queue to an exchange (cd91109)
59
+ * refactor(exchange): remove code redundancies and clean up (2dc2cba)
60
+ * chore: bump up redis-smq-common to v1.0.4 (5181ad7)
61
+ * feat(exchange): implement missing methods of TopicExchange class (e2119b5)
62
+ * feat(redis-keys): allow redis keys to include a dot (92b8b05)
63
+ * perf(queue-manager): use sscan instead of smembers (8f491f4)
64
+ * feat(exchange): implement direct, fanout, and topic exchanges (1617e9b)
65
+ * chore: bump up redis-smq-common to 1.0.3 (d7f4aba)
66
+ * chore: clean up (ee88201)
67
+
3
68
  ## 7.0.7 (2022-08-10)
4
69
 
5
70
  * Bump up redis-smq-common to v1.0.2 (ff385ad)
package/README.md CHANGED
@@ -7,10 +7,10 @@
7
7
 
8
8
  <p>
9
9
  <a href="https://github.com/weyoss/redis-smq/actions/workflows/tests.yml"><img src="https://github.com/weyoss/redis-smq/actions/workflows/tests.yml/badge.svg" alt="Tests" style="max-width:100%;" /></a>
10
+ <a href="https://github.com/weyoss/redis-smq/actions/workflows/codeql.yml" rel="nofollow"><img src="https://github.com/weyoss/redis-smq/actions/workflows/codeql.yml/badge.svg" alt="Code quality" /></a>
10
11
  <a href="https://codecov.io/github/weyoss/redis-smq?branch=master" rel="nofollow"><img src="https://img.shields.io/codecov/c/github/weyoss/redis-smq" alt="Coverage Status" /></a>
11
12
  <a href="https://npmjs.org/package/redis-smq" rel="nofollow"><img src="https://img.shields.io/npm/v/redis-smq.svg" alt="NPM version" /></a>
12
13
  <a href="https://npmjs.org/package/redis-smq" rel="nofollow"><img src="https://img.shields.io/npm/dm/redis-smq.svg" alt="NPM downloads" /></a>
13
- <a href="https://lgtm.com/projects/g/weyoss/redis-smq/context:javascript" rel="nofollow"><img src="https://img.shields.io/lgtm/grade/javascript/github/weyoss/redis-smq.svg?logo=lgtm&logoWidth=18" alt="Code quality" /></a>
14
14
  </p>
15
15
 
16
16
  RedisSMQ is a Node.js library for queuing messages (aka jobs) and processing them asynchronously with consumers. Backed by Redis, it allows scaling up your application with ease of use.
@@ -20,6 +20,7 @@ RedisSMQ is a Node.js library for queuing messages (aka jobs) and processing the
20
20
  * **[High-performance message processing](/docs/performance.md)**.
21
21
  * **[Multi-Queue Producers](#producer-class) & [Multi-Queue Consumers](#consumer-class)**: Offering flexible Producer/Consumer models, with focus on simplicity and without tons of features. This can make RedisSMQ an ideal message broker for your microservices.
22
22
  * **[Supports both at-least-once/at-most-once delivery](/docs/api/message.md#messageprototypesetretrythreshold)**: In case of failures, while delivering or processing a message, RedisSMQ can guaranty that the message will be not lost and redelivered again. When configured to do so, RedisSMQ can also ensure that the message is delivered at-most-once.
23
+ * **[Supports Different Exchange Types](/docs/message-exchanges.md)**: RedisSMQ offers 3 types of exchanges: [Direct Exchange](/docs/message-exchanges.md#direct-exchange), [Topic Exchange](/docs/message-exchanges.md#topic-exchange), and [Fanout Exchange](/docs/message-exchanges.md#fanout-exchange) for publishing a message to one or multiple queues.
23
24
  * **[Message Expiration](/docs/api/message.md#messageprototypesetttl)**: A message will not be delivered if it has been in a queue for longer than a given amount of time, called TTL (time-to-live).
24
25
  * **[Message Consumption Timeout](/docs/api/message.md#messageprototypesetconsumetimeout)**: Timeout for consuming messages.
25
26
  * **[Queue Rate Limiting](/docs/queue-rate-limiting.md)**: Allowing you to control the rate at which the messages are consumed from a given queue.
@@ -54,13 +55,14 @@ RedisSMQ is a Node.js library for queuing messages (aka jobs) and processing the
54
55
  2. Advanced Topics
55
56
  1. [Scheduling Messages](/docs/scheduling-messages.md)
56
57
  2. [Priority Queues](/docs/priority-queues.md)
57
- 3. [Queue Rate Limiting](/docs/queue-rate-limiting.md)
58
- 4. [Multiplexing](/docs/multiplexing.md)
59
- 5. [Message Manager](/docs/api/message-manager.md)
60
- 6. [Queue Manager](/docs/api/queue-manager.md)
61
- 7. [HTTP API](https://github.com/weyoss/redis-smq-monitor)
62
- 8. [Web UI](https://github.com/weyoss/redis-smq-monitor-client)
63
- 9. [Logs](https://github.com/weyoss/redis-smq-common/blob/master/docs/logs.md)
58
+ 3. [Message Exchanges](/docs/message-exchanges.md)
59
+ 4. [Queue Rate Limiting](/docs/queue-rate-limiting.md)
60
+ 5. [Multiplexing](/docs/multiplexing.md)
61
+ 6. [Message Manager](/docs/api/message-manager.md)
62
+ 7. [Queue Manager](/docs/api/queue-manager.md)
63
+ 8. [HTTP API](https://github.com/weyoss/redis-smq-monitor)
64
+ 9. [Web UI](https://github.com/weyoss/redis-smq-monitor-client)
65
+ 10. [Logs](https://github.com/weyoss/redis-smq-common/blob/master/docs/logs.md)
64
66
  5. [RedisSMQ Architecture](/docs/redis-smq-architecture.md)
65
67
  6. [Performance](#performance)
66
68
  7. [Contributing](#contributing)
@@ -68,10 +70,11 @@ RedisSMQ is a Node.js library for queuing messages (aka jobs) and processing the
68
70
 
69
71
  ## What's new?
70
72
 
71
- **2022.06.18**
73
+ **2022.10.06**
72
74
 
73
- :rocket: Release v7 is finally ready! The RedisSMQ v7 is a refinement release with many improvements toward making
74
- things more simple to use and removing any confusions that can occur while working with the message queue.
75
+ :rocket: Release v7.1 is out! The RedisSMQ v7.1 extends the message queue features by introducing **[Message Exchanges](/docs/message-exchanges.md)**.
76
+ Also, the [Web UI](https://github.com/weyoss/redis-smq-monitor-client) has been reworked for better user experience and to support the new features.
77
+ So feel to play with the new release, if you encounter any issue, or you have a question do not hesitate to open an issue.
75
78
 
76
79
  ## Installation
77
80
 
@@ -224,6 +227,8 @@ See [Consumer Reference](/docs/api/consumer.md) for more details.
224
227
 
225
228
  * [Priority Queues](/docs/priority-queues.md)
226
229
 
230
+ * [Message Exchanges](/docs/message-exchanges.md)
231
+
227
232
  * [Queue Rate Limiting](/docs/queue-rate-limiting.md)
228
233
 
229
234
  * [Multiplexing](/docs/multiplexing.md)
package/dist/index.d.ts CHANGED
@@ -4,3 +4,7 @@ export { Producer } from './src/lib/producer/producer';
4
4
  export { Message } from './src/lib/message/message';
5
5
  export { MessageManager } from './src/lib/message-manager/message-manager';
6
6
  export { QueueManager } from './src/lib/queue-manager/queue-manager';
7
+ export { DirectExchange } from './src/lib/exchange/direct-exchange';
8
+ export { TopicExchange } from './src/lib/exchange/topic-exchange';
9
+ export { FanOutExchange } from './src/lib/exchange/fan-out-exchange';
10
+ export { FanOutExchangeManager } from './src/lib/exchange/fan-out-exchange-manager';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueueManager = exports.MessageManager = exports.Message = exports.Producer = exports.Consumer = exports.events = void 0;
3
+ exports.FanOutExchangeManager = exports.FanOutExchange = exports.TopicExchange = exports.DirectExchange = exports.QueueManager = exports.MessageManager = exports.Message = exports.Producer = exports.Consumer = exports.events = void 0;
4
4
  var events_1 = require("./src/common/events/events");
5
5
  Object.defineProperty(exports, "events", { enumerable: true, get: function () { return events_1.events; } });
6
6
  var consumer_1 = require("./src/lib/consumer/consumer");
@@ -13,4 +13,12 @@ var message_manager_1 = require("./src/lib/message-manager/message-manager");
13
13
  Object.defineProperty(exports, "MessageManager", { enumerable: true, get: function () { return message_manager_1.MessageManager; } });
14
14
  var queue_manager_1 = require("./src/lib/queue-manager/queue-manager");
15
15
  Object.defineProperty(exports, "QueueManager", { enumerable: true, get: function () { return queue_manager_1.QueueManager; } });
16
+ var direct_exchange_1 = require("./src/lib/exchange/direct-exchange");
17
+ Object.defineProperty(exports, "DirectExchange", { enumerable: true, get: function () { return direct_exchange_1.DirectExchange; } });
18
+ var topic_exchange_1 = require("./src/lib/exchange/topic-exchange");
19
+ Object.defineProperty(exports, "TopicExchange", { enumerable: true, get: function () { return topic_exchange_1.TopicExchange; } });
20
+ var fan_out_exchange_1 = require("./src/lib/exchange/fan-out-exchange");
21
+ Object.defineProperty(exports, "FanOutExchange", { enumerable: true, get: function () { return fan_out_exchange_1.FanOutExchange; } });
22
+ var fan_out_exchange_manager_1 = require("./src/lib/exchange/fan-out-exchange-manager");
23
+ Object.defineProperty(exports, "FanOutExchangeManager", { enumerable: true, get: function () { return fan_out_exchange_manager_1.FanOutExchangeManager; } });
16
24
  //# sourceMappingURL=index.js.map
@@ -1,21 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const redis_smq_common_1 = require("redis-smq-common");
4
- const __1 = require("../..");
4
+ const index_1 = require("../../index");
5
5
  const events_1 = require("../../src/common/events/events");
6
6
  const queue = `queue_${Date.now()}`;
7
- const producer = new __1.Producer();
7
+ const producer = new index_1.Producer();
8
8
  const produceForever = (err) => {
9
9
  if (err)
10
10
  console.log(err);
11
11
  else {
12
12
  if (producer.isGoingUp() || producer.isRunning()) {
13
- const message = new __1.Message().setBody('some data').setQueue(queue);
13
+ const message = new index_1.Message().setBody('some data').setQueue(queue);
14
14
  producer.produce(message, produceForever);
15
15
  }
16
16
  }
17
17
  };
18
- const consumer = new __1.Consumer();
18
+ const consumer = new index_1.Consumer();
19
19
  consumer.consume(queue, (message, cb) => cb(), (err) => err && console.log(err));
20
20
  consumer.on(events_1.events.UP, () => {
21
21
  console.log('UP');
@@ -37,12 +37,12 @@ const serialOnOff = (cb) => redis_smq_common_1.async.waterfall([
37
37
  ], cb);
38
38
  let queueManager = null;
39
39
  redis_smq_common_1.async.waterfall([
40
- (cb) => __1.QueueManager.createInstance({}, (err, instance) => {
40
+ (cb) => index_1.QueueManager.createInstance({}, (err, instance) => {
41
41
  if (err)
42
42
  cb(err);
43
43
  else {
44
44
  queueManager = instance;
45
- queueManager === null || queueManager === void 0 ? void 0 : queueManager.queue.create(queue, false, cb);
45
+ queueManager === null || queueManager === void 0 ? void 0 : queueManager.queue.create(queue, false, (err) => cb(err));
46
46
  }
47
47
  }),
48
48
  (cb) => producer.run((err) => cb(err)),
@@ -12,8 +12,7 @@ export declare const redisKeys: {
12
12
  keyDelayedMessages: string;
13
13
  keyRequeueMessages: string;
14
14
  keyNamespaces: string;
15
- keyQueueSettingsRateLimit: string;
16
- keyQueueSettingsPriorityQueuing: string;
15
+ keyExchanges: string;
17
16
  };
18
17
  getQueueKeys(queueParams: TQueueParams): {
19
18
  keyQueuePending: string;
@@ -36,8 +35,21 @@ export declare const redisKeys: {
36
35
  keyDelayedMessages: string;
37
36
  keyRequeueMessages: string;
38
37
  keyNamespaces: string;
39
- keyQueueSettingsRateLimit: string;
40
- keyQueueSettingsPriorityQueuing: string;
38
+ keyExchanges: string;
39
+ };
40
+ getFanOutExchangeKeys(bindingKey: string): {
41
+ keyExchangeBindings: string;
42
+ keyQueues: string;
43
+ keyProcessingQueues: string;
44
+ keyHeartbeats: string;
45
+ keyHeartbeatConsumerWeight: string;
46
+ keyScheduledMessages: string;
47
+ keyScheduledMessageWeight: string;
48
+ keyLockConsumerWorkersRunner: string;
49
+ keyDelayedMessages: string;
50
+ keyRequeueMessages: string;
51
+ keyNamespaces: string;
52
+ keyExchanges: string;
41
53
  };
42
54
  getConsumerKeys(instanceId: string): {
43
55
  keyConsumerQueues: string;
@@ -51,8 +63,7 @@ export declare const redisKeys: {
51
63
  keyDelayedMessages: string;
52
64
  keyRequeueMessages: string;
53
65
  keyNamespaces: string;
54
- keyQueueSettingsRateLimit: string;
55
- keyQueueSettingsPriorityQueuing: string;
66
+ keyExchanges: string;
56
67
  };
57
68
  getQueueConsumerKeys(queueParams: TQueueParams, instanceId: string): {
58
69
  keyQueueProcessing: string;
@@ -67,8 +78,7 @@ export declare const redisKeys: {
67
78
  keyDelayedMessages: string;
68
79
  keyRequeueMessages: string;
69
80
  keyNamespaces: string;
70
- keyQueueSettingsRateLimit: string;
71
- keyQueueSettingsPriorityQueuing: string;
81
+ keyExchanges: string;
72
82
  keyQueuePending: string;
73
83
  keyQueueDL: string;
74
84
  keyQueueProcessingQueues: string;
@@ -80,7 +90,7 @@ export declare const redisKeys: {
80
90
  keyQueueSettings: string;
81
91
  keyNsQueues: string;
82
92
  };
83
- getMainKeys(): Record<"keyQueues" | "keyProcessingQueues" | "keyHeartbeats" | "keyHeartbeatConsumerWeight" | "keyScheduledMessages" | "keyScheduledMessageWeight" | "keyLockConsumerWorkersRunner" | "keyDelayedMessages" | "keyRequeueMessages" | "keyNamespaces" | "keyQueueSettingsRateLimit" | "keyQueueSettingsPriorityQueuing", string>;
93
+ getMainKeys(): Record<"keyQueues" | "keyProcessingQueues" | "keyHeartbeats" | "keyHeartbeatConsumerWeight" | "keyScheduledMessages" | "keyScheduledMessageWeight" | "keyLockConsumerWorkersRunner" | "keyDelayedMessages" | "keyRequeueMessages" | "keyNamespaces" | "keyExchanges", string>;
84
94
  validateNamespace(ns: string): string;
85
95
  validateRedisKey(key?: string): string;
86
96
  };
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.redisKeys = void 0;
4
4
  const redis_keys_error_1 = require("./redis-keys.error");
5
5
  const keySegmentSeparator = ':';
6
- const nsPrefix = 'redis-smq-v7';
6
+ const nsPrefix = 'redis-smq-v7.1';
7
7
  const globalNamespace = 'global';
8
8
  var ERedisKey;
9
9
  (function (ERedisKey) {
@@ -29,8 +29,8 @@ var ERedisKey;
29
29
  ERedisKey[ERedisKey["KEY_NAMESPACES"] = 20] = "KEY_NAMESPACES";
30
30
  ERedisKey[ERedisKey["KEY_QUEUE_RATE_LIMIT_COUNTER"] = 21] = "KEY_QUEUE_RATE_LIMIT_COUNTER";
31
31
  ERedisKey[ERedisKey["KEY_QUEUE_SETTINGS"] = 22] = "KEY_QUEUE_SETTINGS";
32
- ERedisKey[ERedisKey["KEY_QUEUE_SETTINGS_RATE_LIMIT"] = 23] = "KEY_QUEUE_SETTINGS_RATE_LIMIT";
33
- ERedisKey[ERedisKey["KEY_QUEUE_SETTINGS_PRIORITY_QUEUING"] = 24] = "KEY_QUEUE_SETTINGS_PRIORITY_QUEUING";
32
+ ERedisKey[ERedisKey["KEY_EXCHANGE_BINDINGS"] = 23] = "KEY_EXCHANGE_BINDINGS";
33
+ ERedisKey[ERedisKey["KEY_EXCHANGES"] = 24] = "KEY_EXCHANGES";
34
34
  })(ERedisKey || (ERedisKey = {}));
35
35
  function makeNamespacedKeys(keys, namespace, ...rest) {
36
36
  const result = {};
@@ -62,6 +62,13 @@ exports.redisKeys = {
62
62
  };
63
63
  return Object.assign(Object.assign({}, nsKeys), makeNamespacedKeys(queueKeys, queueParams.ns, queueParams.name));
64
64
  },
65
+ getFanOutExchangeKeys(bindingKey) {
66
+ const mainKeys = this.getMainKeys();
67
+ const exchangeKeys = {
68
+ keyExchangeBindings: ERedisKey.KEY_EXCHANGE_BINDINGS,
69
+ };
70
+ return Object.assign(Object.assign({}, mainKeys), makeNamespacedKeys(exchangeKeys, globalNamespace, bindingKey));
71
+ },
65
72
  getConsumerKeys(instanceId) {
66
73
  const mainKeys = this.getMainKeys();
67
74
  const consumerKeys = {
@@ -89,8 +96,7 @@ exports.redisKeys = {
89
96
  keyDelayedMessages: ERedisKey.KEY_DELAYED_MESSAGES,
90
97
  keyRequeueMessages: ERedisKey.KEY_REQUEUE_MESSAGES,
91
98
  keyNamespaces: ERedisKey.KEY_NAMESPACES,
92
- keyQueueSettingsRateLimit: ERedisKey.KEY_QUEUE_SETTINGS_RATE_LIMIT,
93
- keyQueueSettingsPriorityQueuing: ERedisKey.KEY_QUEUE_SETTINGS_PRIORITY_QUEUING,
99
+ keyExchanges: ERedisKey.KEY_EXCHANGES,
94
100
  };
95
101
  return makeNamespacedKeys(mainKeys, globalNamespace);
96
102
  },
@@ -105,11 +111,12 @@ exports.redisKeys = {
105
111
  if (!key || !key.length) {
106
112
  throw new redis_keys_error_1.RedisKeysError('Invalid Redis key. Expected be a non empty string.');
107
113
  }
108
- const filtered = key.toLowerCase().replace(/[^a-z0-9_-]/g, '');
109
- if (filtered.length !== key.length) {
110
- throw new redis_keys_error_1.RedisKeysError('Invalid Redis key. Only letters (a-z), numbers (0-9) and (-_) are allowed.');
114
+ const lowerCase = key.toLowerCase();
115
+ const filtered = lowerCase.replace(/(?:[a-z][a-z0-9]?)+(?:[-_.]?[a-z0-9])*/, '');
116
+ if (filtered.length) {
117
+ throw new redis_keys_error_1.RedisKeysError('Invalid Redis key. Valid characters are letters (a-z) and numbers (0-9). (-_) are allowed between alphanumerics. Use a dot (.) to denote hierarchies.');
111
118
  }
112
- return filtered;
119
+ return lowerCase;
113
120
  },
114
121
  };
115
122
  //# sourceMappingURL=redis-keys.js.map
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.acknowledgeMessage = void 0;
4
4
  const redis_keys_1 = require("../../../common/redis-keys/redis-keys");
5
5
  function acknowledgeMessage(config, redisClient, message, keyQueueProcessing, cb) {
6
- const queue = message.getRequiredQueue();
6
+ const queue = message.getDestinationQueue();
7
7
  const { store, queueSize, expire } = config.messages.store.acknowledged;
8
8
  if (store) {
9
9
  const { keyQueueAcknowledged } = redis_keys_1.redisKeys.getQueueKeys(queue);
@@ -4,7 +4,7 @@ exports.deadLetterMessage = void 0;
4
4
  const redis_keys_1 = require("../../../common/redis-keys/redis-keys");
5
5
  const redis_smq_common_1 = require("redis-smq-common");
6
6
  function deadLetterMessageTransaction(config, mixed, message, keyQueueProcessing) {
7
- const queue = message.getRequiredQueue();
7
+ const queue = message.getDestinationQueue();
8
8
  const { keyQueueDL } = redis_keys_1.redisKeys.getQueueKeys(queue);
9
9
  const { store, expire, queueSize } = config.messages.store.deadLettered;
10
10
  if (store) {
@@ -25,7 +25,7 @@ function deadLetterMessage(config, mixed, message, keyQueueProcessing, unacknowl
25
25
  if (mixed instanceof redis_smq_common_1.RedisClient) {
26
26
  if (!cb)
27
27
  throw new redis_smq_common_1.errors.PanicError(`Expected a callback function`);
28
- const queue = message.getRequiredQueue();
28
+ const queue = message.getDestinationQueue();
29
29
  const { keyQueueDL } = redis_keys_1.redisKeys.getQueueKeys(queue);
30
30
  const { store, expire, queueSize } = config.messages.store.deadLettered;
31
31
  if (store) {
@@ -4,7 +4,7 @@ exports.delayMessage = exports.delayMessageTransaction = void 0;
4
4
  const redis_keys_1 = require("../../../common/redis-keys/redis-keys");
5
5
  const redis_smq_common_1 = require("redis-smq-common");
6
6
  function delayMessageTransaction(mixed, message, keyQueueProcessing) {
7
- const queue = message.getRequiredQueue();
7
+ const queue = message.getDestinationQueue();
8
8
  const { keyDelayedMessages } = redis_keys_1.redisKeys.getQueueKeys(queue);
9
9
  mixed.rpoplpush(keyQueueProcessing, keyDelayedMessages);
10
10
  }
@@ -13,7 +13,7 @@ function delayMessage(mixed, message, keyQueueProcessing, unacknowledgedCause, c
13
13
  if (mixed instanceof redis_smq_common_1.RedisClient) {
14
14
  if (!cb)
15
15
  throw new redis_smq_common_1.errors.PanicError(`Expected a callback function`);
16
- const queue = message.getRequiredQueue();
16
+ const queue = message.getDestinationQueue();
17
17
  const { keyDelayedMessages } = redis_keys_1.redisKeys.getQueueKeys(queue);
18
18
  mixed.rpoplpush(keyQueueProcessing, keyDelayedMessages, (err) => cb(err));
19
19
  }
@@ -4,7 +4,7 @@ exports.requeueMessage = void 0;
4
4
  const redis_keys_1 = require("../../../common/redis-keys/redis-keys");
5
5
  const redis_smq_common_1 = require("redis-smq-common");
6
6
  function requeueMessage(mixed, message, keyQueueProcessing, unacknowledgedCause, cb) {
7
- const queue = message.getRequiredQueue();
7
+ const queue = message.getDestinationQueue();
8
8
  const { keyRequeueMessages } = redis_keys_1.redisKeys.getQueueKeys(queue);
9
9
  if (mixed instanceof redis_smq_common_1.RedisClient) {
10
10
  if (!cb)
@@ -0,0 +1,10 @@
1
+ import { Exchange } from './exchange';
2
+ import { EExchangeType, IDirectExchangeParams, IRequiredConfig, TQueueParams } from '../../../types';
3
+ import { RedisClient } from 'redis-smq-common';
4
+ import { ICallback } from 'redis-smq-common/dist/types';
5
+ export declare class DirectExchange extends Exchange<TQueueParams | string, EExchangeType.DIRECT> {
6
+ constructor(queue: TQueueParams | string);
7
+ protected validateBindingParams(queue: TQueueParams | string): TQueueParams | string;
8
+ getQueues(redisClient: RedisClient, config: IRequiredConfig, cb: ICallback<TQueueParams[]>): void;
9
+ static fromJSON(json: Partial<IDirectExchangeParams>): DirectExchange;
10
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DirectExchange = void 0;
4
+ const exchange_1 = require("./exchange");
5
+ const types_1 = require("../../../types");
6
+ const redis_keys_1 = require("../../common/redis-keys/redis-keys");
7
+ const queue_1 = require("../queue-manager/queue");
8
+ const invalid_exchange_data_error_1 = require("./errors/invalid-exchange-data.error");
9
+ class DirectExchange extends exchange_1.Exchange {
10
+ constructor(queue) {
11
+ super(queue, types_1.EExchangeType.DIRECT);
12
+ }
13
+ validateBindingParams(queue) {
14
+ return typeof queue === 'string'
15
+ ? redis_keys_1.redisKeys.validateRedisKey(queue)
16
+ : {
17
+ name: redis_keys_1.redisKeys.validateRedisKey(queue.name),
18
+ ns: redis_keys_1.redisKeys.validateNamespace(queue.ns),
19
+ };
20
+ }
21
+ getQueues(redisClient, config, cb) {
22
+ const queue = queue_1.Queue.getParams(config, this.bindingParams);
23
+ cb(null, [queue]);
24
+ }
25
+ static fromJSON(json) {
26
+ if (!json.bindingParams || json.type !== types_1.EExchangeType.DIRECT)
27
+ throw new invalid_exchange_data_error_1.InvalidExchangeDataError();
28
+ const e = new DirectExchange(json.bindingParams);
29
+ e.fromJSON(json);
30
+ return e;
31
+ }
32
+ }
33
+ exports.DirectExchange = DirectExchange;
34
+ //# sourceMappingURL=direct-exchange.js.map
@@ -0,0 +1,4 @@
1
+ import { ExchangeError } from './exchange.error';
2
+ export declare class DestinationQueueRequiredError extends ExchangeError {
3
+ constructor();
4
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DestinationQueueRequiredError = void 0;
4
+ const exchange_error_1 = require("./exchange.error");
5
+ class DestinationQueueRequiredError extends exchange_error_1.ExchangeError {
6
+ constructor() {
7
+ super(`Destination queue is required`);
8
+ }
9
+ }
10
+ exports.DestinationQueueRequiredError = DestinationQueueRequiredError;
11
+ //# sourceMappingURL=destination-queue-required.error.js.map
@@ -0,0 +1,3 @@
1
+ import { RedisSMQError } from 'redis-smq-common/dist/src/errors/redis-smq.error';
2
+ export declare class ExchangeError extends RedisSMQError {
3
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExchangeError = void 0;
4
+ const redis_smq_error_1 = require("redis-smq-common/dist/src/errors/redis-smq.error");
5
+ class ExchangeError extends redis_smq_error_1.RedisSMQError {
6
+ }
7
+ exports.ExchangeError = ExchangeError;
8
+ //# sourceMappingURL=exchange.error.js.map
@@ -0,0 +1,4 @@
1
+ import { ExchangeError } from './exchange.error';
2
+ export declare class InvalidExchangeDataError extends ExchangeError {
3
+ constructor();
4
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidExchangeDataError = void 0;
4
+ const exchange_error_1 = require("./exchange.error");
5
+ class InvalidExchangeDataError extends exchange_error_1.ExchangeError {
6
+ constructor() {
7
+ super('Invalid exchange data');
8
+ }
9
+ }
10
+ exports.InvalidExchangeDataError = InvalidExchangeDataError;
11
+ //# sourceMappingURL=invalid-exchange-data.error.js.map
@@ -0,0 +1,19 @@
1
+ import { EExchangeType, IExchangeParams, IRequiredConfig, TQueueParams } from '../../../types';
2
+ import { RedisClient } from 'redis-smq-common';
3
+ import { ICallback } from 'redis-smq-common/dist/types';
4
+ export declare abstract class Exchange<TBindingParams, TBindingType extends EExchangeType> {
5
+ protected exchangeTag: string;
6
+ protected destinationQueue: TQueueParams | null;
7
+ protected bindingParams: TBindingParams;
8
+ protected type: TBindingType;
9
+ protected constructor(bindingParams: TBindingParams, type: TBindingType);
10
+ protected generateExchangeTag(): string;
11
+ setDestinationQueue(queue: TQueueParams | null): void;
12
+ getBindingParams(): TBindingParams;
13
+ getDestinationQueue(): TQueueParams | null;
14
+ getRequiredDestinationQueue(): TQueueParams;
15
+ toJSON(): IExchangeParams<TBindingParams, TBindingType>;
16
+ fromJSON(JSON: Partial<IExchangeParams<TBindingParams, TBindingType>>): void;
17
+ protected abstract validateBindingParams(bindingParams: TBindingParams): TBindingParams;
18
+ abstract getQueues(redisClient: RedisClient, config: IRequiredConfig, cb: ICallback<TQueueParams[]>): void;
19
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Exchange = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const destination_queue_required_error_1 = require("./errors/destination-queue-required.error");
6
+ class Exchange {
7
+ constructor(bindingParams, type) {
8
+ this.destinationQueue = null;
9
+ this.bindingParams = this.validateBindingParams(bindingParams);
10
+ this.type = type;
11
+ this.exchangeTag = this.generateExchangeTag();
12
+ }
13
+ generateExchangeTag() {
14
+ return `${this.constructor.name
15
+ .replace(/([a-z])([A-Z])/, '$1-$2')
16
+ .toLowerCase()}-${(0, uuid_1.v4)()}`;
17
+ }
18
+ setDestinationQueue(queue) {
19
+ this.destinationQueue = queue;
20
+ }
21
+ getBindingParams() {
22
+ return this.bindingParams;
23
+ }
24
+ getDestinationQueue() {
25
+ return this.destinationQueue;
26
+ }
27
+ getRequiredDestinationQueue() {
28
+ if (!this.destinationQueue) {
29
+ throw new destination_queue_required_error_1.DestinationQueueRequiredError();
30
+ }
31
+ return this.destinationQueue;
32
+ }
33
+ toJSON() {
34
+ return {
35
+ exchangeTag: this.exchangeTag,
36
+ destinationQueue: this.destinationQueue,
37
+ bindingParams: this.bindingParams,
38
+ type: this.type,
39
+ };
40
+ }
41
+ fromJSON(JSON) {
42
+ if (JSON.destinationQueue)
43
+ this.setDestinationQueue(JSON.destinationQueue);
44
+ if (JSON.exchangeTag)
45
+ this.exchangeTag = JSON.exchangeTag;
46
+ if (JSON.type)
47
+ this.type = JSON.type;
48
+ }
49
+ }
50
+ exports.Exchange = Exchange;
51
+ //# sourceMappingURL=exchange.js.map
@@ -0,0 +1,21 @@
1
+ import { IConfig, IRequiredConfig, TQueueParams } from '../../../types';
2
+ import { RedisClient } from 'redis-smq-common';
3
+ import { ICallback, ICompatibleLogger } from 'redis-smq-common/dist/types';
4
+ import { FanOutExchange } from './fan-out-exchange';
5
+ export declare class FanOutExchangeManager {
6
+ protected config: IRequiredConfig;
7
+ protected redisClient: RedisClient;
8
+ protected logger: ICompatibleLogger;
9
+ protected constructor(config: IRequiredConfig, redisClient: RedisClient, logger: ICompatibleLogger);
10
+ createExchange(exchange: FanOutExchange, cb: ICallback<void>): void;
11
+ deleteExchange(exchange: FanOutExchange, cb: ICallback<void>): void;
12
+ bindQueue(queue: TQueueParams | string, exchange: FanOutExchange, cb: ICallback<void>): void;
13
+ unbindQueue(queue: TQueueParams | string, exchange: FanOutExchange, cb: ICallback<void>): void;
14
+ getExchanges(cb: ICallback<string[]>): void;
15
+ getExchangeQueues(exchange: FanOutExchange, cb: ICallback<TQueueParams[]>): void;
16
+ getQueueExchange(queue: TQueueParams | string, cb: ICallback<FanOutExchange | null>): void;
17
+ quit(cb: ICallback<void>): void;
18
+ static getExchangeQueues(redisClient: RedisClient, exchange: FanOutExchange, cb: ICallback<TQueueParams[]>): void;
19
+ static getQueueExchange(config: IRequiredConfig, redisClient: RedisClient, queue: TQueueParams | string, cb: ICallback<FanOutExchange | null>): void;
20
+ static createInstance(config: IConfig | undefined, cb: ICallback<FanOutExchangeManager>): void;
21
+ }