@hotmeshio/hotmesh 0.0.51 → 0.0.53

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 (126) hide show
  1. package/README.md +13 -9
  2. package/build/index.d.ts +1 -2
  3. package/build/index.js +1 -3
  4. package/build/modules/enums.d.ts +8 -3
  5. package/build/modules/enums.js +16 -8
  6. package/build/modules/errors.d.ts +98 -18
  7. package/build/modules/errors.js +90 -33
  8. package/build/package.json +7 -2
  9. package/build/services/activities/activity.d.ts +8 -0
  10. package/build/services/activities/activity.js +65 -16
  11. package/build/services/activities/await.js +6 -6
  12. package/build/services/activities/cycle.d.ts +2 -2
  13. package/build/services/activities/cycle.js +5 -5
  14. package/build/services/activities/hook.js +4 -4
  15. package/build/services/activities/interrupt.d.ts +3 -3
  16. package/build/services/activities/interrupt.js +15 -6
  17. package/build/services/activities/signal.d.ts +2 -2
  18. package/build/services/activities/signal.js +4 -4
  19. package/build/services/activities/trigger.js +12 -3
  20. package/build/services/activities/worker.js +6 -6
  21. package/build/services/compiler/deployer.js +33 -5
  22. package/build/services/compiler/validator.d.ts +2 -0
  23. package/build/services/compiler/validator.js +5 -1
  24. package/build/services/durable/client.d.ts +7 -1
  25. package/build/services/durable/client.js +56 -30
  26. package/build/services/durable/exporter.d.ts +7 -72
  27. package/build/services/durable/exporter.js +105 -295
  28. package/build/services/durable/handle.d.ts +11 -6
  29. package/build/services/durable/handle.js +59 -46
  30. package/build/services/durable/index.d.ts +0 -2
  31. package/build/services/durable/index.js +0 -2
  32. package/build/services/durable/schemas/factory.d.ts +33 -0
  33. package/build/services/durable/schemas/factory.js +2356 -0
  34. package/build/services/durable/search.js +8 -8
  35. package/build/services/durable/worker.js +117 -25
  36. package/build/services/durable/workflow.d.ts +46 -43
  37. package/build/services/durable/workflow.js +273 -277
  38. package/build/services/engine/index.js +3 -0
  39. package/build/services/exporter/index.d.ts +2 -4
  40. package/build/services/exporter/index.js +4 -5
  41. package/build/services/mapper/index.d.ts +6 -2
  42. package/build/services/mapper/index.js +6 -2
  43. package/build/services/pipe/functions/array.d.ts +2 -10
  44. package/build/services/pipe/functions/array.js +30 -28
  45. package/build/services/pipe/functions/conditional.d.ts +1 -0
  46. package/build/services/pipe/functions/conditional.js +3 -0
  47. package/build/services/pipe/functions/date.d.ts +1 -0
  48. package/build/services/pipe/functions/date.js +4 -0
  49. package/build/services/pipe/functions/index.d.ts +2 -0
  50. package/build/services/pipe/functions/index.js +2 -0
  51. package/build/services/pipe/functions/logical.d.ts +5 -0
  52. package/build/services/pipe/functions/logical.js +12 -0
  53. package/build/services/pipe/functions/object.d.ts +3 -0
  54. package/build/services/pipe/functions/object.js +25 -7
  55. package/build/services/pipe/index.d.ts +20 -3
  56. package/build/services/pipe/index.js +82 -16
  57. package/build/services/router/index.js +14 -3
  58. package/build/services/serializer/index.d.ts +3 -2
  59. package/build/services/serializer/index.js +11 -4
  60. package/build/services/store/clients/ioredis.js +6 -6
  61. package/build/services/store/clients/redis.js +7 -7
  62. package/build/services/store/index.d.ts +2 -0
  63. package/build/services/store/index.js +4 -1
  64. package/build/services/stream/clients/ioredis.js +8 -8
  65. package/build/services/stream/clients/redis.js +1 -1
  66. package/build/types/activity.d.ts +60 -5
  67. package/build/types/durable.d.ts +168 -33
  68. package/build/types/exporter.d.ts +26 -4
  69. package/build/types/index.d.ts +2 -2
  70. package/build/types/job.d.ts +69 -5
  71. package/build/types/pipe.d.ts +81 -3
  72. package/build/types/stream.d.ts +61 -1
  73. package/build/types/stream.js +4 -0
  74. package/index.ts +1 -2
  75. package/modules/enums.ts +16 -8
  76. package/modules/errors.ts +174 -32
  77. package/package.json +7 -2
  78. package/services/activities/activity.ts +67 -18
  79. package/services/activities/await.ts +6 -6
  80. package/services/activities/cycle.ts +7 -6
  81. package/services/activities/hook.ts +4 -4
  82. package/services/activities/interrupt.ts +19 -9
  83. package/services/activities/signal.ts +6 -5
  84. package/services/activities/trigger.ts +16 -4
  85. package/services/activities/worker.ts +7 -7
  86. package/services/compiler/deployer.ts +33 -6
  87. package/services/compiler/validator.ts +7 -3
  88. package/services/durable/client.ts +47 -14
  89. package/services/durable/exporter.ts +110 -318
  90. package/services/durable/handle.ts +63 -50
  91. package/services/durable/index.ts +0 -2
  92. package/services/durable/schemas/factory.ts +2358 -0
  93. package/services/durable/search.ts +8 -8
  94. package/services/durable/worker.ts +128 -29
  95. package/services/durable/workflow.ts +304 -288
  96. package/services/engine/index.ts +4 -0
  97. package/services/exporter/index.ts +10 -12
  98. package/services/mapper/index.ts +6 -2
  99. package/services/pipe/functions/array.ts +24 -37
  100. package/services/pipe/functions/conditional.ts +4 -0
  101. package/services/pipe/functions/date.ts +6 -0
  102. package/services/pipe/functions/index.ts +7 -5
  103. package/services/pipe/functions/logical.ts +11 -0
  104. package/services/pipe/functions/object.ts +26 -7
  105. package/services/pipe/index.ts +99 -21
  106. package/services/quorum/index.ts +1 -3
  107. package/services/router/index.ts +14 -3
  108. package/services/serializer/index.ts +12 -5
  109. package/services/store/clients/ioredis.ts +6 -6
  110. package/services/store/clients/redis.ts +7 -7
  111. package/services/store/index.ts +4 -1
  112. package/services/stream/clients/ioredis.ts +8 -8
  113. package/services/stream/clients/redis.ts +1 -1
  114. package/types/activity.ts +87 -15
  115. package/types/durable.ts +246 -73
  116. package/types/exporter.ts +31 -5
  117. package/types/index.ts +6 -7
  118. package/types/job.ts +130 -36
  119. package/types/pipe.ts +84 -3
  120. package/types/stream.ts +82 -23
  121. package/build/services/durable/factory.d.ts +0 -17
  122. package/build/services/durable/factory.js +0 -817
  123. package/build/services/durable/meshos.d.ts +0 -127
  124. package/build/services/durable/meshos.js +0 -380
  125. package/services/durable/factory.ts +0 -818
  126. package/services/durable/meshos.ts +0 -441
