@hotmeshio/hotmesh 0.0.36 → 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 (67) hide show
  1. package/README.md +11 -11
  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/index.d.ts +9 -4
  29. package/build/services/store/index.js +21 -10
  30. package/build/services/task/index.d.ts +13 -4
  31. package/build/services/task/index.js +115 -17
  32. package/build/services/telemetry/index.js +6 -6
  33. package/build/services/worker/index.d.ts +3 -3
  34. package/build/services/worker/index.js +8 -8
  35. package/build/types/job.d.ts +2 -0
  36. package/build/types/stream.d.ts +1 -0
  37. package/modules/enums.ts +3 -0
  38. package/modules/errors.ts +18 -0
  39. package/modules/key.ts +21 -20
  40. package/package.json +1 -1
  41. package/services/activities/activity.ts +44 -4
  42. package/services/activities/await.ts +14 -10
  43. package/services/activities/cycle.ts +14 -10
  44. package/services/activities/hook.ts +70 -47
  45. package/services/activities/interrupt.ts +13 -10
  46. package/services/activities/signal.ts +11 -8
  47. package/services/activities/trigger.ts +5 -1
  48. package/services/activities/worker.ts +13 -9
  49. package/services/durable/meshos.ts +1 -1
  50. package/services/durable/worker.ts +1 -1
  51. package/services/durable/workflow.ts +1 -1
  52. package/services/engine/index.ts +82 -44
  53. package/services/hotmesh/index.ts +3 -3
  54. package/services/{signaler/stream.ts → router/index.ts} +5 -5
  55. package/services/serializer/index.ts +1 -1
  56. package/services/store/index.ts +23 -12
  57. package/services/task/index.ts +120 -21
  58. package/services/telemetry/index.ts +6 -6
  59. package/services/worker/index.ts +7 -7
  60. package/types/job.ts +2 -0
  61. package/types/stream.ts +6 -5
  62. package/build/services/signaler/store.d.ts +0 -15
  63. package/build/services/signaler/store.js +0 -68
  64. package/services/signaler/store.ts +0 -76
  65. /package/build/{services/durable/asyncLocalStorage.d.ts → modules/storage.d.ts} +0 -0
  66. /package/build/{services/durable/asyncLocalStorage.js → modules/storage.js} +0 -0
  67. /package/{services/durable/asyncLocalStorage.ts → modules/storage.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { KeyType } from "../../modules/key";
2
2
  import { ILogger } from "../logger";
3
- import { StreamSignaler } from "../signaler/stream";
3
+ import { Router } from "../router";
4
4
  import { StoreService } from '../store';
5
5
  import { RedisStoreService as RedisStore } from '../store/clients/redis';
6
6
  import { IORedisStoreService as IORedisStore } from '../store/clients/ioredis';
@@ -30,7 +30,7 @@ class WorkerService {
30
30
  store: StoreService<RedisClient, RedisMulti> | null;
31
31
  stream: StreamService<RedisClient, RedisMulti> | null;
32
32
  subscribe: SubService<RedisClient, RedisMulti> | null;
33
- streamSignaler: StreamSignaler | null;
33
+ router: Router | null;
34
34
  logger: ILogger;
35
35
  reporting = false;
36
36
 
@@ -66,10 +66,10 @@ class WorkerService {
66
66
  await service.subscribe.subscribe(KeyType.QUORUM, service.subscriptionHandler(), appId, service.topic);
67
67
  await service.subscribe.subscribe(KeyType.QUORUM, service.subscriptionHandler(), appId, service.guid);
68
68
  await service.initStreamChannel(service, worker.stream);
69
- service.streamSignaler = service.initStreamSignaler(worker, logger);
69
+ service.router = service.initRouter(worker, logger);
70
70
 
71
71
  const key = service.stream.mintKey(KeyType.STREAMS, { appId: service.appId, topic: worker.topic });
72
- await service.streamSignaler.consumeMessages(
72
+ await service.router.consumeMessages(
73
73
  key,
74
74
  'WORKER',
75
75
  service.guid,
@@ -130,8 +130,8 @@ class WorkerService {
130
130
  );
131
131
  }
132
132
 
133
- initStreamSignaler(worker: HotMeshWorker, logger: ILogger): StreamSignaler {
134
- return new StreamSignaler(
133
+ initRouter(worker: HotMeshWorker, logger: ILogger): Router {
134
+ return new Router(
135
135
  {
136
136
  namespace: this.namespace,
137
137
  appId: this.appId,
@@ -158,7 +158,7 @@ class WorkerService {
158
158
  }
159
159
 
160
160
  async throttle(delayInMillis: number) {
161
- this.streamSignaler.setThrottle(delayInMillis);
161
+ this.router.setThrottle(delayInMillis);
162
162
  }
163
163
  }
164
164
 
package/types/job.ts CHANGED
@@ -8,10 +8,12 @@ type ActivityData = {
8
8
 
9
9
  type JobMetadata = {
10
10
  key?: string; //job_key
11
+ gid: string; //system assigned guid; ensured created/deleted/created jobs are unique
11
12
  jid: string; //job_id (jid+dad+aid) is composite key for activity
12
13
  dad: string; //dimensional address for the activity (,0,0,1)
13
14
  aid: string; //activity_id as in the YAML file
14
15
  pj?: string; //parent_job_id (pj+pd+pa) is composite key for parent activity
16
+ pg?: string; //parent_generational_id (system assigned at trigger inception); pg is the parent job's gid (just in case user created/deleted/created a job with same jid)
15
17
  pd?: string; //parent_dimensional_address
16
18
  pa?: string; //parent_activity_id
17
19
  ngn?: string; //engine guid (one time subscriptions)
package/types/stream.ts CHANGED
@@ -35,12 +35,13 @@ export interface StreamData {
35
35
  metadata: {
36
36
  guid: string; //every message is minted with a guid to distinguish retries from new messages
37
37
  topic?: string;
38
- jid?: string; //is optonal if type is WEBHOOK
39
- dad?: string; //dimensional address
38
+ jid?: string; //is optional if type is WEBHOOK (system assigned or user assigned)
39
+ gid?: string; //is optional if type is WEBHOOK (system assigned job guid)
40
+ dad?: string; //dimensional address
40
41
  aid: string;
41
- trc?: string; //trace id
42
- spn?: string; //span id
43
- try?: number; //current try count
42
+ trc?: string; //trace id
43
+ spn?: string; //span id
44
+ try?: number; //current try count
44
45
  };
45
46
  type?: StreamDataType;
46
47
  data: Record<string, unknown>;
@@ -1,15 +0,0 @@
1
- import { ILogger } from '../logger';
2
- import { StoreService } from '../store';
3
- import { HookRule } from '../../types/hook';
4
- import { JobState } from '../../types/job';
5
- import { RedisClient, RedisMulti } from '../../types/redis';
6
- declare class StoreSignaler {
7
- store: StoreService<RedisClient, RedisMulti>;
8
- logger: ILogger;
9
- constructor(store: StoreService<RedisClient, RedisMulti>, logger: ILogger);
10
- getHookRule(topic: string): Promise<HookRule | undefined>;
11
- registerWebHook(topic: string, context: JobState, dad: string, multi?: RedisMulti): Promise<string>;
12
- processWebHookSignal(topic: string, data: Record<string, unknown>): Promise<[string, string, string] | undefined>;
13
- deleteWebHookSignal(topic: string, data: Record<string, unknown>): Promise<number>;
14
- }
15
- export { StoreSignaler };
@@ -1,68 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StoreSignaler = void 0;
4
- const pipe_1 = require("../pipe");
5
- class StoreSignaler {
6
- constructor(store, logger) {
7
- this.store = store;
8
- this.logger = logger;
9
- }
10
- async getHookRule(topic) {
11
- const rules = await this.store.getHookRules();
12
- return rules?.[topic]?.[0];
13
- }
14
- async registerWebHook(topic, context, dad, multi) {
15
- const hookRule = await this.getHookRule(topic);
16
- if (hookRule) {
17
- const mapExpression = hookRule.conditions.match[0].expected;
18
- const resolved = pipe_1.Pipe.resolve(mapExpression, context);
19
- const jobId = context.metadata.jid;
20
- const hook = {
21
- topic,
22
- resolved,
23
- //hookSignalId is composed of `<dad>::<jid>`
24
- jobId: `${dad}::${jobId}`,
25
- };
26
- await this.store.setHookSignal(hook, multi);
27
- return jobId;
28
- }
29
- else {
30
- throw new Error('signaler.registerWebHook:error: hook rule not found');
31
- }
32
- }
33
- async processWebHookSignal(topic, data) {
34
- const hookRule = await this.getHookRule(topic);
35
- if (hookRule) {
36
- //NOTE: both formats are supported: $self.hook.data OR $hook.data
37
- const context = { $self: { hook: { data } }, $hook: { data } };
38
- const mapExpression = hookRule.conditions.match[0].actual;
39
- const resolved = pipe_1.Pipe.resolve(mapExpression, context);
40
- const hookSignalId = await this.store.getHookSignal(topic, resolved);
41
- if (!hookSignalId) {
42
- //messages can be double-processed; not an issue; return undefined
43
- //users can also provide a bogus topic; not an issue; return undefined
44
- return undefined;
45
- }
46
- const [dad, jid] = hookSignalId.split('::');
47
- //return [jid, aid, dad]
48
- return [jid, hookRule.to, dad];
49
- }
50
- else {
51
- throw new Error('signal-not-found');
52
- }
53
- }
54
- async deleteWebHookSignal(topic, data) {
55
- const hookRule = await this.getHookRule(topic);
56
- if (hookRule) {
57
- //NOTE: both formats are supported: $self.hook.data OR $hook.data
58
- const context = { $self: { hook: { data } }, $hook: { data } };
59
- const mapExpression = hookRule.conditions.match[0].actual;
60
- const resolved = pipe_1.Pipe.resolve(mapExpression, context);
61
- return await this.store.deleteHookSignal(topic, resolved);
62
- }
63
- else {
64
- throw new Error('signaler.process:error: hook rule not found');
65
- }
66
- }
67
- }
68
- exports.StoreSignaler = StoreSignaler;
@@ -1,76 +0,0 @@
1
- import { ILogger } from '../logger';
2
- import { StoreService } from '../store';
3
- import { HookRule, HookSignal } from '../../types/hook';
4
- import { JobState } from '../../types/job';
5
- import { RedisClient, RedisMulti } from '../../types/redis';
6
- import { Pipe } from '../pipe';
7
-
8
- class StoreSignaler {
9
- store: StoreService<RedisClient, RedisMulti>;
10
- logger: ILogger
11
-
12
- constructor(store: StoreService<RedisClient, RedisMulti>, logger: ILogger) {
13
- this.store = store;
14
- this.logger = logger;
15
- }
16
-
17
- async getHookRule(topic: string): Promise<HookRule | undefined> {
18
- const rules = await this.store.getHookRules();
19
- return rules?.[topic]?.[0] as HookRule;
20
- }
21
-
22
- async registerWebHook(topic: string, context: JobState, dad: string, multi?: RedisMulti): Promise<string> {
23
- const hookRule = await this.getHookRule(topic);
24
- if (hookRule) {
25
- const mapExpression = hookRule.conditions.match[0].expected;
26
- const resolved = Pipe.resolve(mapExpression, context);
27
- const jobId = context.metadata.jid;
28
- const hook: HookSignal = {
29
- topic,
30
- resolved,
31
- //hookSignalId is composed of `<dad>::<jid>`
32
- jobId: `${dad}::${jobId}`,
33
- }
34
- await this.store.setHookSignal(hook, multi);
35
- return jobId;
36
- } else {
37
- throw new Error('signaler.registerWebHook:error: hook rule not found');
38
- }
39
- }
40
-
41
- async processWebHookSignal(topic: string, data: Record<string, unknown>): Promise<[string, string, string] | undefined> {
42
- const hookRule = await this.getHookRule(topic);
43
- if (hookRule) {
44
- //NOTE: both formats are supported: $self.hook.data OR $hook.data
45
- const context = { $self: { hook: { data }}, $hook: { data }};
46
- const mapExpression = hookRule.conditions.match[0].actual;
47
- const resolved = Pipe.resolve(mapExpression, context);
48
- const hookSignalId = await this.store.getHookSignal(topic, resolved);
49
- if (!hookSignalId) {
50
- //messages can be double-processed; not an issue; return undefined
51
- //users can also provide a bogus topic; not an issue; return undefined
52
- return undefined;
53
- }
54
- const [dad, jid] = hookSignalId.split('::');
55
- //return [jid, aid, dad]
56
- return [jid, hookRule.to, dad];
57
- } else {
58
- throw new Error('signal-not-found');
59
- }
60
- }
61
-
62
- async deleteWebHookSignal(topic: string, data: Record<string, unknown>): Promise<number> {
63
- const hookRule = await this.getHookRule(topic);
64
- if (hookRule) {
65
- //NOTE: both formats are supported: $self.hook.data OR $hook.data
66
- const context = { $self: { hook: { data }}, $hook: { data }};
67
- const mapExpression = hookRule.conditions.match[0].actual;
68
- const resolved = Pipe.resolve(mapExpression, context);
69
- return await this.store.deleteHookSignal(topic, resolved);
70
- } else {
71
- throw new Error('signaler.process:error: hook rule not found');
72
- }
73
- }
74
- }
75
-
76
- export { StoreSignaler };