@hotmeshio/hotmesh 0.0.52 → 0.0.54

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 (134) hide show
  1. package/README.md +22 -18
  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 +58 -20
  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 +63 -14
  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 +9 -5
  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.d.ts +5 -2
  20. package/build/services/activities/trigger.js +34 -4
  21. package/build/services/activities/worker.js +6 -6
  22. package/build/services/compiler/deployer.js +33 -5
  23. package/build/services/compiler/validator.d.ts +2 -0
  24. package/build/services/compiler/validator.js +5 -1
  25. package/build/services/durable/client.d.ts +7 -1
  26. package/build/services/durable/client.js +57 -38
  27. package/build/services/durable/exporter.d.ts +27 -81
  28. package/build/services/durable/exporter.js +153 -325
  29. package/build/services/durable/handle.d.ts +13 -8
  30. package/build/services/durable/handle.js +61 -48
  31. package/build/services/durable/index.d.ts +0 -2
  32. package/build/services/durable/index.js +0 -2
  33. package/build/services/durable/schemas/factory.d.ts +33 -0
  34. package/build/services/durable/schemas/factory.js +2356 -0
  35. package/build/services/durable/search.js +8 -8
  36. package/build/services/durable/worker.js +117 -25
  37. package/build/services/durable/workflow.d.ts +67 -52
  38. package/build/services/durable/workflow.js +322 -306
  39. package/build/services/engine/index.d.ts +2 -2
  40. package/build/services/engine/index.js +5 -2
  41. package/build/services/exporter/index.d.ts +2 -4
  42. package/build/services/exporter/index.js +4 -5
  43. package/build/services/hotmesh/index.d.ts +2 -2
  44. package/build/services/hotmesh/index.js +2 -2
  45. package/build/services/mapper/index.d.ts +6 -2
  46. package/build/services/mapper/index.js +6 -2
  47. package/build/services/pipe/functions/array.d.ts +2 -10
  48. package/build/services/pipe/functions/array.js +30 -28
  49. package/build/services/pipe/functions/conditional.d.ts +1 -0
  50. package/build/services/pipe/functions/conditional.js +3 -0
  51. package/build/services/pipe/functions/date.d.ts +1 -0
  52. package/build/services/pipe/functions/date.js +4 -0
  53. package/build/services/pipe/functions/index.d.ts +2 -0
  54. package/build/services/pipe/functions/index.js +2 -0
  55. package/build/services/pipe/functions/logical.d.ts +5 -0
  56. package/build/services/pipe/functions/logical.js +12 -0
  57. package/build/services/pipe/functions/object.d.ts +3 -0
  58. package/build/services/pipe/functions/object.js +25 -7
  59. package/build/services/pipe/index.d.ts +20 -3
  60. package/build/services/pipe/index.js +82 -16
  61. package/build/services/router/index.js +14 -3
  62. package/build/services/serializer/index.d.ts +3 -2
  63. package/build/services/serializer/index.js +11 -4
  64. package/build/services/store/clients/ioredis.js +6 -6
  65. package/build/services/store/clients/redis.js +7 -7
  66. package/build/services/store/index.d.ts +2 -0
  67. package/build/services/store/index.js +4 -1
  68. package/build/services/stream/clients/ioredis.js +8 -8
  69. package/build/services/stream/clients/redis.js +1 -1
  70. package/build/types/activity.d.ts +60 -5
  71. package/build/types/durable.d.ts +183 -36
  72. package/build/types/error.d.ts +48 -0
  73. package/build/types/error.js +2 -0
  74. package/build/types/exporter.d.ts +35 -7
  75. package/build/types/index.d.ts +4 -3
  76. package/build/types/job.d.ts +93 -6
  77. package/build/types/pipe.d.ts +81 -3
  78. package/build/types/stream.d.ts +61 -1
  79. package/build/types/stream.js +4 -0
  80. package/index.ts +1 -2
  81. package/modules/enums.ts +16 -8
  82. package/modules/errors.ts +139 -34
  83. package/package.json +7 -2
  84. package/services/activities/activity.ts +63 -14
  85. package/services/activities/await.ts +6 -6
  86. package/services/activities/cycle.ts +7 -6
  87. package/services/activities/hook.ts +12 -5
  88. package/services/activities/interrupt.ts +19 -9
  89. package/services/activities/signal.ts +6 -5
  90. package/services/activities/trigger.ts +43 -6
  91. package/services/activities/worker.ts +7 -7
  92. package/services/compiler/deployer.ts +33 -6
  93. package/services/compiler/validator.ts +7 -3
  94. package/services/durable/client.ts +49 -22
  95. package/services/durable/exporter.ts +162 -349
  96. package/services/durable/handle.ts +66 -53
  97. package/services/durable/index.ts +0 -2
  98. package/services/durable/schemas/factory.ts +2358 -0
  99. package/services/durable/search.ts +8 -8
  100. package/services/durable/worker.ts +128 -29
  101. package/services/durable/workflow.ts +371 -322
  102. package/services/engine/index.ts +8 -3
  103. package/services/exporter/index.ts +10 -12
  104. package/services/hotmesh/index.ts +4 -3
  105. package/services/mapper/index.ts +6 -2
  106. package/services/pipe/functions/array.ts +24 -37
  107. package/services/pipe/functions/conditional.ts +4 -0
  108. package/services/pipe/functions/date.ts +6 -0
  109. package/services/pipe/functions/index.ts +7 -5
  110. package/services/pipe/functions/logical.ts +11 -0
  111. package/services/pipe/functions/object.ts +26 -7
  112. package/services/pipe/index.ts +99 -21
  113. package/services/quorum/index.ts +1 -3
  114. package/services/router/index.ts +14 -3
  115. package/services/serializer/index.ts +12 -5
  116. package/services/store/clients/ioredis.ts +6 -6
  117. package/services/store/clients/redis.ts +7 -7
  118. package/services/store/index.ts +4 -1
  119. package/services/stream/clients/ioredis.ts +8 -8
  120. package/services/stream/clients/redis.ts +1 -1
  121. package/types/activity.ts +87 -15
  122. package/types/durable.ts +263 -75
  123. package/types/error.ts +52 -0
  124. package/types/exporter.ts +43 -9
  125. package/types/index.ts +14 -8
  126. package/types/job.ts +157 -36
  127. package/types/pipe.ts +84 -3
  128. package/types/stream.ts +82 -23
  129. package/build/services/durable/factory.d.ts +0 -17
  130. package/build/services/durable/factory.js +0 -817
  131. package/build/services/durable/meshos.d.ts +0 -127
  132. package/build/services/durable/meshos.js +0 -380
  133. package/services/durable/factory.ts +0 -818
  134. package/services/durable/meshos.ts +0 -441
