@hotmeshio/hotmesh 0.4.0 → 0.4.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 (283) hide show
  1. package/build/modules/enums.d.ts +110 -0
  2. package/build/modules/enums.js +134 -0
  3. package/build/modules/errors.d.ts +124 -0
  4. package/build/modules/errors.js +191 -0
  5. package/build/modules/key.d.ts +66 -0
  6. package/build/modules/key.js +190 -0
  7. package/build/modules/storage.d.ts +3 -0
  8. package/build/modules/storage.js +5 -0
  9. package/build/modules/utils.d.ts +119 -0
  10. package/build/modules/utils.js +374 -0
  11. package/build/package.json +1 -1
  12. package/build/services/activities/activity.d.ts +104 -0
  13. package/build/services/activities/activity.js +549 -0
  14. package/build/services/activities/await.d.ts +12 -0
  15. package/build/services/activities/await.js +114 -0
  16. package/build/services/activities/cycle.d.ts +19 -0
  17. package/build/services/activities/cycle.js +112 -0
  18. package/build/services/activities/hook.d.ts +27 -0
  19. package/build/services/activities/hook.js +168 -0
  20. package/build/services/activities/index.d.ts +19 -0
  21. package/build/services/activities/index.js +20 -0
  22. package/build/services/activities/interrupt.d.ts +16 -0
  23. package/build/services/activities/interrupt.js +158 -0
  24. package/build/services/activities/signal.d.ts +20 -0
  25. package/build/services/activities/signal.js +134 -0
  26. package/build/services/activities/trigger.d.ts +37 -0
  27. package/build/services/activities/trigger.js +246 -0
  28. package/build/services/activities/worker.d.ts +12 -0
  29. package/build/services/activities/worker.js +106 -0
  30. package/build/services/collator/index.d.ts +111 -0
  31. package/build/services/collator/index.js +293 -0
  32. package/build/services/compiler/deployer.d.ts +40 -0
  33. package/build/services/compiler/deployer.js +488 -0
  34. package/build/services/compiler/index.d.ts +32 -0
  35. package/build/services/compiler/index.js +112 -0
  36. package/build/services/compiler/validator.d.ts +34 -0
  37. package/build/services/compiler/validator.js +147 -0
  38. package/build/services/connector/factory.d.ts +22 -0
  39. package/build/services/connector/factory.js +99 -0
  40. package/build/services/connector/index.d.ts +30 -0
  41. package/build/services/connector/index.js +54 -0
  42. package/build/services/connector/providers/ioredis.d.ts +9 -0
  43. package/build/services/connector/providers/ioredis.js +26 -0
  44. package/build/services/connector/providers/nats.d.ts +9 -0
  45. package/build/services/connector/providers/nats.js +34 -0
  46. package/build/services/connector/providers/postgres.d.ts +20 -0
  47. package/build/services/connector/providers/postgres.js +102 -0
  48. package/build/services/connector/providers/redis.d.ts +9 -0
  49. package/build/services/connector/providers/redis.js +38 -0
  50. package/build/services/engine/index.d.ts +264 -0
  51. package/build/services/engine/index.js +761 -0
  52. package/build/services/exporter/index.d.ts +44 -0
  53. package/build/services/exporter/index.js +126 -0
  54. package/build/services/hotmesh/index.d.ts +483 -0
  55. package/build/services/hotmesh/index.js +622 -0
  56. package/build/services/logger/index.d.ts +16 -0
  57. package/build/services/logger/index.js +54 -0
  58. package/build/services/mapper/index.d.ts +28 -0
  59. package/build/services/mapper/index.js +81 -0
  60. package/build/services/memflow/client.d.ts +108 -0
  61. package/build/services/memflow/client.js +372 -0
  62. package/build/services/memflow/connection.d.ts +23 -0
  63. package/build/services/memflow/connection.js +33 -0
  64. package/build/services/memflow/context.d.ts +143 -0
  65. package/build/services/memflow/context.js +299 -0
  66. package/build/services/memflow/exporter.d.ts +51 -0
  67. package/build/services/memflow/exporter.js +215 -0
  68. package/build/services/memflow/handle.d.ts +90 -0
  69. package/build/services/memflow/handle.js +176 -0
  70. package/build/services/memflow/index.d.ts +116 -0
  71. package/build/services/memflow/index.js +122 -0
  72. package/build/services/memflow/schemas/factory.d.ts +29 -0
  73. package/build/services/memflow/schemas/factory.js +2492 -0
  74. package/build/services/memflow/search.d.ts +142 -0
  75. package/build/services/memflow/search.js +320 -0
  76. package/build/services/memflow/worker.d.ts +124 -0
  77. package/build/services/memflow/worker.js +514 -0
  78. package/build/services/memflow/workflow/all.d.ts +7 -0
  79. package/build/services/memflow/workflow/all.js +15 -0
  80. package/build/services/memflow/workflow/common.d.ts +20 -0
  81. package/build/services/memflow/workflow/common.js +47 -0
  82. package/build/services/memflow/workflow/context.d.ts +6 -0
  83. package/build/services/memflow/workflow/context.js +45 -0
  84. package/build/services/memflow/workflow/contextMethods.d.ts +14 -0
  85. package/build/services/memflow/workflow/contextMethods.js +33 -0
  86. package/build/services/memflow/workflow/didRun.d.ts +7 -0
  87. package/build/services/memflow/workflow/didRun.js +22 -0
  88. package/build/services/memflow/workflow/emit.d.ts +11 -0
  89. package/build/services/memflow/workflow/emit.js +29 -0
  90. package/build/services/memflow/workflow/enrich.d.ts +9 -0
  91. package/build/services/memflow/workflow/enrich.js +17 -0
  92. package/build/services/memflow/workflow/execChild.d.ts +18 -0
  93. package/build/services/memflow/workflow/execChild.js +102 -0
  94. package/build/services/memflow/workflow/execHook.d.ts +65 -0
  95. package/build/services/memflow/workflow/execHook.js +73 -0
  96. package/build/services/memflow/workflow/hook.d.ts +9 -0
  97. package/build/services/memflow/workflow/hook.js +56 -0
  98. package/build/services/memflow/workflow/index.d.ts +74 -0
  99. package/build/services/memflow/workflow/index.js +87 -0
  100. package/build/services/memflow/workflow/interrupt.d.ts +9 -0
  101. package/build/services/memflow/workflow/interrupt.js +24 -0
  102. package/build/services/memflow/workflow/isSideEffectAllowed.d.ts +10 -0
  103. package/build/services/memflow/workflow/isSideEffectAllowed.js +33 -0
  104. package/build/services/memflow/workflow/proxyActivities.d.ts +20 -0
  105. package/build/services/memflow/workflow/proxyActivities.js +97 -0
  106. package/build/services/memflow/workflow/random.d.ts +6 -0
  107. package/build/services/memflow/workflow/random.js +16 -0
  108. package/build/services/memflow/workflow/searchMethods.d.ts +6 -0
  109. package/build/services/memflow/workflow/searchMethods.js +25 -0
  110. package/build/services/memflow/workflow/signal.d.ts +7 -0
  111. package/build/services/memflow/workflow/signal.js +28 -0
  112. package/build/services/memflow/workflow/sleepFor.d.ts +8 -0
  113. package/build/services/memflow/workflow/sleepFor.js +35 -0
  114. package/build/services/memflow/workflow/trace.d.ts +14 -0
  115. package/build/services/memflow/workflow/trace.js +33 -0
  116. package/build/services/memflow/workflow/waitFor.d.ts +8 -0
  117. package/build/services/memflow/workflow/waitFor.js +35 -0
  118. package/build/services/meshcall/index.d.ts +194 -0
  119. package/build/services/meshcall/index.js +452 -0
  120. package/build/services/meshcall/schemas/factory.d.ts +9 -0
  121. package/build/services/meshcall/schemas/factory.js +189 -0
  122. package/build/services/meshdata/index.d.ts +795 -0
  123. package/build/services/meshdata/index.js +1235 -0
  124. package/build/services/meshos/index.d.ts +293 -0
  125. package/build/services/meshos/index.js +547 -0
  126. package/build/services/pipe/functions/array.d.ts +17 -0
  127. package/build/services/pipe/functions/array.js +74 -0
  128. package/build/services/pipe/functions/bitwise.d.ts +9 -0
  129. package/build/services/pipe/functions/bitwise.js +24 -0
  130. package/build/services/pipe/functions/conditional.d.ts +13 -0
  131. package/build/services/pipe/functions/conditional.js +36 -0
  132. package/build/services/pipe/functions/cron.d.ts +12 -0
  133. package/build/services/pipe/functions/cron.js +40 -0
  134. package/build/services/pipe/functions/date.d.ts +58 -0
  135. package/build/services/pipe/functions/date.js +171 -0
  136. package/build/services/pipe/functions/index.d.ts +29 -0
  137. package/build/services/pipe/functions/index.js +30 -0
  138. package/build/services/pipe/functions/json.d.ts +5 -0
  139. package/build/services/pipe/functions/json.js +12 -0
  140. package/build/services/pipe/functions/logical.d.ts +5 -0
  141. package/build/services/pipe/functions/logical.js +12 -0
  142. package/build/services/pipe/functions/math.d.ts +42 -0
  143. package/build/services/pipe/functions/math.js +184 -0
  144. package/build/services/pipe/functions/number.d.ts +21 -0
  145. package/build/services/pipe/functions/number.js +60 -0
  146. package/build/services/pipe/functions/object.d.ts +25 -0
  147. package/build/services/pipe/functions/object.js +81 -0
  148. package/build/services/pipe/functions/string.d.ts +23 -0
  149. package/build/services/pipe/functions/string.js +69 -0
  150. package/build/services/pipe/functions/symbol.d.ts +12 -0
  151. package/build/services/pipe/functions/symbol.js +33 -0
  152. package/build/services/pipe/functions/unary.d.ts +7 -0
  153. package/build/services/pipe/functions/unary.js +18 -0
  154. package/build/services/pipe/index.d.ts +48 -0
  155. package/build/services/pipe/index.js +242 -0
  156. package/build/services/quorum/index.d.ts +90 -0
  157. package/build/services/quorum/index.js +263 -0
  158. package/build/services/reporter/index.d.ts +50 -0
  159. package/build/services/reporter/index.js +348 -0
  160. package/build/services/router/config/index.d.ts +11 -0
  161. package/build/services/router/config/index.js +36 -0
  162. package/build/services/router/consumption/index.d.ts +34 -0
  163. package/build/services/router/consumption/index.js +395 -0
  164. package/build/services/router/error-handling/index.d.ts +8 -0
  165. package/build/services/router/error-handling/index.js +98 -0
  166. package/build/services/router/index.d.ts +57 -0
  167. package/build/services/router/index.js +121 -0
  168. package/build/services/router/lifecycle/index.d.ts +27 -0
  169. package/build/services/router/lifecycle/index.js +80 -0
  170. package/build/services/router/telemetry/index.d.ts +11 -0
  171. package/build/services/router/telemetry/index.js +32 -0
  172. package/build/services/router/throttling/index.d.ts +23 -0
  173. package/build/services/router/throttling/index.js +76 -0
  174. package/build/services/search/factory.d.ts +7 -0
  175. package/build/services/search/factory.js +24 -0
  176. package/build/services/search/index.d.ts +23 -0
  177. package/build/services/search/index.js +10 -0
  178. package/build/services/search/providers/postgres/postgres.d.ts +25 -0
  179. package/build/services/search/providers/postgres/postgres.js +149 -0
  180. package/build/services/search/providers/redis/ioredis.d.ts +19 -0
  181. package/build/services/search/providers/redis/ioredis.js +121 -0
  182. package/build/services/search/providers/redis/redis.d.ts +19 -0
  183. package/build/services/search/providers/redis/redis.js +134 -0
  184. package/build/services/serializer/index.d.ts +42 -0
  185. package/build/services/serializer/index.js +282 -0
  186. package/build/services/store/cache.d.ts +67 -0
  187. package/build/services/store/cache.js +128 -0
  188. package/build/services/store/factory.d.ts +8 -0
  189. package/build/services/store/factory.js +24 -0
  190. package/build/services/store/index.d.ts +89 -0
  191. package/build/services/store/index.js +9 -0
  192. package/build/services/store/providers/postgres/kvsql.d.ts +168 -0
  193. package/build/services/store/providers/postgres/kvsql.js +198 -0
  194. package/build/services/store/providers/postgres/kvtables.d.ts +20 -0
  195. package/build/services/store/providers/postgres/kvtables.js +441 -0
  196. package/build/services/store/providers/postgres/kvtransaction.d.ts +36 -0
  197. package/build/services/store/providers/postgres/kvtransaction.js +248 -0
  198. package/build/services/store/providers/postgres/kvtypes/hash.d.ts +60 -0
  199. package/build/services/store/providers/postgres/kvtypes/hash.js +1287 -0
  200. package/build/services/store/providers/postgres/kvtypes/list.d.ts +33 -0
  201. package/build/services/store/providers/postgres/kvtypes/list.js +194 -0
  202. package/build/services/store/providers/postgres/kvtypes/string.d.ts +20 -0
  203. package/build/services/store/providers/postgres/kvtypes/string.js +115 -0
  204. package/build/services/store/providers/postgres/kvtypes/zset.d.ts +41 -0
  205. package/build/services/store/providers/postgres/kvtypes/zset.js +214 -0
  206. package/build/services/store/providers/postgres/postgres.d.ts +145 -0
  207. package/build/services/store/providers/postgres/postgres.js +1036 -0
  208. package/build/services/store/providers/redis/_base.d.ts +137 -0
  209. package/build/services/store/providers/redis/_base.js +980 -0
  210. package/build/services/store/providers/redis/ioredis.d.ts +20 -0
  211. package/build/services/store/providers/redis/ioredis.js +180 -0
  212. package/build/services/store/providers/redis/redis.d.ts +18 -0
  213. package/build/services/store/providers/redis/redis.js +199 -0
  214. package/build/services/store/providers/store-initializable.d.ts +5 -0
  215. package/build/services/store/providers/store-initializable.js +2 -0
  216. package/build/services/stream/factory.d.ts +8 -0
  217. package/build/services/stream/factory.js +37 -0
  218. package/build/services/stream/index.d.ts +69 -0
  219. package/build/services/stream/index.js +11 -0
  220. package/build/services/stream/providers/nats/nats.d.ts +60 -0
  221. package/build/services/stream/providers/nats/nats.js +225 -0
  222. package/build/services/stream/providers/postgres/kvtables.d.ts +3 -0
  223. package/build/services/stream/providers/postgres/kvtables.js +146 -0
  224. package/build/services/stream/providers/postgres/postgres.d.ts +107 -0
  225. package/build/services/stream/providers/postgres/postgres.js +519 -0
  226. package/build/services/stream/providers/redis/ioredis.d.ts +61 -0
  227. package/build/services/stream/providers/redis/ioredis.js +272 -0
  228. package/build/services/stream/providers/redis/redis.d.ts +61 -0
  229. package/build/services/stream/providers/redis/redis.js +305 -0
  230. package/build/services/stream/providers/stream-initializable.d.ts +4 -0
  231. package/build/services/stream/providers/stream-initializable.js +2 -0
  232. package/build/services/sub/factory.d.ts +7 -0
  233. package/build/services/sub/factory.js +29 -0
  234. package/build/services/sub/index.d.ts +22 -0
  235. package/build/services/sub/index.js +10 -0
  236. package/build/services/sub/providers/nats/nats.d.ts +19 -0
  237. package/build/services/sub/providers/nats/nats.js +105 -0
  238. package/build/services/sub/providers/postgres/postgres.d.ts +19 -0
  239. package/build/services/sub/providers/postgres/postgres.js +92 -0
  240. package/build/services/sub/providers/redis/ioredis.d.ts +17 -0
  241. package/build/services/sub/providers/redis/ioredis.js +81 -0
  242. package/build/services/sub/providers/redis/redis.d.ts +17 -0
  243. package/build/services/sub/providers/redis/redis.js +72 -0
  244. package/build/services/task/index.d.ts +36 -0
  245. package/build/services/task/index.js +206 -0
  246. package/build/services/telemetry/index.d.ts +52 -0
  247. package/build/services/telemetry/index.js +306 -0
  248. package/build/services/worker/index.d.ts +77 -0
  249. package/build/services/worker/index.js +197 -0
  250. package/package.json +1 -1
  251. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  252. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  253. package/typedoc.json +0 -47
  254. package/types/activity.ts +0 -268
  255. package/types/app.ts +0 -20
  256. package/types/async.ts +0 -6
  257. package/types/cache.ts +0 -1
  258. package/types/collator.ts +0 -9
  259. package/types/error.ts +0 -56
  260. package/types/exporter.ts +0 -102
  261. package/types/hook.ts +0 -44
  262. package/types/hotmesh.ts +0 -314
  263. package/types/index.ts +0 -306
  264. package/types/job.ts +0 -233
  265. package/types/logger.ts +0 -8
  266. package/types/manifest.ts +0 -70
  267. package/types/map.ts +0 -5
  268. package/types/memflow.ts +0 -645
  269. package/types/meshcall.ts +0 -235
  270. package/types/meshdata.ts +0 -278
  271. package/types/ms.d.ts +0 -7
  272. package/types/nats.ts +0 -270
  273. package/types/pipe.ts +0 -90
  274. package/types/postgres.ts +0 -114
  275. package/types/provider.ts +0 -161
  276. package/types/quorum.ts +0 -167
  277. package/types/redis.ts +0 -404
  278. package/types/serializer.ts +0 -40
  279. package/types/stats.ts +0 -117
  280. package/types/stream.ts +0 -231
  281. package/types/task.ts +0 -7
  282. package/types/telemetry.ts +0 -16
  283. package/types/transition.ts +0 -20
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IORedisStreamService = void 0;
4
+ const index_1 = require("../../index");
5
+ const utils_1 = require("../../../../modules/utils");
6
+ const key_1 = require("../../../../modules/key");
7
+ const enums_1 = require("../../../../modules/enums");
8
+ class IORedisStreamService extends index_1.StreamService {
9
+ constructor(streamClient, storeClient, config = {}) {
10
+ super(streamClient, storeClient, config);
11
+ }
12
+ async init(namespace, appId, logger) {
13
+ this.namespace = namespace;
14
+ this.logger = logger;
15
+ this.appId = appId;
16
+ }
17
+ mintKey(type, params) {
18
+ if (!this.namespace)
19
+ throw new Error('namespace not set');
20
+ return key_1.KeyService.mintKey(this.namespace, type, {
21
+ ...params,
22
+ appId: this.appId,
23
+ });
24
+ }
25
+ transact() {
26
+ return this.streamClient.multi();
27
+ }
28
+ // Core streaming operations
29
+ async createStream(streamName) {
30
+ try {
31
+ // streams are created when you add messages.
32
+ // To create an empty stream, we can add and delete a dummy message.
33
+ const dummyId = await this.streamClient.xadd(streamName, '*', 'field', 'value');
34
+ await this.streamClient.xdel(streamName, dummyId);
35
+ return true;
36
+ }
37
+ catch (error) {
38
+ this.logger.error(`Error creating stream ${streamName}`, { error });
39
+ throw error;
40
+ }
41
+ }
42
+ async deleteStream(streamName) {
43
+ try {
44
+ const result = await this.streamClient.del(streamName);
45
+ return result > 0;
46
+ }
47
+ catch (error) {
48
+ this.logger.error(`Error deleting stream ${streamName}`, { error });
49
+ throw error;
50
+ }
51
+ }
52
+ // Consumer group operations
53
+ async createConsumerGroup(key, groupName) {
54
+ try {
55
+ return ((await this.storeClient.xgroup('CREATE', key, groupName, '$', 'MKSTREAM')) === 'OK');
56
+ }
57
+ catch (err) {
58
+ this.logger.debug('stream-mkstream-caught', { key, group: groupName });
59
+ throw err;
60
+ }
61
+ }
62
+ async deleteConsumerGroup(streamName, groupName) {
63
+ try {
64
+ const result = await this.streamClient.xgroup('DESTROY', streamName, groupName);
65
+ return result === 1;
66
+ }
67
+ catch (error) {
68
+ this.logger.error(`Error deleting consumer group ${groupName} for stream ${streamName}`, { error });
69
+ throw error;
70
+ }
71
+ }
72
+ // Message operations
73
+ async publishMessages(streamName, messages, options) {
74
+ try {
75
+ const multi = options?.transaction ||
76
+ (messages.length > 1 && this.storeClient.multi());
77
+ let response;
78
+ for (const message of messages) {
79
+ response = await (multi || this.storeClient).xadd(streamName, '*', 'message', message);
80
+ }
81
+ if (multi && !options?.transaction) {
82
+ //only exec if we created the multi;
83
+ //otherwise caller is responsible
84
+ return (await multi.exec()).map((result) => result[1]);
85
+ }
86
+ else {
87
+ return [response];
88
+ }
89
+ }
90
+ catch (error) {
91
+ this.logger.error(`ioredis-xadd-error key: ${streamName}`, { error });
92
+ throw error;
93
+ }
94
+ }
95
+ async consumeMessages(streamName, groupName, consumerName, options) {
96
+ try {
97
+ const result = await this.streamClient.xreadgroup('GROUP', groupName, consumerName, 'BLOCK', options?.blockTimeout ?? enums_1.HMSH_BLOCK_TIME_MS, 'STREAMS', streamName, '>');
98
+ const response = [];
99
+ if ((0, utils_1.isStreamMessage)(result)) {
100
+ const [[, messages]] = result;
101
+ for (const [id, message] of messages) {
102
+ response.push({
103
+ id,
104
+ data: (0, utils_1.parseStreamMessage)(message[1]),
105
+ });
106
+ }
107
+ }
108
+ else {
109
+ return [];
110
+ }
111
+ return response;
112
+ }
113
+ catch (error) {
114
+ this.logger.error(`Error consuming messages from ${streamName}`, {
115
+ error,
116
+ });
117
+ throw error;
118
+ }
119
+ }
120
+ async ackAndDelete(stream, group, ids) {
121
+ const multi = this.storeClient.multi();
122
+ this.acknowledgeMessages(stream, group, ids, { multi });
123
+ this.deleteMessages(stream, group, ids, { multi });
124
+ await multi.exec();
125
+ return ids.length;
126
+ }
127
+ async acknowledgeMessages(stream, group, ids, options) {
128
+ try {
129
+ if (options?.multi) {
130
+ options.multi.xack(stream, group, ...ids);
131
+ return options.multi;
132
+ }
133
+ else {
134
+ return await this.streamClient.xack(stream, group, ...ids);
135
+ }
136
+ }
137
+ catch (error) {
138
+ this.logger.error(`Error in acknowledging messages: [${ids}] in group: ${group} for key: ${stream}`, { error });
139
+ throw error;
140
+ }
141
+ }
142
+ async deleteMessages(stream, group, ids, options) {
143
+ try {
144
+ if (options?.multi) {
145
+ options.multi.xdel(stream, ...ids);
146
+ return options.multi;
147
+ }
148
+ else {
149
+ return await this.streamClient.xdel(stream, ...ids);
150
+ }
151
+ }
152
+ catch (error) {
153
+ this.logger.error(`Error in deleting messages: ${ids} for key: ${stream}`, { error });
154
+ throw error;
155
+ }
156
+ }
157
+ async getPendingMessages(stream, group, count, consumer) {
158
+ const start = '-';
159
+ const end = '+';
160
+ try {
161
+ const args = [stream, group];
162
+ if (start)
163
+ args.push(start);
164
+ if (end)
165
+ args.push(end);
166
+ if (count !== undefined)
167
+ args.push(count.toString());
168
+ if (consumer)
169
+ args.push(consumer);
170
+ try {
171
+ return (await this.streamClient.call('XPENDING', ...args));
172
+ }
173
+ catch (error) {
174
+ this.logger.error('err, args', { error }, args);
175
+ }
176
+ }
177
+ catch (error) {
178
+ this.logger.error(`Error in retrieving pending messages for [stream ${stream}], [group ${group}]`, { error });
179
+ throw error;
180
+ }
181
+ }
182
+ // Retry Method
183
+ async retryMessages(streamName, groupName, options) {
184
+ let pendingMessages = [];
185
+ const pendingMessagesInfo = await this.getPendingMessages(streamName, groupName, options?.limit); //[[ '1688768134881-0', 'testConsumer1', 1017, 1 ]]
186
+ for (const pendingMessageInfo of pendingMessagesInfo) {
187
+ if (Array.isArray(pendingMessageInfo)) {
188
+ const [id, , elapsedTimeMs, deliveryCount] = pendingMessageInfo;
189
+ if (elapsedTimeMs > options?.minIdleTime) {
190
+ const reclaimedMessage = await this.claimMessage(streamName, groupName, options?.consumerName, options?.minIdleTime, id);
191
+ pendingMessages = pendingMessages.concat(reclaimedMessage);
192
+ }
193
+ }
194
+ }
195
+ return pendingMessages;
196
+ }
197
+ async claimMessage(streamName, groupName, consumerName, minIdleTime, messageId, ...args) {
198
+ try {
199
+ const message = (await this.streamClient.xclaim(streamName, groupName, consumerName, minIdleTime, messageId, ...args));
200
+ return {
201
+ id: message[0][0],
202
+ data: (0, utils_1.parseStreamMessage)(message[0][1][1]),
203
+ };
204
+ }
205
+ catch (error) {
206
+ this.logger.error(`Error in claiming message with id: ${messageId} in group: ${groupName} for key: ${streamName}`, { error });
207
+ throw error;
208
+ }
209
+ }
210
+ async getStreamStats(streamName) {
211
+ return {
212
+ messageCount: await this.getStreamDepth(streamName),
213
+ };
214
+ }
215
+ async getStreamDepth(streamName, options) {
216
+ try {
217
+ if (options?.multi) {
218
+ options.multi.xlen(streamName);
219
+ return 0;
220
+ }
221
+ const length = await this.streamClient.xlen(streamName);
222
+ return length;
223
+ }
224
+ catch (error) {
225
+ this.logger.error(`Error getting depth for ${streamName}`, { error });
226
+ throw error;
227
+ }
228
+ }
229
+ async getStreamDepths(streamNames) {
230
+ const multi = this.storeClient.multi();
231
+ const uniqueStreams = new Map(); // to store unique streams
232
+ // Add unique streams to the multi command
233
+ streamNames.forEach((profile) => {
234
+ if (!uniqueStreams.has(profile.stream)) {
235
+ uniqueStreams.set(profile.stream, -1); // initialize depth to -1 as a placeholder
236
+ this.getStreamDepth(profile.stream, { multi });
237
+ }
238
+ });
239
+ // Execute all commands
240
+ const streamDepthResults = (await multi.exec());
241
+ // Update the uniqueStreams map with the actual depths from multi.exec() results
242
+ Array.from(uniqueStreams.keys()).forEach((stream, idx) => {
243
+ uniqueStreams.set(stream, streamDepthResults[idx][1]);
244
+ });
245
+ // Map back to the original `streamNames` array with correct depths
246
+ const updatedNames = streamNames.map((profile) => {
247
+ return {
248
+ stream: profile.stream,
249
+ depth: uniqueStreams.get(profile.stream) || 0,
250
+ };
251
+ });
252
+ return updatedNames;
253
+ }
254
+ async trimStream(streamName, options) {
255
+ //no-op for now
256
+ return 0;
257
+ }
258
+ // Provider-specific helpers
259
+ getProviderSpecificFeatures() {
260
+ return {
261
+ supportsBatching: true,
262
+ supportsDeadLetterQueue: false,
263
+ supportsOrdering: true,
264
+ supportsTrimming: true,
265
+ supportsRetry: true,
266
+ supportsNotifications: false,
267
+ maxMessageSize: 512 * 1024 * 1024,
268
+ maxBatchSize: 1000,
269
+ };
270
+ }
271
+ }
272
+ exports.IORedisStreamService = IORedisStreamService;
@@ -0,0 +1,61 @@
1
+ import { ILogger } from '../../../logger';
2
+ import { StreamService } from '../../index';
3
+ import { RedisRedisClientType, RedisRedisMultiType } from '../../../../types/redis';
4
+ import { PublishMessageConfig, StreamConfig, StreamMessage, StreamStats } from '../../../../types/stream';
5
+ import { KeyStoreParams, StringAnyType } from '../../../../types';
6
+ import { KeyType } from '../../../../modules/key';
7
+ import { ProviderTransaction } from '../../../../types/provider';
8
+ declare class RedisStreamService extends StreamService<RedisRedisClientType, RedisRedisMultiType> {
9
+ constructor(streamClient: RedisRedisClientType, storeClient: RedisRedisClientType, config?: StreamConfig);
10
+ init(namespace: string, appId: string, logger: ILogger): Promise<void>;
11
+ mintKey(type: KeyType, params: KeyStoreParams): string;
12
+ transact(): ProviderTransaction;
13
+ createStream(streamName: string): Promise<boolean>;
14
+ deleteStream(streamName: string): Promise<boolean>;
15
+ createConsumerGroup(streamName: string, groupName: string): Promise<boolean>;
16
+ deleteConsumerGroup(streamName: string, groupName: string): Promise<boolean>;
17
+ publishMessages(streamName: string, messages: string[], options?: PublishMessageConfig): Promise<string[]>;
18
+ consumeMessages(streamName: string, groupName: string, consumerName: string, options?: {
19
+ batchSize?: number;
20
+ blockTimeout?: number;
21
+ }): Promise<StreamMessage[]>;
22
+ ackAndDelete(stream: string, group: string, ids: string[]): Promise<number>;
23
+ acknowledgeMessages(stream: string, group: string, ids: string[], options?: StringAnyType): Promise<number | RedisRedisMultiType>;
24
+ deleteMessages(stream: string, group: string, ids: string[], options?: StringAnyType): Promise<number | RedisRedisMultiType>;
25
+ getPendingMessages(stream: string, group: string, count?: number, consumer?: string): Promise<[string, string, number, [string, number][]][] | [string, string, number, number]>;
26
+ retryMessages(streamName: string, groupName: string, options?: {
27
+ consumerName?: string;
28
+ minIdleTime?: number;
29
+ messageIds?: string[];
30
+ delay?: number;
31
+ maxRetries?: number;
32
+ limit?: number;
33
+ }): Promise<StreamMessage[]>;
34
+ claimMessage(stream: string, group: string, consumer: string, minIdleTime: number, id: string, ...args: string[]): Promise<StreamMessage>;
35
+ getStreamStats(streamName: string): Promise<StreamStats>;
36
+ getStreamDepth(streamName: string, options?: {
37
+ multi: RedisRedisMultiType;
38
+ }): Promise<number>;
39
+ getStreamDepths(streamNames: {
40
+ stream: string;
41
+ }[]): Promise<{
42
+ stream: string;
43
+ depth: number;
44
+ }[]>;
45
+ trimStream(streamName: string, options: {
46
+ maxLen?: number;
47
+ maxAge?: number;
48
+ exactLimit?: boolean;
49
+ }): Promise<number>;
50
+ getProviderSpecificFeatures(): {
51
+ supportsBatching: boolean;
52
+ supportsDeadLetterQueue: boolean;
53
+ supportsOrdering: boolean;
54
+ supportsTrimming: boolean;
55
+ supportsRetry: boolean;
56
+ supportsNotifications: boolean;
57
+ maxMessageSize: number;
58
+ maxBatchSize: number;
59
+ };
60
+ }
61
+ export { RedisStreamService };
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisStreamService = void 0;
4
+ const index_1 = require("../../index");
5
+ const utils_1 = require("../../../../modules/utils");
6
+ const key_1 = require("../../../../modules/key");
7
+ const enums_1 = require("../../../../modules/enums");
8
+ class RedisStreamService extends index_1.StreamService {
9
+ constructor(streamClient, storeClient, config = {}) {
10
+ super(streamClient, storeClient, config);
11
+ }
12
+ async init(namespace, appId, logger) {
13
+ this.namespace = namespace;
14
+ this.logger = logger;
15
+ this.appId = appId;
16
+ }
17
+ mintKey(type, params) {
18
+ if (!this.namespace)
19
+ throw new Error('namespace not set');
20
+ return key_1.KeyService.mintKey(this.namespace, type, {
21
+ ...params,
22
+ appId: this.appId,
23
+ });
24
+ }
25
+ transact() {
26
+ return this.streamClient.multi();
27
+ }
28
+ // Core streaming operations
29
+ async createStream(streamName) {
30
+ try {
31
+ // streams are created when you add messages.
32
+ // To create an empty stream, we can add and delete a dummy message.
33
+ const dummyId = await this.streamClient.XADD(streamName, '*', {
34
+ field: 'value',
35
+ });
36
+ await this.streamClient.XDEL(streamName, dummyId);
37
+ return true;
38
+ }
39
+ catch (error) {
40
+ this.logger.error(`Error creating stream ${streamName}`, { error });
41
+ throw error;
42
+ }
43
+ }
44
+ async deleteStream(streamName) {
45
+ try {
46
+ const result = await this.streamClient.DEL(streamName);
47
+ return result > 0;
48
+ }
49
+ catch (error) {
50
+ this.logger.error(`Error deleting stream ${streamName}`, { error });
51
+ throw error;
52
+ }
53
+ }
54
+ // Consumer group operations
55
+ async createConsumerGroup(streamName, groupName) {
56
+ try {
57
+ const result = (await this.storeClient.sendCommand([
58
+ 'XGROUP',
59
+ 'CREATE',
60
+ streamName,
61
+ groupName,
62
+ '$',
63
+ 'MKSTREAM',
64
+ ]));
65
+ return result === 'OK';
66
+ }
67
+ catch (error) {
68
+ const streamType = 'with MKSTREAM';
69
+ this.logger.debug(`x-group-error ${streamType} for key: ${streamName} and group: ${groupName}`, { error });
70
+ throw error;
71
+ }
72
+ }
73
+ async deleteConsumerGroup(streamName, groupName) {
74
+ try {
75
+ const result = await this.streamClient.xGroupDestroy(streamName, groupName);
76
+ return result;
77
+ }
78
+ catch (error) {
79
+ this.logger.error(`Error deleting consumer group ${groupName} for stream ${streamName}`, { error });
80
+ throw error;
81
+ }
82
+ }
83
+ async publishMessages(streamName, messages, options) {
84
+ try {
85
+ const multi = options?.transaction ||
86
+ (messages.length > 1 && this.storeClient.multi());
87
+ let response;
88
+ for (const message of messages) {
89
+ response = await (multi || this.storeClient).XADD(streamName, '*', {
90
+ message: message,
91
+ });
92
+ }
93
+ if (multi && !options?.transaction) {
94
+ //only exec if we created the multi;
95
+ //otherwise caller is responsible
96
+ return (await multi.exec()).map((result) => result[1]);
97
+ }
98
+ else {
99
+ return [response];
100
+ }
101
+ }
102
+ catch (error) {
103
+ this.logger.error(`ioredis-xadd-error key: ${streamName}`, { error });
104
+ throw error;
105
+ }
106
+ }
107
+ async consumeMessages(streamName, groupName, consumerName, options) {
108
+ const command = 'GROUP';
109
+ const blockOption = 'BLOCK';
110
+ const streamsOption = 'STREAMS';
111
+ const id = '>';
112
+ try {
113
+ const result = await this.streamClient.sendCommand([
114
+ 'XREADGROUP',
115
+ command,
116
+ groupName,
117
+ consumerName,
118
+ blockOption,
119
+ options?.blockTimeout?.toString() ?? enums_1.HMSH_BLOCK_TIME_MS.toString(),
120
+ streamsOption,
121
+ streamName,
122
+ id,
123
+ ]);
124
+ const response = [];
125
+ if ((0, utils_1.isStreamMessage)(result)) {
126
+ const [[, messages]] = result;
127
+ for (const [id, message] of messages) {
128
+ response.push({
129
+ id,
130
+ data: (0, utils_1.parseStreamMessage)(message[1]),
131
+ });
132
+ }
133
+ }
134
+ else {
135
+ return [];
136
+ }
137
+ return response;
138
+ }
139
+ catch (error) {
140
+ this.logger.error(`Error consuming messages from ${streamName}`, {
141
+ error,
142
+ });
143
+ throw error;
144
+ }
145
+ }
146
+ async ackAndDelete(stream, group, ids) {
147
+ const multi = this.storeClient.multi();
148
+ await this.acknowledgeMessages(stream, group, ids, { multi });
149
+ await this.deleteMessages(stream, group, ids, { multi });
150
+ await multi.exec();
151
+ return ids.length;
152
+ }
153
+ async acknowledgeMessages(stream, group, ids, options) {
154
+ try {
155
+ if (options?.multi) {
156
+ options.multi.XACK(stream, group, ids);
157
+ return options.multi;
158
+ }
159
+ else {
160
+ return await this.streamClient.XACK(stream, group, ...ids);
161
+ }
162
+ }
163
+ catch (error) {
164
+ this.logger.error(`Error in acknowledging messages in group: ${group} for key: ${stream}`, { error });
165
+ throw error;
166
+ }
167
+ }
168
+ async deleteMessages(stream, group, ids, options) {
169
+ try {
170
+ if (options?.multi) {
171
+ options.multi.xDel(stream, ids);
172
+ return options.multi;
173
+ }
174
+ else {
175
+ return await this.streamClient.XDEL(stream, ...ids);
176
+ }
177
+ }
178
+ catch (error) {
179
+ this.logger.error(`Error in deleting messages with ids: ${ids.join(',')} for key: ${stream}`, { error });
180
+ throw error;
181
+ }
182
+ }
183
+ async getPendingMessages(stream, group, count, consumer) {
184
+ try {
185
+ const start = '-';
186
+ const end = '+';
187
+ const args = [stream, group];
188
+ if (start)
189
+ args.push(start);
190
+ if (end)
191
+ args.push(end);
192
+ if (count !== undefined)
193
+ args.push(count.toString());
194
+ if (consumer)
195
+ args.push(consumer);
196
+ try {
197
+ return await this.streamClient.sendCommand(['XPENDING', ...args]);
198
+ }
199
+ catch (error) {
200
+ this.logger.error('error, args', { error }, args);
201
+ }
202
+ }
203
+ catch (error) {
204
+ this.logger.error(`Error retrieving pending messages for group: ${group} in key: ${stream}`, { error });
205
+ throw error;
206
+ }
207
+ }
208
+ // Retry Method
209
+ async retryMessages(streamName, groupName, options) {
210
+ let pendingMessages = [];
211
+ const pendingMessagesInfo = await this.getPendingMessages(streamName, groupName, options?.limit); //[[ '1688768134881-0', 'testConsumer1', 1017, 1 ]]
212
+ for (const pendingMessageInfo of pendingMessagesInfo) {
213
+ if (Array.isArray(pendingMessageInfo)) {
214
+ const [id, , elapsedTimeMs, deliveryCount] = pendingMessageInfo;
215
+ if (elapsedTimeMs > options?.minIdleTime) {
216
+ const reclaimedMessage = await this.claimMessage(streamName, groupName, options?.consumerName, options?.minIdleTime, id);
217
+ pendingMessages = pendingMessages.concat(reclaimedMessage);
218
+ }
219
+ }
220
+ }
221
+ return pendingMessages;
222
+ }
223
+ async claimMessage(stream, group, consumer, minIdleTime, id, ...args) {
224
+ try {
225
+ const message = (await this.streamClient.sendCommand([
226
+ 'XCLAIM',
227
+ stream,
228
+ group,
229
+ consumer,
230
+ minIdleTime.toString(),
231
+ id,
232
+ ...args,
233
+ ]));
234
+ return {
235
+ id: message[0][0],
236
+ data: (0, utils_1.parseStreamMessage)(message[0][1][1]),
237
+ };
238
+ }
239
+ catch (error) {
240
+ this.logger.error(`Error in claiming message with id: ${id} in group: ${group} for key: ${stream}`, { error });
241
+ throw error;
242
+ }
243
+ }
244
+ async getStreamStats(streamName) {
245
+ return {
246
+ messageCount: await this.getStreamDepth(streamName),
247
+ };
248
+ }
249
+ async getStreamDepth(streamName, options) {
250
+ try {
251
+ if (options?.multi) {
252
+ options.multi.XLEN(streamName);
253
+ return 0;
254
+ }
255
+ const length = await this.streamClient.XLEN(streamName);
256
+ return length;
257
+ }
258
+ catch (error) {
259
+ this.logger.error(`Error getting depth for ${streamName}`, { error });
260
+ throw error;
261
+ }
262
+ }
263
+ async getStreamDepths(streamNames) {
264
+ const multi = this.storeClient.multi();
265
+ const uniqueStreams = new Map(); // Use a Map to track unique streams
266
+ // Add unique streams to the multi command
267
+ streamNames.forEach((profile) => {
268
+ if (!uniqueStreams.has(profile.stream)) {
269
+ uniqueStreams.set(profile.stream, -1); // Initialize depth to -1 as a placeholder
270
+ this.getStreamDepth(profile.stream, { multi: multi });
271
+ }
272
+ });
273
+ // Execute all commands in multi (ioredis strips null fields)
274
+ const streamDepthResults = (await multi.exec());
275
+ // Update the uniqueStreams map with actual depths from multi.exec() results
276
+ Array.from(uniqueStreams.keys()).forEach((stream, idx) => {
277
+ uniqueStreams.set(stream, streamDepthResults[idx]);
278
+ });
279
+ // Map back to the original `streamNames` array with correct depths
280
+ return streamNames.map((profile) => {
281
+ return {
282
+ stream: profile.stream,
283
+ depth: uniqueStreams.get(profile.stream) || 0,
284
+ };
285
+ });
286
+ }
287
+ async trimStream(streamName, options) {
288
+ //no-op for now
289
+ return 0;
290
+ }
291
+ // Provider-specific helpers
292
+ getProviderSpecificFeatures() {
293
+ return {
294
+ supportsBatching: true,
295
+ supportsDeadLetterQueue: false,
296
+ supportsOrdering: true,
297
+ supportsTrimming: true,
298
+ supportsRetry: true,
299
+ supportsNotifications: false,
300
+ maxMessageSize: 512 * 1024 * 1024,
301
+ maxBatchSize: 1000,
302
+ };
303
+ }
304
+ }
305
+ exports.RedisStreamService = RedisStreamService;
@@ -0,0 +1,4 @@
1
+ import { ILogger } from '../../logger';
2
+ export interface StreamInitializable {
3
+ init(namespace: string, appId: string, logger: ILogger): Promise<void>;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ import { ILogger } from '../logger';
2
+ import { ProviderClient } from '../../types/provider';
3
+ import { SubService } from './index';
4
+ declare class SubServiceFactory {
5
+ static init(providerSubClient: ProviderClient, providerPubClient: ProviderClient, namespace: string, appId: string, engineId: string, logger: ILogger): Promise<SubService<ProviderClient>>;
6
+ }
7
+ export { SubServiceFactory };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubServiceFactory = void 0;
4
+ const utils_1 = require("../../modules/utils");
5
+ const redis_1 = require("./providers/redis/redis");
6
+ const postgres_1 = require("./providers/postgres/postgres");
7
+ const nats_1 = require("./providers/nats/nats");
8
+ const ioredis_1 = require("./providers/redis/ioredis");
9
+ class SubServiceFactory {
10
+ static async init(providerSubClient, providerPubClient, namespace, appId, engineId, logger) {
11
+ let service;
12
+ const providerType = (0, utils_1.identifyProvider)(providerSubClient);
13
+ if (providerType === 'nats') {
14
+ service = new nats_1.NatsSubService(providerSubClient, providerPubClient);
15
+ }
16
+ else if (providerType === 'redis') {
17
+ service = new redis_1.RedisSubService(providerSubClient, providerPubClient);
18
+ }
19
+ else if (providerType === 'postgres') {
20
+ service = new postgres_1.PostgresSubService(providerSubClient, providerPubClient);
21
+ }
22
+ else {
23
+ service = new ioredis_1.IORedisSubService(providerSubClient, providerPubClient);
24
+ }
25
+ await service.init(namespace, appId, engineId, logger);
26
+ return service;
27
+ }
28
+ }
29
+ exports.SubServiceFactory = SubServiceFactory;