@hotmeshio/hotmesh 0.4.0 → 0.4.2

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 (284) hide show
  1. package/README.md +39 -14
  2. package/build/modules/enums.d.ts +110 -0
  3. package/build/modules/enums.js +134 -0
  4. package/build/modules/errors.d.ts +124 -0
  5. package/build/modules/errors.js +191 -0
  6. package/build/modules/key.d.ts +66 -0
  7. package/build/modules/key.js +190 -0
  8. package/build/modules/storage.d.ts +3 -0
  9. package/build/modules/storage.js +5 -0
  10. package/build/modules/utils.d.ts +119 -0
  11. package/build/modules/utils.js +374 -0
  12. package/build/package.json +1 -1
  13. package/build/services/activities/activity.d.ts +104 -0
  14. package/build/services/activities/activity.js +549 -0
  15. package/build/services/activities/await.d.ts +12 -0
  16. package/build/services/activities/await.js +114 -0
  17. package/build/services/activities/cycle.d.ts +19 -0
  18. package/build/services/activities/cycle.js +112 -0
  19. package/build/services/activities/hook.d.ts +27 -0
  20. package/build/services/activities/hook.js +168 -0
  21. package/build/services/activities/index.d.ts +19 -0
  22. package/build/services/activities/index.js +20 -0
  23. package/build/services/activities/interrupt.d.ts +16 -0
  24. package/build/services/activities/interrupt.js +158 -0
  25. package/build/services/activities/signal.d.ts +20 -0
  26. package/build/services/activities/signal.js +134 -0
  27. package/build/services/activities/trigger.d.ts +37 -0
  28. package/build/services/activities/trigger.js +246 -0
  29. package/build/services/activities/worker.d.ts +12 -0
  30. package/build/services/activities/worker.js +106 -0
  31. package/build/services/collator/index.d.ts +111 -0
  32. package/build/services/collator/index.js +293 -0
  33. package/build/services/compiler/deployer.d.ts +40 -0
  34. package/build/services/compiler/deployer.js +488 -0
  35. package/build/services/compiler/index.d.ts +32 -0
  36. package/build/services/compiler/index.js +112 -0
  37. package/build/services/compiler/validator.d.ts +34 -0
  38. package/build/services/compiler/validator.js +147 -0
  39. package/build/services/connector/factory.d.ts +22 -0
  40. package/build/services/connector/factory.js +99 -0
  41. package/build/services/connector/index.d.ts +30 -0
  42. package/build/services/connector/index.js +54 -0
  43. package/build/services/connector/providers/ioredis.d.ts +9 -0
  44. package/build/services/connector/providers/ioredis.js +26 -0
  45. package/build/services/connector/providers/nats.d.ts +9 -0
  46. package/build/services/connector/providers/nats.js +34 -0
  47. package/build/services/connector/providers/postgres.d.ts +20 -0
  48. package/build/services/connector/providers/postgres.js +102 -0
  49. package/build/services/connector/providers/redis.d.ts +9 -0
  50. package/build/services/connector/providers/redis.js +38 -0
  51. package/build/services/engine/index.d.ts +264 -0
  52. package/build/services/engine/index.js +761 -0
  53. package/build/services/exporter/index.d.ts +44 -0
  54. package/build/services/exporter/index.js +126 -0
  55. package/build/services/hotmesh/index.d.ts +483 -0
  56. package/build/services/hotmesh/index.js +622 -0
  57. package/build/services/logger/index.d.ts +16 -0
  58. package/build/services/logger/index.js +54 -0
  59. package/build/services/mapper/index.d.ts +28 -0
  60. package/build/services/mapper/index.js +81 -0
  61. package/build/services/memflow/client.d.ts +108 -0
  62. package/build/services/memflow/client.js +372 -0
  63. package/build/services/memflow/connection.d.ts +23 -0
  64. package/build/services/memflow/connection.js +33 -0
  65. package/build/services/memflow/context.d.ts +143 -0
  66. package/build/services/memflow/context.js +299 -0
  67. package/build/services/memflow/exporter.d.ts +51 -0
  68. package/build/services/memflow/exporter.js +215 -0
  69. package/build/services/memflow/handle.d.ts +90 -0
  70. package/build/services/memflow/handle.js +176 -0
  71. package/build/services/memflow/index.d.ts +116 -0
  72. package/build/services/memflow/index.js +122 -0
  73. package/build/services/memflow/schemas/factory.d.ts +29 -0
  74. package/build/services/memflow/schemas/factory.js +2492 -0
  75. package/build/services/memflow/search.d.ts +142 -0
  76. package/build/services/memflow/search.js +320 -0
  77. package/build/services/memflow/worker.d.ts +124 -0
  78. package/build/services/memflow/worker.js +514 -0
  79. package/build/services/memflow/workflow/all.d.ts +7 -0
  80. package/build/services/memflow/workflow/all.js +15 -0
  81. package/build/services/memflow/workflow/common.d.ts +20 -0
  82. package/build/services/memflow/workflow/common.js +47 -0
  83. package/build/services/memflow/workflow/context.d.ts +6 -0
  84. package/build/services/memflow/workflow/context.js +45 -0
  85. package/build/services/memflow/workflow/contextMethods.d.ts +14 -0
  86. package/build/services/memflow/workflow/contextMethods.js +33 -0
  87. package/build/services/memflow/workflow/didRun.d.ts +7 -0
  88. package/build/services/memflow/workflow/didRun.js +22 -0
  89. package/build/services/memflow/workflow/emit.d.ts +11 -0
  90. package/build/services/memflow/workflow/emit.js +29 -0
  91. package/build/services/memflow/workflow/enrich.d.ts +9 -0
  92. package/build/services/memflow/workflow/enrich.js +17 -0
  93. package/build/services/memflow/workflow/execChild.d.ts +18 -0
  94. package/build/services/memflow/workflow/execChild.js +102 -0
  95. package/build/services/memflow/workflow/execHook.d.ts +65 -0
  96. package/build/services/memflow/workflow/execHook.js +73 -0
  97. package/build/services/memflow/workflow/hook.d.ts +9 -0
  98. package/build/services/memflow/workflow/hook.js +56 -0
  99. package/build/services/memflow/workflow/index.d.ts +74 -0
  100. package/build/services/memflow/workflow/index.js +87 -0
  101. package/build/services/memflow/workflow/interrupt.d.ts +9 -0
  102. package/build/services/memflow/workflow/interrupt.js +24 -0
  103. package/build/services/memflow/workflow/isSideEffectAllowed.d.ts +10 -0
  104. package/build/services/memflow/workflow/isSideEffectAllowed.js +33 -0
  105. package/build/services/memflow/workflow/proxyActivities.d.ts +20 -0
  106. package/build/services/memflow/workflow/proxyActivities.js +97 -0
  107. package/build/services/memflow/workflow/random.d.ts +6 -0
  108. package/build/services/memflow/workflow/random.js +16 -0
  109. package/build/services/memflow/workflow/searchMethods.d.ts +6 -0
  110. package/build/services/memflow/workflow/searchMethods.js +25 -0
  111. package/build/services/memflow/workflow/signal.d.ts +29 -0
  112. package/build/services/memflow/workflow/signal.js +50 -0
  113. package/build/services/memflow/workflow/sleepFor.d.ts +24 -0
  114. package/build/services/memflow/workflow/sleepFor.js +51 -0
  115. package/build/services/memflow/workflow/trace.d.ts +14 -0
  116. package/build/services/memflow/workflow/trace.js +33 -0
  117. package/build/services/memflow/workflow/waitFor.d.ts +29 -0
  118. package/build/services/memflow/workflow/waitFor.js +56 -0
  119. package/build/services/meshcall/index.d.ts +194 -0
  120. package/build/services/meshcall/index.js +452 -0
  121. package/build/services/meshcall/schemas/factory.d.ts +9 -0
  122. package/build/services/meshcall/schemas/factory.js +189 -0
  123. package/build/services/meshdata/index.d.ts +795 -0
  124. package/build/services/meshdata/index.js +1235 -0
  125. package/build/services/meshos/index.d.ts +293 -0
  126. package/build/services/meshos/index.js +547 -0
  127. package/build/services/pipe/functions/array.d.ts +17 -0
  128. package/build/services/pipe/functions/array.js +74 -0
  129. package/build/services/pipe/functions/bitwise.d.ts +9 -0
  130. package/build/services/pipe/functions/bitwise.js +24 -0
  131. package/build/services/pipe/functions/conditional.d.ts +13 -0
  132. package/build/services/pipe/functions/conditional.js +36 -0
  133. package/build/services/pipe/functions/cron.d.ts +12 -0
  134. package/build/services/pipe/functions/cron.js +40 -0
  135. package/build/services/pipe/functions/date.d.ts +58 -0
  136. package/build/services/pipe/functions/date.js +171 -0
  137. package/build/services/pipe/functions/index.d.ts +29 -0
  138. package/build/services/pipe/functions/index.js +30 -0
  139. package/build/services/pipe/functions/json.d.ts +5 -0
  140. package/build/services/pipe/functions/json.js +12 -0
  141. package/build/services/pipe/functions/logical.d.ts +5 -0
  142. package/build/services/pipe/functions/logical.js +12 -0
  143. package/build/services/pipe/functions/math.d.ts +42 -0
  144. package/build/services/pipe/functions/math.js +184 -0
  145. package/build/services/pipe/functions/number.d.ts +21 -0
  146. package/build/services/pipe/functions/number.js +60 -0
  147. package/build/services/pipe/functions/object.d.ts +25 -0
  148. package/build/services/pipe/functions/object.js +81 -0
  149. package/build/services/pipe/functions/string.d.ts +23 -0
  150. package/build/services/pipe/functions/string.js +69 -0
  151. package/build/services/pipe/functions/symbol.d.ts +12 -0
  152. package/build/services/pipe/functions/symbol.js +33 -0
  153. package/build/services/pipe/functions/unary.d.ts +7 -0
  154. package/build/services/pipe/functions/unary.js +18 -0
  155. package/build/services/pipe/index.d.ts +48 -0
  156. package/build/services/pipe/index.js +242 -0
  157. package/build/services/quorum/index.d.ts +90 -0
  158. package/build/services/quorum/index.js +263 -0
  159. package/build/services/reporter/index.d.ts +50 -0
  160. package/build/services/reporter/index.js +348 -0
  161. package/build/services/router/config/index.d.ts +11 -0
  162. package/build/services/router/config/index.js +36 -0
  163. package/build/services/router/consumption/index.d.ts +34 -0
  164. package/build/services/router/consumption/index.js +395 -0
  165. package/build/services/router/error-handling/index.d.ts +8 -0
  166. package/build/services/router/error-handling/index.js +98 -0
  167. package/build/services/router/index.d.ts +57 -0
  168. package/build/services/router/index.js +121 -0
  169. package/build/services/router/lifecycle/index.d.ts +27 -0
  170. package/build/services/router/lifecycle/index.js +80 -0
  171. package/build/services/router/telemetry/index.d.ts +11 -0
  172. package/build/services/router/telemetry/index.js +32 -0
  173. package/build/services/router/throttling/index.d.ts +23 -0
  174. package/build/services/router/throttling/index.js +76 -0
  175. package/build/services/search/factory.d.ts +7 -0
  176. package/build/services/search/factory.js +24 -0
  177. package/build/services/search/index.d.ts +23 -0
  178. package/build/services/search/index.js +10 -0
  179. package/build/services/search/providers/postgres/postgres.d.ts +25 -0
  180. package/build/services/search/providers/postgres/postgres.js +149 -0
  181. package/build/services/search/providers/redis/ioredis.d.ts +19 -0
  182. package/build/services/search/providers/redis/ioredis.js +121 -0
  183. package/build/services/search/providers/redis/redis.d.ts +19 -0
  184. package/build/services/search/providers/redis/redis.js +134 -0
  185. package/build/services/serializer/index.d.ts +42 -0
  186. package/build/services/serializer/index.js +282 -0
  187. package/build/services/store/cache.d.ts +67 -0
  188. package/build/services/store/cache.js +128 -0
  189. package/build/services/store/factory.d.ts +8 -0
  190. package/build/services/store/factory.js +24 -0
  191. package/build/services/store/index.d.ts +89 -0
  192. package/build/services/store/index.js +9 -0
  193. package/build/services/store/providers/postgres/kvsql.d.ts +168 -0
  194. package/build/services/store/providers/postgres/kvsql.js +198 -0
  195. package/build/services/store/providers/postgres/kvtables.d.ts +20 -0
  196. package/build/services/store/providers/postgres/kvtables.js +441 -0
  197. package/build/services/store/providers/postgres/kvtransaction.d.ts +36 -0
  198. package/build/services/store/providers/postgres/kvtransaction.js +248 -0
  199. package/build/services/store/providers/postgres/kvtypes/hash.d.ts +60 -0
  200. package/build/services/store/providers/postgres/kvtypes/hash.js +1287 -0
  201. package/build/services/store/providers/postgres/kvtypes/list.d.ts +33 -0
  202. package/build/services/store/providers/postgres/kvtypes/list.js +194 -0
  203. package/build/services/store/providers/postgres/kvtypes/string.d.ts +20 -0
  204. package/build/services/store/providers/postgres/kvtypes/string.js +115 -0
  205. package/build/services/store/providers/postgres/kvtypes/zset.d.ts +41 -0
  206. package/build/services/store/providers/postgres/kvtypes/zset.js +214 -0
  207. package/build/services/store/providers/postgres/postgres.d.ts +178 -0
  208. package/build/services/store/providers/postgres/postgres.js +1244 -0
  209. package/build/services/store/providers/redis/_base.d.ts +137 -0
  210. package/build/services/store/providers/redis/_base.js +980 -0
  211. package/build/services/store/providers/redis/ioredis.d.ts +20 -0
  212. package/build/services/store/providers/redis/ioredis.js +180 -0
  213. package/build/services/store/providers/redis/redis.d.ts +18 -0
  214. package/build/services/store/providers/redis/redis.js +199 -0
  215. package/build/services/store/providers/store-initializable.d.ts +5 -0
  216. package/build/services/store/providers/store-initializable.js +2 -0
  217. package/build/services/stream/factory.d.ts +8 -0
  218. package/build/services/stream/factory.js +37 -0
  219. package/build/services/stream/index.d.ts +69 -0
  220. package/build/services/stream/index.js +11 -0
  221. package/build/services/stream/providers/nats/nats.d.ts +60 -0
  222. package/build/services/stream/providers/nats/nats.js +225 -0
  223. package/build/services/stream/providers/postgres/kvtables.d.ts +3 -0
  224. package/build/services/stream/providers/postgres/kvtables.js +146 -0
  225. package/build/services/stream/providers/postgres/postgres.d.ts +107 -0
  226. package/build/services/stream/providers/postgres/postgres.js +519 -0
  227. package/build/services/stream/providers/redis/ioredis.d.ts +61 -0
  228. package/build/services/stream/providers/redis/ioredis.js +272 -0
  229. package/build/services/stream/providers/redis/redis.d.ts +61 -0
  230. package/build/services/stream/providers/redis/redis.js +305 -0
  231. package/build/services/stream/providers/stream-initializable.d.ts +4 -0
  232. package/build/services/stream/providers/stream-initializable.js +2 -0
  233. package/build/services/sub/factory.d.ts +7 -0
  234. package/build/services/sub/factory.js +29 -0
  235. package/build/services/sub/index.d.ts +22 -0
  236. package/build/services/sub/index.js +10 -0
  237. package/build/services/sub/providers/nats/nats.d.ts +19 -0
  238. package/build/services/sub/providers/nats/nats.js +105 -0
  239. package/build/services/sub/providers/postgres/postgres.d.ts +19 -0
  240. package/build/services/sub/providers/postgres/postgres.js +92 -0
  241. package/build/services/sub/providers/redis/ioredis.d.ts +17 -0
  242. package/build/services/sub/providers/redis/ioredis.js +81 -0
  243. package/build/services/sub/providers/redis/redis.d.ts +17 -0
  244. package/build/services/sub/providers/redis/redis.js +72 -0
  245. package/build/services/task/index.d.ts +48 -0
  246. package/build/services/task/index.js +253 -0
  247. package/build/services/telemetry/index.d.ts +52 -0
  248. package/build/services/telemetry/index.js +306 -0
  249. package/build/services/worker/index.d.ts +77 -0
  250. package/build/services/worker/index.js +197 -0
  251. package/package.json +1 -1
  252. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  253. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  254. package/typedoc.json +0 -47
  255. package/types/activity.ts +0 -268
  256. package/types/app.ts +0 -20
  257. package/types/async.ts +0 -6
  258. package/types/cache.ts +0 -1
  259. package/types/collator.ts +0 -9
  260. package/types/error.ts +0 -56
  261. package/types/exporter.ts +0 -102
  262. package/types/hook.ts +0 -44
  263. package/types/hotmesh.ts +0 -314
  264. package/types/index.ts +0 -306
  265. package/types/job.ts +0 -233
  266. package/types/logger.ts +0 -8
  267. package/types/manifest.ts +0 -70
  268. package/types/map.ts +0 -5
  269. package/types/memflow.ts +0 -645
  270. package/types/meshcall.ts +0 -235
  271. package/types/meshdata.ts +0 -278
  272. package/types/ms.d.ts +0 -7
  273. package/types/nats.ts +0 -270
  274. package/types/pipe.ts +0 -90
  275. package/types/postgres.ts +0 -114
  276. package/types/provider.ts +0 -161
  277. package/types/quorum.ts +0 -167
  278. package/types/redis.ts +0 -404
  279. package/types/serializer.ts +0 -40
  280. package/types/stats.ts +0 -117
  281. package/types/stream.ts +0 -231
  282. package/types/task.ts +0 -7
  283. package/types/telemetry.ts +0 -16
  284. package/types/transition.ts +0 -20