@@ -1,14 +1,19 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ var _a;
2
6
  Object.defineProperty(exports, "__esModule", { value: true });
3
7
  exports.ClientService = void 0;
4
- const factory_1 = require("./factory");
8
+ const ms_1 = __importDefault(require("ms"));
9
+ const factory_1 = require("./schemas/factory");
10
+ const enums_1 = require("../../modules/enums");
11
+ const utils_1 = require("../../modules/utils");
5
12
  const handle_1 = require("./handle");
6
13
  const hotmesh_1 = require("../hotmesh");
7
14
  const key_1 = require("../../modules/key");
8
15
  const search_1 = require("./search");
9
16
  const types_1 = require("../../types");
10
- const enums_1 = require("../../modules/enums");
11
- const utils_1 = require("../../modules/utils");
12
17
  class ClientService {
13
18
  constructor(config) {
14
19
  this.getHotMeshClient = async (workflowTopic, namespace) => {
@@ -18,7 +23,7 @@ class ClientService {
18
23
  await this.verifyWorkflowActive(hotMeshClient, targetNS);
19
24
  if (!ClientService.topics.includes(workflowTopic)) {
20
25
  ClientService.topics.push(workflowTopic);
21
- await this.createStream(hotMeshClient, workflowTopic, namespace);
26
+ await ClientService.createStream(hotMeshClient, workflowTopic, namespace);
22
27
  }
23
28
  return hotMeshClient;
24
29
  }
@@ -34,27 +39,10 @@ class ClientService {
34
39
  }
35
40
  });
36
41
  ClientService.instances.set(targetNS, hotMeshClient);
37
- await this.createStream(await hotMeshClient, workflowTopic, namespace);
42
+ await ClientService.createStream(await hotMeshClient, workflowTopic, namespace);
38
43
  await this.activateWorkflow(await hotMeshClient, targetNS);
39
44
  return hotMeshClient;
40
45
  };
