@ddd-ts-kit/redis 0.0.0-stage → 0.1.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 (282) hide show
  1. package/README.md +699 -2
  2. package/dist/cache/cache-codec.d.ts +6 -0
  3. package/dist/cache/cache-codec.d.ts.map +1 -0
  4. package/dist/cache/cache-codec.js +2 -0
  5. package/dist/cache/cache-codec.js.map +1 -0
  6. package/dist/cache/cache-operation.d.ts +3 -0
  7. package/dist/cache/cache-operation.d.ts.map +1 -0
  8. package/dist/cache/cache-operation.js +2 -0
  9. package/dist/cache/cache-operation.js.map +1 -0
  10. package/dist/cache/json-codec.d.ts +4 -0
  11. package/dist/cache/json-codec.d.ts.map +1 -0
  12. package/dist/cache/json-codec.js +9 -0
  13. package/dist/cache/json-codec.js.map +1 -0
  14. package/dist/cache/redis-cache.d.ts +65 -0
  15. package/dist/cache/redis-cache.d.ts.map +1 -0
  16. package/dist/cache/redis-cache.js +147 -0
  17. package/dist/cache/redis-cache.js.map +1 -0
  18. package/dist/connection/close-redis.d.ts +4 -0
  19. package/dist/connection/close-redis.d.ts.map +1 -0
  20. package/dist/connection/close-redis.js +20 -0
  21. package/dist/connection/close-redis.js.map +1 -0
  22. package/dist/connection/connect-redis.d.ts +10 -0
  23. package/dist/connection/connect-redis.d.ts.map +1 -0
  24. package/dist/connection/connect-redis.js +26 -0
  25. package/dist/connection/connect-redis.js.map +1 -0
  26. package/dist/connection/fail-fast.d.ts +9 -0
  27. package/dist/connection/fail-fast.d.ts.map +1 -0
  28. package/dist/connection/fail-fast.js +8 -0
  29. package/dist/connection/fail-fast.js.map +1 -0
  30. package/dist/connection/redis-connection-options.d.ts +7 -0
  31. package/dist/connection/redis-connection-options.d.ts.map +1 -0
  32. package/dist/connection/redis-connection-options.js +2 -0
  33. package/dist/connection/redis-connection-options.js.map +1 -0
  34. package/dist/connection/redis-health.d.ts +15 -0
  35. package/dist/connection/redis-health.d.ts.map +1 -0
  36. package/dist/connection/redis-health.js +31 -0
  37. package/dist/connection/redis-health.js.map +1 -0
  38. package/dist/connection/redis-source.d.ts +5 -0
  39. package/dist/connection/redis-source.d.ts.map +1 -0
  40. package/dist/connection/redis-source.js +2 -0
  41. package/dist/connection/redis-source.js.map +1 -0
  42. package/dist/event-bus.d.ts +22 -0
  43. package/dist/event-bus.d.ts.map +1 -0
  44. package/dist/event-bus.js +10 -0
  45. package/dist/event-bus.js.map +1 -0
  46. package/dist/index.d.ts +17 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +13 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/keys/namespaced.d.ts +3 -0
  51. package/dist/keys/namespaced.d.ts.map +1 -0
  52. package/dist/keys/namespaced.js +5 -0
  53. package/dist/keys/namespaced.js.map +1 -0
  54. package/dist/keys/prefix-pattern.d.ts +3 -0
  55. package/dist/keys/prefix-pattern.d.ts.map +1 -0
  56. package/dist/keys/prefix-pattern.js +5 -0
  57. package/dist/keys/prefix-pattern.js.map +1 -0
  58. package/dist/lock/redis-lock.d.ts +31 -0
  59. package/dist/lock/redis-lock.d.ts.map +1 -0
  60. package/dist/lock/redis-lock.js +66 -0
  61. package/dist/lock/redis-lock.js.map +1 -0
  62. package/dist/rate-limiter/redis-rate-limiter.d.ts +35 -0
  63. package/dist/rate-limiter/redis-rate-limiter.d.ts.map +1 -0
  64. package/dist/rate-limiter/redis-rate-limiter.js +77 -0
  65. package/dist/rate-limiter/redis-rate-limiter.js.map +1 -0
  66. package/dist/relay/redis-relay-signal.d.ts +36 -0
  67. package/dist/relay/redis-relay-signal.d.ts.map +1 -0
  68. package/dist/relay/redis-relay-signal.js +72 -0
  69. package/dist/relay/redis-relay-signal.js.map +1 -0
  70. package/dist/relay/relay-wake-up-middleware.d.ts +11 -0
  71. package/dist/relay/relay-wake-up-middleware.d.ts.map +1 -0
  72. package/dist/relay/relay-wake-up-middleware.js +16 -0
  73. package/dist/relay/relay-wake-up-middleware.js.map +1 -0
  74. package/dist/replies/list-of.d.ts +3 -0
  75. package/dist/replies/list-of.d.ts.map +1 -0
  76. package/dist/replies/list-of.js +8 -0
  77. package/dist/replies/list-of.js.map +1 -0
  78. package/dist/secrecy/conceal.d.ts +8 -0
  79. package/dist/secrecy/conceal.d.ts.map +1 -0
  80. package/dist/secrecy/conceal.js +12 -0
  81. package/dist/secrecy/conceal.js.map +1 -0
  82. package/dist/streams/bury.d.ts +13 -0
  83. package/dist/streams/bury.d.ts.map +1 -0
  84. package/dist/streams/bury.js +14 -0
  85. package/dist/streams/bury.js.map +1 -0
  86. package/dist/streams/claim-due.d.ts +18 -0
  87. package/dist/streams/claim-due.d.ts.map +1 -0
  88. package/dist/streams/claim-due.js +41 -0
  89. package/dist/streams/claim-due.js.map +1 -0
  90. package/dist/streams/codec/decode.d.ts +5 -0
  91. package/dist/streams/codec/decode.d.ts.map +1 -0
  92. package/dist/streams/codec/decode.js +40 -0
  93. package/dist/streams/codec/decode.js.map +1 -0
  94. package/dist/streams/codec/encode.d.ts +7 -0
  95. package/dist/streams/codec/encode.d.ts.map +1 -0
  96. package/dist/streams/codec/encode.js +20 -0
  97. package/dist/streams/codec/encode.js.map +1 -0
  98. package/dist/streams/codec/entries-by-stream.d.ts +4 -0
  99. package/dist/streams/codec/entries-by-stream.d.ts.map +1 -0
  100. package/dist/streams/codec/entries-by-stream.js +14 -0
  101. package/dist/streams/codec/entries-by-stream.js.map +1 -0
  102. package/dist/streams/codec/entries-of.d.ts +4 -0
  103. package/dist/streams/codec/entries-of.d.ts.map +1 -0
  104. package/dist/streams/codec/entries-of.js +16 -0
  105. package/dist/streams/codec/entries-of.js.map +1 -0
  106. package/dist/streams/codec/entry-fields.d.ts +13 -0
  107. package/dist/streams/codec/entry-fields.d.ts.map +1 -0
  108. package/dist/streams/codec/entry-fields.js +13 -0
  109. package/dist/streams/codec/entry-fields.js.map +1 -0
  110. package/dist/streams/codec/entry.d.ts +6 -0
  111. package/dist/streams/codec/entry.d.ts.map +1 -0
  112. package/dist/streams/codec/entry.js +2 -0
  113. package/dist/streams/codec/entry.js.map +1 -0
  114. package/dist/streams/codec/fields-with.d.ts +4 -0
  115. package/dist/streams/codec/fields-with.d.ts.map +1 -0
  116. package/dist/streams/codec/fields-with.js +6 -0
  117. package/dist/streams/codec/fields-with.js.map +1 -0
  118. package/dist/streams/codec/pending-entry.d.ts +7 -0
  119. package/dist/streams/codec/pending-entry.d.ts.map +1 -0
  120. package/dist/streams/codec/pending-entry.js +2 -0
  121. package/dist/streams/codec/pending-entry.js.map +1 -0
  122. package/dist/streams/codec/pending-of.d.ts +4 -0
  123. package/dist/streams/codec/pending-of.d.ts.map +1 -0
  124. package/dist/streams/codec/pending-of.js +11 -0
  125. package/dist/streams/codec/pending-of.js.map +1 -0
  126. package/dist/streams/codec/replay-fields.d.ts +4 -0
  127. package/dist/streams/codec/replay-fields.d.ts.map +1 -0
  128. package/dist/streams/codec/replay-fields.js +15 -0
  129. package/dist/streams/codec/replay-fields.js.map +1 -0
  130. package/dist/streams/consumption.d.ts +22 -0
  131. package/dist/streams/consumption.d.ts.map +1 -0
  132. package/dist/streams/consumption.js +46 -0
  133. package/dist/streams/consumption.js.map +1 -0
  134. package/dist/streams/delivery.d.ts +8 -0
  135. package/dist/streams/delivery.d.ts.map +1 -0
  136. package/dist/streams/delivery.js +2 -0
  137. package/dist/streams/delivery.js.map +1 -0
  138. package/dist/streams/errors/broker-unavailable-error.d.ts +8 -0
  139. package/dist/streams/errors/broker-unavailable-error.d.ts.map +1 -0
  140. package/dist/streams/errors/broker-unavailable-error.js +12 -0
  141. package/dist/streams/errors/broker-unavailable-error.js.map +1 -0
  142. package/dist/streams/errors/consumer-name-required-error.d.ts +5 -0
  143. package/dist/streams/errors/consumer-name-required-error.d.ts.map +1 -0
  144. package/dist/streams/errors/consumer-name-required-error.js +8 -0
  145. package/dist/streams/errors/consumer-name-required-error.js.map +1 -0
  146. package/dist/streams/errors/event-bus-closed-error.d.ts +5 -0
  147. package/dist/streams/errors/event-bus-closed-error.d.ts.map +1 -0
  148. package/dist/streams/errors/event-bus-closed-error.js +8 -0
  149. package/dist/streams/errors/event-bus-closed-error.js.map +1 -0
  150. package/dist/streams/errors/failure-code.d.ts +7 -0
  151. package/dist/streams/errors/failure-code.d.ts.map +1 -0
  152. package/dist/streams/errors/failure-code.js +28 -0
  153. package/dist/streams/errors/failure-code.js.map +1 -0
  154. package/dist/streams/errors/publish-not-confirmed-error.d.ts +9 -0
  155. package/dist/streams/errors/publish-not-confirmed-error.d.ts.map +1 -0
  156. package/dist/streams/errors/publish-not-confirmed-error.js +14 -0
  157. package/dist/streams/errors/publish-not-confirmed-error.js.map +1 -0
  158. package/dist/streams/group-reader.d.ts +57 -0
  159. package/dist/streams/group-reader.d.ts.map +1 -0
  160. package/dist/streams/group-reader.js +187 -0
  161. package/dist/streams/group-reader.js.map +1 -0
  162. package/dist/streams/messaging-system.d.ts +3 -0
  163. package/dist/streams/messaging-system.d.ts.map +1 -0
  164. package/dist/streams/messaging-system.js +3 -0
  165. package/dist/streams/messaging-system.js.map +1 -0
  166. package/dist/streams/options/deduplication-options.d.ts +5 -0
  167. package/dist/streams/options/deduplication-options.d.ts.map +1 -0
  168. package/dist/streams/options/deduplication-options.js +2 -0
  169. package/dist/streams/options/deduplication-options.js.map +1 -0
  170. package/dist/streams/options/default-prefix.d.ts +2 -0
  171. package/dist/streams/options/default-prefix.d.ts.map +1 -0
  172. package/dist/streams/options/default-prefix.js +2 -0
  173. package/dist/streams/options/default-prefix.js.map +1 -0
  174. package/dist/streams/options/reconnect-delay.d.ts +4 -0
  175. package/dist/streams/options/reconnect-delay.d.ts.map +1 -0
  176. package/dist/streams/options/reconnect-delay.js +5 -0
  177. package/dist/streams/options/reconnect-delay.js.map +1 -0
  178. package/dist/streams/options/reconnect-options.d.ts +9 -0
  179. package/dist/streams/options/reconnect-options.d.ts.map +1 -0
  180. package/dist/streams/options/reconnect-options.js +2 -0
  181. package/dist/streams/options/reconnect-options.js.map +1 -0
  182. package/dist/streams/options/redis-streams-delivery.d.ts +13 -0
  183. package/dist/streams/options/redis-streams-delivery.d.ts.map +1 -0
  184. package/dist/streams/options/redis-streams-delivery.js +2 -0
  185. package/dist/streams/options/redis-streams-delivery.js.map +1 -0
  186. package/dist/streams/options/redis-streams-event-bus-options.d.ts +48 -0
  187. package/dist/streams/options/redis-streams-event-bus-options.d.ts.map +1 -0
  188. package/dist/streams/options/redis-streams-event-bus-options.js +2 -0
  189. package/dist/streams/options/redis-streams-event-bus-options.js.map +1 -0
  190. package/dist/streams/options/redis-streams-failure.d.ts +19 -0
  191. package/dist/streams/options/redis-streams-failure.d.ts.map +1 -0
  192. package/dist/streams/options/redis-streams-failure.js +2 -0
  193. package/dist/streams/options/redis-streams-failure.js.map +1 -0
  194. package/dist/streams/options/retention-options.d.ts +10 -0
  195. package/dist/streams/options/retention-options.d.ts.map +1 -0
  196. package/dist/streams/options/retention-options.js +2 -0
  197. package/dist/streams/options/retention-options.js.map +1 -0
  198. package/dist/streams/options/retry-options.d.ts +7 -0
  199. package/dist/streams/options/retry-options.d.ts.map +1 -0
  200. package/dist/streams/options/retry-options.js +2 -0
  201. package/dist/streams/options/retry-options.js.map +1 -0
  202. package/dist/streams/options/settings-of.d.ts +4 -0
  203. package/dist/streams/options/settings-of.d.ts.map +1 -0
  204. package/dist/streams/options/settings-of.js +47 -0
  205. package/dist/streams/options/settings-of.js.map +1 -0
  206. package/dist/streams/options/settings.d.ts +28 -0
  207. package/dist/streams/options/settings.d.ts.map +1 -0
  208. package/dist/streams/options/settings.js +2 -0
  209. package/dist/streams/options/settings.js.map +1 -0
  210. package/dist/streams/publications.d.ts +22 -0
  211. package/dist/streams/publications.d.ts.map +1 -0
  212. package/dist/streams/publications.js +75 -0
  213. package/dist/streams/publications.js.map +1 -0
  214. package/dist/streams/redis-streams-event-bus.d.ts +55 -0
  215. package/dist/streams/redis-streams-event-bus.d.ts.map +1 -0
  216. package/dist/streams/redis-streams-event-bus.js +120 -0
  217. package/dist/streams/redis-streams-event-bus.js.map +1 -0
  218. package/dist/streams/replay.d.ts +13 -0
  219. package/dist/streams/replay.d.ts.map +1 -0
  220. package/dist/streams/replay.js +26 -0
  221. package/dist/streams/replay.js.map +1 -0
  222. package/dist/streams/server-link.d.ts +45 -0
  223. package/dist/streams/server-link.d.ts.map +1 -0
  224. package/dist/streams/server-link.js +129 -0
  225. package/dist/streams/server-link.js.map +1 -0
  226. package/dist/streams/settlement.d.ts +46 -0
  227. package/dist/streams/settlement.d.ts.map +1 -0
  228. package/dist/streams/settlement.js +139 -0
  229. package/dist/streams/settlement.js.map +1 -0
  230. package/dist/streams/topology/consumer-binding.d.ts +5 -0
  231. package/dist/streams/topology/consumer-binding.d.ts.map +1 -0
  232. package/dist/streams/topology/consumer-binding.js +2 -0
  233. package/dist/streams/topology/consumer-binding.js.map +1 -0
  234. package/dist/streams/topology/create-group.d.ts +4 -0
  235. package/dist/streams/topology/create-group.d.ts.map +1 -0
  236. package/dist/streams/topology/create-group.js +13 -0
  237. package/dist/streams/topology/create-group.js.map +1 -0
  238. package/dist/streams/topology/dead-stream-of.d.ts +3 -0
  239. package/dist/streams/topology/dead-stream-of.d.ts.map +1 -0
  240. package/dist/streams/topology/dead-stream-of.js +5 -0
  241. package/dist/streams/topology/dead-stream-of.js.map +1 -0
  242. package/dist/streams/topology/declare-topology.d.ts +5 -0
  243. package/dist/streams/topology/declare-topology.d.ts.map +1 -0
  244. package/dist/streams/topology/declare-topology.js +8 -0
  245. package/dist/streams/topology/declare-topology.js.map +1 -0
  246. package/dist/streams/topology/group-description.d.ts +7 -0
  247. package/dist/streams/topology/group-description.d.ts.map +1 -0
  248. package/dist/streams/topology/group-description.js +2 -0
  249. package/dist/streams/topology/group-description.js.map +1 -0
  250. package/dist/streams/topology/group-of.d.ts +5 -0
  251. package/dist/streams/topology/group-of.d.ts.map +1 -0
  252. package/dist/streams/topology/group-of.js +4 -0
  253. package/dist/streams/topology/group-of.js.map +1 -0
  254. package/dist/streams/topology/redis-streams-topology.d.ts +8 -0
  255. package/dist/streams/topology/redis-streams-topology.d.ts.map +1 -0
  256. package/dist/streams/topology/redis-streams-topology.js +2 -0
  257. package/dist/streams/topology/redis-streams-topology.js.map +1 -0
  258. package/dist/streams/topology/stream-description.d.ts +12 -0
  259. package/dist/streams/topology/stream-description.d.ts.map +1 -0
  260. package/dist/streams/topology/stream-description.js +2 -0
  261. package/dist/streams/topology/stream-description.js.map +1 -0
  262. package/dist/streams/topology/stream-names-of.d.ts +5 -0
  263. package/dist/streams/topology/stream-names-of.d.ts.map +1 -0
  264. package/dist/streams/topology/stream-names-of.js +11 -0
  265. package/dist/streams/topology/stream-names-of.js.map +1 -0
  266. package/dist/streams/topology/stream-names.d.ts +5 -0
  267. package/dist/streams/topology/stream-names.d.ts.map +1 -0
  268. package/dist/streams/topology/stream-names.js +2 -0
  269. package/dist/streams/topology/stream-names.js.map +1 -0
  270. package/dist/streams/topology/topology-of.d.ts +5 -0
  271. package/dist/streams/topology/topology-of.d.ts.map +1 -0
  272. package/dist/streams/topology/topology-of.js +21 -0
  273. package/dist/streams/topology/topology-of.js.map +1 -0
  274. package/dist/streams/topology/topology-settings.d.ts +7 -0
  275. package/dist/streams/topology/topology-settings.d.ts.map +1 -0
  276. package/dist/streams/topology/topology-settings.js +2 -0
  277. package/dist/streams/topology/topology-settings.js.map +1 -0
  278. package/dist/testing.d.ts +2 -0
  279. package/dist/testing.d.ts.map +1 -0
  280. package/dist/testing.js +2 -0
  281. package/dist/testing.js.map +1 -0
  282. package/package.json +51 -4