@@ -0,0 +1,761 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EngineService = void 0;
7
+ const key_1 = require("../../modules/key");
8
+ const enums_1 = require("../../modules/enums");
9
+ const utils_1 = require("../../modules/utils");
10
+ const activities_1 = __importDefault(require("../activities"));
11
+ const compiler_1 = require("../compiler");
12
+ const exporter_1 = require("../exporter");
13
+ const reporter_1 = require("../reporter");
14
+ const router_1 = require("../router");
15
+ const serializer_1 = require("../serializer");
16
+ const factory_1 = require("../search/factory");
17
+ const factory_2 = require("../store/factory");
18
+ const factory_3 = require("../stream/factory");
19
+ const factory_4 = require("../sub/factory");
20
+ const task_1 = require("../task");
21
+ const stream_1 = require("../../types/stream");
22
+ class EngineService {
23
+ /**
24
+ * @private
25
+ */
26
+ constructor() {
27
+ this.cacheMode = 'cache';
28
+ this.untilVersion = null;
29
+ this.jobCallbacks = {};
30
+ this.reporting = false;
31
+ this.jobId = 1;
32
+ }
33
+ /**
34
+ * @private
35
+ */
36
+ static async init(namespace, appId, guid, config, logger) {
37
+ if (config.engine) {
38
+ const instance = new EngineService();
39
+ instance.verifyEngineFields(config);
40
+ instance.namespace = namespace;
41
+ instance.appId = appId;
42
+ instance.guid = guid;
43
+ instance.logger = logger;
44
+ await instance.initSearchChannel(config.engine.store);
45
+ await instance.initStoreChannel(config.engine.store);
46
+ //NOTE: if `pub` is present, use it; otherwise, use `store`
47
+ await instance.initSubChannel(config.engine.sub, config.engine.pub ?? config.engine.store);
48
+ await instance.initStreamChannel(config.engine.stream, config.engine.store);
49
+ instance.router = await instance.initRouter(config);
50
+ const streamName = instance.store.mintKey(key_1.KeyType.STREAMS, {
51
+ appId: instance.appId,
52
+ });
53
+ instance.router.consumeMessages(streamName, 'ENGINE', instance.guid, instance.processStreamMessage.bind(instance));
54
+ instance.taskService = new task_1.TaskService(instance.store, logger);
55
+ instance.exporter = new exporter_1.ExporterService(instance.appId, instance.store, logger);
56
+ instance.inited = (0, utils_1.formatISODate)(new Date());
57
+ return instance;
58
+ }
59
+ }
60
+ /**
61
+ * @private
62
+ */
63
+ verifyEngineFields(config) {
64
+ if (!(0, utils_1.identifyProvider)(config.engine.store) ||
65
+ !(0, utils_1.identifyProvider)(config.engine.stream) ||
66
+ !(0, utils_1.identifyProvider)(config.engine.sub)) {
67
+ throw new Error('engine must include `store`, `stream`, and `sub` fields.');
68
+ }
69
+ }
70
+ /**
71
+ * @private
72
+ */
73
+ async initSearchChannel(search, store) {
74
+ this.search = await factory_1.SearchServiceFactory.init(search, store, this.namespace, this.appId, this.logger);
75
+ }
76
+ /**
77
+ * @private
78
+ */
79
+ async initStoreChannel(store) {
80
+ this.store = await factory_2.StoreServiceFactory.init(store, this.namespace, this.appId, this.logger);
81
+ }
82
+ /**
83
+ * @private
84
+ */
85
+ async initSubChannel(sub, store) {
86
+ this.subscribe = await factory_4.SubServiceFactory.init(sub, store, this.namespace, this.appId, this.guid, this.logger);
87
+ }
88
+ /**
89
+ * @private
90
+ */
91
+ async initStreamChannel(stream, store) {
92
+ this.stream = await factory_3.StreamServiceFactory.init(stream, store, this.namespace, this.appId, this.logger);
93
+ }
94
+ /**
95
+ * @private
96
+ */
97
+ async initRouter(config) {
98
+ const throttle = await this.store.getThrottleRate(':');
99
+ return new router_1.Router({
100
+ namespace: this.namespace,
101
+ appId: this.appId,
102
+ guid: this.guid,
103
+ role: stream_1.StreamRole.ENGINE,
104
+ reclaimDelay: config.engine.reclaimDelay,
105
+ reclaimCount: config.engine.reclaimCount,
106
+ throttle,
107
+ readonly: config.engine.readonly,
108
+ }, this.stream, this.logger);
109
+ }
110
+ /**
111
+ * resolves the distributed executable version using a delay
112
+ * to allow deployment race conditions to resolve
113
+ * @private
114
+ */
115
+ async fetchAndVerifyVID(vid, count = 0) {
116
+ if (isNaN(Number(vid.version))) {
117
+ const app = await this.store.getApp(vid.id, true);
118
+ if (!isNaN(Number(app.version))) {
119
+ if (!this.apps)
120
+ this.apps = {};
121
+ this.apps[vid.id] = app;
122
+ return { id: vid.id, version: app.version };
123
+ }
124
+ else if (count < 10) {
125
+ await (0, utils_1.sleepFor)(enums_1.HMSH_QUORUM_DELAY_MS * 2);
126
+ return await this.fetchAndVerifyVID(vid, count + 1);
127
+ }
128
+ else {
129
+ this.logger.error('engine-vid-resolution-error', {
130
+ id: vid.id,
131
+ guid: this.guid,
132
+ });
133
+ }
134
+ }
135
+ return vid;
136
+ }
137
+ async getVID(vid) {
138
+ if (this.cacheMode === 'nocache') {
139
+ const app = await this.store.getApp(this.appId, true);
140
+ if (app.version.toString() === this.untilVersion.toString()) {
141
+ //new version is deployed; OK to cache again
142
+ if (!this.apps)
143
+ this.apps = {};
144
+ this.apps[this.appId] = app;
145
+ this.setCacheMode('cache', app.version.toString());
146
+ }
147
+ return { id: this.appId, version: app.version };
148
+ }
149
+ else if (!this.apps && vid) {
150
+ this.apps = {};
151
+ this.apps[this.appId] = vid;
152
+ return vid;
153
+ }
154
+ else {
155
+ return await this.fetchAndVerifyVID({
156
+ id: this.appId,
157
+ version: this.apps?.[this.appId].version,
158
+ });
159
+ }
160
+ }
161
+ /**
162
+ * @private
163
+ */
164
+ setCacheMode(cacheMode, untilVersion) {
165
+ this.logger.info(`engine-executable-cache`, {
166
+ mode: cacheMode,
167
+ [cacheMode === 'cache' ? 'target' : 'until']: untilVersion,
168
+ });
169
+ this.cacheMode = cacheMode;
170
+ this.untilVersion = untilVersion;
171
+ }
172
+ /**
173
+ * @private
174
+ */
175
+ async routeToSubscribers(topic, message) {
176
+ const jobCallback = this.jobCallbacks[message.metadata.jid];
177
+ if (jobCallback) {
178
+ this.delistJobCallback(message.metadata.jid);
179
+ jobCallback(topic, message);
180
+ }
181
+ }
182
+ /**
183
+ * @private
184
+ */
185
+ async processWebHooks() {
186
+ this.taskService.processWebHooks(this.hook.bind(this));
187
+ }
188
+ /**
189
+ * @private
190
+ */
191
+ async processTimeHooks() {
192
+ this.taskService.processTimeHooks(this.hookTime.bind(this));
193
+ }
194
+ /**
195
+ * @private
196
+ */
197
+ async throttle(delayInMillis) {
198
+ try {
199
+ this.router?.setThrottle(delayInMillis);
200
+ }
201
+ catch (e) {
202
+ this.logger.error('engine-throttle-error', { error: e });
203
+ }
204
+ }
205
+ // ************* METADATA/MODEL METHODS *************
206
+ /**
207
+ * @private
208
+ */
209
+ async initActivity(topic, data = {}, context) {
210
+ const [activityId, schema] = await this.getSchema(topic);
211
+ const ActivityHandler = activities_1.default[schema.type];
212
+ if (ActivityHandler) {
213
+ const utc = (0, utils_1.formatISODate)(new Date());
214
+ const metadata = {
215
+ aid: activityId,
216
+ atp: schema.type,
217
+ stp: schema.subtype,
218
+ ac: utc,
219
+ au: utc,
220
+ };
221
+ const hook = null;
222
+ return new ActivityHandler(schema, data, metadata, hook, this, context);
223
+ }
224
+ else {
225
+ throw new Error(`activity type ${schema.type} not found`);
226
+ }
227
+ }
228
+ async getSchema(topic) {
229
+ const app = (await this.store.getApp(this.appId));
230
+ if (!app) {
231
+ throw new Error(`no app found for id ${this.appId}`);
232
+ }
233
+ if (this.isPrivate(topic)) {
234
+ //private subscriptions use the schema id (.activityId)
235
+ const activityId = topic.substring(1);
236
+ const schema = await this.store.getSchema(activityId, await this.getVID(app));
237
+ return [activityId, schema];
238
+ }
239
+ else {
240
+ //public subscriptions use a topic (a.b.c) that is associated with a schema id
241
+ const activityId = await this.store.getSubscription(topic, await this.getVID(app));
242
+ if (activityId) {
243
+ const schema = await this.store.getSchema(activityId, await this.getVID(app));
244
+ return [activityId, schema];
245
+ }
246
+ }
247
+ throw new Error(`no subscription found for topic ${topic} in app ${this.appId} for app version ${app.version}`);
248
+ }
249
+ /**
250
+ * @private
251
+ */
252
+ async getSettings() {
253
+ return await this.store.getSettings();
254
+ }
255
+ /**
256
+ * @private
257
+ */
258
+ isPrivate(topic) {
259
+ return topic.startsWith('.');
260
+ }
261
+ // ************* COMPILER METHODS *************
262
+ /**
263
+ * @private
264
+ */
265
+ async plan(pathOrYAML) {
266
+ const compiler = new compiler_1.CompilerService(this.store, this.stream, this.logger);
267
+ return await compiler.plan(pathOrYAML);
268
+ }
269
+ /**
270
+ * @private
271
+ */
272
+ async deploy(pathOrYAML) {
273
+ const compiler = new compiler_1.CompilerService(this.store, this.stream, this.logger);
274
+ return await compiler.deploy(pathOrYAML);
275
+ }
276
+ // ************* REPORTER METHODS *************
277
+ /**
278
+ * @private
279
+ */
280
+ async getStats(topic, query) {
281
+ const { id, version } = await this.getVID();
282
+ const reporter = new reporter_1.ReporterService({ id, version }, this.store, this.logger);
283
+ const resolvedQuery = await this.resolveQuery(topic, query);
284
+ return await reporter.getStats(resolvedQuery);
285
+ }
286
+ /**
287
+ * @private
288
+ */
289
+ async getIds(topic, query, queryFacets = []) {
290
+ const { id, version } = await this.getVID();
291
+ const reporter = new reporter_1.ReporterService({ id, version }, this.store, this.logger);
292
+ const resolvedQuery = await this.resolveQuery(topic, query);
293
+ return await reporter.getIds(resolvedQuery, queryFacets);
294
+ }
295
+ /**
296
+ * @private
297
+ */
298
+ async resolveQuery(topic, query) {
299
+ const trigger = (await this.initActivity(topic, query.data));
300
+ await trigger.getState();
301
+ return {
302
+ end: query.end,
303
+ start: query.start,
304
+ range: query.range,
305
+ granularity: trigger.resolveGranularity(),
306
+ key: trigger.resolveJobKey(trigger.createInputContext()),
307
+ sparse: query.sparse,
308
+ };
309
+ }
310
+ // ****************** STREAM RE-ENTRY POINT *****************
311
+ /**
312
+ * @private
313
+ */
314
+ async processStreamMessage(streamData) {
315
+ this.logger.debug('engine-process', {
316
+ jid: streamData.metadata.jid,
317
+ gid: streamData.metadata.gid,
318
+ dad: streamData.metadata.dad,
319
+ aid: streamData.metadata.aid,
320
+ status: streamData.status || stream_1.StreamStatus.SUCCESS,
321
+ code: streamData.code || 200,
322
+ type: streamData.type,
323
+ });
324
+ const context = {
325
+ metadata: {
326
+ guid: streamData.metadata.guid,
327
+ jid: streamData.metadata.jid,
328
+ gid: streamData.metadata.gid,
329
+ dad: streamData.metadata.dad,
330
+ aid: streamData.metadata.aid,
331
+ },
332
+ data: streamData.data,
333
+ };
334
+ if (streamData.type === stream_1.StreamDataType.TIMEHOOK) {
335
+ //TIMEHOOK AWAKEN
336
+ const activityHandler = (await this.initActivity(`.${streamData.metadata.aid}`, context.data, context));
337
+ await activityHandler.processTimeHookEvent(streamData.metadata.jid);
338
+ }
339
+ else if (streamData.type === stream_1.StreamDataType.WEBHOOK) {
340
+ //WEBHOOK AWAKEN (SIGNAL IN)
341
+ const activityHandler = (await this.initActivity(`.${streamData.metadata.aid}`, context.data, context));
342
+ await activityHandler.processWebHookEvent(streamData.status, streamData.code);
343
+ }
344
+ else if (streamData.type === stream_1.StreamDataType.TRANSITION) {
345
+ //TRANSITION (ADJACENT ACTIVITY)
346
+ const activityHandler = (await this.initActivity(`.${streamData.metadata.aid}`, context.data, context)); //todo: `as Activity` (type is more generic)
347
+ await activityHandler.process();
348
+ }
349
+ else if (streamData.type === stream_1.StreamDataType.AWAIT) {
350
+ //TRIGGER JOB
351
+ context.metadata = {
352
+ ...context.metadata,
353
+ pj: streamData.metadata.jid,
354
+ pg: streamData.metadata.gid,
355
+ pd: streamData.metadata.dad,
356
+ pa: streamData.metadata.aid,
357
+ px: streamData.metadata.await === false,
358
+ trc: streamData.metadata.trc,
359
+ spn: streamData.metadata.spn,
360
+ };
361
+ const activityHandler = (await this.initActivity(streamData.metadata.topic, streamData.data, context));
362
+ await activityHandler.process();
363
+ }
364
+ else if (streamData.type === stream_1.StreamDataType.RESULT) {
365
+ //AWAIT RESULT
366
+ const activityHandler = (await this.initActivity(`.${context.metadata.aid}`, streamData.data, context));
367
+ await activityHandler.processEvent(streamData.status, streamData.code);
368
+ }
369
+ else {
370
+ //WORKER RESULT
371
+ const activityHandler = (await this.initActivity(`.${streamData.metadata.aid}`, streamData.data, context));
372
+ await activityHandler.processEvent(streamData.status, streamData.code, 'output');
373
+ }
374
+ this.logger.debug('engine-process-end', {
375
+ jid: streamData.metadata.jid,
376
+ gid: streamData.metadata.gid,
377
+ aid: streamData.metadata.aid,
378
+ });
379
+ }
380
+ // ***************** `AWAIT` ACTIVITY RETURN RESPONSE ****************
381
+ /**
382
+ * @private
383
+ */
384
+ async execAdjacentParent(context, jobOutput, emit = false) {
385
+ if (this.hasParentJob(context)) {
386
+ //errors are stringified `StreamError` objects
387
+ const error = this.resolveError(jobOutput.metadata);
388
+ const spn = context['$self']?.output?.metadata?.l2s ||
389
+ context['$self']?.output?.metadata?.l1s;
390
+ const streamData = {
391
+ metadata: {
392
+ guid: (0, utils_1.guid)(),
393
+ jid: context.metadata.pj,
394
+ gid: context.metadata.pg,
395
+ dad: context.metadata.pd,
396
+ aid: context.metadata.pa,
397
+ trc: context.metadata.trc,
398
+ spn,
399
+ },
400
+ type: stream_1.StreamDataType.RESULT,
401
+ data: jobOutput.data,
402
+ };
403
+ if (error && error.code) {
404
+ streamData.status = stream_1.StreamStatus.ERROR;
405
+ streamData.data = error;
406
+ streamData.code = error.code;
407
+ streamData.stack = error.stack;
408
+ }
409
+ else if (emit) {
410
+ streamData.status = stream_1.StreamStatus.PENDING;
411
+ streamData.code = enums_1.HMSH_CODE_PENDING;
412
+ }
413
+ else {
414
+ streamData.status = stream_1.StreamStatus.SUCCESS;
415
+ streamData.code = enums_1.HMSH_CODE_SUCCESS;
416
+ }
417
+ return (await this.router?.publishMessage(null, streamData));
418
+ }
419
+ }
420
+ /**
421
+ * @private
422
+ */
423
+ hasParentJob(context, checkSevered = false) {
424
+ if (checkSevered) {
425
+ return Boolean(context.metadata.pj && context.metadata.pa && !context.metadata.px);
426
+ }
427
+ return Boolean(context.metadata.pj && context.metadata.pa);
428
+ }
429
+ /**
430
+ * @private
431
+ */
432
+ resolveError(metadata) {
433
+ if (metadata && metadata.err) {
434
+ return JSON.parse(metadata.err);
435
+ }
436
+ }
437
+ // ****************** `INTERRUPT` ACTIVE JOBS *****************
438
+ /**
439
+ * @private
440
+ */
441
+ async interrupt(topic, jobId, options = {}) {
442
+ //immediately interrupt the job, going directly to the data source
443
+ await this.store.interrupt(topic, jobId, options);
444
+ //now that the job is interrupted, we can clean up
445
+ const context = (await this.getState(topic, jobId));
446
+ const completionOpts = {
447
+ interrupt: options.descend,
448
+ expire: options.expire,
449
+ };
450
+ return (await this.runJobCompletionTasks(context, completionOpts));
451
+ }
452
+ // ****************** `SCRUB` CLEAN COMPLETED JOBS *****************
453
+ /**
454
+ * @private
455
+ */
456
+ async scrub(jobId) {
457
+ //todo: do not allow scrubbing of non-existent or actively running job
458
+ await this.store.scrub(jobId);
459
+ }
460
+ // ****************** `HOOK` ACTIVITY RE-ENTRY POINT *****************
461
+ /**
462
+ * @private
463
+ */
464
+ async hook(topic, data, status = stream_1.StreamStatus.SUCCESS, code = 200) {
465
+ const hookRule = await this.taskService.getHookRule(topic);
466
+ const [aid] = await this.getSchema(`.${hookRule.to}`);
467
+ const streamData = {
468
+ type: stream_1.StreamDataType.WEBHOOK,
469
+ status,
470
+ code,
471
+ metadata: {
472
+ guid: (0, utils_1.guid)(),
473
+ aid,
474
+ topic,
475
+ },
476
+ data,
477
+ };
478
+ return (await this.router?.publishMessage(null, streamData));
479
+ }
480
+ /**
481
+ * @private
482
+ */
483
+ async hookTime(jobId, gId, topicOrActivity, type) {
484
+ if (type === 'interrupt' || type === 'expire') {
485
+ return await this.interrupt(topicOrActivity, jobId, {
486
+ suppress: true,
487
+ expire: 1,
488
+ });
489
+ }
490
+ const [aid, ...dimensions] = topicOrActivity.split(',');
491
+ const dad = `,${dimensions.join(',')}`;
492
+ const streamData = {
493
+ type: stream_1.StreamDataType.TIMEHOOK,
494
+ metadata: {
495
+ guid: (0, utils_1.guid)(),
496
+ jid: jobId,
497
+ gid: gId,
498
+ dad,
499
+ aid,
500
+ },
501
+ data: { timestamp: Date.now() },
502
+ };
503
+ await this.router?.publishMessage(null, streamData);
504
+ }
505
+ /**
506
+ * @private
507
+ */
508
+ async hookAll(hookTopic, data, keyResolver, queryFacets = []) {
509
+ const config = await this.getVID();
510
+ const hookRule = await this.taskService.getHookRule(hookTopic);
511
+ if (hookRule) {
512
+ const subscriptionTopic = await (0, utils_1.getSubscriptionTopic)(hookRule.to, this.store, config);
513
+ const resolvedQuery = await this.resolveQuery(subscriptionTopic, keyResolver);
514
+ const reporter = new reporter_1.ReporterService(config, this.store, this.logger);
515
+ const workItems = await reporter.getWorkItems(resolvedQuery, queryFacets);
516
+ if (workItems.length) {
517
+ const taskService = new task_1.TaskService(this.store, this.logger);
518
+ await taskService.enqueueWorkItems(workItems.map((workItem) => [
519
+ hookTopic,
520
+ workItem,
521
+ keyResolver.scrub || false,
522
+ JSON.stringify(data),
523
+ ].join(key_1.VALSEP)));
524
+ this.subscribe.publish(key_1.KeyType.QUORUM, { type: 'work', originator: this.guid }, this.appId);
525
+ }
526
+ return workItems;
527
+ }
528
+ else {
529
+ throw new Error(`unable to find hook rule for topic ${hookTopic}`);
530
+ }
531
+ }
532
+ // ********************** PUB/SUB ENTRY POINT **********************
533
+ /**
534
+ * @private
535
+ */
536
+ async pub(topic, data, context, extended) {
537
+ const activityHandler = await this.initActivity(topic, data, context);
538
+ if (activityHandler) {
539
+ return await activityHandler.process(extended);
540
+ }
541
+ else {
542
+ throw new Error(`unable to process activity for topic ${topic}`);
543
+ }
544
+ }
545
+ /**
546
+ * @private
547
+ */
548
+ async sub(topic, callback) {
549
+ const subscriptionCallback = async (topic, message) => {
550
+ callback(message.topic, message.job);
551
+ };
552
+ return await this.subscribe.subscribe(key_1.KeyType.QUORUM, subscriptionCallback, this.appId, topic);
553
+ }
554
+ /**
555
+ * @private
556
+ */
557
+ async unsub(topic) {
558
+ return await this.subscribe.unsubscribe(key_1.KeyType.QUORUM, this.appId, topic);
559
+ }
560
+ /**
561
+ * @private
562
+ */
563
+ async psub(wild, callback) {
564
+ const subscriptionCallback = async (topic, message) => {
565
+ callback(message.topic, message.job);
566
+ };
567
+ return await this.subscribe.psubscribe(key_1.KeyType.QUORUM, subscriptionCallback, this.appId, wild);
568
+ }
569
+ /**
570
+ * @private
571
+ */
572
+ async punsub(wild) {
573
+ return await this.subscribe.punsubscribe(key_1.KeyType.QUORUM, this.appId, wild);
574
+ }
575
+ /**
576
+ * @private
577
+ */
578
+ async pubsub(topic, data, context, timeout = enums_1.HMSH_OTT_WAIT_TIME) {
579
+ context = {
580
+ metadata: {
581
+ ngn: this.guid,
582
+ trc: context?.metadata?.trc,
583
+ spn: context?.metadata?.spn,
584
+ },
585
+ };
586
+ const jobId = await this.pub(topic, data, context);
587
+ return new Promise((resolve, reject) => {
588
+ this.registerJobCallback(jobId, (topic, output) => {
589
+ if (output.metadata.err) {
590
+ const error = JSON.parse(output.metadata.err);
591
+ reject({
592
+ error,
593
+ job_id: output.metadata.jid,
594
+ });
595
+ }
596
+ else {
597
+ resolve(output);
598
+ }
599
+ });
600
+ setTimeout(() => {
601
+ //note: job is still active (the subscriber timed out)
602
+ this.delistJobCallback(jobId);
603
+ reject({
604
+ code: enums_1.HMSH_CODE_TIMEOUT,
605
+ message: 'timeout',
606
+ job_id: jobId,
607
+ });
608
+ }, timeout);
609
+ });
610
+ }
611
+ /**
612
+ * @private
613
+ */
614
+ async pubOneTimeSubs(context, jobOutput, emit = false) {
615
+ //todo: subscriber should query for the job...only publish minimum context needed
616
+ if (this.hasOneTimeSubscription(context)) {
617
+ const message = {
618
+ type: 'job',
619
+ topic: context.metadata.jid,
620
+ job: (0, utils_1.restoreHierarchy)(jobOutput),
621
+ };
622
+ this.subscribe.publish(key_1.KeyType.QUORUM, message, this.appId, context.metadata.ngn);
623
+ }
624
+ }
625
+ /**
626
+ * @private
627
+ */
628
+ async getPublishesTopic(context) {
629
+ const config = await this.getVID();
630
+ const activityId = context.metadata.aid || context['$self']?.output?.metadata?.aid;
631
+ const schema = await this.store.getSchema(activityId, config);
632
+ return schema.publishes;
633
+ }
634
+ /**
635
+ * @private
636
+ */
637
+ async pubPermSubs(context, jobOutput, emit = false) {
638
+ const topic = await this.getPublishesTopic(context);
639
+ if (topic) {
640
+ const message = {
641
+ type: 'job',
642
+ topic,
643
+ job: (0, utils_1.restoreHierarchy)(jobOutput),
644
+ };
645
+ this.subscribe.publish(key_1.KeyType.QUORUM, message, this.appId, `${topic}.${context.metadata.jid}`);
646
+ }
647
+ }
648
+ /**
649
+ * @private
650
+ */
651
+ async add(streamData) {
652
+ return (await this.router?.publishMessage(null, streamData));
653
+ }
654
+ /**
655
+ * @private
656
+ */
657
+ registerJobCallback(jobId, jobCallback) {
658
+ this.jobCallbacks[jobId] = jobCallback;
659
+ }
660
+ /**
661
+ * @private
662
+ */
663
+ delistJobCallback(jobId) {
664
+ delete this.jobCallbacks[jobId];
665
+ }
666
+ /**
667
+ * @private
668
+ */
669
+ hasOneTimeSubscription(context) {
670
+ return Boolean(context.metadata.ngn);
671
+ }
672
+ // ********** JOB COMPLETION/CLEANUP (AND JOB EMIT) ***********
673
+ /**
674
+ * @private
675
+ */
676
+ async runJobCompletionTasks(context, options = {}) {
677
+ //'emit' indicates the job is still active
678
+ const isAwait = this.hasParentJob(context, true);
679
+ const isOneTimeSub = this.hasOneTimeSubscription(context);
680
+ const topic = await this.getPublishesTopic(context);
681
+ let msgId;
682
+ if (isAwait || isOneTimeSub || topic) {
683
+ const jobOutput = await this.getState(context.metadata.tpc, context.metadata.jid);
684
+ msgId = await this.execAdjacentParent(context, jobOutput, options.emit);
685
+ this.pubOneTimeSubs(context, jobOutput, options.emit);
686
+ this.pubPermSubs(context, jobOutput, options.emit);
687
+ }
688
+ if (!options.emit) {
689
+ this.taskService.registerJobForCleanup(context.metadata.jid, this.resolveExpires(context, options), options);
690
+ }
691
+ return msgId;
692
+ }
693
+ /**
694
+ * Job hash expiration is typically reliant on the metadata field
695
+ * if the activity concludes normally. However, if the job is `interrupted`,
696
+ * it will be expired immediately.
697
+ * @private
698
+ */
699
+ resolveExpires(context, options) {
700
+ return options.expire ?? context.metadata.expire ?? enums_1.HMSH_EXPIRE_JOB_SECONDS;
701
+ }
702
+ // ****** GET JOB STATE/COLLATION STATUS BY ID *********
703
+ /**
704
+ * @private
705
+ */
706
+ async export(jobId) {
707
+ return await this.exporter.export(jobId);
708
+ }
709
+ /**
710
+ * @private
711
+ */
712
+ async getRaw(jobId) {
713
+ return await this.store.getRaw(jobId);
714
+ }
715
+ /**
716
+ * @private
717
+ */
718
+ async getStatus(jobId) {
719
+ const { id: appId } = await this.getVID();
720
+ return await this.store.getStatus(jobId, appId);
721
+ }
722
+ /**
723
+ * @private
724
+ */
725
+ async getState(topic, jobId) {
726
+ const jobSymbols = await this.store.getSymbols(`$${topic}`);
727
+ const consumes = {
728
+ [`$${topic}`]: Object.keys(jobSymbols),
729
+ };
730
+ //job data exists at the 'zero' dimension; pass an empty object
731
+ const dIds = {};
732
+ const output = await this.store.getState(jobId, consumes, dIds);
733
+ if (!output) {
734
+ throw new Error(`not found ${jobId}`);
735
+ }
736
+ const [state, status] = output;
737
+ const stateTree = (0, utils_1.restoreHierarchy)(state);
738
+ if (status && stateTree.metadata) {
739
+ stateTree.metadata.js = status;
740
+ }
741
+ return stateTree;
742
+ }
743
+ /**
744
+ * @private
745
+ */
746
+ async getQueryState(jobId, fields) {
747
+ return await this.store.getQueryState(jobId, fields);
748
+ }
749
+ /**
750
+ * @private
751
+ * @deprecated
752
+ */
753
+ async compress(terms) {
754
+ const existingSymbols = await this.store.getSymbolValues();
755
+ const startIndex = Object.keys(existingSymbols).length;
756
+ const maxIndex = Math.pow(52, 2) - 1;
757
+ const newSymbols = serializer_1.SerializerService.filterSymVals(startIndex, maxIndex, existingSymbols, new Set(terms));
758
+ return await this.store.addSymbolValues(newSymbols);
759
+ }
760
+ }
761
+ exports.EngineService = EngineService;