41
- /**
42
- * Creates a stream (Redis `XGROUP.CREATE`) where events can be published (XADD).
43
- * It is possible that the worker that will read from this stream channel
44
- * has not yet been initialized, so this call ensures that the channel
45
- * exists and is ready to serve as a container for events.
46
- */
47
- this.createStream = async (hotMeshClient, workflowTopic, namespace) => {
48
- const store = hotMeshClient.engine.store;
49
- const params = { appId: namespace ?? factory_1.APP_ID, topic: workflowTopic };
50
- const streamKey = store.mintKey(key_1.KeyType.STREAMS, params);
51
- try {
52
- await store.xgroup('CREATE', streamKey, 'WORKER', '$', 'MKSTREAM');
53
- }
54
- catch (err) {
55
- //ignore if already exists
56
- }
57
- };
58
46
  /**
59
47
  * For those deployments with a redis stack backend (with the FT module),
60
48
  * this method will configure the search index for the workflow.
@@ -80,8 +68,8 @@ class ClientService {
80
68
  const prefixes = search.prefix.map((prefix) => `${hotMeshPrefix}${prefix}`);
81
69
  await store.exec('FT.CREATE', `${search.index}`, 'ON', 'HASH', 'PREFIX', prefixes.length, ...prefixes, 'SCHEMA', ...schema);
82
70
  }
83
- catch (err) {
84
- hotMeshClient.engine.logger.info('durable-client-search-err', { err });
71
+ catch (error) {
72
+ hotMeshClient.engine.logger.info('durable-client-search-err', { ...error });
85
73
  }
86
74
  }
87
75
  };
@@ -110,7 +98,9 @@ class ClientService {
110
98
  parentWorkflowId: options.parentWorkflowId,
111
99
  workflowId: options.workflowId || hotmesh_1.HotMeshService.guid(),
112
100
  workflowTopic: workflowTopic,
113
- backoffCoefficient: options.config?.backoffCoefficient || factory_1.DEFAULT_COEFFICIENT,
101
+ backoffCoefficient: options.config?.backoffCoefficient || enums_1.HMSH_DURABLE_EXP_BACKOFF,
102
+ maximumAttempts: options.config?.maximumAttempts || enums_1.HMSH_DURABLE_MAX_ATTEMPTS,
103
+ maximumInterval: (0, ms_1.default)(options.config?.maximumInterval || enums_1.HMSH_DURABLE_MAX_INTERVAL) / 1000,
114
104
  };
115
105
  const context = { metadata: { trc, spn }, data: {} };
116
106
  const jobId = await hotMeshClient.pub(`${options.namespace ?? factory_1.APP_ID}.execute`, payload, context);
@@ -142,7 +132,9 @@ class ClientService {
142
132
  arguments: [...options.args],
143
133
  id: options.workflowId,
144
134
  workflowTopic,
145
- backoffCoefficient: options.config?.backoffCoefficient || factory_1.DEFAULT_COEFFICIENT,
135
+ backoffCoefficient: options.config?.backoffCoefficient || enums_1.HMSH_DURABLE_EXP_BACKOFF,
136
+ maximumAttempts: options.config?.maximumAttempts || enums_1.HMSH_DURABLE_MAX_ATTEMPTS,
137
+ maximumInterval: (0, ms_1.default)(options.config?.maximumInterval || enums_1.HMSH_DURABLE_MAX_INTERVAL) / 1000,
146
138
  };
147
139
  //seed search data if presentthe hook before entering
148
140
  const hotMeshClient = await this.getHotMeshClient(workflowTopic, options.namespace);
@@ -166,9 +158,9 @@ class ClientService {
166
158
  try {
167
159
  return await this.search(hotMeshClient, index, query);
168
160
  }
169
- catch (err) {
170
- hotMeshClient.engine.logger.error('durable-client-search-err', { err });
171
- throw err;
161
+ catch (error) {
162
+ hotMeshClient.engine.logger.error('durable-client-search-err', { ...error });
163
+ throw error;
172
164
  }
173
165
  }
174
166
  };
@@ -195,7 +187,7 @@ class ClientService {
195
187
  await hotMesh.activate(version);
196
188
  }
197
189
  catch (error) {
198
- hotMesh.engine.logger.error('durable-client-deploy-activate-err', { error });
190
+ hotMesh.engine.logger.error('durable-client-deploy-activate-err', { ...error });
199
191
  throw error;
200
192
  }
201
193
  }
@@ -215,6 +207,40 @@ class ClientService {
215
207
  }
216
208
  }
217
209
  }
210
+ _a = ClientService;
218
211
  ClientService.topics = [];
219
212
  ClientService.instances = new Map();
213
+ /**
214
+ * Creates a stream (Redis `XGROUP.CREATE`) where events can be published (XADD).
215
+ * It is possible that the worker that will read from this stream channel
216
+ * has not yet been initialized, so this call ensures that the channel
217
+ * exists and is ready to serve as a container for events.
218
+ */
219
+ ClientService.createStream = async (hotMeshClient, workflowTopic, namespace) => {
220
+ const store = hotMeshClient.engine.store;
221
+ const params = { appId: namespace ?? factory_1.APP_ID, topic: workflowTopic };
222
+ const streamKey = store.mintKey(key_1.KeyType.STREAMS, params);
223
+ try {
224
+ await store.xgroup('CREATE', streamKey, 'WORKER', '$', 'MKSTREAM');
225
+ }
226
+ catch (err) {
227
+ //ignore if already exists
228
+ }
229
+ };
230
+ /**
231
+ * It is possible for a client to invoke a workflow without first
232
+ * creating the stream. This method will verify that the stream
233
+ * exists and if not, create it.
234
+ */
235
+ ClientService.verifyStream = async (workflowTopic, namespace) => {
236
+ const targetNS = namespace ?? factory_1.APP_ID;
237
+ if (ClientService.instances.has(targetNS)) {
238
+ const hotMeshClient = await ClientService.instances.get(targetNS);
239
+ if (!ClientService.topics.includes(workflowTopic)) {
240
+ ClientService.topics.push(workflowTopic);
241
+ await ClientService.createStream(hotMeshClient, workflowTopic, namespace);
242
+ }
243
+ return hotMeshClient;
244
+ }
245
+ };
220
246
  exports.ClientService = ClientService;
