@hotmeshio/hotmesh 0.0.16 → 0.0.18

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 (53) hide show
  1. package/build/modules/utils.d.ts +3 -0
  2. package/build/modules/utils.js +10 -1
  3. package/build/package.json +1 -1
  4. package/build/services/activities/activity.d.ts +4 -12
  5. package/build/services/activities/activity.js +19 -156
  6. package/build/services/activities/hook.d.ts +20 -0
  7. package/build/services/activities/hook.js +124 -0
  8. package/build/services/activities/index.d.ts +2 -0
  9. package/build/services/activities/index.js +2 -0
  10. package/build/services/activities/trigger.js +1 -1
  11. package/build/services/collator/index.js +0 -1
  12. package/build/services/compiler/deployer.d.ts +2 -0
  13. package/build/services/compiler/deployer.js +29 -2
  14. package/build/services/durable/client.d.ts +8 -1
  15. package/build/services/durable/client.js +47 -0
  16. package/build/services/durable/factory.js +88 -11
  17. package/build/services/durable/search.d.ts +15 -0
  18. package/build/services/durable/search.js +45 -0
  19. package/build/services/durable/workflow.d.ts +1 -0
  20. package/build/services/durable/workflow.js +36 -0
  21. package/build/services/engine/index.d.ts +7 -2
  22. package/build/services/engine/index.js +2 -1
  23. package/build/services/store/clients/ioredis.d.ts +1 -0
  24. package/build/services/store/clients/ioredis.js +12 -0
  25. package/build/services/store/clients/redis.d.ts +1 -0
  26. package/build/services/store/clients/redis.js +3 -0
  27. package/build/services/store/index.d.ts +1 -0
  28. package/build/services/telemetry/index.js +2 -1
  29. package/build/types/activity.d.ts +6 -3
  30. package/build/types/durable.d.ts +11 -1
  31. package/build/types/hook.d.ts +1 -0
  32. package/build/types/index.d.ts +2 -2
  33. package/modules/utils.ts +11 -0
  34. package/package.json +1 -1
  35. package/services/activities/activity.ts +20 -167
  36. package/services/activities/hook.ts +149 -0
  37. package/services/activities/index.ts +2 -0
  38. package/services/activities/trigger.ts +1 -1
  39. package/services/collator/index.ts +0 -1
  40. package/services/compiler/deployer.ts +32 -2
  41. package/services/durable/client.ts +51 -2
  42. package/services/durable/factory.ts +88 -11
  43. package/services/durable/search.ts +54 -0
  44. package/services/durable/workflow.ts +34 -1
  45. package/services/engine/index.ts +8 -4
  46. package/services/store/clients/ioredis.ts +13 -0
  47. package/services/store/clients/redis.ts +4 -0
  48. package/services/store/index.ts +1 -0
  49. package/services/telemetry/index.ts +2 -1
  50. package/types/activity.ts +7 -2
  51. package/types/durable.ts +9 -0
  52. package/types/hook.ts +1 -0
  53. package/types/index.ts +2 -0
