@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,75 @@
1
+ import { encode } from './codec/encode.js';
2
+ import { failureCode } from './errors/failure-code.js';
3
+ import { PublishNotConfirmedError } from './errors/publish-not-confirmed-error.js';
4
+ /**
5
+ * Appends unless the event id was appended within the window, and answers the entry id either
6
+ * way. The append comes first: were the mark written first, a failed append would make the
7
+ * retry believe the event is there. KEYS: mark, stream. ARGV: window, then the arguments of
8
+ * `XADD` after the key.
9
+ */
10
+ const GUARDED_APPEND = `
11
+ local known = redis.call('GET', KEYS[1])
12
+ if known then
13
+ return known
14
+ end
15
+ local entry = redis.call('XADD', KEYS[2], unpack(ARGV, 2))
16
+ redis.call('SET', KEYS[1], entry, 'PX', ARGV[1])
17
+ return entry`;
18
+ /**
19
+ * Publishing: one `XADD` per event, the whole batch in one `MULTI`. A publication succeeds
20
+ * only once the server answered an entry id for every event, which is what lets an outbox
21
+ * relay mark them published.
22
+ */
23
+ export class Publications {
24
+ settings;
25
+ constructor(settings) {
26
+ this.settings = settings;
27
+ }
28
+ /** Resolves when every event has an entry; rejects with the first failure otherwise. */
29
+ async publish(client, events) {
30
+ const transaction = client.multi();
31
+ for (const event of events) {
32
+ this.append(transaction, event);
33
+ }
34
+ const answers = await executed(transaction, events);
35
+ events.forEach((event, index) => {
36
+ const [error, entryId] = answers[index] ?? [new Error('no answer'), undefined];
37
+ if (error !== null) {
38
+ throw new PublishNotConfirmedError(event.id, failureCode(error));
39
+ }
40
+ if (typeof entryId !== 'string') {
41
+ throw new PublishNotConfirmedError(event.id, 'NO_ENTRY_ID');
42
+ }
43
+ });
44
+ }
45
+ append(transaction, event) {
46
+ const stream = this.settings.streamOf(event.type);
47
+ const entry = [...trimming(this.settings.retention), '*', ...encode(event)];
48
+ const { deduplication } = this.settings;
49
+ if (deduplication === undefined) {
50
+ transaction.call('XADD', stream, ...entry);
51
+ }
52
+ else {
53
+ transaction.eval(GUARDED_APPEND, 2, `${stream}:${event.id}:published`, stream, deduplication.windowMs, ...entry);
54
+ }
55
+ }
56
+ }
57
+ /** A transaction the server did not answer, or refused as a whole, confirms none of its events. */
58
+ async function executed(transaction, events) {
59
+ try {
60
+ return (await transaction.exec()) ?? [];
61
+ }
62
+ catch (error) {
63
+ throw new PublishNotConfirmedError(events[0]?.id ?? '', failureCode(error));
64
+ }
65
+ }
66
+ function trimming(retention) {
67
+ if (retention === undefined) {
68
+ return [];
69
+ }
70
+ if ('maxLength' in retention) {
71
+ return ['MAXLEN', '~', String(retention.maxLength)];
72
+ }
73
+ return ['MINID', '~', `${String(Date.now() - retention.maxAgeMs)}-0`];
74
+ }
75
+ //# sourceMappingURL=publications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publications.js","sourceRoot":"","sources":["../../src/streams/publications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { inspect } from 'node:util';
2
+ import type { EventBus, IntegrationEvent, IntegrationEventCallback, IntegrationEventSubscriber, Subscription } from '@ddd-ts-kit/kernel';
3
+ import type { RedisStreamsEventBusOptions } from './options/redis-streams-event-bus-options.js';
4
+ import type { ConsumerBinding } from './topology/consumer-binding.js';
5
+ import type { RedisStreamsTopology } from './topology/redis-streams-topology.js';
6
+ /**
7
+ * The provider on Redis Streams, for Redis, Dragonfly and Valkey.
8
+ *
9
+ * Publishing: one stream per event type, one `XADD` per event, and `publish` resolves only
10
+ * when the server answered an entry id for every event, so it is a safe target for the outbox
11
+ * relay. Consuming: one consumer group per consumer name, a blocking read on a dedicated
12
+ * connection, `XACK` after the handlers resolved, a bounded number of delayed redeliveries
13
+ * from the pending entry list, then a dead stream. Delivery is at least once: consumers
14
+ * deduplicate.
15
+ */
16
+ export declare class RedisStreamsEventBus implements EventBus {
17
+ /** Read by what observes the bus from outside: the name of the transport. */
18
+ readonly messagingSystem = "redis";
19
+ private readonly settings;
20
+ private readonly link;
21
+ private readonly publications;
22
+ private readonly consumption;
23
+ private closed;
24
+ constructor(options: RedisStreamsEventBusOptions);
25
+ /** Entries delivered to this bus whose handlers have not finished yet. */
26
+ get deliveriesInFlight(): number;
27
+ /**
28
+ * Resolves when the server acknowledged every event, rejects otherwise: nothing is buffered
29
+ * for later, so the caller (the outbox relay) knows what to retry.
30
+ */
31
+ publish(events: readonly IntegrationEvent[]): Promise<void>;
32
+ /** Subscribes the consumer named by the `consumer` option. */
33
+ subscribe(type: string, handler: IntegrationEventCallback): Subscription;
34
+ /** A subscriber for one consuming context, with a reading connection of its own. */
35
+ forConsumer(consumer: string): IntegrationEventSubscriber;
36
+ /**
37
+ * Connects if needed and creates the streams and the groups of the subscriptions made so
38
+ * far. Idempotent: a group that exists keeps its position.
39
+ */
40
+ assertTopology(): Promise<void>;
41
+ describeTopology(): RedisStreamsTopology;
42
+ /**
43
+ * Moves up to `limit` entries from the dead stream of a consumer back to the stream of
44
+ * their type, for that consumer only, with a fresh attempt budget. Returns how many moved.
45
+ */
46
+ replayDead(binding: ConsumerBinding, limit?: number): Promise<number>;
47
+ /** Stops reading, waits for the handlers in progress to settle, disconnects what it opened. */
48
+ close(): Promise<void>;
49
+ /** What a serialisation shows of the bus: its name, never its connection. */
50
+ toJSON(): string;
51
+ /** What `console.log` and `util.inspect` show of the bus: the same. */
52
+ [inspect.custom](): string;
53
+ private bind;
54
+ }
55
+ //# sourceMappingURL=redis-streams-event-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-event-bus.d.ts","sourceRoot":"","sources":["../../src/streams/redis-streams-event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,YAAY,EACb,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAOhG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAMjF;;;;;;;;;GASG;AACH,qBAAa,oBAAqB,YAAW,QAAQ;IACnD,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,WAAoB;IAE5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAEpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAE1C,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,OAAO,EAAE,2BAA2B,EAY/C;IAED,0EAA0E;IAC1E,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAchE;IAED,8DAA8D;IAC9D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,GAAG,YAAY,CAMvE;IAED,oFAAoF;IACpF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,0BAA0B,CAMxD;IAED;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC;IAED,gBAAgB,IAAI,oBAAoB,CAEvC;IAED;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,SAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKvE;IAED,+FAA+F;IACzF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ3B;IAED,6EAA6E;IAC7E,MAAM,IAAI,MAAM,CAEf;IAED,uEAAuE;IACvE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,IAAI;CAOb"}
@@ -0,0 +1,120 @@
1
+ import { inspect } from 'node:util';
2
+ import { replay } from './replay.js';
3
+ import { Consumption } from './consumption.js';
4
+ import { ConsumerNameRequiredError } from './errors/consumer-name-required-error.js';
5
+ import { EventBusClosedError } from './errors/event-bus-closed-error.js';
6
+ import { MESSAGING_SYSTEM } from './messaging-system.js';
7
+ import { settingsOf } from './options/settings-of.js';
8
+ import { conceal } from '../secrecy/conceal.js';
9
+ import { Publications } from './publications.js';
10
+ import { ServerLink } from './server-link.js';
11
+ import { declareTopology } from './topology/declare-topology.js';
12
+ import { streamNamesOf } from './topology/stream-names-of.js';
13
+ import { topologyOf } from './topology/topology-of.js';
14
+ const DESCRIPTION = 'RedisStreamsEventBus [connection concealed]';
15
+ /**
16
+ * The provider on Redis Streams, for Redis, Dragonfly and Valkey.
17
+ *
18
+ * Publishing: one stream per event type, one `XADD` per event, and `publish` resolves only
19
+ * when the server answered an entry id for every event, so it is a safe target for the outbox
20
+ * relay. Consuming: one consumer group per consumer name, a blocking read on a dedicated
21
+ * connection, `XACK` after the handlers resolved, a bounded number of delayed redeliveries
22
+ * from the pending entry list, then a dead stream. Delivery is at least once: consumers
23
+ * deduplicate.
24
+ */
25
+ export class RedisStreamsEventBus {
26
+ /** Read by what observes the bus from outside: the name of the transport. */
27
+ messagingSystem = MESSAGING_SYSTEM;
28
+ settings;
29
+ link;
30
+ publications;
31
+ consumption;
32
+ closed = false;
33
+ constructor(options) {
34
+ this.settings = settingsOf(options);
35
+ const { reconnect, blockMs } = this.settings;
36
+ this.link = new ServerLink({ connection: options.connection, reconnect, blockMs }, (code) => {
37
+ this.settings.onFailure({ kind: 'connection', code });
38
+ });
39
+ this.publications = new Publications(this.settings);
40
+ this.consumption = new Consumption(this.link, this.settings);
41
+ conceal(this);
42
+ }
43
+ /** Entries delivered to this bus whose handlers have not finished yet. */
44
+ get deliveriesInFlight() {
45
+ return this.consumption.inFlight;
46
+ }
47
+ /**
48
+ * Resolves when the server acknowledged every event, rejects otherwise: nothing is buffered
49
+ * for later, so the caller (the outbox relay) knows what to retry.
50
+ */
51
+ async publish(events) {
52
+ if (events.length === 0) {
53
+ return;
54
+ }
55
+ if (this.closed) {
56
+ throw new EventBusClosedError();
57
+ }
58
+ const client = await this.link.ready();
59
+ // The groups of this bus exist before it publishes: it never misses its own events.
60
+ await this.consumption.declare(client);
61
+ await this.publications.publish(client, events);
62
+ }
63
+ /** Subscribes the consumer named by the `consumer` option. */
64
+ subscribe(type, handler) {
65
+ if (this.settings.consumer === undefined) {
66
+ throw new ConsumerNameRequiredError();
67
+ }
68
+ return this.bind({ consumer: this.settings.consumer, type }, handler);
69
+ }
70
+ /** A subscriber for one consuming context, with a reading connection of its own. */
71
+ forConsumer(consumer) {
72
+ if (consumer.length === 0) {
73
+ throw new ConsumerNameRequiredError();
74
+ }
75
+ return { subscribe: (type, handler) => this.bind({ consumer, type }, handler) };
76
+ }
77
+ /**
78
+ * Connects if needed and creates the streams and the groups of the subscriptions made so
79
+ * far. Idempotent: a group that exists keeps its position.
80
+ */
81
+ async assertTopology() {
82
+ await declareTopology(await this.link.ready(), this.describeTopology());
83
+ }
84
+ describeTopology() {
85
+ return topologyOf(this.settings, this.consumption.bindings());
86
+ }
87
+ /**
88
+ * Moves up to `limit` entries from the dead stream of a consumer back to the stream of
89
+ * their type, for that consumer only, with a fresh attempt budget. Returns how many moved.
90
+ */
91
+ async replayDead(binding, limit = 100) {
92
+ const { events, dead } = streamNamesOf(binding, this.settings.streamOf);
93
+ const client = await this.link.ready();
94
+ return replay(client, { stream: events, deadStream: dead, consumer: binding.consumer, limit });
95
+ }
96
+ /** Stops reading, waits for the handlers in progress to settle, disconnects what it opened. */
97
+ async close() {
98
+ if (this.closed) {
99
+ return;
100
+ }
101
+ this.closed = true;
102
+ await this.consumption.drain();
103
+ await this.link.close();
104
+ }
105
+ /** What a serialisation shows of the bus: its name, never its connection. */
106
+ toJSON() {
107
+ return DESCRIPTION;
108
+ }
109
+ /** What `console.log` and `util.inspect` show of the bus: the same. */
110
+ [inspect.custom]() {
111
+ return DESCRIPTION;
112
+ }
113
+ bind(binding, handler) {
114
+ if (this.closed) {
115
+ throw new EventBusClosedError();
116
+ }
117
+ return this.consumption.add(binding, handler);
118
+ }
119
+ }
120
+ //# sourceMappingURL=redis-streams-event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-streams-event-bus.js","sourceRoot":"","sources":["../../src/streams/redis-streams-event-bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Redis } from 'ioredis';
2
+ export interface Replay {
3
+ readonly stream: string;
4
+ readonly deadStream: string;
5
+ readonly consumer: string;
6
+ readonly limit: number;
7
+ }
8
+ /**
9
+ * Moves up to `limit` dead entries back, oldest first, and answers how many. The new entry
10
+ * names the consumer it is for: the other groups of the stream acknowledge it unseen.
11
+ */
12
+ export declare function replay(client: Redis, { stream, deadStream, consumer, limit }: Replay): Promise<number>;
13
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/streams/replay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAIrC,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAcD;;;GAGG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G"}
@@ -0,0 +1,26 @@
1
+ import { entriesOf } from './codec/entries-of.js';
2
+ import { replayFields } from './codec/replay-fields.js';
3
+ /**
4
+ * Appends a dead entry to its stream again and deletes it from the dead stream, unless
5
+ * another replay took it meanwhile. KEYS: dead stream, stream. ARGV: dead entry id, then the
6
+ * fields of the new entry.
7
+ */
8
+ const REPLAY = `
9
+ if #redis.call('XRANGE', KEYS[1], ARGV[1], ARGV[1]) == 0 then
10
+ return 0
11
+ end
12
+ redis.call('XADD', KEYS[2], '*', unpack(ARGV, 2))
13
+ return redis.call('XDEL', KEYS[1], ARGV[1])`;
14
+ /**
15
+ * Moves up to `limit` dead entries back, oldest first, and answers how many. The new entry
16
+ * names the consumer it is for: the other groups of the stream acknowledge it unseen.
17
+ */
18
+ export async function replay(client, { stream, deadStream, consumer, limit }) {
19
+ const dead = entriesOf(await client.xrange(deadStream, '-', '+', 'COUNT', limit));
20
+ let replayed = 0;
21
+ for (const entry of dead) {
22
+ replayed += Number(await client.eval(REPLAY, 2, deadStream, stream, entry.id, ...replayFields(entry, consumer)));
23
+ }
24
+ return replayed;
25
+ }
26
+ //# sourceMappingURL=replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/streams/replay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AASxD;;;;GAIG;AACH,MAAM,MAAM,GAAG;;;;;4CAK6B,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAa,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAU;IACzF,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAClF,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,QAAQ,IAAI,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { inspect } from 'node:util';
2
+ import { Redis } from 'ioredis';
3
+ import type { RedisSource } from '../connection/redis-source.js';
4
+ import type { ReconnectOptions } from './options/reconnect-options.js';
5
+ export interface LinkSettings {
6
+ readonly connection: RedisSource;
7
+ readonly reconnect: Required<ReconnectOptions>;
8
+ readonly blockMs: number;
9
+ }
10
+ /**
11
+ * The connection the bus publishes and acknowledges on, and the source of the connections
12
+ * its readers block on. ioredis reconnects by itself; the link reports what happens to the
13
+ * connection as codes and answers at once, instead of queueing, while the server is away.
14
+ */
15
+ export declare class ServerLink {
16
+ private readonly connection;
17
+ private readonly owned;
18
+ private readonly blockMs;
19
+ private readonly failed;
20
+ private reason;
21
+ private wasReady;
22
+ private closed;
23
+ constructor(settings: LinkSettings, failed: (code: string) => void);
24
+ /** The connection for commands that answer at once. A command sent while the server is away fails by the rules of the client. */
25
+ get client(): Redis;
26
+ /**
27
+ * The live connection. Waits for the first connection in progress and fails at once between
28
+ * two reconnection attempts, so that a publisher never hangs on a server that is down.
29
+ */
30
+ ready(): Promise<Redis>;
31
+ /**
32
+ * A connection of its own for a blocking reader. Its command timeout leaves the server the
33
+ * time to answer a read that found nothing; beyond it the connection is deemed dead.
34
+ */
35
+ reader(): Redis;
36
+ close(): Promise<void>;
37
+ toJSON(): string;
38
+ [inspect.custom](): string;
39
+ private refuseOnceClosed;
40
+ private readonly onReady;
41
+ private readonly onError;
42
+ private readonly onClose;
43
+ private lost;
44
+ }
45
+ //# sourceMappingURL=server-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-link.d.ts","sourceRoot":"","sources":["../../src/streams/server-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAMjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAID;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAEnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAEhD,OAAO,CAAC,MAAM,CAAmB;IAEjC,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAUjE;IAED,iIAAiI;IACjI,IAAI,MAAM,IAAI,KAAK,CAElB;IAED;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAyB5B;IAED;;;OAGG;IACH,MAAM,IAAI,KAAK,CAQd;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ3B;IAED,MAAM,IAAI,MAAM,CAEf;IAED,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAItB;IAEF,OAAO,CAAC,IAAI;CAQb"}
@@ -0,0 +1,129 @@
1
+ import { inspect } from 'node:util';
2
+ import { Redis } from 'ioredis';
3
+ import { closeRedis } from '../connection/close-redis.js';
4
+ import { FAIL_FAST } from '../connection/fail-fast.js';
5
+ import { conceal } from '../secrecy/conceal.js';
6
+ import { BrokerUnavailableError } from './errors/broker-unavailable-error.js';
7
+ import { EventBusClosedError } from './errors/event-bus-closed-error.js';
8
+ import { failureCode } from './errors/failure-code.js';
9
+ import { reconnectDelay } from './options/reconnect-delay.js';
10
+ const DESCRIPTION = 'ServerLink [connection concealed]';
11
+ /**
12
+ * The connection the bus publishes and acknowledges on, and the source of the connections
13
+ * its readers block on. ioredis reconnects by itself; the link reports what happens to the
14
+ * connection as codes and answers at once, instead of queueing, while the server is away.
15
+ */
16
+ export class ServerLink {
17
+ connection;
18
+ owned;
19
+ blockMs;
20
+ failed;
21
+ reason = 'NOT_CONNECTED';
22
+ wasReady;
23
+ closed = false;
24
+ constructor(settings, failed) {
25
+ const { connection } = settings;
26
+ this.owned = !(connection instanceof Redis);
27
+ this.connection = connection instanceof Redis ? connection : opened(connection, settings.reconnect);
28
+ this.blockMs = settings.blockMs;
29
+ this.failed = failed;
30
+ this.wasReady = this.connection.status === 'ready';
31
+ this.connection.on('ready', this.onReady).on('error', this.onError).on('close', this.onClose);
32
+ conceal(this);
33
+ }
34
+ /** The connection for commands that answer at once. A command sent while the server is away fails by the rules of the client. */
35
+ get client() {
36
+ return this.connection;
37
+ }
38
+ /**
39
+ * The live connection. Waits for the first connection in progress and fails at once between
40
+ * two reconnection attempts, so that a publisher never hangs on a server that is down.
41
+ */
42
+ async ready() {
43
+ this.refuseOnceClosed();
44
+ const client = this.connection;
45
+ if (client.status === 'ready') {
46
+ return client;
47
+ }
48
+ if (client.status === 'wait') {
49
+ void client.connect().catch(ignore);
50
+ }
51
+ if (!CONNECTING.has(client.status)) {
52
+ throw new BrokerUnavailableError(this.reason);
53
+ }
54
+ await connected(client);
55
+ this.refuseOnceClosed();
56
+ if (!this.wasReady) {
57
+ throw new BrokerUnavailableError(this.reason);
58
+ }
59
+ return client;
60
+ }
61
+ /**
62
+ * A connection of its own for a blocking reader. Its command timeout leaves the server the
63
+ * time to answer a read that found nothing; beyond it the connection is deemed dead.
64
+ */
65
+ reader() {
66
+ const patience = this.connection.options.commandTimeout ?? FAIL_FAST.commandTimeout ?? 0;
67
+ const reader = this.connection.duplicate({ commandTimeout: this.blockMs + patience });
68
+ // Without a handler ioredis prints connection errors; the reader reports its own failures.
69
+ reader.on('error', ignore);
70
+ return reader;
71
+ }
72
+ async close() {
73
+ this.closed = true;
74
+ this.connection.off('ready', this.onReady).off('error', this.onError).off('close', this.onClose);
75
+ if (this.owned) {
76
+ this.connection.on('error', ignore);
77
+ await closeRedis(this.connection);
78
+ }
79
+ }
80
+ toJSON() {
81
+ return DESCRIPTION;
82
+ }
83
+ [inspect.custom]() {
84
+ return DESCRIPTION;
85
+ }
86
+ refuseOnceClosed() {
87
+ if (this.closed) {
88
+ throw new EventBusClosedError();
89
+ }
90
+ }
91
+ onReady = () => {
92
+ this.wasReady = true;
93
+ };
94
+ onError = (error) => {
95
+ this.lost(failureCode(error));
96
+ };
97
+ onClose = () => {
98
+ if (this.wasReady) {
99
+ this.lost('CONNECTION_LOST');
100
+ }
101
+ };
102
+ lost(code) {
103
+ this.wasReady = false;
104
+ this.reason = code;
105
+ if (!this.closed) {
106
+ this.failed(code);
107
+ }
108
+ }
109
+ }
110
+ const CONNECTING = new Set(['wait', 'connecting', 'connect']);
111
+ function opened(source, reconnect) {
112
+ const retryStrategy = (attempt) => reconnectDelay(reconnect, attempt);
113
+ const defaults = { ...FAIL_FAST, retryStrategy };
114
+ return typeof source === 'string' ? new Redis(source, defaults) : new Redis({ ...defaults, ...source });
115
+ }
116
+ /** Resolves when the connection in progress succeeded or failed. */
117
+ function connected(client) {
118
+ return new Promise((resolve) => {
119
+ const settle = () => {
120
+ client.off('ready', settle).off('close', settle).off('end', settle);
121
+ resolve();
122
+ };
123
+ client.once('ready', settle).once('close', settle).once('end', settle);
124
+ });
125
+ }
126
+ function ignore() {
127
+ return undefined;
128
+ }
129
+ //# sourceMappingURL=server-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-link.js","sourceRoot":"","sources":["../../src/streams/server-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAS9D,MAAM,WAAW,GAAG,mCAAmC,CAAC;AAExD;;;;GAIG;AACH,MAAM,OAAO,UAAU;IACJ,UAAU,CAAQ;IAElB,KAAK,CAAU;IAEf,OAAO,CAAS;IAEhB,MAAM,CAAyB;IAExC,MAAM,GAAG,eAAe,CAAC;IAEzB,QAAQ,CAAU;IAElB,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAY,QAAsB,EAAE,MAA8B;QAChE,MAAM,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;QAEhC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,UAAU,YAAY,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,UAAU,GAAG,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpG,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9F,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,iIAAiI;IACjI,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAE/B,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,cAAc,IAAI,SAAS,CAAC,cAAc,IAAI,CAAC,CAAC;QACzF,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC;QAEtF,2FAA2F;QAC3F,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE3B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAEjG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACpC,MAAM,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,CAAC,OAAO,CAAC,MAAM,CAAC;QACd,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IAEgB,OAAO,GAAG,GAAS,EAAE;QACpC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC,CAAC;IAEe,OAAO,GAAG,CAAC,KAAc,EAAQ,EAAE;QAClD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC;IAEe,OAAO,GAAG,GAAS,EAAE;QACpC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,CAAC;IAEM,IAAI,CAAC,IAAY;QACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAEnB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAEnF,SAAS,MAAM,CAAC,MAAmC,EAAE,SAAqC;IACxF,MAAM,aAAa,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,EAAE,GAAG,SAAS,EAAE,aAAa,EAAE,CAAC;IAEjD,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;AAC1G,CAAC;AAED,oEAAoE;AACpE,SAAS,SAAS,CAAC,MAAa;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACpE,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,MAAM;IACb,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { Redis } from 'ioredis';
2
+ import type { IntegrationEventCallback } from '@ddd-ts-kit/kernel';
3
+ import type { Delivery } from './delivery.js';
4
+ import type { RedisStreamsDelivery } from './options/redis-streams-delivery.js';
5
+ import type { RedisStreamsFailure } from './options/redis-streams-failure.js';
6
+ import type { RetryOptions } from './options/retry-options.js';
7
+ export interface SettlementSettings {
8
+ /** The consumer name, which is the name of its group. */
9
+ readonly consumer: string;
10
+ readonly instance: string;
11
+ readonly retry: Required<RetryOptions>;
12
+ readonly onFailure: (failure: RedisStreamsFailure) => void;
13
+ readonly onDelivery: (delivery: RedisStreamsDelivery) => void;
14
+ }
15
+ export declare const POISON_ENTRY = "POISON_ENTRY";
16
+ /** The code of an entry that used its deliveries up without a handler answering: its consumers crashed on it. */
17
+ export declare const ATTEMPTS_EXHAUSTED = "ATTEMPTS_EXHAUSTED";
18
+ /**
19
+ * What becomes of a delivered entry: acknowledged once every handler resolved; left pending
20
+ * after a failure, to be claimed again after the delay; copied to the dead stream when its
21
+ * attempts are spent or when it does not hold an envelope.
22
+ */
23
+ export declare class Settlement {
24
+ private readonly client;
25
+ private readonly settings;
26
+ constructor(client: Redis, settings: SettlementSettings);
27
+ /** Never rejects: an entry that could not be settled stays pending and is delivered again. */
28
+ settle(delivery: Delivery, handlers: ReadonlySet<IntegrationEventCallback>): Promise<void>;
29
+ private decide;
30
+ /** A replayed dead entry is addressed to the consumer it died for. */
31
+ private isForAnotherConsumer;
32
+ private acknowledge;
33
+ private buryPoison;
34
+ private handle;
35
+ private deliveryOf;
36
+ private fail;
37
+ private settled;
38
+ private bury;
39
+ /**
40
+ * The entry stays pending; claiming it for ourselves without reading it (`JUSTID`) restarts
41
+ * its idle time and leaves its delivery counter alone, so the retry delay runs from the
42
+ * failure, not from the delivery.
43
+ */
44
+ private postpone;
45
+ }
46
+ //# sourceMappingURL=settlement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settlement.d.ts","sourceRoot":"","sources":["../../src/streams/settlement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAmC,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAYpG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEvC,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAE3D,QAAQ,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,iHAAiH;AACjH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;GAIG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAF3B,YACmB,MAAM,EAAE,KAAK,EACb,QAAQ,EAAE,kBAAkB,EAC3C;IAEJ,8FAA8F;IACxF,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,wBAAwB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/F;YAEa,MAAM;IAkBpB,sEAAsE;IACtE,OAAO,CAAC,oBAAoB;YAMd,WAAW;YAIX,UAAU;YAQV,MAAM;IAepB,OAAO,CAAC,UAAU;YAMJ,IAAI;IAyBlB,OAAO,CAAC,OAAO;YAID,IAAI;IAoBlB;;;;OAIG;YACW,QAAQ;CAGvB"}