@@ -1,388 +1,216 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ExporterService = void 0;
4
- const serializer_1 = require("../serializer");
5
4
  const utils_1 = require("../../modules/utils");
6
- const key_1 = require("../../modules/key");
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
+ const serializer_1 = require("../serializer");
11
6
  class ExporterService {
12
7
  constructor(appId, store, logger) {
13
- /**
14
- * Friendly names for the activity ids
15
- */
16
- this.activitySymbols = {
17
- t1: 'trigger',
18
- a1: 'pivot',
19
- w1: 'worker',
20
- a592: 'sleeper',
21
- a594: 'awaiter',
22
- a599: 'retryer',
23
- c592: 'sleep_cycler',
24
- c594: 'await_cycler',
25
- c599: 'retry_cycler',
26
- s5: 'scrubber',
27
- sig: 'hook',
28
- siga1: 'hook_pivot',
29
- sigw1: 'hook_worker',
30
- siga592: 'hook_sleeper',
31
- siga594: 'hook_awaiter',
32
- siga599: 'hook_retryer',
33
- sigc592: 'hook_sleep_cycler',
34
- sigc594: 'hook_await_cycler',
35
- sigc599: 'hook_retry_cycler',
36
- };
37
- //adjacent transitions
38
- this.transitions = {
39
- trigger: ['pivot', 'hook'],
40
- pivot: ['worker'],
41
- worker: ['sleeper', 'awaiter', 'retryer', 'scrubber'],
42
- sleeper: ['sleep_cycler'],
43
- awaiter: ['await_cycler'],
44
- retryer: ['retry_cycler'],
45
- hook: ['hook_pivot'],
46
- hook_pivot: ['hook_worker'],
47
- hook_worker: ['hook_sleeper', 'hook_awaiter', 'hook_retryer'],
48
- hook_sleeper: ['hook_sleep_cycler'],
49
- hook_awaiter: ['hook_await_cycler'],
50
- hook_retryer: ['hook_retry_cycler'],
51
- };
52
- //goto transitions
53
- this.cycles = {
54
- sleep_cycler: ['pivot'],
55
- await_cycler: ['pivot'],
56
- retry_cycler: ['pivot'],
57
- hook_sleep_cycler: ['hook_pivot'],
58
- hook_await_cycler: ['hook_pivot'],
59
- hook_retry_cycler: ['hook_pivot'],
60
- };
61
8
  this.appId = appId;
62
9
  this.logger = logger;
63
10
  this.store = store;
64
- this.serializer = new serializer_1.SerializerService();
65
11
  }
66
12
  /**
67
- * Convert the job hash and dependency list into a DurableJobExport object.
68
- * This object contains various facets that describe the interaction
69
- * 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.
70
15
  */
71
16
  async export(jobId, options = {}) {
72
- if (!this.symbols) {
73
- this.symbols = this.store.getAllSymbols();
74
- this.symbols = await this.symbols;
17
+ if (!ExporterService.symbols.has(this.appId)) {
18
+ const symbols = this.store.getAllSymbols();
19
+ ExporterService.symbols.set(this.appId, await symbols);
75
20
  }
76
- const depData = await this.store.getDependencies(jobId);
77
21
  const jobData = await this.store.getRaw(jobId);
78
- const jobExport = this.inflate(jobData, depData);
22
+ const jobExport = this.inflate(jobData, options);
79
23
  return jobExport;
80
24
  }
81
25
  /**
82
- * Interleave actions into the replay timeline to create
83
- * a time-ordered timeline of the entire interaction, beginning
84
- * with the entry trigger and concluding with the scrubber
85
- * activity. Using the returned timeline, it is possible to
86
- * create an animated narrative of the job, highlighting
87
- * activities in the graph according to the timeline's
88
- * activity-created (/ac) and activity-updated (/au) entries.
26
+ * Inflates the job data from Redis into a DurableJobExport object
27
+ * @param jobHash - the job data from Redis
28
+ * @param dependencyList - the list of dependencies for the job
29
+ * @returns - the inflated job data
89
30
  */
90
- createTimeline(replay, actions) {
31
+ inflate(jobHash, options) {
91
32
  const timeline = [];
92
- replay.forEach((item) => {
93
- const dimensions = item[0];
94
- const parts = dimensions.split('/');
95
- const activityName = item[1].split('/')[0];
96
- const duplex = item[1].endsWith('/ac') ? 'entry' : 'exit';
97
- const timestamp = item[2];
98
- let event = {
99
- activity: activityName,
100
- duplex: duplex,
101
- dimension: dimensions,
102
- timestamp,
103
- created: timestamp,
104
- updated: timestamp,
105
- };
106
- const prior = timeline[timeline.length - 1];
107
- if (prior && prior.activity === event.activity && prior.duplex !== event.duplex && prior.dimension === event.dimension) {
108
- if (event.duplex === 'exit') {
109
- prior.updated = event.timestamp;
110
- }
111
- else {
112
- prior.created = event.timestamp;
113
- }
114
- event = prior;
33
+ const state = {};
34
+ const data = {};
35
+ const transitionsObject = {};
36
+ const regex = /^([a-zA-Z]{3}),(\d+(?:,\d+)*)/;
37
+ Object.entries(jobHash).forEach(([key, value]) => {
38
+ const match = key.match(regex);
39
+ if (match) {
40
+ //transitions
41
+ this.inflateTransition(match, value, transitionsObject);
115
42
  }
116
- else {
117
- timeline.push(event);
43
+ else if (key.length === 3) {
44
+ //state
45
+ state[this.inflateKey(key)] = serializer_1.SerializerService.fromString(value);
118
46
  }
119
- if (this.isMainEntry(item[1])) {
120
- event.actions = [];
121
- this.interleaveActions(actions.main, event.actions);
47
+ else if (key.startsWith('_')) {
48
+ //data
49
+ data[key.substring(1)] = value;
122
50
  }
123
- else if (this.isHookEntry(item[1])) {
124
- const hookDimension = `/${parts[1]}/${parts[2]}`;
125
- const hookActions = actions.hooks[hookDimension];
126
- event.actions = [];
127
- this.interleaveActions(hookActions, event.actions);
51
+ else if (key.startsWith('-')) {
52
+ //timeline
53
+ const keyParts = this.keyToObject(key); //key parts have meaning
54
+ timeline.push({
55
+ ...keyParts,
56
+ key,
57
+ value: this.resolveValue(value, options.values),
58
+ });
128
59
  }
129
60
  });
130
- return timeline;
61
+ return this.filterFields({
62
+ data: (0, utils_1.restoreHierarchy)(data),
63
+ state: Object.entries((0, utils_1.restoreHierarchy)(state))[0][1],
64
+ status: parseInt(jobHash[':'], 10),
65
+ timeline: this.sortParts(timeline),
66
+ transitions: this.sortEntriesByCreated(transitionsObject),
67
+ }, options.block, options.allow);
131
68
  }
132
- /**
133
- * Interleave actions into the 'worker' and 'hook_worker'
134
- * activities (between their /ac and /au entries)
135
- */
136
- interleaveActions(target, actions) {
137
- if (target) {
138
- for (let i = target.cursor + 1; i < target.items.length; i++) {
139
- const [_, actionType, jobOrIndex] = target.items[i];
140
- actions.push({ action: actionType, target: jobOrIndex });
141
- target.cursor = i;
142
- if (this.isPausingAction(actionType)) {
143
- break;
144
- }
69
+ resolveValue(raw, withValues) {
70
+ const resolved = serializer_1.SerializerService.fromString(raw);
71
+ if (withValues !== false) {
72
+ return resolved;
73
+ }
74
+ if (resolved && typeof resolved === 'object') {
75
+ if ('data' in resolved) {
76
+ resolved.data = {};
77
+ }
78
+ if ('$error' in resolved) {
79
+ resolved.$error = {};
145
80
  }
146
81
  }
147
- }
148
- isPausingAction(actionType) {
149
- return actionType === 'sleep' || actionType === 'waitForSignal';
150
- }
151
- isMainEntry(key) {
152
- return key.startsWith('worker/') && key.endsWith('/ac');
153
- }
154
- isHookEntry(key) {
155
- return key.startsWith('hook_worker/') && key.endsWith('/ac');
82
+ return resolved;
156
83
  }
157
84
  /**
158
85
  * Inflates the key from Redis, 3-character symbol
159
86
  * into a human-readable JSON path, reflecting the
160
87
  * tree-like structure of the unidimensional Hash
88
+ * @private
161
89
  */
162
90
  inflateKey(key) {
163
- if (key in this.symbols) {
164
- const path = this.symbols[key];
91
+ const symbols = ExporterService.symbols.get(this.appId);
92
+ if (key in symbols) {
93
+ const path = symbols[key];
165
94
  const parts = path.split('/');
166
- if (parts[0] in this.activitySymbols) {
167
- parts[0] = this.activitySymbols[parts[0]];
168
- }
169
95
  return parts.join('/');
170
96
  }
171
97
  return key;
172
98
  }
173
- /**
174
- * Inflates the dependency data from Redis into a DurableJobExport object by
175
- * organizing the dimensional isolate in sch a way asto interleave
176
- * into a story
177
- * @param data - the dependency data from Redis
178
- * @returns - the organized dependency data
179
- */
180
- inflateDependencyData(data, actions) {
181
- const hookReg = /([0-9,]+)-(\d+)$/;
182
- const flowReg = /-(\d+)$/;
183
- return data.map((dependency, index) => {
184
- const [action, topic, gid, _pd, ...jid] = dependency.split(key_1.VALSEP);
185
- const jobId = jid.join(key_1.VALSEP);
186
- const match = jobId.match(hookReg);
187
- let prefix;
188
- let type;
189
- let dimensionKey = '';
190
- if (match) {
191
- //hook-originating dependency
192
- const [_, dimension, counter] = match;
193
- dimensionKey = dimension.split(',').join('/');
194
- prefix = `${dimensionKey}[${counter}]`;
195
- type = 'hook';
196
- }
197
- else {
198
- const match = jobId.match(flowReg);
199
- if (match) {
200
- //main workflow-originating dependency
201
- const [_, counter] = match;
202
- prefix = `[${counter}]`;
203
- type = 'flow';
99
+ filterFields(fullObject, block = [], allow = []) {
100
+ let result = {};
101
+ if (allow && allow.length > 0) {
102
+ allow.forEach(field => {
103
+ if (field in fullObject) {
104
+ result[field] = fullObject[field];
204
105
  }
205
- else {
206
- //'other' types like signal cleanup
207
- prefix = '/';
208
- type = 'other';
106
+ });
107
+ }
108
+ else {
109
+ result = { ...fullObject };
110
+ }
111
+ if (block && block.length > 0) {
112
+ block.forEach(field => {
113
+ if (field in result) {
114
+ delete result[field];
209
115
  }
210
- }
211
- this.seedActions(type, action, topic, dependency, prefix, dimensionKey, actions, jobId);
212
- return {
213
- type: action,
214
- topic,
215
- gid,
216
- jid: jobId,
217
- };
218
- });
116
+ });
117
+ }
118
+ return result;
219
119
  }
220
- /**
221
- * Adds historical actions (proxyActivity, executeChild)
222
- * using the `dependency list` to determine
223
- * after-the-fact what happened within the 'black-box'
224
- * worker function. This is necessary to interleave the
225
- * actions into the replay timeline, given that it isn't
226
- * really possible to know the inner-workings of the user's
227
- * function
228
- *
229
- */
230
- seedActions(type, action, topic, dep, prefix, dimensionKey, actions, jobId) {
231
- if (type !== 'other' && action === 'expire-child') {
232
- let depType;
233
- if (topic == `${this.appId}.activity.execute`) {
234
- depType = 'proxyActivity';
235
- }
236
- else if (topic == `${this.appId}.execute`) {
237
- depType = 'executeChild';
238
- }
239
- else if (topic == `${this.appId}.wfsc.execute`) {
240
- depType = 'waitForSignal';
120
+ inflateTransition(match, value, transitionsObject) {
121
+ const [_, letters, dimensions] = match;
122
+ const path = this.inflateKey(letters);
123
+ const parts = path.split('/');
124
+ const activity = parts[0];
125
+ const isCreate = path.endsWith('/output/metadata/ac');
126
+ const isUpdate = path.endsWith('/output/metadata/au');
127
+ //for now only export activity start/stop; activity data would also be interesting
128
+ if (isCreate || isUpdate) {
129
+ const targetName = `${activity},${dimensions}`;
130
+ let target = transitionsObject[targetName];
131
+ if (!target) {
132
+ transitionsObject[targetName] = {
133
+ activity,
134
+ dimensions,
135
+ created: isCreate ? value : null,
136
+ updated: isUpdate ? value : null,
137
+ };
241
138
  }
242
- if (depType) {
243
- if (type === 'flow') {
244
- actions.main.items.push([prefix, depType, jobId]);
245
- }
246
- else if (type === 'hook') {
247
- if (!actions.hooks[dimensionKey]) {
248
- actions.hooks[dimensionKey] = {
249
- cursor: -1,
250
- items: [],
251
- };
252
- }
253
- actions.hooks[dimensionKey].items.push([prefix, depType, jobId]);
254
- }
139
+ else {
140
+ target[isCreate ? 'created' : 'updated'] = value;
255
141
  }
256
142
  }
257
143
  }
144
+ sortEntriesByCreated(obj) {
145
+ const entriesArray = Object.values(obj);
146
+ entriesArray.sort((a, b) => {
147
+ return (a.created || a.updated).localeCompare(b.created || b.updated);
148
+ });
149
+ return entriesArray;
150
+ }
258
151
  /**
259
- * Inflates the job data from Redis into a DurableJobExport object
260
- * @param jobHash - the job data from Redis
261
- * @param dependencyList - the list of dependencies for the job
262
- * @returns - the inflated job data
152
+ * marker names are overloaded with details like sequence, type, etc
263
153
  */
264
- inflate(jobHash, dependencyList) {
265
- //the list of actions taken in the workflow and hook functions
266
- const actions = {
267
- hooks: {},
268
- main: { cursor: -1, items: [] },
269
- };
270
- const dependencies = this.inflateDependencyData(dependencyList, actions);
271
- const state = {};
272
- const data = {};
273
- const other = [];
274
- const replay = [];
275
- const regex = /^([a-zA-Z]{3}),(\d+(?:,\d+)*)/;
276
- Object.entries(jobHash).forEach(([key, value]) => {
277
- const match = key.match(regex);
278
- if (match) {
279
- //activity process state
280
- this.inflateProcess(match, value, replay);
281
- }
282
- else if (key.length === 3) {
283
- //job state
284
- state[this.inflateKey(key)] = this.serializer.fromString(value);
154
+ keyToObject(key) {
155
+ function extractDimension(label) {
156
+ const parts = label.split(',');
157
+ if (parts.length > 1) {
158
+ parts.shift();
159
+ return parts.join(',');
285
160
  }
286
- else if (key.startsWith('_')) {
287
- //job data
288
- data[key.substring(1)] = value;
289
- }
290
- else if (key.startsWith('-')) {
291
- //actions with side effect (replayable)
292
- this.inflateActions(key, value, actions);
293
- }
294
- else {
295
- //collator guids, etc
296
- other.push([null, key, value]);
297
- }
298
- });
299
- replay.sort(this.dateSort);
300
- actions.main.items.sort(this.reverseSort);
301
- Object.entries(actions.hooks).forEach(([key, value]) => {
302
- value.items.sort(this.reverseSort);
303
- });
304
- return {
305
- data: (0, utils_1.restoreHierarchy)(data),
306
- dependencies,
307
- state: Object.entries((0, utils_1.restoreHierarchy)(state))[0][1],
308
- status: jobHash[':'],
309
- timeline: this.createTimeline(replay, actions),
310
- transitions: { ...this.transitions },
311
- cycles: { ...this.cycles },
312
- };
313
- }
314
- inflateProcess(match, value, replay) {
315
- const [_, letters, numbers] = match;
316
- const path = this.inflateKey(letters);
317
- if (path.endsWith('/output/metadata/ac') ||
318
- path.endsWith('/output/metadata/au')) {
319
- const dimensions = `/${numbers.replace(/,/g, '/')}`;
320
- const resolved = this.serializer.fromString(value);
321
- replay.push([
322
- dimensions,
323
- path,
324
- resolved,
325
- ]);
326
161
  }
327
- }
328
- inflateActions(key, value, actions) {
329
- let [_, dimensionalType, counter, subcounter] = key.split('-');
330
- if (subcounter) {
331
- counter = `${counter}.${subcounter}`;
332
- }
333
- const [type, ...dimensions] = dimensionalType.split(',');
334
- let dimensionKey = '';
335
- let isHook = false;
336
- if (dimensions.length > 0) {
337
- dimensionKey = `/${dimensions.join('/')}`;
338
- isHook = true;
339
- }
340
- let targetList;
341
- if (isHook) {
342
- if (!actions.hooks[dimensionKey]) {
343
- actions.hooks[dimensionKey] = {
344
- cursor: -1,
345
- items: [],
346
- };
347
- }
348
- targetList = actions.hooks[dimensionKey].items;
162
+ const parts = key.split('-');
163
+ if (parts.length === 4) {
164
+ //-proxy-5- -search-1-1-
165
+ return {
166
+ index: parseInt(parts[2], 10),
167
+ dimension: extractDimension(parts[1]),
168
+ };
349
169
  }
350
170
  else {
351
- targetList = actions.main.items;
171
+ //-search,0,0-1-1- -proxy,0,0-1-
172
+ return {
173
+ index: parseInt(parts[2], 10),
174
+ secondary: parseInt(parts[3], 10),
175
+ dimension: extractDimension(parts[1]),
176
+ };
352
177
  }
353
- targetList.push([
354
- `${dimensionKey}[${counter}]`,
355
- type,
356
- value,
357
- ]);
358
178
  }
359
- reverseSort(aKey, bKey) {
360
- if (aKey[0] > bKey[0]) {
361
- return 1;
362
- }
363
- else if (aKey[0] < bKey[0]) {
364
- return -1;
365
- }
366
- else {
367
- if (aKey[1] > bKey[1]) {
179
+ /**
180
+ * idem list has a complicated sort order based on indexes and dimensions
181
+ */
182
+ sortParts(parts) {
183
+ return parts.sort((a, b) => {
184
+ const { dimension: aDim, index: aIdx, secondary: aSec } = a;
185
+ const { dimension: bDim, index: bIdx, secondary: bSec } = b;
186
+ if (aDim === undefined && bDim !== undefined)
187
+ return -1;
188
+ if (aDim !== undefined && bDim === undefined)
368
189
  return 1;
190
+ if (aDim !== undefined && bDim !== undefined) {
191
+ if (aDim < bDim)
192
+ return -1;
193
+ if (aDim > bDim)
194
+ return 1;
369
195
  }
370
- else if (aKey[1] < bKey[1]) {
196
+ if (aIdx < bIdx)
197
+ return -1;
198
+ if (aIdx > bIdx)
199
+ return 1;
200
+ if (aSec === undefined && bSec !== undefined)
371
201
  return -1;
202
+ if (aSec !== undefined && bSec === undefined)
203
+ return 1;
204
+ if (aSec !== undefined && bSec !== undefined) {
205
+ if (aSec < bSec)
206
+ return -1;
207
+ if (aSec > bSec)
208
+ return 1;
372
209
  }
373
210
  return 0;
374
- }
375
- }
376
- dateSort(aKey, bKey) {
377
- if (aKey[2] > bKey[2]) {
378
- return 1;
379
- }
380
- else if (aKey[2] < bKey[2]) {
381
- return -1;
382
- }
383
- else {
384
- return 0;
385
- }
211
+ });
386
212
  }
213
+ ;
387
214
  }
388
215
  exports.ExporterService = ExporterService;
216
+ ExporterService.symbols = new Map();
@@ -1,19 +1,20 @@
1
1
  import { ExporterService } from './exporter';
2
2
  import { HotMeshService as HotMesh } from '../hotmesh';
3
- import { DurableJobExport } from '../../types/exporter';
3
+ import { DurableJobExport, ExportOptions } from '../../types/exporter';
4
4
  import { JobInterruptOptions } from '../../types/job';
5
+ import { StreamError } from '../../types/stream';
5
6
  export declare class WorkflowHandleService {
6
7
  exporter: ExporterService;
7
8
  hotMesh: HotMesh;
8
9
  workflowTopic: string;
9
10
  workflowId: string;
10
11
  constructor(hotMesh: HotMesh, workflowTopic: string, workflowId: string);
11
- export(): Promise<DurableJobExport>;
12
+ export(options?: ExportOptions): Promise<DurableJobExport>;
12
13
  /**
13
14
  * Sends a signal to the workflow. This is a way to send
14
15
  * a message to a workflow that is paused due to having
15
- * executed a `waitForSignal` workflow extension. Awakens
16
- * the workflow if no other signals are pending.
16
+ * executed `Durable.workflow.waitFor`. The workflow
17
+ * will awaken if no other signals are pending.
17
18
  */
18
19
  signal(signalId: string, data: Record<any, any>): Promise<void>;
19
20
  /**
@@ -45,9 +46,13 @@ export declare class WorkflowHandleService {
45
46
  */
46
47
  interrupt(options?: JobInterruptOptions): Promise<string>;
47
48
  /**
48
- * Awaits for the workflow to complete and returns the result. If
49
- * the workflow thows and error, this method will likewise throw
50
- * an error.
49
+ * Waits for the workflow to complete and returns the result. If
50
+ * the workflow response includes an error, this method will rethrow
51
+ * the error, including the stack trace if available.
52
+ * Wrap calls in a try/catch as necessary to avoid unhandled exceptions.
51
53
  */
52
- result(loadState?: boolean): Promise<any>;
54
+ result<T>(config?: {
55
+ state?: boolean;
56
+ throwOnError?: boolean;
57
+ }): Promise<T | StreamError>;
53
58
  }