@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.
- package/README.md +22 -18
- package/build/index.d.ts +1 -2
- package/build/index.js +1 -3
- package/build/modules/enums.d.ts +8 -3
- package/build/modules/enums.js +16 -8
- package/build/modules/errors.d.ts +58 -20
- package/build/modules/errors.js +90 -33
- package/build/package.json +7 -2
- package/build/services/activities/activity.d.ts +8 -0
- package/build/services/activities/activity.js +63 -14
- package/build/services/activities/await.js +6 -6
- package/build/services/activities/cycle.d.ts +2 -2
- package/build/services/activities/cycle.js +5 -5
- package/build/services/activities/hook.js +9 -5
- package/build/services/activities/interrupt.d.ts +3 -3
- package/build/services/activities/interrupt.js +15 -6
- package/build/services/activities/signal.d.ts +2 -2
- package/build/services/activities/signal.js +4 -4
- package/build/services/activities/trigger.d.ts +5 -2
- package/build/services/activities/trigger.js +34 -4
- package/build/services/activities/worker.js +6 -6
- package/build/services/compiler/deployer.js +33 -5
- package/build/services/compiler/validator.d.ts +2 -0
- package/build/services/compiler/validator.js +5 -1
- package/build/services/durable/client.d.ts +7 -1
- package/build/services/durable/client.js +57 -38
- package/build/services/durable/exporter.d.ts +27 -81
- package/build/services/durable/exporter.js +153 -325
- package/build/services/durable/handle.d.ts +13 -8
- package/build/services/durable/handle.js +61 -48
- package/build/services/durable/index.d.ts +0 -2
- package/build/services/durable/index.js +0 -2
- package/build/services/durable/schemas/factory.d.ts +33 -0
- package/build/services/durable/schemas/factory.js +2356 -0
- package/build/services/durable/search.js +8 -8
- package/build/services/durable/worker.js +117 -25
- package/build/services/durable/workflow.d.ts +67 -52
- package/build/services/durable/workflow.js +322 -306
- package/build/services/engine/index.d.ts +2 -2
- package/build/services/engine/index.js +5 -2
- package/build/services/exporter/index.d.ts +2 -4
- package/build/services/exporter/index.js +4 -5
- package/build/services/hotmesh/index.d.ts +2 -2
- package/build/services/hotmesh/index.js +2 -2
- package/build/services/mapper/index.d.ts +6 -2
- package/build/services/mapper/index.js +6 -2
- package/build/services/pipe/functions/array.d.ts +2 -10
- package/build/services/pipe/functions/array.js +30 -28
- package/build/services/pipe/functions/conditional.d.ts +1 -0
- package/build/services/pipe/functions/conditional.js +3 -0
- package/build/services/pipe/functions/date.d.ts +1 -0
- package/build/services/pipe/functions/date.js +4 -0
- package/build/services/pipe/functions/index.d.ts +2 -0
- package/build/services/pipe/functions/index.js +2 -0
- package/build/services/pipe/functions/logical.d.ts +5 -0
- package/build/services/pipe/functions/logical.js +12 -0
- package/build/services/pipe/functions/object.d.ts +3 -0
- package/build/services/pipe/functions/object.js +25 -7
- package/build/services/pipe/index.d.ts +20 -3
- package/build/services/pipe/index.js +82 -16
- package/build/services/router/index.js +14 -3
- package/build/services/serializer/index.d.ts +3 -2
- package/build/services/serializer/index.js +11 -4
- package/build/services/store/clients/ioredis.js +6 -6
- package/build/services/store/clients/redis.js +7 -7
- package/build/services/store/index.d.ts +2 -0
- package/build/services/store/index.js +4 -1
- package/build/services/stream/clients/ioredis.js +8 -8
- package/build/services/stream/clients/redis.js +1 -1
- package/build/types/activity.d.ts +60 -5
- package/build/types/durable.d.ts +183 -36
- package/build/types/error.d.ts +48 -0
- package/build/types/error.js +2 -0
- package/build/types/exporter.d.ts +35 -7
- package/build/types/index.d.ts +4 -3
- package/build/types/job.d.ts +93 -6
- package/build/types/pipe.d.ts +81 -3
- package/build/types/stream.d.ts +61 -1
- package/build/types/stream.js +4 -0
- package/index.ts +1 -2
- package/modules/enums.ts +16 -8
- package/modules/errors.ts +139 -34
- package/package.json +7 -2
- package/services/activities/activity.ts +63 -14
- package/services/activities/await.ts +6 -6
- package/services/activities/cycle.ts +7 -6
- package/services/activities/hook.ts +12 -5
- package/services/activities/interrupt.ts +19 -9
- package/services/activities/signal.ts +6 -5
- package/services/activities/trigger.ts +43 -6
- package/services/activities/worker.ts +7 -7
- package/services/compiler/deployer.ts +33 -6
- package/services/compiler/validator.ts +7 -3
- package/services/durable/client.ts +49 -22
- package/services/durable/exporter.ts +162 -349
- package/services/durable/handle.ts +66 -53
- package/services/durable/index.ts +0 -2
- package/services/durable/schemas/factory.ts +2358 -0
- package/services/durable/search.ts +8 -8
- package/services/durable/worker.ts +128 -29
- package/services/durable/workflow.ts +371 -322
- package/services/engine/index.ts +8 -3
- package/services/exporter/index.ts +10 -12
- package/services/hotmesh/index.ts +4 -3
- package/services/mapper/index.ts +6 -2
- package/services/pipe/functions/array.ts +24 -37
- package/services/pipe/functions/conditional.ts +4 -0
- package/services/pipe/functions/date.ts +6 -0
- package/services/pipe/functions/index.ts +7 -5
- package/services/pipe/functions/logical.ts +11 -0
- package/services/pipe/functions/object.ts +26 -7
- package/services/pipe/index.ts +99 -21
- package/services/quorum/index.ts +1 -3
- package/services/router/index.ts +14 -3
- package/services/serializer/index.ts +12 -5
- package/services/store/clients/ioredis.ts +6 -6
- package/services/store/clients/redis.ts +7 -7
- package/services/store/index.ts +4 -1
- package/services/stream/clients/ioredis.ts +8 -8
- package/services/stream/clients/redis.ts +1 -1
- package/types/activity.ts +87 -15
- package/types/durable.ts +263 -75
- package/types/error.ts +52 -0
- package/types/exporter.ts +43 -9
- package/types/index.ts +14 -8
- package/types/job.ts +157 -36
- package/types/pipe.ts +84 -3
- package/types/stream.ts +82 -23
- package/build/services/durable/factory.d.ts +0 -17
- package/build/services/durable/factory.js +0 -817
- package/build/services/durable/meshos.d.ts +0 -127
- package/build/services/durable/meshos.js +0 -380
- package/services/durable/factory.ts +0 -818
- 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
|
|
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
|
|
68
|
-
*
|
|
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.
|
|
73
|
-
|
|
74
|
-
this.
|
|
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,
|
|
22
|
+
const jobExport = this.inflate(jobData, options);
|
|
79
23
|
return jobExport;
|
|
80
24
|
}
|
|
81
25
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
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
|
-
|
|
31
|
+
inflate(jobHash, options) {
|
|
91
32
|
const timeline = [];
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
43
|
+
else if (key.length === 3) {
|
|
44
|
+
//state
|
|
45
|
+
state[this.inflateKey(key)] = serializer_1.SerializerService.fromString(value);
|
|
118
46
|
}
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
47
|
+
else if (key.startsWith('_')) {
|
|
48
|
+
//data
|
|
49
|
+
data[key.substring(1)] = value;
|
|
122
50
|
}
|
|
123
|
-
else if (
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
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
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
164
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
type: action,
|
|
214
|
-
topic,
|
|
215
|
-
gid,
|
|
216
|
-
jid: jobId,
|
|
217
|
-
};
|
|
218
|
-
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
219
119
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
243
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
|
|
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
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
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
|
|
16
|
-
*
|
|
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
|
-
*
|
|
49
|
-
* the workflow
|
|
50
|
-
*
|
|
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(
|
|
54
|
+
result<T>(config?: {
|
|
55
|
+
state?: boolean;
|
|
56
|
+
throwOnError?: boolean;
|
|
57
|
+
}): Promise<T | StreamError>;
|
|
53
58
|
}
|