@hotmeshio/hotmesh 0.0.33 → 0.0.35

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 (94) hide show
  1. package/README.md +30 -18
  2. package/build/modules/enums.d.ts +22 -0
  3. package/build/modules/enums.js +29 -0
  4. package/build/modules/errors.d.ts +10 -2
  5. package/build/modules/errors.js +14 -3
  6. package/build/modules/key.d.ts +16 -15
  7. package/build/modules/key.js +18 -15
  8. package/build/modules/utils.d.ts +1 -0
  9. package/build/modules/utils.js +6 -1
  10. package/build/package.json +4 -1
  11. package/build/services/activities/activity.d.ts +5 -0
  12. package/build/services/activities/activity.js +27 -6
  13. package/build/services/activities/await.js +11 -3
  14. package/build/services/activities/cycle.js +10 -2
  15. package/build/services/activities/hook.js +8 -2
  16. package/build/services/activities/index.d.ts +2 -2
  17. package/build/services/activities/index.js +2 -2
  18. package/build/services/activities/interrupt.d.ts +16 -0
  19. package/build/services/activities/interrupt.js +129 -0
  20. package/build/services/activities/signal.js +9 -2
  21. package/build/services/activities/trigger.d.ts +4 -0
  22. package/build/services/activities/trigger.js +14 -4
  23. package/build/services/activities/worker.js +10 -2
  24. package/build/services/collator/index.d.ts +4 -0
  25. package/build/services/collator/index.js +8 -0
  26. package/build/services/compiler/deployer.js +1 -3
  27. package/build/services/connector/index.js +2 -3
  28. package/build/services/durable/client.js +9 -6
  29. package/build/services/durable/factory.js +65 -284
  30. package/build/services/durable/handle.d.ts +37 -0
  31. package/build/services/durable/handle.js +52 -9
  32. package/build/services/durable/index.d.ts +5 -0
  33. package/build/services/durable/index.js +10 -0
  34. package/build/services/durable/meshos.js +3 -6
  35. package/build/services/durable/worker.js +11 -5
  36. package/build/services/durable/workflow.d.ts +24 -0
  37. package/build/services/durable/workflow.js +56 -1
  38. package/build/services/engine/index.d.ts +14 -6
  39. package/build/services/engine/index.js +52 -27
  40. package/build/services/hotmesh/index.d.ts +6 -2
  41. package/build/services/hotmesh/index.js +23 -5
  42. package/build/services/quorum/index.d.ts +1 -0
  43. package/build/services/quorum/index.js +10 -0
  44. package/build/services/signaler/stream.js +25 -29
  45. package/build/services/store/index.d.ts +40 -4
  46. package/build/services/store/index.js +114 -9
  47. package/build/services/task/index.d.ts +5 -4
  48. package/build/services/task/index.js +12 -14
  49. package/build/types/activity.d.ts +35 -5
  50. package/build/types/durable.d.ts +4 -0
  51. package/build/types/index.d.ts +1 -1
  52. package/build/types/job.d.ts +18 -1
  53. package/build/types/quorum.d.ts +11 -7
  54. package/build/types/stream.d.ts +4 -1
  55. package/build/types/stream.js +2 -0
  56. package/modules/enums.ts +32 -0
  57. package/modules/errors.ts +24 -9
  58. package/modules/key.ts +4 -1
  59. package/modules/utils.ts +5 -0
  60. package/package.json +4 -1
  61. package/services/activities/activity.ts +34 -8
  62. package/services/activities/await.ts +11 -4
  63. package/services/activities/cycle.ts +10 -3
  64. package/services/activities/hook.ts +8 -3
  65. package/services/activities/index.ts +2 -2
  66. package/services/activities/interrupt.ts +159 -0
  67. package/services/activities/signal.ts +9 -3
  68. package/services/activities/trigger.ts +21 -5
  69. package/services/activities/worker.ts +10 -3
  70. package/services/collator/index.ts +10 -1
  71. package/services/compiler/deployer.ts +1 -3
  72. package/services/connector/index.ts +3 -5
  73. package/services/durable/client.ts +10 -7
  74. package/services/durable/factory.ts +65 -284
  75. package/services/durable/handle.ts +55 -9
  76. package/services/durable/index.ts +11 -0
  77. package/services/durable/meshos.ts +3 -7
  78. package/services/durable/worker.ts +11 -5
  79. package/services/durable/workflow.ts +66 -2
  80. package/services/engine/index.ts +74 -26
  81. package/services/hotmesh/index.ts +28 -6
  82. package/services/quorum/index.ts +9 -0
  83. package/services/signaler/stream.ts +28 -25
  84. package/services/store/index.ts +119 -11
  85. package/services/task/index.ts +18 -18
  86. package/types/activity.ts +38 -8
  87. package/types/durable.ts +8 -4
  88. package/types/index.ts +1 -1
  89. package/types/job.ts +30 -1
  90. package/types/quorum.ts +13 -8
  91. package/types/stream.ts +3 -0
  92. package/build/services/activities/iterate.d.ts +0 -9
  93. package/build/services/activities/iterate.js +0 -13
  94. package/services/activities/iterate.ts +0 -26