@@ -0,0 +1,187 @@
1
+ import { inEventScope } from '@ddd-ts-kit/kernel';
2
+ import { closeRedis } from '../connection/close-redis.js';
3
+ import { claimDue } from './claim-due.js';
4
+ import { entriesByStream } from './codec/entries-by-stream.js';
5
+ import { BrokerUnavailableError } from './errors/broker-unavailable-error.js';
6
+ import { EventBusClosedError } from './errors/event-bus-closed-error.js';
7
+ import { failureCode } from './errors/failure-code.js';
8
+ import { reconnectDelay } from './options/reconnect-delay.js';
9
+ import { Settlement } from './settlement.js';
10
+ import { createGroup } from './topology/create-group.js';
11
+ import { groupOf } from './topology/group-of.js';
12
+ const NO_HANDLER = new Set();
13
+ /**
14
+ * One consumer on its dedicated connection: a blocking read must not hold up the connection
15
+ * that publishes and acknowledges. The consumer is a group on each stream it subscribed to,
16
+ * and this process one member of it. A turn takes back the pending entries that are due, then
17
+ * waits for new ones for a bounded time; the entries of a stream are handled in their order,
18
+ * one at a time.
19
+ */
20
+ export class GroupReader {
21
+ consumer;
22
+ link;
23
+ settings;
24
+ subscriptions = new Map();
25
+ declared = new Set();
26
+ settlement;
27
+ running;
28
+ interrupt;
29
+ stopping = false;
30
+ unsettled = 0;
31
+ failures = 0;
32
+ sweptAt = 0;
33
+ constructor(consumer, link, settings) {
34
+ this.consumer = consumer;
35
+ this.link = link;
36
+ this.settings = settings;
37
+ this.settlement = new Settlement(link.client, { ...settings, consumer });
38
+ }
39
+ /** Entries read by this reader and not settled yet. */
40
+ get inFlight() {
41
+ return this.unsettled;
42
+ }
43
+ get idle() {
44
+ return this.subscriptions.size === 0;
45
+ }
46
+ bindings() {
47
+ return [...this.subscriptions.values()].map(({ type }) => ({ consumer: this.consumer, type }));
48
+ }
49
+ subscribe(type, handler) {
50
+ const stream = this.settings.streamOf(type);
51
+ const subscription = this.subscriptions.get(stream) ?? { type, handlers: new Set() };
52
+ const { scope } = this.settings;
53
+ const scoped = scope === undefined ? handler : inEventScope(scope, { consumer: this.consumer }, handler);
54
+ subscription.handlers.add(scoped);
55
+ this.subscriptions.set(stream, subscription);
56
+ this.running ??= this.run();
57
+ return {
58
+ unsubscribe: () => {
59
+ this.remove(stream, scoped);
60
+ },
61
+ };
62
+ }
63
+ /** Creates the group on every stream subscribed to so far that does not have it yet. */
64
+ async declare(client) {
65
+ for (const { consumer, type } of this.bindings()) {
66
+ const group = groupOf(this.settings, { consumer, type });
67
+ if (!this.declared.has(group.stream)) {
68
+ await createGroup(client, group);
69
+ this.declared.add(group.stream);
70
+ }
71
+ }
72
+ }
73
+ /** Reads nothing more, lets the batch in progress finish and settle, then leaves the group. */
74
+ async stop() {
75
+ this.stopping = true;
76
+ this.interrupt?.();
77
+ await this.running;
78
+ }
79
+ // The group stays, with its position: the consumer keeps accumulating, it only stopped reading.
80
+ remove(stream, handler) {
81
+ const subscription = this.subscriptions.get(stream);
82
+ subscription?.handlers.delete(handler);
83
+ if (subscription?.handlers.size === 0) {
84
+ this.subscriptions.delete(stream);
85
+ }
86
+ }
87
+ async run() {
88
+ const reader = this.link.reader();
89
+ while (!this.stopping) {
90
+ try {
91
+ await this.turn(reader);
92
+ this.failures = 0;
93
+ }
94
+ catch (error) {
95
+ await this.recover(error);
96
+ }
97
+ }
98
+ await this.leave(reader);
99
+ }
100
+ async turn(reader) {
101
+ await this.declare(await this.link.ready());
102
+ const streams = [...this.subscriptions.keys()];
103
+ if (this.sweepIsDue()) {
104
+ const due = await Promise.all(streams.map((stream) => claimDue(reader, stream, this.redelivery())));
105
+ await this.handle(due.flat());
106
+ }
107
+ if (!this.stopping && streams.length > 0) {
108
+ await this.handle(await this.read(reader, streams));
109
+ }
110
+ }
111
+ sweepIsDue() {
112
+ const { blockMs, retry } = this.settings;
113
+ if (Date.now() - this.sweptAt < Math.min(blockMs, retry.delayMs)) {
114
+ return false;
115
+ }
116
+ this.sweptAt = Date.now();
117
+ return true;
118
+ }
119
+ redelivery() {
120
+ const { instance, batchSize, retry } = this.settings;
121
+ // Never below the retry delay: an entry waiting for its retry is not an abandoned one.
122
+ const visibilityTimeoutMs = Math.max(this.settings.visibilityTimeoutMs, retry.delayMs);
123
+ return { consumer: this.consumer, instance, batchSize, retryDelayMs: retry.delayMs, visibilityTimeoutMs };
124
+ }
125
+ async handle(deliveries) {
126
+ this.unsettled += deliveries.length;
127
+ const streams = [...new Set(deliveries.map((delivery) => delivery.stream))];
128
+ await Promise.all(streams.map((stream) => this.inOrder(deliveries.filter((delivery) => delivery.stream === stream))));
129
+ }
130
+ async inOrder(deliveries) {
131
+ for (const delivery of deliveries) {
132
+ const handlers = this.subscriptions.get(delivery.stream)?.handlers ?? NO_HANDLER;
133
+ await this.settlement.settle(delivery, handlers);
134
+ this.unsettled -= 1;
135
+ }
136
+ }
137
+ async read(reader, streams) {
138
+ const { instance, batchSize, blockMs } = this.settings;
139
+ const ids = streams.map(() => '>');
140
+ // The named command, not `call`: ioredis maps the reply of the commands it knows to its classic shape.
141
+ const reply = await reader.xreadgroup('GROUP', this.consumer, instance, 'COUNT', batchSize, 'BLOCK', blockMs, 'STREAMS', ...streams, ...ids);
142
+ return [...entriesByStream(reply)].flatMap(([stream, entries]) => entries.map((entry) => ({ stream, entry, attempt: 1 })));
143
+ }
144
+ /**
145
+ * After a failure the groups are created again before the next read: a server that came
146
+ * back without its data has lost them. The link already reported a connection that is down.
147
+ */
148
+ async recover(error) {
149
+ this.declared.clear();
150
+ if (!(error instanceof BrokerUnavailableError) && !(error instanceof EventBusClosedError)) {
151
+ this.settings.onFailure({ kind: 'connection', code: failureCode(error) });
152
+ }
153
+ this.failures += 1;
154
+ await this.rest(reconnectDelay(this.settings.reconnect, this.failures));
155
+ }
156
+ rest(ms) {
157
+ if (this.stopping) {
158
+ return Promise.resolve();
159
+ }
160
+ return new Promise((resolve) => {
161
+ const timer = setTimeout(resolve, ms);
162
+ this.interrupt = () => {
163
+ clearTimeout(timer);
164
+ resolve();
165
+ };
166
+ });
167
+ }
168
+ async leave(reader) {
169
+ await this.retire().catch(() => undefined);
170
+ await closeRedis(reader);
171
+ }
172
+ /**
173
+ * Removes this process from its groups, where it leaves nothing pending: deleting a
174
+ * consumer drops its pending entries, and those must stay for another instance to claim.
175
+ */
176
+ async retire() {
177
+ const { client } = this.link;
178
+ const { instance } = this.settings;
179
+ for (const stream of this.declared) {
180
+ const pending = await client.xpending(stream, this.consumer, '-', '+', 1, instance);
181
+ if (pending.length === 0) {
182
+ await client.xgroup('DELCONSUMER', stream, this.consumer, instance);
183
+ }
184
+ }
185
+ }
186
+ }
187
+ //# sourceMappingURL=group-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-reader.js","sourceRoot":"","sources":["../../src/streams/group-reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The name of the transport in what the bus says of itself and of each delivery. */
2
+ export declare const MESSAGING_SYSTEM = "redis";
3
+ //# sourceMappingURL=messaging-system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-system.d.ts","sourceRoot":"","sources":["../../src/streams/messaging-system.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,eAAO,MAAM,gBAAgB,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The name of the transport in what the bus says of itself and of each delivery. */
2
+ export const MESSAGING_SYSTEM = 'redis';
3
+ //# sourceMappingURL=messaging-system.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-system.js","sourceRoot":"","sources":["../../src/streams/messaging-system.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface DeduplicationOptions {
2
+ /** How long the id of a published event is remembered. A relay retry within it appends nothing. */
3
+ readonly windowMs: number;
4
+ }
5
+ //# sourceMappingURL=deduplication-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deduplication-options.d.ts","sourceRoot":"","sources":["../../../src/streams/options/deduplication-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,mGAAmG;IACnG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=deduplication-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deduplication-options.js","sourceRoot":"","sources":["../../../src/streams/options/deduplication-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_PREFIX = "integration-events";
2
+ //# sourceMappingURL=default-prefix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-prefix.d.ts","sourceRoot":"","sources":["../../../src/streams/options/default-prefix.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_PREFIX = 'integration-events';
2
+ //# sourceMappingURL=default-prefix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-prefix.js","sourceRoot":"","sources":["../../../src/streams/options/default-prefix.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,oBAAoB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ReconnectOptions } from './reconnect-options.js';
2
+ /** The delay before the given attempt, counted from 1: it grows by the factor up to the bound. */
3
+ export declare function reconnectDelay(reconnect: Required<ReconnectOptions>, attempt: number): number;
4
+ //# sourceMappingURL=reconnect-delay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect-delay.d.ts","sourceRoot":"","sources":["../../../src/streams/options/reconnect-delay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7F"}
@@ -0,0 +1,5 @@
1
+ /** The delay before the given attempt, counted from 1: it grows by the factor up to the bound. */
2
+ export function reconnectDelay(reconnect, attempt) {
3
+ return Math.min(reconnect.maxMs, reconnect.initialMs * reconnect.factor ** (attempt - 1));
4
+ }
5
+ //# sourceMappingURL=reconnect-delay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect-delay.js","sourceRoot":"","sources":["../../../src/streams/options/reconnect-delay.ts"],"names":[],"mappings":"AAEA,kGAAkG;AAClG,MAAM,UAAU,cAAc,CAAC,SAAqC,EAAE,OAAe;IACnF,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface ReconnectOptions {
2
+ /** Delay before the first reconnection attempt. Default 200. */
3
+ readonly initialMs?: number;
4
+ /** Multiplier applied at each further attempt. Default 2. */
5
+ readonly factor?: number;
6
+ /** Upper bound of the delay. Default 30000. */
7
+ readonly maxMs?: number;
8
+ }
9
+ //# sourceMappingURL=reconnect-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect-options.d.ts","sourceRoot":"","sources":["../../../src/streams/options/reconnect-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reconnect-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect-options.js","sourceRoot":"","sources":["../../../src/streams/options/reconnect-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ /** One entry settled by a consumer of this bus. Counted by outcome, it is the metric to watch. */
2
+ export interface RedisStreamsDelivery {
3
+ readonly stream: string;
4
+ readonly consumer: string;
5
+ /** Which delivery of the entry this was, starting at 1: the delivery counter of the pending entry list. */
6
+ readonly attempt: number;
7
+ /**
8
+ * `acknowledged`: every handler resolved. `retried`: left pending for another delivery.
9
+ * `dead`: attempts spent, moved to the dead stream. `poison`: not an envelope, moved there too.
10
+ */
11
+ readonly outcome: 'acknowledged' | 'retried' | 'dead' | 'poison';
12
+ }
13
+ //# sourceMappingURL=redis-streams-delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-delivery.d.ts","sourceRoot":"","sources":["../../../src/streams/options/redis-streams-delivery.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,2GAA2G;IAC3G,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;CAClE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=redis-streams-delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-delivery.js","sourceRoot":"","sources":["../../../src/streams/options/redis-streams-delivery.ts"],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import type { ExecutionScope } from '@ddd-ts-kit/kernel';
2
+ import type { RedisSource } from '../../connection/redis-source.js';
3
+ import type { DeduplicationOptions } from './deduplication-options.js';
4
+ import type { ReconnectOptions } from './reconnect-options.js';
5
+ import type { RedisStreamsDelivery } from './redis-streams-delivery.js';
6
+ import type { RedisStreamsFailure } from './redis-streams-failure.js';
7
+ import type { RetentionOptions } from './retention-options.js';
8
+ import type { RetryOptions } from './retry-options.js';
9
+ export interface RedisStreamsEventBusOptions {
10
+ /**
11
+ * A connection URL, ioredis options, or a client the application already owns. The bus
12
+ * publishes and acknowledges on it, and duplicates it for each blocking reader. It closes
13
+ * what it opened; a client it was handed stays open.
14
+ */
15
+ readonly connection: RedisSource;
16
+ /** Events of a type go to the stream `<prefix>:<type>`. Default `integration-events`. */
17
+ readonly prefix?: string;
18
+ /** The stream of an event type, when `<prefix>:<type>` does not suit. Publishers and consumers must agree. */
19
+ readonly streamOf?: (type: string) => string;
20
+ /** The consuming context `subscribe` reads for: the name of its consumer group. See also `forConsumer`. */
21
+ readonly consumer?: string;
22
+ /** The name of this process inside its groups. Default: host, process id and a random suffix. */
23
+ readonly instance?: string;
24
+ /** Entries read at once per stream, then handled one after the other. Default 10. */
25
+ readonly batchSize?: number;
26
+ /** How long a read waits for new entries. It bounds `close()` and the precision of the retry delay. Default 1000. */
27
+ readonly blockMs?: number;
28
+ /**
29
+ * Idle time after which the pending entries of ANOTHER instance are taken over: it crashed,
30
+ * or it is stuck. Keep it above the worst case of a whole batch. Default 60000.
31
+ */
32
+ readonly visibilityTimeoutMs?: number;
33
+ /** Where a group created by this bus starts: entries published from now on (default), or the whole stream. */
34
+ readonly startFrom?: 'new' | 'beginning';
35
+ readonly retry?: RetryOptions;
36
+ readonly reconnect?: ReconnectOptions;
37
+ /** Default: none, streams grow until trimmed by the operator. */
38
+ readonly retention?: RetentionOptions;
39
+ /** A publish-side guard against the duplicates of a relay retry. Default: none, consumers deduplicate. */
40
+ readonly deduplication?: DeduplicationOptions;
41
+ /** When given, every handler runs inside it, in the execution context of its event. */
42
+ readonly scope?: ExecutionScope;
43
+ /** Observability hook. It receives codes only, so it is safe to log as is. */
44
+ readonly onFailure?: (failure: RedisStreamsFailure) => void;
45
+ /** Metrics hook, called once per entry a consumer settles, before it is acknowledged. */
46
+ readonly onDelivery?: (delivery: RedisStreamsDelivery) => void;
47
+ }
48
+ //# sourceMappingURL=redis-streams-event-bus-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-event-bus-options.d.ts","sourceRoot":"","sources":["../../../src/streams/options/redis-streams-event-bus-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IAEjC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,8GAA8G;IAC9G,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAE7C,2GAA2G;IAC3G,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,iGAAiG;IACjG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,qFAAqF;IACrF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,qHAAqH;IACrH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAEtC,8GAA8G;IAC9G,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;IAEzC,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAE9B,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAEtC,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAEtC,0GAA0G;IAC1G,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,CAAC;IAE9C,uFAAuF;IACvF,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAEhC,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAE5D,yFAAyF;IACzF,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAChE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=redis-streams-event-bus-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-event-bus-options.js","sourceRoot":"","sources":["../../../src/streams/options/redis-streams-event-bus-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ export type RedisStreamsFailure = {
2
+ readonly kind: 'handler';
3
+ readonly stream: string;
4
+ readonly consumer: string;
5
+ readonly eventId: string;
6
+ readonly eventType: string;
7
+ readonly code: string;
8
+ readonly attempt: number;
9
+ readonly dead: boolean;
10
+ } | {
11
+ readonly kind: 'poison';
12
+ readonly stream: string;
13
+ readonly consumer: string;
14
+ readonly code: string;
15
+ } | {
16
+ readonly kind: 'connection';
17
+ readonly code: string;
18
+ };
19
+ //# sourceMappingURL=redis-streams-failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-failure.d.ts","sourceRoot":"","sources":["../../../src/streams/options/redis-streams-failure.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=redis-streams-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-failure.js","sourceRoot":"","sources":["../../../src/streams/options/redis-streams-failure.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Trimming applied by each publication, approximately (`~`). It drops the oldest entries
3
+ * whether or not every consumer group has read them: an opt-in, never a default.
4
+ */
5
+ export type RetentionOptions = {
6
+ readonly maxLength: number;
7
+ } | {
8
+ readonly maxAgeMs: number;
9
+ };
10
+ //# sourceMappingURL=retention-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention-options.d.ts","sourceRoot":"","sources":["../../../src/streams/options/retention-options.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAA+D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC3F;IAAwF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retention-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention-options.js","sourceRoot":"","sources":["../../../src/streams/options/retention-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ export interface RetryOptions {
2
+ /** Deliveries after which an entry goes to the dead stream. Default 5. */
3
+ readonly maxAttempts?: number;
4
+ /** Time a failed entry waits before it is delivered again. Default 5000. */
5
+ readonly delayMs?: number;
6
+ }
7
+ //# sourceMappingURL=retry-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-options.d.ts","sourceRoot":"","sources":["../../../src/streams/options/retry-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retry-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-options.js","sourceRoot":"","sources":["../../../src/streams/options/retry-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { RedisStreamsEventBusOptions } from './redis-streams-event-bus-options.js';
2
+ import type { Settings } from './settings.js';
3
+ export declare function settingsOf(options: RedisStreamsEventBusOptions): Settings;
4
+ //# sourceMappingURL=settings-of.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-of.d.ts","sourceRoot":"","sources":["../../../src/streams/options/settings-of.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AAExF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,wBAAgB,UAAU,CAAC,OAAO,EAAE,2BAA2B,GAAG,QAAQ,CAmBzE"}
@@ -0,0 +1,47 @@
1
+ import { hostname } from 'node:os';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { DEFAULT_PREFIX } from './default-prefix.js';
4
+ export function settingsOf(options) {
5
+ const prefix = options.prefix ?? DEFAULT_PREFIX;
6
+ return {
7
+ streamOf: options.streamOf ?? ((type) => `${prefix}:${type}`),
8
+ consumer: options.consumer,
9
+ instance: options.instance ?? processName(),
10
+ batchSize: options.batchSize ?? 10,
11
+ blockMs: options.blockMs ?? 1_000,
12
+ visibilityTimeoutMs: options.visibilityTimeoutMs ?? 60_000,
13
+ startFrom: options.startFrom ?? 'new',
14
+ retry: retryOf(options.retry),
15
+ reconnect: reconnectOf(options.reconnect),
16
+ retention: options.retention,
17
+ deduplication: options.deduplication,
18
+ scope: options.scope,
19
+ onFailure: guarded(options.onFailure),
20
+ onDelivery: guarded(options.onDelivery),
21
+ };
22
+ }
23
+ function processName() {
24
+ return `${hostname()}-${String(process.pid)}-${randomBytes(4).toString('hex')}`;
25
+ }
26
+ function retryOf(retry = {}) {
27
+ return { maxAttempts: retry.maxAttempts ?? 5, delayMs: retry.delayMs ?? 5_000 };
28
+ }
29
+ function reconnectOf(reconnect = {}) {
30
+ return {
31
+ initialMs: reconnect.initialMs ?? 200,
32
+ factor: reconnect.factor ?? 2,
33
+ maxMs: reconnect.maxMs ?? 30_000,
34
+ };
35
+ }
36
+ // A hook that throws must not leave an entry unsettled or stop a reader.
37
+ function guarded(hook) {
38
+ return (value) => {
39
+ try {
40
+ hook?.(value);
41
+ }
42
+ catch {
43
+ return;
44
+ }
45
+ };
46
+ }
47
+ //# sourceMappingURL=settings-of.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-of.js","sourceRoot":"","sources":["../../../src/streams/options/settings-of.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMrD,MAAM,UAAU,UAAU,CAAC,OAAoC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC;IAEhD,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;QAC7D,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE;QAC3C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;QACjC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,IAAI,MAAM;QAC1D,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;QACrC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QAC7B,SAAS,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC;QACzC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QACrC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,GAAG,QAAQ,EAAE,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAClF,CAAC;AAED,SAAS,OAAO,CAAC,KAAK,GAAiB,EAAE;IACvC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC;AAClF,CAAC;AAED,SAAS,WAAW,CAAC,SAAS,GAAqB,EAAE;IACnD,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,GAAG;QACrC,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,CAAC;QAC7B,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,MAAM;KACjC,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,OAAO,CAAI,IAAsC;IACxD,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { ExecutionScope } from '@ddd-ts-kit/kernel';
2
+ import type { DeduplicationOptions } from './deduplication-options.js';
3
+ import type { ReconnectOptions } from './reconnect-options.js';
4
+ import type { RedisStreamsDelivery } from './redis-streams-delivery.js';
5
+ import type { RedisStreamsFailure } from './redis-streams-failure.js';
6
+ import type { RetentionOptions } from './retention-options.js';
7
+ import type { RetryOptions } from './retry-options.js';
8
+ /**
9
+ * The options of a bus with their defaults applied. The connection is not among them: a URL
10
+ * may carry a password, and nothing that outlives the constructor keeps it.
11
+ */
12
+ export interface Settings {
13
+ readonly streamOf: (type: string) => string;
14
+ readonly consumer: string | undefined;
15
+ readonly instance: string;
16
+ readonly batchSize: number;
17
+ readonly blockMs: number;
18
+ readonly visibilityTimeoutMs: number;
19
+ readonly startFrom: 'new' | 'beginning';
20
+ readonly retry: Required<RetryOptions>;
21
+ readonly reconnect: Required<ReconnectOptions>;
22
+ readonly retention: RetentionOptions | undefined;
23
+ readonly deduplication: DeduplicationOptions | undefined;
24
+ readonly scope: ExecutionScope | undefined;
25
+ readonly onFailure: (failure: RedisStreamsFailure) => void;
26
+ readonly onDelivery: (delivery: RedisStreamsDelivery) => void;
27
+ }
28
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/streams/options/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,WAAW,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC/D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/streams/options/settings.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import type { Redis } from 'ioredis';
2
+ import type { IntegrationEvent } from '@ddd-ts-kit/kernel';
3
+ import type { DeduplicationOptions } from './options/deduplication-options.js';
4
+ import type { RetentionOptions } from './options/retention-options.js';
5
+ export interface PublicationSettings {
6
+ readonly streamOf: (type: string) => string;
7
+ readonly retention: RetentionOptions | undefined;
8
+ readonly deduplication: DeduplicationOptions | undefined;
9
+ }
10
+ /**
11
+ * Publishing: one `XADD` per event, the whole batch in one `MULTI`. A publication succeeds
12
+ * only once the server answered an entry id for every event, which is what lets an outbox
13
+ * relay mark them published.
14
+ */
15
+ export declare class Publications {
16
+ private readonly settings;
17
+ constructor(settings: PublicationSettings);
18
+ /** Resolves when every event has an entry; rejects with the first failure otherwise. */
19
+ publish(client: Redis, events: readonly IntegrationEvent[]): Promise<void>;
20
+ private append;
21
+ }
22
+ //# sourceMappingURL=publications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publications.d.ts","sourceRoot":"","sources":["../../src/streams/publications.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,KAAK,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,oBAAoB,GAAG,SAAS,CAAC;CAC1D;AAiBD;;;;GAIG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAArC,YAA6B,QAAQ,EAAE,mBAAmB,EAAI;IAE9D,wFAAwF;IAClF,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB/E;IAED,OAAO,CAAC,MAAM;CAWf"}