@@ -24,6 +24,8 @@ const getWorkflowYAML = (app: string, version: string) => {
24
24
  schema:
25
25
  type: object
26
26
  properties:
27
+ parentWorkflowId:
28
+ type: string
27
29
  workflowId:
28
30
  type: string
29
31
  arguments:
@@ -46,12 +48,17 @@ const getWorkflowYAML = (app: string, version: string) => {
46
48
  type: trigger
47
49
  stats:
48
50
  id: '{$self.input.data.workflowId}'
51
+ key: '{$self.input.data.parentWorkflowId}'
52
+ granularity: infinity
53
+ measures:
54
+ - measure: index
55
+ target: '{$self.input.data.parentWorkflowId}'
49
56
  job:
50
57
  maps:
51
58
  done: false
52
59
 
53
60
  a1:
54
- type: activity
61
+ type: hook
55
62
  cycle: true
56
63
  output:
57
64
  schema:
@@ -65,6 +72,7 @@ const getWorkflowYAML = (app: string, version: string) => {
65
72
  w1:
66
73
  type: worker
67
74
  topic: '{t1.output.data.workflowTopic}'
75
+ emit: '{$job.data.done}'
68
76
  retry:
69
77
  '599': [2]
70
78
  input:
@@ -122,6 +130,19 @@ const getWorkflowYAML = (app: string, version: string) => {
122
130
  response: '{$self.output.data.response}'
123
131
  done: '{$self.output.data.done}'
124
132
 
133
+ a2:
134
+ type: hook
135
+ title: Wait for cleanup signal
136
+ hook:
137
+ type: object
138
+ properties:
139
+ done:
140
+ type: boolean
141
+ job:
142
+ maps:
143
+ workflowId: '{t1.output.data.workflowId}'
144
+
145
+
125
146
  a594:
126
147
  title: Wait for signals
127
148
  type: await
@@ -226,7 +247,7 @@ const getWorkflowYAML = (app: string, version: string) => {
226
247
 
227
248
  a599:
228
249
  title: Sleep exponentially longer before retrying
229
- type: activity
250
+ type: hook
230
251
  sleep: '{a1.output.data.duration}'
231
252
 
232
253
  c599:
@@ -279,7 +300,7 @@ const getWorkflowYAML = (app: string, version: string) => {
279
300
  done: true
280
301
 
281
302
  s2:
282
- title: Awaken sleep flows so they end and self-clean
303
+ title: Awaken sleeping flows so they end and self-clean
283
304
  type: signal
284
305
  subtype: all
285
306
  key_name: parentWorkflowId
@@ -351,10 +372,55 @@ const getWorkflowYAML = (app: string, version: string) => {
351
372
  type: boolean
352
373
  maps:
353
374
  done: true
375
+
376
+ s4:
377
+ title: Awaken child FLOWS so they end and self-clean
378
+ type: signal
379
+ subtype: all
380
+ key_name: parentWorkflowId
381
+ key_value:
382
+ '@pipe':
383
+ - ['{$job.metadata.jid}', '-f']
384
+ - ['{@string.concat}']
385
+ topic: ${app}.childflow.awaken
386
+ resolver:
387
+ schema:
388
+ type: object
389
+ properties:
390
+ data:
391
+ type: object
392
+ properties:
393
+ parentWorkflowId:
394
+ type: string
395
+ scrub:
396
+ type: boolean
397
+ maps:
398
+ data:
399
+ parentWorkflowId:
400
+ '@pipe':
401
+ - ['{$job.metadata.jid}', '-f']
402
+ - ['{@string.concat}']
403
+ scrub: true
404
+ signal:
405
+ schema:
406
+ type: object
407
+ properties:
408
+ done:
409
+ type: boolean
410
+ maps:
411
+ done: true
354
412
 
355
413
  transitions:
356
414
  t1:
357
415
  - to: a1
416
+ - to: a2
417
+ conditions:
418
+ match:
419
+ - expected: true
420
+ actual:
421
+ '@pipe':
422
+ - ['{$job.metadata.key}', true, false]
423
+ - ['{@conditional.ternary}']
358
424
  a1:
359
425
  - to: w1
360
426
  w1:
@@ -376,11 +442,13 @@ const getWorkflowYAML = (app: string, version: string) => {
376
442
  - to: s3
377
443
  conditions:
378
444
  code: [200, 598, 597, 596]
445
+ - to: s4
446
+ conditions:
447
+ code: [200, 598, 597, 596]
379
448
  a594:
380
449
  - to: c594
381
450
  conditions:
382
451
  code: 202
383
-
384
452
  a595:
385
453
  - to: c595
386
454
  conditions:
@@ -388,6 +456,14 @@ const getWorkflowYAML = (app: string, version: string) => {
388
456
  a599:
389
457
  - to: c599
390
458
 
459
+ hooks:
460
+ ${app}.childflow.awaken:
461
+ - to: a2
462
+ conditions:
463
+ match:
464
+ - expected: '{t1.output.data.workflowId}'
465
+ actual: '{$self.hook.data.id}'
466
+
391
467
  - subscribes: ${app}.activity.execute
392
468
  publishes: ${app}.activity.executed
393
469
 
@@ -463,7 +539,7 @@ const getWorkflowYAML = (app: string, version: string) => {
463
539
  done: true
464
540
 
465
541
  s1a:
466
- type: activity
542
+ type: hook
467
543
  title: Wait for cleanup signal
468
544
  hook:
469
545
  type: object
@@ -483,6 +559,7 @@ const getWorkflowYAML = (app: string, version: string) => {
483
559
  hooks:
484
560
  ${app}.activity.awaken:
485
561
  - to: s1a
562
+ keep_alive: true
486
563
  conditions:
487
564
  match:
488
565
  - expected: '{t1a.output.data.workflowId}'
@@ -529,13 +606,13 @@ const getWorkflowYAML = (app: string, version: string) => {
529
606
  target: '{$self.input.data.parentWorkflowId}'
530
607
 
531
608
  a1s:
532
- type: activity
609
+ type: hook
533
610
  title: Sleep for a duration
534
611
  sleep: '{t1s.output.data.duration}'
535
612
  emit: true
536
613
 
537
614
  a2s:
538
- type: activity
615
+ type: hook
539
616
  title: Wait for cleanup signal
540
617
  hook:
541
618
  type: object
@@ -607,7 +684,7 @@ const getWorkflowYAML = (app: string, version: string) => {
607
684
 
608
685
  a1wc:
609
686
  title: Split signal data
610
- type: activity
687
+ type: hook
611
688
  cycle: true
612
689
  output:
613
690
  schema:
@@ -645,7 +722,7 @@ const getWorkflowYAML = (app: string, version: string) => {
645
722
  - ['{t1wc.output.data.signals}', 1]
646
723
  - ['{@array.slice}']
647
724
  a2wc:
648
- type: activity
725
+ type: hook
649
726
  output:
650
727
  schema:
651
728
  type: object
@@ -772,7 +849,7 @@ const getWorkflowYAML = (app: string, version: string) => {
772
849
  target: '{$self.input.data.parentWorkflowId}'
773
850
 
774
851
  a1ww:
775
- type: activity
852
+ type: hook
776
853
  title: Wait for custom signal
777
854
  emit: true
778
855
  hook:
@@ -787,7 +864,7 @@ const getWorkflowYAML = (app: string, version: string) => {
787
864
  signalId: '{t1ww.output.data.signalId}'
788
865
 
789
866
  a2ww:
790
- type: activity
867
+ type: hook
791
868
  title: Wait for cleanup signal
792
869
  hook:
793
870
  type: object
@@ -0,0 +1,54 @@
1
+ import { HotMeshService as HotMesh } from '../hotmesh'
2
+ import { RedisClient, RedisMulti } from '../../types/redis';
3
+ import { StoreService } from '../store';
4
+ import { KeyService, KeyType } from '../../modules/key';
5
+
6
+ export class Search {
7
+ jobId: string;
8
+ hotMeshClient: HotMesh;
9
+ store: StoreService<RedisClient, RedisMulti> | null;
10
+
11
+ safeKey(key:string): string {
12
+ //note: protect the execution namespace with a prefix,
13
+ //so its design never conflicts with the hotmesh keyspace
14
+ return `_${key}`;
15
+ }
16
+
17
+ constructor(workflowId: string, hotMeshClient: HotMesh) {
18
+ const keyParams = {
19
+ appId: hotMeshClient.appId,
20
+ jobId: ''
21
+ }
22
+ const hotMeshPrefix = KeyService.mintKey(hotMeshClient.namespace, KeyType.JOB_STATE, keyParams);
23
+ this.jobId = `${hotMeshPrefix}${workflowId}`;
24
+ this.hotMeshClient = hotMeshClient;
25
+ this.store = hotMeshClient.engine.store as StoreService<RedisClient, RedisMulti>;
26
+ }
27
+
28
+ async set(key: string, value: string): Promise<void> {
29
+ await this.store.exec('HSET', this.jobId, this.safeKey(key), value.toString());
30
+ }
31
+
32
+ async get(key: string): Promise<string> {
33
+ try {
34
+ return await this.store.exec('HGET',this.jobId, this.safeKey(key)) as string;
35
+ } catch (err) {
36
+ this.hotMeshClient.logger.error('durable-search-get-error', { err });
37
+ return '';
38
+ }
39
+ }
40
+
41
+ async del(key: string): Promise<void> {
42
+ await this.store.exec('HDEL', this.jobId, this.safeKey(key));
43
+ }
44
+
45
+ async incr(key: string, val: number): Promise<number> {
46
+ return Number(await this.store.exec('HINCRBYFLOAT', this.jobId, this.safeKey(key), val.toString()) as string);
47
+ }
48
+
49
+ async mult(key: string, val: number): Promise<number> {
50
+ const log = Math.log(val);
51
+ const logTotal = Number(await this.store.exec('HINCRBYFLOAT', this.jobId, this.safeKey(key), log.toString()) as string);
52
+ return Math.exp(logTotal);
53
+ }
54
+ }
@@ -4,10 +4,11 @@ import { asyncLocalStorage } from './asyncLocalStorage';
4
4
  import { WorkerService } from './worker';
5
5
  import { ClientService as Client } from './client';
6
6
  import { ConnectionService as Connection } from './connection';
7
- import { ActivityConfig, ProxyType, WorkflowOptions } from "../../types/durable";
7
+ import { ActivityConfig, ProxyType, WorkflowConfig, WorkflowOptions, WorkflowSearchOptions } from "../../types/durable";
8
8
  import { JobOutput, JobState } from '../../types';
9
9
  import { ACTIVITY_PUBLISHES_TOPIC, ACTIVITY_SUBSCRIBES_TOPIC, SLEEP_SUBSCRIBES_TOPIC, WFS_SUBSCRIBES_TOPIC } from './factory';
10
10
  import { DurableIncompleteSignalError, DurableSleepError, DurableWaitForSignalError } from '../../modules/errors';
11
+ import { Search } from './search';
11
12
 
12
13
  /*
13
14
  `proxyActivities` returns a wrapped instance of the
@@ -54,6 +55,7 @@ export class WorkflowService {
54
55
  const COUNTER = store.get('counter');
55
56
  const execIndex = COUNTER.counter = COUNTER.counter + 1;
56
57
  const childJobId = `${workflowId}-$${options.workflowName}-${execIndex}`;
58
+ const parentWorkflowId = `${workflowId}-f`;
57
59
 
58
60
  const client = new Client({
59
61
  connection: await Connection.connect(WorkerService.connection),
@@ -71,6 +73,7 @@ export class WorkflowService {
71
73
  handle = await client.workflow.start({
72
74
  ...options,
73
75
  workflowId: childJobId,
76
+ parentWorkflowId,
74
77
  workflowTrace,
75
78
  workflowSpan,
76
79
  });
@@ -95,6 +98,36 @@ export class WorkflowService {
95
98
  return proxy;
96
99
  }
97
100
 
101
+ static async data(command: 'del' | 'get' | 'set' | 'incr' | 'mult', ...args: string[]): Promise<number | boolean | string> {
102
+ const store = asyncLocalStorage.getStore();
103
+ if (!store) {
104
+ throw new Error('durable-store-not-found');
105
+ }
106
+ const workflowId = store.get('workflowId');
107
+ const workflowTopic = store.get('workflowTopic');
108
+
109
+ try {
110
+ const hotMeshClient = await WorkerService.getHotMesh(workflowTopic);
111
+ const search = new Search(workflowId, hotMeshClient);
112
+ if (command === 'get') {
113
+ return await search.get(args[0]) as string;
114
+ } else if (command === 'set') {
115
+ await search.set(args[0], args[1]);
116
+ return true;
117
+ } else if (command === 'del') {
118
+ await search.del(args[0]);
119
+ return true;
120
+ } else if (command === 'incr') {
121
+ return await search.incr(args[0], Number(args[1])) as number;
122
+ } else if (command === 'mult') {
123
+ return await search.mult(args[0], Number(args[1])) as number;
124
+ }
125
+ } catch (e) {
126
+ console.error(e);
127
+ return '';
128
+ }
129
+ }
130
+
98
131
  static async sleep(duration: string): Promise<number> {
99
132
  const seconds = ms(duration) / 1000;
100
133
 
@@ -3,10 +3,13 @@ import {
3
3
  formatISODate,
4
4
  getSubscriptionTopic,
5
5
  identifyRedisType,
6
+ polyfill,
6
7
  restoreHierarchy } from '../../modules/utils';
7
8
  import Activities from '../activities';
8
- import { Activity } from '../activities/activity';
9
9
  import { Await } from '../activities/await';
10
+ import { Cycle } from '../activities/cycle';
11
+ import { Hook } from '../activities/hook';
12
+ import { Signal } from '../activities/signal';
10
13
  import { Worker } from '../activities/worker';
11
14
  import { Trigger } from '../activities/trigger';
12
15
  import { CompilerService } from '../compiler';
@@ -235,9 +238,10 @@ class EngineService {
235
238
  }
236
239
 
237
240
  // ************* METADATA/MODEL METHODS *************
238
- async initActivity(topic: string, data: JobData = {}, context?: JobState): Promise<Activity> {
241
+ async initActivity(topic: string, data: JobData = {}, context?: JobState): Promise<Await|Cycle|Hook|Signal|Trigger|Worker> {
239
242
  const [activityId, schema] = await this.getSchema(topic);
240
- const ActivityHandler = Activities[schema.type];
243
+ polyfill
244
+ const ActivityHandler = Activities[polyfill.resolveActivityType(schema.type)];
241
245
  if (ActivityHandler) {
242
246
  const utc = formatISODate(new Date());
243
247
  const metadata: ActivityMetadata = {
@@ -334,7 +338,7 @@ class EngineService {
334
338
  data: streamData.data,
335
339
  };
336
340
  if (streamData.type === StreamDataType.TIMEHOOK || streamData.type === StreamDataType.WEBHOOK || streamData.type === StreamDataType.TRANSITION) {
337
- const activityHandler = await this.initActivity(`.${streamData.metadata.aid}`, context.data, context as JobState) as Activity;
341
+ const activityHandler = await this.initActivity(`.${streamData.metadata.aid}`, context.data, context as JobState) as Hook;
338
342
  if (streamData.type === StreamDataType.TIMEHOOK) {
339
343
  await activityHandler.processTimeHookEvent(streamData.metadata.jid);
340
344
  } else if (streamData.type === StreamDataType.TRANSITION) {
@@ -5,6 +5,7 @@ import { Cache } from '../cache';
5
5
  import { StoreService } from '../index';
6
6
  import { RedisClientType, RedisMultiType } from '../../../types/ioredisclient';
7
7
  import { ReclaimedMessageType } from '../../../types/stream';
8
+ import { type } from 'os';
8
9
 
9
10
  class IORedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
10
11
  redisClient: RedisClientType;
@@ -22,6 +23,18 @@ class IORedisStoreService extends StoreService<RedisClientType, RedisMultiType>
22
23
  return this.redisClient.multi();
23
24
  }
24
25
 
26
+ async exec(...args: any[]): Promise<string|string[]|string[][]> {
27
+ const response = await this.redisClient.call.apply(this.redisClient, args as any);
28
+ if (typeof response === 'string') {
29
+ return response as string;
30
+ } else if (Array.isArray(response)) {
31
+ if (Array.isArray(response[0])) {
32
+ return response as string[][];
33
+ }
34
+ return response as string[];
35
+ }
36
+ }
37
+
25
38
  hGetAllResult(result: any) {
26
39
  //ioredis response signature is [null, {}] or [null, null]
27
40
  return result[1];
@@ -50,6 +50,10 @@ class RedisStoreService extends StoreService<RedisClientType, RedisMultiType> {
50
50
  return multi as unknown as RedisMultiType;
51
51
  }
52
52
 
53
+ async exec(...args: any[]): Promise<string|string[]|string[][]> {
54
+ return await this.redisClient.sendCommand(args);
55
+ }
56
+
53
57
  async publish(keyType: KeyType.QUORUM, message: Record<string, any>, appId: string, engineId?: string): Promise<boolean> {
54
58
  const topic = this.mintKey(keyType, { appId, engineId });
55
59
  const status: number = await this.redisClient.publish(topic, JSON.stringify(message));
@@ -70,6 +70,7 @@ abstract class StoreService<T, U extends AbstractRedisClient> {
70
70
 
71
71
  //todo: standardize signatures and move concrete methods to this class
72
72
  abstract getMulti(): U;
73
+ abstract exec(...args: any[]): Promise<string|string[]|string[][]>;
73
74
  abstract publish(
74
75
  keyType: KeyType.QUORUM,
75
76
  message: Record<string, any>,
@@ -18,6 +18,7 @@ import {
18
18
  Context,
19
19
  context,
20
20
  SpanStatusCode } from '../../types/telemetry';
21
+ import { polyfill } from '../../modules/utils';
21
22
 
22
23
  class TelemetryService {
23
24
  span: Span;
@@ -253,7 +254,7 @@ class TelemetryService {
253
254
  if (config.type === 'trigger') {
254
255
  state[`${metadata.aid}/output/metadata/l1s`] = context['$self'].output.metadata.l1s;
255
256
  state[`${metadata.aid}/output/metadata/l2s`] = context['$self'].output.metadata.l2s;
256
- } else if (config.type === 'activity' && leg === 1) {
257
+ } else if (polyfill.resolveActivityType(config.type) === 'hook' && leg === 1) {
257
258
  //activities run non-duplexed and only have a single leg
258
259
  state[`${metadata.aid}/output/metadata/l1s`] = context['$self'].output.metadata.l1s;
259
260
  state[`${metadata.aid}/output/metadata/l2s`] = context['$self'].output.metadata.l1s;
package/types/activity.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { MetricTypes } from "./stats";
2
2
  import { StreamRetryPolicy } from "./stream";
3
3
 
4
- type ActivityExecutionType = 'trigger' | 'await' | 'worker' | 'activity' | 'emit' | 'iterate' | 'cycle' | 'signal';
4
+ type ActivityExecutionType = 'trigger' | 'await' | 'worker' | 'activity' | 'emit' | 'iterate' | 'cycle' | 'signal' | 'hook';
5
5
 
6
6
  type Consumes = Record<string, string[]>;
7
7
 
@@ -65,6 +65,10 @@ interface CycleActivity extends BaseActivity {
65
65
  ancestor: string; //ancestor activity id
66
66
  }
67
67
 
68
+ interface HookActivity extends BaseActivity {
69
+ type: 'hook';
70
+ }
71
+
68
72
  interface SignalActivity extends BaseActivity {
69
73
  type: 'signal'; //signal activities call hook/hookAll
70
74
  subtype: 'one' | 'all'; //trigger: hook(One) or hookAll
@@ -80,7 +84,7 @@ interface IterateActivity extends BaseActivity {
80
84
  type: 'iterate';
81
85
  }
82
86
 
83
- type ActivityType = BaseActivity | TriggerActivity | AwaitActivity | WorkerActivity | IterateActivity;
87
+ type ActivityType = BaseActivity | TriggerActivity | AwaitActivity | WorkerActivity | IterateActivity | HookActivity;
84
88
 
85
89
  type ActivityData = Record<string, any>;
86
90
  type ActivityMetadata = {
@@ -124,6 +128,7 @@ export {
124
128
  TriggerActivityStats,
125
129
  AwaitActivity,
126
130
  CycleActivity,
131
+ HookActivity,
127
132
  SignalActivity,
128
133
  BaseActivity,
129
134
  IterateActivity,
package/types/durable.ts CHANGED
@@ -7,13 +7,21 @@ type WorkflowConfig = {
7
7
  initialInterval?: string; //default 1s
8
8
  }
9
9
 
10
+ type WorkflowSearchOptions = {
11
+ index: string; //FT index name (myapp:myindex)
12
+ prefix: string[]; //FT prefixes (['myapp:myindex:prefix1', 'myapp:myindex:prefix2'])
13
+ schema: Record<string, {type: 'TEXT' | 'NUMERIC' | 'TAG', sortable: boolean}>;
14
+ }
15
+
10
16
  type WorkflowOptions = {
11
17
  taskQueue: string;
12
18
  args: any[]; //input arguments to pass in
13
19
  workflowId: string; //execution id (the job id)
14
20
  workflowName?: string; //the name of the user's workflow function
21
+ parentWorkflowId?: string; //system reserved; the id of the parent; if present the flow will not self-clean until the parent that spawned it self-cleans
15
22
  workflowTrace?: string;
16
23
  workflowSpan?: string;
24
+ search?: WorkflowSearchOptions
17
25
  config?: WorkflowConfig;
18
26
  }
19
27
 
@@ -100,6 +108,7 @@ export {
100
108
  WorkerConfig,
101
109
  WorkflowConfig,
102
110
  WorkerOptions,
111
+ WorkflowSearchOptions,
103
112
  WorkflowDataType,
104
113
  WorkflowOptions,
105
114
  };
package/types/hook.ts CHANGED
@@ -16,6 +16,7 @@ interface HookConditions {
16
16
 
17
17
  interface HookRule {
18
18
  to: string;
19
+ keep_alive?: boolean; //if true, the hook will not be deleted after use
19
20
  conditions: HookConditions;
20
21
  }
21
22
 
package/types/index.ts CHANGED
@@ -10,6 +10,7 @@ export {
10
10
  AwaitActivity,
11
11
  BaseActivity,
12
12
  CycleActivity,
13
+ HookActivity,
13
14
  WorkerActivity,
14
15
  IterateActivity,
15
16
  SignalActivity,
@@ -39,6 +40,7 @@ export {
39
40
  WorkflowConfig,
40
41
  WorkerConfig,
41
42
  WorkerOptions,
43
+ WorkflowSearchOptions,
42
44
  WorkflowDataType,
43
45
  WorkflowOptions,
44
46
  }from './durable'