@@ -2,7 +2,7 @@ import { Activity } from './activity';
2
2
  import { Await } from './await';
3
3
  import { Cycle } from './cycle';
4
4
  import { Hook } from './hook';
5
- import { Iterate } from './iterate';
5
+ import { Interrupt } from './interrupt';
6
6
  import { Signal } from './signal';
7
7
  import { Trigger } from './trigger';
8
8
  import { Worker } from './worker';
@@ -11,7 +11,7 @@ declare const _default: {
11
11
  await: typeof Await;
12
12
  cycle: typeof Cycle;
13
13
  hook: typeof Hook;
14
- iterate: typeof Iterate;
14
+ interrupt: typeof Interrupt;
15
15
  signal: typeof Signal;
16
16
  trigger: typeof Trigger;
17
17
  worker: typeof Worker;
@@ -4,7 +4,7 @@ const activity_1 = require("./activity");
4
4
  const await_1 = require("./await");
5
5
  const cycle_1 = require("./cycle");
6
6
  const hook_1 = require("./hook");
7
- const iterate_1 = require("./iterate");
7
+ const interrupt_1 = require("./interrupt");
8
8
  const signal_1 = require("./signal");
9
9
  const trigger_1 = require("./trigger");
10
10
  const worker_1 = require("./worker");
@@ -13,7 +13,7 @@ exports.default = {
13
13
  await: await_1.Await,
14
14
  cycle: cycle_1.Cycle,
15
15
  hook: hook_1.Hook,
16
- iterate: iterate_1.Iterate,
16
+ interrupt: interrupt_1.Interrupt,
17
17
  signal: signal_1.Signal,
18
18
  trigger: trigger_1.Trigger,
19
19
  worker: worker_1.Worker,
@@ -0,0 +1,16 @@
1
+ import { EngineService } from '../engine';
2
+ import { Activity, ActivityType } from './activity';
3
+ import { ActivityData, ActivityMetadata, InterruptActivity } from '../../types/activity';
4
+ import { JobInterruptOptions, JobState } from '../../types/job';
5
+ import { TelemetryService } from '../telemetry';
6
+ declare class Interrupt extends Activity {
7
+ config: InterruptActivity;
8
+ constructor(config: ActivityType, data: ActivityData, metadata: ActivityMetadata, hook: ActivityData | null, engine: EngineService, context?: JobState);
9
+ process(): Promise<string>;
10
+ interruptSelf(telemetry: TelemetryService): Promise<string>;
11
+ interruptAnother(telemetry: TelemetryService): Promise<string>;
12
+ isInterruptingSelf(): boolean;
13
+ resolveInterruptOptions(): JobInterruptOptions;
14
+ interrupt(): Promise<string>;
15
+ }
16
+ export { Interrupt };
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Interrupt = void 0;
4
+ const activity_1 = require("./activity");
5
+ const errors_1 = require("../../modules/errors");
6
+ const collator_1 = require("../collator");
7
+ const telemetry_1 = require("../telemetry");
8
+ const pipe_1 = require("../pipe");
9
+ class Interrupt extends activity_1.Activity {
10
+ constructor(config, data, metadata, hook, engine, context) {
11
+ super(config, data, metadata, hook, engine, context);
12
+ }
13
+ //******** LEG 1 ENTRY ********//
14
+ async process() {
15
+ this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
16
+ let telemetry;
17
+ try {
18
+ this.setLeg(1);
19
+ await collator_1.CollatorService.notarizeEntry(this);
20
+ await this.getState();
21
+ collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid); // Ensure job active
22
+ telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
23
+ telemetry.startActivitySpan(this.leg);
24
+ if (this.isInterruptingSelf()) {
25
+ return await this.interruptSelf(telemetry);
26
+ }
27
+ else {
28
+ return await this.interruptAnother(telemetry);
29
+ }
30
+ }
31
+ catch (error) {
32
+ if (error instanceof errors_1.InactiveJobError) {
33
+ this.logger.error('interrupt-inactive-job-error', { error });
34
+ return;
35
+ }
36
+ else if (error instanceof errors_1.GetStateError) {
37
+ this.logger.error('interrupt-get-state-error', { error });
38
+ return;
39
+ }
40
+ else {
41
+ this.logger.error('interrupt-process-error', { error });
42
+ }
43
+ telemetry.setActivityError(error.message);
44
+ throw error;
45
+ }
46
+ finally {
47
+ telemetry?.endActivitySpan();
48
+ this.logger.debug('interrupt-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
49
+ }
50
+ }
51
+ async interruptSelf(telemetry) {
52
+ // Apply final updates to THIS job's state
53
+ if (this.config.job?.maps) {
54
+ this.mapJobData();
55
+ await this.setState();
56
+ }
57
+ // Interrupt THIS job
58
+ const messageId = await this.interrupt();
59
+ // Notarize completion and log
60
+ telemetry.mapActivityAttributes();
61
+ const multi = this.store.getMulti();
62
+ await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
63
+ await this.setStatus(-1, multi);
64
+ const multiResponse = await multi.exec();
65
+ const jobStatus = this.resolveStatus(multiResponse);
66
+ telemetry.setActivityAttributes({
67
+ 'app.activity.mid': messageId,
68
+ 'app.job.jss': jobStatus
69
+ });
70
+ return this.context.metadata.aid;
71
+ }
72
+ async interruptAnother(telemetry) {
73
+ // Interrupt ANOTHER job
74
+ const messageId = await this.interrupt();
75
+ const attrs = { 'app.activity.mid': messageId };
76
+ // Apply updates to THIS job's state
77
+ telemetry.mapActivityAttributes();
78
+ this.adjacencyList = await this.filterAdjacent();
79
+ if (this.config.job?.maps || this.config.output?.maps) {
80
+ this.mapOutputData();
81
+ this.mapJobData();
82
+ const multi = this.store.getMulti();
83
+ await this.setState(multi);
84
+ }
85
+ // Notarize completion
86
+ const multi = this.store.getMulti();
87
+ await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
88
+ await this.setStatus(this.adjacencyList.length - 1, multi);
89
+ const multiResponse = await multi.exec();
90
+ const jobStatus = this.resolveStatus(multiResponse);
91
+ attrs['app.job.jss'] = jobStatus;
92
+ // Transition next generation and log
93
+ const messageIds = await this.transition(this.adjacencyList, jobStatus);
94
+ if (messageIds.length) {
95
+ attrs['app.activity.mids'] = messageIds.join(',');
96
+ }
97
+ telemetry.setActivityAttributes(attrs);
98
+ return this.context.metadata.aid;
99
+ }
100
+ isInterruptingSelf() {
101
+ if (!this.config.target) {
102
+ return true;
103
+ }
104
+ const resolvedJob = pipe_1.Pipe.resolve(this.config.target, this.context);
105
+ return resolvedJob == this.context.metadata.jid;
106
+ }
107
+ resolveInterruptOptions() {
108
+ return {
109
+ reason: this.config.reason !== undefined
110
+ ? pipe_1.Pipe.resolve(this.config.reason, this.context)
111
+ : undefined,
112
+ throw: this.config.throw !== undefined
113
+ ? pipe_1.Pipe.resolve(this.config.throw, this.context)
114
+ : undefined,
115
+ descend: this.config.descend !== undefined
116
+ ? pipe_1.Pipe.resolve(this.config.descend, this.context)
117
+ : undefined,
118
+ };
119
+ }
120
+ async interrupt() {
121
+ const options = this.resolveInterruptOptions();
122
+ return await this.engine.interrupt(this.config.topic !== undefined
123
+ ? pipe_1.Pipe.resolve(this.config.topic, this.context)
124
+ : this.context.metadata.tpc, this.config.target !== undefined
125
+ ? pipe_1.Pipe.resolve(this.config.target, this.context)
126
+ : this.context.metadata.jid, options);
127
+ }
128
+ }
129
+ exports.Interrupt = Interrupt;
@@ -20,6 +20,7 @@ class Signal extends activity_1.Activity {
20
20
  this.setLeg(1);
21
21
  await collator_1.CollatorService.notarizeEntry(this);
22
22
  await this.getState();
23
+ collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
23
24
  telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
24
25
  telemetry.startActivitySpan(this.leg);
25
26
  //save state and notarize early completion (signals only run leg1)
@@ -31,6 +32,7 @@ class Signal extends activity_1.Activity {
31
32
  await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
32
33
  await this.setStatus(this.adjacencyList.length - 1, multi);
33
34
  const multiResponse = await multi.exec();
35
+ //todo: this should execute BEFORE the status is decremented
34
36
  if (this.config.subtype === 'all') {
35
37
  await this.hookAll();
36
38
  }
@@ -49,8 +51,13 @@ class Signal extends activity_1.Activity {
49
51
  return this.context.metadata.aid;
50
52
  }
51
53
  catch (error) {
52
- if (error instanceof errors_1.GetStateError) {
54
+ if (error instanceof errors_1.InactiveJobError) {
55
+ this.logger.error('signal-inactive-job-error', { error });
56
+ return;
57
+ }
58
+ else if (error instanceof errors_1.GetStateError) {
53
59
  this.logger.error('signal-get-state-error', { error });
60
+ return;
54
61
  }
55
62
  else {
56
63
  this.logger.error('signal-process-error', { error });
@@ -59,7 +66,7 @@ class Signal extends activity_1.Activity {
59
66
  throw error;
60
67
  }
61
68
  finally {
62
- telemetry.endActivitySpan();
69
+ telemetry?.endActivitySpan();
63
70
  this.logger.debug('signal-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
64
71
  }
65
72
  }
@@ -17,6 +17,10 @@ declare class Trigger extends Activity {
17
17
  resolveJobId(context: Partial<JobState>): string;
18
18
  resolveJobKey(context: Partial<JobState>): string;
19
19
  setStateNX(): Promise<void>;
20
+ /**
21
+ * Registers this job as a dependent of the parent job
22
+ */
23
+ setDependency(multi?: RedisMulti): Promise<void>;
20
24
  setStats(multi?: RedisMulti): Promise<void>;
21
25
  }
22
26
  export { Trigger };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Trigger = void 0;
4
- const nanoid_1 = require("nanoid");
5
4
  const errors_1 = require("../../modules/errors");
6
5
  const utils_1 = require("../../modules/utils");
7
6
  const activity_1 = require("./activity");
@@ -30,6 +29,7 @@ class Trigger extends activity_1.Activity {
30
29
  const multi = this.store.getMulti();
31
30
  await this.setState(multi);
32
31
  await this.setStats(multi);
32
+ await this.setDependency(multi);
33
33
  await multi.exec();
34
34
  telemetry.mapActivityAttributes();
35
35
  const jobStatus = Number(this.context.metadata.js);
@@ -53,8 +53,8 @@ class Trigger extends activity_1.Activity {
53
53
  throw error;
54
54
  }
55
55
  finally {
56
- telemetry.endJobSpan();
57
- telemetry.endActivitySpan();
56
+ telemetry?.endJobSpan();
57
+ telemetry?.endActivitySpan();
58
58
  this.logger.debug('trigger-process-end', { subscribes: this.config.subscribes, jid: this.context.metadata.jid });
59
59
  }
60
60
  }
@@ -137,7 +137,7 @@ class Trigger extends activity_1.Activity {
137
137
  }
138
138
  resolveJobId(context) {
139
139
  const jobId = this.config.stats?.id;
140
- return jobId ? pipe_1.Pipe.resolve(jobId, context) : (0, nanoid_1.nanoid)();
140
+ return jobId ? pipe_1.Pipe.resolve(jobId, context) : (0, utils_1.guid)();
141
141
  }
142
142
  resolveJobKey(context) {
143
143
  const jobKey = this.config.stats?.key;
@@ -149,6 +149,16 @@ class Trigger extends activity_1.Activity {
149
149
  throw new errors_1.DuplicateJobError(jobId);
150
150
  }
151
151
  }
152
+ /**
153
+ * Registers this job as a dependent of the parent job
154
+ */
155
+ async setDependency(multi) {
156
+ const depKey = this.config.stats?.parent;
157
+ const resolvedDepKey = depKey ? pipe_1.Pipe.resolve(depKey, this.context) : '';
158
+ if (resolvedDepKey) {
159
+ await this.store.setDependency(resolvedDepKey, this.context.metadata.tpc, this.context.metadata.jid, multi);
160
+ }
161
+ }
152
162
  async setStats(multi) {
153
163
  const md = this.context.metadata;
154
164
  if (md.key && this.config.stats?.measures) {
@@ -6,6 +6,7 @@ const activity_1 = require("./activity");
6
6
  const collator_1 = require("../collator");
7
7
  const telemetry_1 = require("../telemetry");
8
8
  const pipe_1 = require("../pipe");
9
+ const utils_1 = require("../../modules/utils");
9
10
  class Worker extends activity_1.Activity {
10
11
  constructor(config, data, metadata, hook, engine, context) {
11
12
  super(config, data, metadata, hook, engine, context);
@@ -19,6 +20,7 @@ class Worker extends activity_1.Activity {
19
20
  this.setLeg(1);
20
21
  await collator_1.CollatorService.notarizeEntry(this);
21
22
  await this.getState();
23
+ collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
22
24
  telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
23
25
  telemetry.startActivitySpan(this.leg);
24
26
  this.mapInputData();
@@ -40,8 +42,13 @@ class Worker extends activity_1.Activity {
40
42
  return this.context.metadata.aid;
41
43
  }
42
44
  catch (error) {
43
- if (error instanceof errors_1.GetStateError) {
45
+ if (error instanceof errors_1.InactiveJobError) {
46
+ this.logger.error('await-inactive-job-error', { error });
47
+ return;
48
+ }
49
+ else if (error instanceof errors_1.GetStateError) {
44
50
  this.logger.error('worker-get-state-error', { error });
51
+ return;
45
52
  }
46
53
  else {
47
54
  this.logger.error('worker-process-error', { error });
@@ -50,7 +57,7 @@ class Worker extends activity_1.Activity {
50
57
  throw error;
51
58
  }
52
59
  finally {
53
- telemetry.endActivitySpan();
60
+ telemetry?.endActivitySpan();
54
61
  this.logger.debug('worker-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
55
62
  }
56
63
  }
@@ -58,6 +65,7 @@ class Worker extends activity_1.Activity {
58
65
  const topic = pipe_1.Pipe.resolve(this.config.subtype, this.context);
59
66
  const streamData = {
60
67
  metadata: {
68
+ guid: (0, utils_1.guid)(),
61
69
  jid: this.context.metadata.jid,
62
70
  dad: this.metadata.dad,
63
71
  aid: this.metadata.aid,
@@ -6,6 +6,10 @@ import { Activity } from '../activities/activity';
6
6
  import { Cycle } from '../activities/cycle';
7
7
  declare class CollatorService {
8
8
  static targetLength: number;
9
+ /**
10
+ * Upon re/entry, verify that the job status is active
11
+ */
12
+ static assertJobActive(status: number, jobId: string, activityId: string): void;
9
13
  /**
10
14
  * returns the dimensional address (dad) for the target; due
11
15
  * to the nature of the notary system, the dad for leg 2 entry
@@ -4,6 +4,14 @@ exports.CollatorService = void 0;
4
4
  const errors_1 = require("../../modules/errors");
5
5
  const collator_1 = require("../../types/collator");
6
6
  class CollatorService {
7
+ /**
8
+ * Upon re/entry, verify that the job status is active
9
+ */
10
+ static assertJobActive(status, jobId, activityId) {
11
+ if (status <= 0) {
12
+ throw new errors_1.InactiveJobError(jobId, status, activityId);
13
+ }
14
+ }
7
15
  /**
8
16
  * returns the dimensional address (dad) for the target; due
9
17
  * to the nature of the notary system, the dad for leg 2 entry
@@ -132,9 +132,7 @@ class Deployer {
132
132
  if (graph.publishes) {
133
133
  activities[activityKey].publishes = graph.publishes;
134
134
  }
135
- if (graph.expire) {
136
- activities[activityKey].expire = graph.expire;
137
- }
135
+ activities[activityKey].expire = graph.expire ?? undefined;
138
136
  }
139
137
  }
140
138
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConnectorService = void 0;
4
- const nanoid_1 = require("nanoid");
5
4
  const utils_1 = require("../../modules/utils");
6
5
  const ioredis_1 = require("../connector/clients/ioredis");
7
6
  const redis_1 = require("../connector/clients/redis");
@@ -13,12 +12,12 @@ class ConnectorService {
13
12
  const instances = [];
14
13
  if ((0, utils_1.identifyRedisTypeFromClass)(Redis) === 'redis') {
15
14
  for (let i = 1; i <= 3; i++) {
16
- instances.push(redis_1.RedisConnection.connect((0, nanoid_1.nanoid)(), Redis, options));
15
+ instances.push(redis_1.RedisConnection.connect((0, utils_1.guid)(), Redis, options));
17
16
  }
18
17
  }
19
18
  else {
20
19
  for (let i = 1; i <= 3; i++) {
21
- instances.push(ioredis_1.RedisConnection.connect((0, nanoid_1.nanoid)(), Redis, options));
20
+ instances.push(ioredis_1.RedisConnection.connect((0, utils_1.guid)(), Redis, options));
22
21
  }
23
22
  }
24
23
  const [store, stream, sub] = await Promise.all(instances);
@@ -7,6 +7,7 @@ const hotmesh_1 = require("../hotmesh");
7
7
  const key_1 = require("../../modules/key");
8
8
  const search_1 = require("./search");
9
9
  const types_1 = require("../../types");
10
+ const enums_1 = require("../../modules/enums");
10
11
  class ClientService {
11
12
  constructor(config) {
12
13
  this.getHotMeshClient = async (worflowTopic, namespace) => {
@@ -80,12 +81,15 @@ class ClientService {
80
81
  const workflowName = options.entity ?? options.workflowName;
81
82
  const trc = options.workflowTrace;
82
83
  const spn = options.workflowSpan;
83
- //topic is concat of taskQueue and workflowName
84
+ //NOTE: HotMesh 'workflowTopic' is a created by concatenating
85
+ // the taskQueue and workflowName used by the Durable module
84
86
  const workflowTopic = `${taskQueueName}-${workflowName}`;
85
87
  const hotMeshClient = await this.getHotMeshClient(workflowTopic, options.namespace);
86
88
  this.configureSearchIndex(hotMeshClient, options.search);
87
89
  const payload = {
88
90
  arguments: [...options.args],
91
+ originJobId: options.originJobId,
92
+ expire: options.expire ?? enums_1.DURABLE_EXPIRE_SECONDS,
89
93
  parentWorkflowId: options.parentWorkflowId,
90
94
  workflowId: options.workflowId || hotmesh_1.HotMeshService.guid(),
91
95
  workflowTopic: workflowTopic,
@@ -93,12 +97,12 @@ class ClientService {
93
97
  };
94
98
  const context = { metadata: { trc, spn }, data: {} };
95
99
  const jobId = await hotMeshClient.pub(`${options.namespace ?? factory_1.APP_ID}.execute`, payload, context);
96
- // Seed search data if present
100
+ // Seed search data
97
101
  if (jobId && options.search?.data) {
98
102
  const searchSessionId = `-search-0`;
99
103
  const search = new search_1.Search(jobId, hotMeshClient, searchSessionId);
100
104
  const entries = Object.entries(options.search.data).flat();
101
- search.set(...entries);
105
+ await search.set(...entries);
102
106
  }
103
107
  return new handle_1.WorkflowHandleService(hotMeshClient, workflowTopic, jobId);
104
108
  },
@@ -178,9 +182,8 @@ class ClientService {
178
182
  }
179
183
  }
180
184
  static async shutdown() {
181
- for (const [key, value] of ClientService.instances) {
182
- const hotMesh = await value;
183
- await hotMesh.stop();
185
+ for (const [_, hotMeshInstance] of ClientService.instances) {
186
+ (await hotMeshInstance).stop();
184
187
  }
185
188
  }
186
189
  }