@@ -1,70 +1,19 @@
1
1
  import { ILogger } from '../logger';
2
2
  import { StoreService } from '../store';
3
- import { StringStringType, Symbols } from "../../types";
3
+ import { ExportOptions, DurableJobExport } from '../../types/exporter';
4
4
  import { RedisClient, RedisMulti } from '../../types/redis';
5
- import { ActivityAction, DependencyExport, ExportItem, ExportOptions, JobAction, JobActionExport, DurableJobExport, JobTimeline } from '../../types/exporter';
6
- import { SerializerService } from '../serializer';
7
- /**
8
- * Downloads job data from Redis (hscan, hmget, hgetall)
9
- * Splits, Inflates, and Sorts the job data for use in durable contexts
10
- */
5
+ import { StringStringType, Symbols } from "../../types/serializer";
11
6
  declare class ExporterService {
12
7
  appId: string;
13
8
  logger: ILogger;
14
- serializer: SerializerService;
15
9
  store: StoreService<RedisClient, RedisMulti>;
16
10
  symbols: Promise<Symbols> | Symbols;
17
- /**
18
- * Friendly names for the activity ids
19
- */
20
- activitySymbols: Symbols;
21
- transitions: {
22
- trigger: string[];
23
- pivot: string[];
24
- worker: string[];
25
- sleeper: string[];
26
- awaiter: string[];
27
- retryer: string[];
28
- hook: string[];
29
- hook_pivot: string[];
30
- hook_worker: string[];
31
- hook_sleeper: string[];
32
- hook_awaiter: string[];
33
- hook_retryer: string[];
34
- };
35
- cycles: {
36
- sleep_cycler: string[];
37
- await_cycler: string[];
38
- retry_cycler: string[];
39
- hook_sleep_cycler: string[];
40
- hook_await_cycler: string[];
41
- hook_retry_cycler: string[];
42
- };
43
11
  constructor(appId: string, store: StoreService<RedisClient, RedisMulti>, logger: ILogger);
44
12
  /**
45
- * Convert the job hash and dependency list into a DurableJobExport object.
46
- * This object contains various facets that describe the interaction
47
- * in terms relevant to narrative storytelling.
13
+ * Convert the job hash from its compiles format into a DurableJobExport object with
14
+ * facets that describe the workflow in terms relevant to narrative storytelling.
48
15
  */
49
16
  export(jobId: string, options?: ExportOptions): Promise<DurableJobExport>;
50
- /**
51
- * Interleave actions into the replay timeline to create
52
- * a time-ordered timeline of the entire interaction, beginning
53
- * with the entry trigger and concluding with the scrubber
54
- * activity. Using the returned timeline, it is possible to
55
- * create an animated narrative of the job, highlighting
56
- * activities in the graph according to the timeline's
57
- * activity-created (/ac) and activity-updated (/au) entries.
58
- */
59
- createTimeline(replay: ExportItem[], actions: JobActionExport): JobTimeline[];
60
- /**
61
- * Interleave actions into the 'worker' and 'hook_worker'
62
- * activities (between their /ac and /au entries)
63
- */
64
- interleaveActions(target: JobAction, actions: ActivityAction[]): void;
65
- isPausingAction(actionType: string): boolean;
66
- isMainEntry(key: string): boolean;
67
- isHookEntry(key: string): boolean;
68
17
  /**
69
18
  * Inflates the key from Redis, 3-character symbol
70
19
  * into a human-readable JSON path, reflecting the
@@ -78,28 +27,14 @@ declare class ExporterService {
78
27
  * @param data - the dependency data from Redis
79
28
  * @returns - the organized dependency data
80
29
  */
81
- inflateDependencyData(data: string[], actions: JobActionExport): DependencyExport[];
82
- /**
83
- * Adds historical actions (proxyActivity, executeChild)
84
- * using the `dependency list` to determine
85
- * after-the-fact what happened within the 'black-box'
86
- * worker function. This is necessary to interleave the
87
- * actions into the replay timeline, given that it isn't
88
- * really possible to know the inner-workings of the user's
89
- * function
90
- *
91
- */
92
- seedActions(type: 'flow' | 'hook' | 'other', action: string, topic: string, dep: string, prefix: string, dimensionKey: string, actions: JobActionExport, jobId: string): void;
30
+ inflateDependencyData(data: string[]): Record<string, any>[];
93
31
  /**
94
32
  * Inflates the job data from Redis into a DurableJobExport object
95
33
  * @param jobHash - the job data from Redis
96
34
  * @param dependencyList - the list of dependencies for the job
97
35
  * @returns - the inflated job data
98
36
  */
99
- inflate(jobHash: StringStringType, dependencyList: string[]): DurableJobExport;
100
- inflateProcess(match: RegExpMatchArray, value: string, replay: ExportItem[]): void;
101
- inflateActions(key: string, value: string, actions: JobActionExport): void;
102
- reverseSort(aKey: ExportItem, bKey: ExportItem): 1 | -1 | 0;
103
- dateSort(aKey: ExportItem, bKey: ExportItem): 1 | -1 | 0;
37
+ inflate(jobHash: StringStringType): DurableJobExport;
38
+ inflateProcess(match: RegExpMatchArray, value: string, replay: Record<string, Record<string, any>>): void;
104
39
  }
105
40
  export { ExporterService };