@hotmeshio/hotmesh 0.0.35 → 0.0.37

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 (69) hide show
  1. package/README.md +12 -12
  2. package/build/modules/enums.d.ts +1 -0
  3. package/build/modules/enums.js +3 -1
  4. package/build/modules/errors.d.ts +9 -1
  5. package/build/modules/errors.js +12 -1
  6. package/build/modules/key.d.ts +20 -19
  7. package/build/modules/key.js +20 -20
  8. package/build/package.json +1 -1
  9. package/build/services/activities/activity.d.ts +10 -0
  10. package/build/services/activities/activity.js +28 -3
  11. package/build/services/activities/await.js +10 -9
  12. package/build/services/activities/cycle.js +10 -9
  13. package/build/services/activities/hook.d.ts +7 -1
  14. package/build/services/activities/hook.js +61 -44
  15. package/build/services/activities/interrupt.js +10 -9
  16. package/build/services/activities/signal.js +7 -7
  17. package/build/services/activities/trigger.js +4 -2
  18. package/build/services/activities/worker.js +9 -8
  19. package/build/services/durable/meshos.js +2 -2
  20. package/build/services/durable/worker.js +2 -2
  21. package/build/services/durable/workflow.js +17 -17
  22. package/build/services/engine/index.d.ts +5 -7
  23. package/build/services/engine/index.js +53 -47
  24. package/build/services/hotmesh/index.js +3 -3
  25. package/build/services/{signaler/stream.d.ts → router/index.d.ts} +3 -3
  26. package/build/services/{signaler/stream.js → router/index.js} +6 -6
  27. package/build/services/serializer/index.js +1 -1
  28. package/build/services/store/clients/ioredis.js +1 -0
  29. package/build/services/store/index.d.ts +9 -4
  30. package/build/services/store/index.js +21 -10
  31. package/build/services/task/index.d.ts +13 -4
  32. package/build/services/task/index.js +115 -17
  33. package/build/services/telemetry/index.js +6 -6
  34. package/build/services/worker/index.d.ts +3 -3
  35. package/build/services/worker/index.js +8 -8
  36. package/build/types/job.d.ts +2 -0
  37. package/build/types/stream.d.ts +1 -0
  38. package/modules/enums.ts +4 -1
  39. package/modules/errors.ts +18 -0
  40. package/modules/key.ts +21 -20
  41. package/package.json +1 -1
  42. package/services/activities/activity.ts +44 -4
  43. package/services/activities/await.ts +14 -10
  44. package/services/activities/cycle.ts +14 -10
  45. package/services/activities/hook.ts +70 -47
  46. package/services/activities/interrupt.ts +13 -10
  47. package/services/activities/signal.ts +11 -8
  48. package/services/activities/trigger.ts +5 -1
  49. package/services/activities/worker.ts +13 -9
  50. package/services/durable/meshos.ts +1 -1
  51. package/services/durable/worker.ts +1 -1
  52. package/services/durable/workflow.ts +1 -1
  53. package/services/engine/index.ts +82 -44
  54. package/services/hotmesh/index.ts +3 -3
  55. package/services/{signaler/stream.ts → router/index.ts} +5 -5
  56. package/services/serializer/index.ts +1 -1
  57. package/services/store/clients/ioredis.ts +1 -0
  58. package/services/store/index.ts +23 -12
  59. package/services/task/index.ts +120 -21
  60. package/services/telemetry/index.ts +6 -6
  61. package/services/worker/index.ts +7 -7
  62. package/types/job.ts +2 -0
  63. package/types/stream.ts +6 -5
  64. package/build/services/signaler/store.d.ts +0 -15
  65. package/build/services/signaler/store.js +0 -68
  66. package/services/signaler/store.ts +0 -76
  67. /package/build/{services/durable/asyncLocalStorage.d.ts → modules/storage.d.ts} +0 -0
  68. /package/build/{services/durable/asyncLocalStorage.js → modules/storage.js} +0 -0
  69. /package/{services/durable/asyncLocalStorage.ts → modules/storage.ts} +0 -0
@@ -1,9 +1,12 @@
1
- import { GetStateError, InactiveJobError } from '../../modules/errors';
1
+ import {
2
+ GenerationalError,
3
+ GetStateError,
4
+ InactiveJobError } from '../../modules/errors';
2
5
  import { Activity } from './activity';
3
6
  import { CollatorService } from '../collator';
4
7
  import { EngineService } from '../engine';
5
8
  import { Pipe } from '../pipe';
6
- import { StoreSignaler } from '../signaler/store';
9
+ import { TaskService } from '../task';
7
10
  import { TelemetryService } from '../telemetry';
8
11
  import {
9
12
  ActivityData,
@@ -19,7 +22,7 @@ import { StringScalarType } from '../../types/serializer';
19
22
  import { StreamCode, StreamStatus } from '../../types/stream';
20
23
 
21
24
  /**
22
- * Listens for `webhook`, `timehook`, and `cycle` (repeat) signals
25
+ * Supports `signal hook`, `time hook`, and `cycle hook` patterns
23
26
  */
24
27
  class Hook extends Activity {
25
28
  config: HookActivity;
@@ -36,48 +39,25 @@ class Hook extends Activity {
36
39
 
37
40
  //******** INITIAL ENTRY POINT (A) ********//
38
41
  async process(): Promise<string> {
39
- this.logger.debug('hook-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
42
+ this.logger.debug('hook-process', {
43
+ jid: this.context.metadata.jid,
44
+ gid: this.context.metadata.gid,
45
+ aid: this.metadata.aid,
46
+ });
40
47
  let telemetry: TelemetryService;
48
+
41
49
  try {
42
- this.setLeg(1);
43
- await CollatorService.notarizeEntry(this);
50
+ await this.verifyEntry();
44
51
 
45
- await this.getState();
46
- CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
47
52
  telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
48
53
  telemetry.startActivitySpan(this.leg);
49
- let multiResponse: MultiResponseFlags;
50
54
 
51
- const multi = this.store.getMulti();
52
55
  if (this.doesHook()) {
53
56
  //sleep and wait to awaken upon a signal
54
- await this.registerHook(multi);
55
- this.mapOutputData();
56
- this.mapJobData();
57
- await this.setState(multi);
58
- await CollatorService.authorizeReentry(this, multi);
59
-
60
- await this.setStatus(0, multi);
61
- await multi.exec();
62
- telemetry.mapActivityAttributes();
57
+ await this.doHook(telemetry);
63
58
  } else {
64
59
  //end the activity and transition to its children
65
- this.adjacencyList = await this.filterAdjacent();
66
- this.mapOutputData();
67
- this.mapJobData();
68
- await this.setState(multi);
69
- await CollatorService.notarizeEarlyCompletion(this, multi);
70
-
71
- await this.setStatus(this.adjacencyList.length - 1, multi);
72
- multiResponse = await multi.exec() as MultiResponseFlags;
73
- telemetry.mapActivityAttributes();
74
- const jobStatus = this.resolveStatus(multiResponse);
75
- const attrs: StringScalarType = { 'app.job.jss': jobStatus };
76
- const messageIds = await this.transition(this.adjacencyList, jobStatus);
77
- if (messageIds.length) {
78
- attrs['app.activity.mids'] = messageIds.join(',')
79
- }
80
- telemetry.setActivityAttributes(attrs);
60
+ await this.doPassThrough(telemetry);
81
61
  }
82
62
 
83
63
  return this.context.metadata.aid;
@@ -85,6 +65,9 @@ class Hook extends Activity {
85
65
  if (error instanceof InactiveJobError) {
86
66
  this.logger.error('hook-inactive-job-error', { error });
87
67
  return;
68
+ } else if (error instanceof GenerationalError) {
69
+ this.logger.info('process-event-generational-job-error', { error });
70
+ return;
88
71
  } else if (error instanceof GetStateError) {
89
72
  this.logger.error('hook-get-state-error', { error });
90
73
  return;
@@ -95,16 +78,52 @@ class Hook extends Activity {
95
78
  throw error;
96
79
  } finally {
97
80
  telemetry?.endActivitySpan();
98
- this.logger.debug('hook-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
81
+ this.logger.debug('hook-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
99
82
  }
100
83
  }
101
84
 
102
- //******** SIGNAL RE-ENTRY POINT ********//
85
+ /**
86
+ * does this activity use a time-hook or web-hook
87
+ */
103
88
  doesHook(): boolean {
104
- //does this activity use a time-hook or web-hook
105
89
  return !!(this.config.hook?.topic || this.config.sleep);
106
90
  }
107
91
 
92
+ async doHook(telemetry: TelemetryService) {
93
+ const multi = this.store.getMulti();
94
+ await this.registerHook(multi);
95
+ this.mapOutputData();
96
+ this.mapJobData();
97
+ await this.setState(multi);
98
+ await CollatorService.authorizeReentry(this, multi);
99
+
100
+ await this.setStatus(0, multi);
101
+ await multi.exec();
102
+ telemetry.mapActivityAttributes();
103
+ }
104
+
105
+ async doPassThrough(telemetry: TelemetryService) {
106
+ const multi = this.store.getMulti();
107
+ let multiResponse: MultiResponseFlags;
108
+
109
+ this.adjacencyList = await this.filterAdjacent();
110
+ this.mapOutputData();
111
+ this.mapJobData();
112
+ await this.setState(multi);
113
+ await CollatorService.notarizeEarlyCompletion(this, multi);
114
+
115
+ await this.setStatus(this.adjacencyList.length - 1, multi);
116
+ multiResponse = await multi.exec() as MultiResponseFlags;
117
+ telemetry.mapActivityAttributes();
118
+ const jobStatus = this.resolveStatus(multiResponse);
119
+ const attrs: StringScalarType = { 'app.job.jss': jobStatus };
120
+ const messageIds = await this.transition(this.adjacencyList, jobStatus);
121
+ if (messageIds.length) {
122
+ attrs['app.activity.mids'] = messageIds.join(',')
123
+ }
124
+ telemetry.setActivityAttributes(attrs);
125
+ }
126
+
108
127
  async getHookRule(topic: string): Promise<HookRule | undefined> {
109
128
  const rules = await this.store.getHookRules();
110
129
  return rules?.[topic]?.[0] as HookRule;
@@ -112,18 +131,20 @@ class Hook extends Activity {
112
131
 
113
132
  async registerHook(multi?: RedisMulti): Promise<string | void> {
114
133
  if (this.config.hook?.topic) {
115
- const signaler = new StoreSignaler(this.store, this.logger);
116
- return await signaler.registerWebHook(this.config.hook.topic, this.context, this.resolveDad(), multi);
134
+ const taskService = new TaskService(this.store, this.logger);
135
+ return await taskService.registerWebHook(this.config.hook.topic, this.context, this.resolveDad(), multi);
117
136
  } else if (this.config.sleep) {
118
137
  const durationInSeconds = Pipe.resolve(this.config.sleep, this.context);
119
138
  const jobId = this.context.metadata.jid;
139
+ const gId = this.context.metadata.gid;
120
140
  const activityId = this.metadata.aid;
121
141
  const dId = this.metadata.dad;
122
- await this.engine.task.registerTimeHook(jobId, `${activityId}${dId||''}`, 'sleep', durationInSeconds);
142
+ await this.engine.taskService.registerTimeHook(jobId, gId, `${activityId}${dId||''}`, 'sleep', durationInSeconds);
123
143
  return jobId;
124
144
  }
125
145
  }
126
146
 
147
+ //******** SIGNAL RE-ENTRY POINT ********//
127
148
  async processWebHookEvent(status: StreamStatus = StreamStatus.SUCCESS, code: StreamCode = 200): Promise<JobStatus | void> {
128
149
  this.logger.debug('hook-process-web-hook-event', {
129
150
  topic: this.config.hook.topic,
@@ -131,23 +152,25 @@ class Hook extends Activity {
131
152
  status,
132
153
  code,
133
154
  });
134
- const signaler = new StoreSignaler(this.store, this.logger);
155
+ const taskService = new TaskService(this.store, this.logger);
135
156
  const data = { ...this.data };
136
- const signal = await signaler.processWebHookSignal(this.config.hook.topic, data);
157
+ const signal = await taskService.processWebHookSignal(this.config.hook.topic, data);
137
158
  if (signal) {
138
- const [jobId, aid, dad] = signal;
159
+ const [jobId, _aid, dad, gId] = signal;
139
160
  this.context.metadata.jid = jobId;
161
+ this.context.metadata.gid = gId;
140
162
  this.context.metadata.dad = dad;
141
163
  await this.processEvent(status, code, 'hook');
142
- if (code === 200) { //otherwise 202 for pending/keepalive
143
- await signaler.deleteWebHookSignal(this.config.hook.topic, data);
144
- }
164
+ if (code === 200) {
165
+ await taskService.deleteWebHookSignal(this.config.hook.topic, data);
166
+ } //else => 202/keep alive
145
167
  } //else => already resolved
146
168
  }
147
169
 
148
170
  async processTimeHookEvent(jobId: string): Promise<JobStatus | void> {
149
171
  this.logger.debug('hook-process-time-hook-event', {
150
172
  jid: jobId,
173
+ gid: this.context.metadata.gid,
151
174
  aid: this.metadata.aid
152
175
  });
153
176
  await this.processEvent(StreamStatus.SUCCESS, 200, 'hook');
@@ -1,10 +1,13 @@
1
+ import {
2
+ GenerationalError,
3
+ GetStateError,
4
+ InactiveJobError } from '../../modules/errors';
1
5
  import { EngineService } from '../engine';
2
6
  import { Activity, ActivityType } from './activity';
3
7
  import {
4
8
  ActivityData,
5
9
  ActivityMetadata,
6
10
  InterruptActivity } from '../../types/activity';
7
- import { GetStateError, InactiveJobError } from '../../modules/errors';
8
11
  import { MultiResponseFlags } from '../../types';
9
12
  import { CollatorService } from '../collator';
10
13
  import { JobInterruptOptions, JobState } from '../../types/job';
@@ -28,25 +31,26 @@ class Interrupt extends Activity {
28
31
 
29
32
  //******** LEG 1 ENTRY ********//
30
33
  async process(): Promise<string> {
31
- this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
34
+ this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
32
35
  let telemetry: TelemetryService;
33
36
  try {
34
- this.setLeg(1);
35
- await CollatorService.notarizeEntry(this);
36
- await this.getState();
37
- CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid); // Ensure job active
37
+ await this.verifyEntry();
38
+
38
39
  telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
39
40
  telemetry.startActivitySpan(this.leg);
40
41
 
41
42
  if (this.isInterruptingSelf()) {
42
- return await this.interruptSelf(telemetry);
43
+ await this.interruptSelf(telemetry);
43
44
  } else {
44
- return await this.interruptAnother(telemetry);
45
+ await this.interruptAnother(telemetry);
45
46
  }
46
47
  } catch (error) {
47
48
  if (error instanceof InactiveJobError) {
48
49
  this.logger.error('interrupt-inactive-job-error', { error });
49
50
  return;
51
+ } else if (error instanceof GenerationalError) {
52
+ this.logger.info('process-event-generational-job-error', { error });
53
+ return;
50
54
  } else if (error instanceof GetStateError) {
51
55
  this.logger.error('interrupt-get-state-error', { error });
52
56
  return;
@@ -57,7 +61,7 @@ class Interrupt extends Activity {
57
61
  throw error;
58
62
  } finally {
59
63
  telemetry?.endActivitySpan();
60
- this.logger.debug('interrupt-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
64
+ this.logger.debug('interrupt-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
61
65
  }
62
66
  }
63
67
 
@@ -118,7 +122,6 @@ class Interrupt extends Activity {
118
122
 
119
123
  return this.context.metadata.aid;
120
124
  }
121
-
122
125
 
123
126
  isInterruptingSelf(): boolean {
124
127
  if (!this.config.target) {
@@ -1,4 +1,7 @@
1
- import { GetStateError, InactiveJobError } from '../../modules/errors';
1
+ import {
2
+ GenerationalError,
3
+ GetStateError,
4
+ InactiveJobError } from '../../modules/errors';
2
5
  import { Activity, ActivityType } from './activity';
3
6
  import { CollatorService } from '../collator';
4
7
  import { EngineService } from '../engine';
@@ -30,14 +33,11 @@ class Signal extends Activity {
30
33
 
31
34
  //******** LEG 1 ENTRY ********//
32
35
  async process(): Promise<string> {
33
- this.logger.debug('signal-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
36
+ this.logger.debug('signal-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
34
37
  let telemetry: TelemetryService;
35
38
  try {
36
- //verify entry is allowed
37
- this.setLeg(1);
38
- await CollatorService.notarizeEntry(this);
39
- await this.getState();
40
- CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
39
+ await this.verifyEntry();
40
+
41
41
  telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
42
42
  telemetry.startActivitySpan(this.leg);
43
43
 
@@ -73,6 +73,9 @@ class Signal extends Activity {
73
73
  if (error instanceof InactiveJobError) {
74
74
  this.logger.error('signal-inactive-job-error', { error });
75
75
  return;
76
+ } else if (error instanceof GenerationalError) {
77
+ this.logger.info('process-event-generational-job-error', { error });
78
+ return;
76
79
  } else if (error instanceof GetStateError) {
77
80
  this.logger.error('signal-get-state-error', { error });
78
81
  return;
@@ -83,7 +86,7 @@ class Signal extends Activity {
83
86
  throw error;
84
87
  } finally {
85
88
  telemetry?.endActivitySpan();
86
- this.logger.debug('signal-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
89
+ this.logger.debug('signal-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
87
90
  }
88
91
  }
89
92
 
@@ -35,6 +35,7 @@ class Trigger extends Activity {
35
35
  try {
36
36
  this.setLeg(2);
37
37
  await this.getState();
38
+
38
39
  telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
39
40
  telemetry.startJobSpan();
40
41
  telemetry.startActivitySpan(this.leg);
@@ -70,7 +71,7 @@ class Trigger extends Activity {
70
71
  } finally {
71
72
  telemetry?.endJobSpan();
72
73
  telemetry?.endActivitySpan();
73
- this.logger.debug('trigger-process-end', { subscribes: this.config.subscribes, jid: this.context.metadata.jid });
74
+ this.logger.debug('trigger-process-end', { subscribes: this.config.subscribes, jid: this.context.metadata.jid, gid: this.context.metadata.gid });
74
75
  }
75
76
  }
76
77
 
@@ -108,8 +109,10 @@ class Trigger extends Activity {
108
109
  this.context = {
109
110
  metadata: {
110
111
  ...this.metadata,
112
+ gid: guid(),
111
113
  ngn: this.context.metadata.ngn,
112
114
  pj: this.context.metadata.pj,
115
+ pg: this.context.metadata.pg,
113
116
  pd: this.context.metadata.pd,
114
117
  pa: this.context.metadata.pa,
115
118
  app: id,
@@ -187,6 +190,7 @@ class Trigger extends Activity {
187
190
  resolvedDepKey,
188
191
  this.context.metadata.tpc,
189
192
  this.context.metadata.jid,
193
+ this.context.metadata.gid,
190
194
  multi,
191
195
  );
192
196
  }
@@ -1,4 +1,7 @@
1
- import { GetStateError, InactiveJobError } from '../../modules/errors';
1
+ import {
2
+ GenerationalError,
3
+ GetStateError,
4
+ InactiveJobError } from '../../modules/errors';
2
5
  import { Activity } from './activity';
3
6
  import { CollatorService } from '../collator';
4
7
  import { EngineService } from '../engine';
@@ -29,14 +32,11 @@ class Worker extends Activity {
29
32
 
30
33
  //******** INITIAL ENTRY POINT (A) ********//
31
34
  async process(): Promise<string> {
32
- this.logger.debug('worker-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
35
+ this.logger.debug('worker-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
33
36
  let telemetry: TelemetryService;
34
37
  try {
35
- //confirm entry is allowed and restore state
36
- this.setLeg(1);
37
- await CollatorService.notarizeEntry(this);
38
- await this.getState();
39
- CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
38
+ await this.verifyEntry();
39
+
40
40
  telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
41
41
  telemetry.startActivitySpan(this.leg);
42
42
  this.mapInputData();
@@ -63,6 +63,9 @@ class Worker extends Activity {
63
63
  if (error instanceof InactiveJobError) {
64
64
  this.logger.error('await-inactive-job-error', { error });
65
65
  return;
66
+ } else if (error instanceof GenerationalError) {
67
+ this.logger.info('process-event-generational-job-error', { error });
68
+ return;
66
69
  } else if (error instanceof GetStateError) {
67
70
  this.logger.error('worker-get-state-error', { error });
68
71
  return;
@@ -73,7 +76,7 @@ class Worker extends Activity {
73
76
  throw error;
74
77
  } finally {
75
78
  telemetry?.endActivitySpan();
76
- this.logger.debug('worker-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
79
+ this.logger.debug('worker-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
77
80
  }
78
81
  }
79
82
 
@@ -83,6 +86,7 @@ class Worker extends Activity {
83
86
  metadata: {
84
87
  guid: guid(),
85
88
  jid: this.context.metadata.jid,
89
+ gid: this.context.metadata.gid,
86
90
  dad: this.metadata.dad,
87
91
  aid: this.metadata.aid,
88
92
  topic,
@@ -96,7 +100,7 @@ class Worker extends Activity {
96
100
  retry: this.config.retry
97
101
  };
98
102
  }
99
- return (await this.engine.streamSignaler?.publishMessage(topic, streamData, multi)) as string;
103
+ return (await this.engine.router?.publishMessage(topic, streamData, multi)) as string;
100
104
  }
101
105
  }
102
106
 
@@ -1,5 +1,5 @@
1
1
  import { Durable } from '.';
2
- import { asyncLocalStorage } from './asyncLocalStorage';
2
+ import { asyncLocalStorage } from '../../modules/storage';
3
3
  import { ClientService as Client } from './client';
4
4
  import { WorkflowHandleService } from './handle';
5
5
  import { Search } from './search';
@@ -7,7 +7,7 @@ import {
7
7
  DurableSleepForError,
8
8
  DurableTimeoutError,
9
9
  DurableWaitForSignalError} from '../../modules/errors';
10
- import { asyncLocalStorage } from './asyncLocalStorage';
10
+ import { asyncLocalStorage } from '../../modules/storage';
11
11
  import { APP_ID, APP_VERSION, getWorkflowYAML } from './factory';
12
12
  import { HotMeshService as HotMesh } from '../hotmesh';
13
13
  import {
@@ -6,7 +6,7 @@ import {
6
6
  DurableSleepForError,
7
7
  DurableWaitForSignalError } from '../../modules/errors';
8
8
  import { KeyService, KeyType } from '../../modules/key';
9
- import { asyncLocalStorage } from './asyncLocalStorage';
9
+ import { asyncLocalStorage } from '../../modules/storage';
10
10
  import { ClientService as Client } from './client';
11
11
  import { ConnectionService as Connection } from './connection';
12
12
  import { DEFAULT_COEFFICIENT } from './factory';