@hotmeshio/hotmesh 0.1.15 → 0.1.17

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 (134) hide show
  1. package/README.md +623 -209
  2. package/build/index.d.ts +14 -3
  3. package/build/index.js +17 -4
  4. package/build/modules/enums.d.ts +12 -12
  5. package/build/modules/enums.js +15 -25
  6. package/build/modules/errors.d.ts +16 -16
  7. package/build/modules/errors.js +28 -28
  8. package/build/modules/key.d.ts +0 -37
  9. package/build/modules/key.js +4 -45
  10. package/build/modules/utils.d.ts +7 -15
  11. package/build/modules/utils.js +21 -44
  12. package/build/package.json +18 -15
  13. package/build/services/activities/activity.d.ts +0 -31
  14. package/build/services/activities/activity.js +1 -50
  15. package/build/services/activities/await.js +0 -4
  16. package/build/services/activities/cycle.d.ts +0 -7
  17. package/build/services/activities/cycle.js +1 -16
  18. package/build/services/activities/hook.d.ts +0 -6
  19. package/build/services/activities/hook.js +2 -12
  20. package/build/services/activities/interrupt.js +0 -8
  21. package/build/services/activities/signal.d.ts +0 -6
  22. package/build/services/activities/signal.js +0 -15
  23. package/build/services/activities/trigger.d.ts +4 -5
  24. package/build/services/activities/trigger.js +22 -16
  25. package/build/services/activities/worker.js +0 -4
  26. package/build/services/collator/index.d.ts +0 -70
  27. package/build/services/collator/index.js +1 -91
  28. package/build/services/compiler/deployer.js +6 -38
  29. package/build/services/compiler/index.d.ts +0 -15
  30. package/build/services/compiler/index.js +0 -20
  31. package/build/services/compiler/validator.d.ts +0 -3
  32. package/build/services/compiler/validator.js +0 -25
  33. package/build/services/connector/clients/ioredis.js +0 -2
  34. package/build/services/connector/clients/redis.js +0 -2
  35. package/build/services/connector/index.js +0 -2
  36. package/build/services/engine/index.d.ts +1 -10
  37. package/build/services/engine/index.js +1 -48
  38. package/build/services/exporter/index.d.ts +0 -27
  39. package/build/services/exporter/index.js +0 -33
  40. package/build/services/hotmesh/index.d.ts +8 -4
  41. package/build/services/hotmesh/index.js +20 -19
  42. package/build/services/logger/index.js +0 -2
  43. package/build/services/mapper/index.d.ts +0 -14
  44. package/build/services/mapper/index.js +0 -14
  45. package/build/services/meshcall/index.d.ts +21 -0
  46. package/build/services/meshcall/index.js +202 -0
  47. package/build/services/meshcall/schemas/factory.d.ts +2 -0
  48. package/build/services/meshcall/schemas/factory.js +179 -0
  49. package/build/services/meshdata/index.d.ts +75 -0
  50. package/build/services/meshdata/index.js +541 -0
  51. package/build/services/meshflow/client.d.ts +18 -0
  52. package/build/services/{durable → meshflow}/client.js +9 -40
  53. package/build/services/{durable → meshflow}/connection.d.ts +2 -1
  54. package/build/services/{durable → meshflow}/connection.js +1 -0
  55. package/build/services/meshflow/exporter.d.ts +29 -0
  56. package/build/services/{durable → meshflow}/exporter.js +0 -29
  57. package/build/services/meshflow/handle.d.ts +22 -0
  58. package/build/services/{durable → meshflow}/handle.js +0 -46
  59. package/build/services/meshflow/index.d.ts +17 -0
  60. package/build/services/meshflow/index.js +23 -0
  61. package/build/services/meshflow/schemas/factory.d.ts +4 -0
  62. package/build/services/{durable → meshflow}/schemas/factory.js +2 -30
  63. package/build/services/meshflow/search.d.ts +23 -0
  64. package/build/services/{durable → meshflow}/search.js +0 -99
  65. package/build/services/{durable → meshflow}/worker.d.ts +3 -2
  66. package/build/services/{durable → meshflow}/worker.js +23 -39
  67. package/build/services/meshflow/workflow.d.ts +27 -0
  68. package/build/services/{durable → meshflow}/workflow.js +27 -169
  69. package/build/services/pipe/functions/date.d.ts +0 -7
  70. package/build/services/pipe/functions/date.js +0 -7
  71. package/build/services/pipe/functions/math.js +0 -2
  72. package/build/services/pipe/index.d.ts +0 -15
  73. package/build/services/pipe/index.js +2 -23
  74. package/build/services/quorum/index.d.ts +1 -7
  75. package/build/services/quorum/index.js +0 -21
  76. package/build/services/reporter/index.d.ts +0 -5
  77. package/build/services/reporter/index.js +0 -9
  78. package/build/services/router/index.d.ts +0 -9
  79. package/build/services/router/index.js +2 -30
  80. package/build/services/serializer/index.js +6 -23
  81. package/build/services/store/cache.d.ts +0 -19
  82. package/build/services/store/cache.js +0 -19
  83. package/build/services/store/clients/ioredis.d.ts +0 -6
  84. package/build/services/store/clients/ioredis.js +0 -7
  85. package/build/services/store/clients/redis.d.ts +0 -6
  86. package/build/services/store/clients/redis.js +0 -6
  87. package/build/services/store/index.d.ts +0 -55
  88. package/build/services/store/index.js +14 -87
  89. package/build/services/stream/clients/ioredis.js +1 -4
  90. package/build/services/task/index.d.ts +0 -9
  91. package/build/services/task/index.js +0 -31
  92. package/build/services/telemetry/index.d.ts +0 -7
  93. package/build/services/telemetry/index.js +1 -13
  94. package/build/services/worker/index.d.ts +1 -4
  95. package/build/services/worker/index.js +0 -6
  96. package/build/types/activity.d.ts +0 -81
  97. package/build/types/error.d.ts +5 -5
  98. package/build/types/exporter.d.ts +1 -14
  99. package/build/types/hotmesh.d.ts +4 -12
  100. package/build/types/hotmesh.js +0 -3
  101. package/build/types/index.d.ts +5 -3
  102. package/build/types/index.js +1 -1
  103. package/build/types/job.d.ts +1 -95
  104. package/build/types/meshcall.d.ts +54 -0
  105. package/build/types/meshdata.d.ts +59 -0
  106. package/build/types/meshdata.js +2 -0
  107. package/build/types/meshflow.d.ts +202 -0
  108. package/build/types/meshflow.js +2 -0
  109. package/build/types/pipe.d.ts +0 -65
  110. package/build/types/quorum.d.ts +0 -12
  111. package/build/types/redis.d.ts +0 -6
  112. package/build/types/stream.d.ts +0 -59
  113. package/build/types/stream.js +0 -4
  114. package/index.ts +12 -3
  115. package/package.json +18 -15
  116. package/typedoc.json +38 -0
  117. package/types/error.ts +5 -5
  118. package/types/exporter.ts +1 -1
  119. package/types/hotmesh.ts +3 -2
  120. package/types/index.ts +25 -7
  121. package/types/job.ts +19 -1
  122. package/types/meshcall.ts +192 -0
  123. package/types/meshdata.ts +273 -0
  124. package/types/{durable.ts → meshflow.ts} +33 -9
  125. package/build/services/durable/client.d.ts +0 -49
  126. package/build/services/durable/exporter.d.ts +0 -51
  127. package/build/services/durable/handle.d.ts +0 -58
  128. package/build/services/durable/index.d.ts +0 -19
  129. package/build/services/durable/index.js +0 -25
  130. package/build/services/durable/schemas/factory.d.ts +0 -33
  131. package/build/services/durable/search.d.ts +0 -120
  132. package/build/services/durable/workflow.d.ts +0 -143
  133. package/build/types/durable.d.ts +0 -467
  134. /package/build/types/{durable.js → meshcall.js} +0 -0
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.restoreHierarchy = exports.getValueByPath = exports.getIndexedHash = exports.getSymVal = exports.getSymKey = exports.formatISODate = exports.getTimeSeries = exports.getSubscriptionTopic = exports.findSubscriptionForTrigger = exports.findTopKey = exports.XSleepFor = exports.matchesStatus = exports.matchesStatusCode = exports.identifyRedisTypeFromClass = exports.polyfill = exports.identifyRedisType = exports.deterministicRandom = exports.guid = exports.deepCopy = exports.sleepImmediate = exports.sleepFor = exports.getSystemHealth = exports.hashOptions = void 0;
6
+ exports.restoreHierarchy = exports.getValueByPath = exports.getIndexedHash = exports.getSymVal = exports.getSymKey = exports.formatISODate = exports.getTimeSeries = exports.getSubscriptionTopic = exports.findSubscriptionForTrigger = exports.findTopKey = exports.matchesStatus = exports.matchesStatusCode = exports.identifyRedisTypeFromClass = exports.polyfill = exports.identifyRedisType = exports.XSleepFor = exports.sleepImmediate = exports.sleepFor = exports.guid = exports.deterministicRandom = exports.deepCopy = exports.getSystemHealth = exports.hashOptions = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const crypto_1 = require("crypto");
9
9
  const nanoid_1 = require("nanoid");
@@ -26,18 +26,6 @@ async function getSystemHealth() {
26
26
  const totalMemory = os_1.default.totalmem();
27
27
  const freeMemory = os_1.default.freemem();
28
28
  const usedMemory = totalMemory - freeMemory;
29
- //NOTE: enable the following if desired; for now, only
30
- // `memory` is emitted when system health is requested
31
- //const cpus = os.cpus();
32
- // CPU load calculation remains unchanged
33
- // const cpuLoad = cpus.map((cpu, i) => {
34
- // const total = Object.values(cpu.times).reduce((acc, tv) => acc + tv, 0);
35
- // const idle = cpu.times.idle;
36
- // const usage = ((total - idle) / total) * 100;
37
- // return { [`CPU ${i} Usage`]: `${usage.toFixed(2)}%` };
38
- // });
39
- // Wrap each systeminformation call with safeExecute (systeminformation npm package)
40
- //const networkStats = await safeExecute(si.networkStats(), []);
41
29
  const systemHealth = {
42
30
  TotalMemoryGB: `${(totalMemory / 1024 / 1024 / 1024).toFixed(2)} GB`,
43
31
  FreeMemoryGB: `${(freeMemory / 1024 / 1024 / 1024).toFixed(2)} GB`,
@@ -48,27 +36,35 @@ async function getSystemHealth() {
48
36
  return systemHealth;
49
37
  }
50
38
  exports.getSystemHealth = getSystemHealth;
51
- async function sleepFor(ms) {
52
- return new Promise((resolve) => setTimeout(resolve, ms));
53
- }
54
- exports.sleepFor = sleepFor;
55
- function sleepImmediate() {
56
- return new Promise((resolve) => setImmediate(resolve));
57
- }
58
- exports.sleepImmediate = sleepImmediate;
59
39
  function deepCopy(obj) {
60
40
  return JSON.parse(JSON.stringify(obj));
61
41
  }
62
42
  exports.deepCopy = deepCopy;
63
- function guid(size = enums_1.HMSH_GUID_SIZE) {
64
- return `H` + (0, nanoid_1.nanoid)(size);
65
- }
66
- exports.guid = guid;
67
43
  function deterministicRandom(seed) {
68
44
  const x = Math.sin(seed) * 10000;
69
45
  return x - Math.floor(x);
70
46
  }
71
47
  exports.deterministicRandom = deterministicRandom;
48
+ function guid(size = enums_1.HMSH_GUID_SIZE) {
49
+ return `H` + (0, nanoid_1.nanoid)(size);
50
+ }
51
+ exports.guid = guid;
52
+ async function sleepFor(ms) {
53
+ return new Promise((resolve) => setTimeout(resolve, ms));
54
+ }
55
+ exports.sleepFor = sleepFor;
56
+ function sleepImmediate() {
57
+ return new Promise((resolve) => setImmediate(resolve));
58
+ }
59
+ exports.sleepImmediate = sleepImmediate;
60
+ function XSleepFor(ms) {
61
+ let timerId;
62
+ const promise = new Promise((resolve) => {
63
+ timerId = setTimeout(resolve, ms);
64
+ });
65
+ return { promise, timerId };
66
+ }
67
+ exports.XSleepFor = XSleepFor;
72
68
  function identifyRedisType(redisInstance) {
73
69
  const prototype = Object.getPrototypeOf(redisInstance);
74
70
  if ('defineCommand' in prototype ||
@@ -95,7 +91,6 @@ function identifyRedisType(redisInstance) {
95
91
  return null;
96
92
  }
97
93
  exports.identifyRedisType = identifyRedisType;
98
- //todo: the polyfill methods will all be deleted in the `beta` release.
99
94
  exports.polyfill = {
100
95
  resolveActivityType(activityType) {
101
96
  if (activityType === 'activity') {
@@ -117,7 +112,6 @@ function identifyRedisTypeFromClass(redisClass) {
117
112
  exports.identifyRedisTypeFromClass = identifyRedisTypeFromClass;
118
113
  function matchesStatusCode(code, pattern) {
119
114
  if (typeof pattern === 'string') {
120
- // Convert '*' wildcard to its regex equivalent (\d)
121
115
  const regexPattern = `^${pattern.replace(/\*/g, '\\d')}$`;
122
116
  return new RegExp(regexPattern).test(code.toString());
123
117
  }
@@ -128,15 +122,6 @@ function matchesStatus(status, targetStatus) {
128
122
  return status === targetStatus;
129
123
  }
130
124
  exports.matchesStatus = matchesStatus;
131
- function XSleepFor(ms) {
132
- //can be interrupted with `clearTimeout`
133
- let timerId;
134
- const promise = new Promise((resolve) => {
135
- timerId = setTimeout(resolve, ms);
136
- });
137
- return { promise, timerId };
138
- }
139
- exports.XSleepFor = XSleepFor;
140
125
  function findTopKey(obj, input) {
141
126
  for (const [key, value] of Object.entries(obj)) {
142
127
  if (value.hasOwnProperty(input)) {
@@ -156,10 +141,6 @@ function findSubscriptionForTrigger(obj, value) {
156
141
  return null;
157
142
  }
158
143
  exports.findSubscriptionForTrigger = findSubscriptionForTrigger;
159
- /**
160
- * Get the subscription topic for the flow to which @activityId belongs.
161
- * TODO: resolve this value in the compiler...do not call this at runtime
162
- */
163
144
  async function getSubscriptionTopic(activityId, store, appVID) {
164
145
  const appTransitions = await store.getTransitions(appVID);
165
146
  const appSubscriptions = await store.getSubscriptions(appVID);
@@ -168,10 +149,6 @@ async function getSubscriptionTopic(activityId, store, appVID) {
168
149
  return topic;
169
150
  }
170
151
  exports.getSubscriptionTopic = getSubscriptionTopic;
171
- /**
172
- * returns the 12-digit format of the iso timestamp (e.g, 202101010000); returns
173
- * an empty string if overridden by the user to not segment by time (infinity).
174
- */
175
152
  function getTimeSeries(granularity) {
176
153
  if (granularity.toString() === 'infinity') {
177
154
  return '0';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotmeshio/hotmesh",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Unbreakable Workflows",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -26,20 +26,20 @@
26
26
  "test:connect:ioredis": "NODE_ENV=test jest ./tests/unit/services/connector/clients/ioredis.test.ts --detectOpenHandles --forceExit --verbose",
27
27
  "test:connect:redis": "NODE_ENV=test jest ./tests/unit/services/connector/clients/redis.test.ts --detectOpenHandles --forceExit --verbose",
28
28
  "test:cycle": "NODE_ENV=test jest ./tests/functional/cycle/index.test.ts --detectOpenHandles --forceExit --verbose",
29
- "test:durable": "NODE_ENV=test jest ./tests/durable/*/index.test.ts --detectOpenHandles --forceExit --verbose",
30
- "test:durable:basic": "NODE_ENV=test jest ./tests/durable/basic/index.test.ts --detectOpenHandles --forceExit --verbose",
31
- "test:durable:collision": "NODE_ENV=test jest ./tests/durable/collision/index.test.ts --detectOpenHandles --forceExit --verbose",
32
- "test:durable:fatal": "NODE_ENV=test jest ./tests/durable/fatal/index.test.ts --detectOpenHandles --forceExit --verbose",
33
- "test:durable:goodbye": "NODE_ENV=test jest ./tests/durable/goodbye/index.test.ts --detectOpenHandles --forceExit --verbose",
34
- "test:durable:hello": "HMSH_IS_CLUSTER=true NODE_ENV=test jest ./tests/durable/helloworld/index.test.ts --detectOpenHandles --forceExit --verbose",
35
- "test:durable:hook": "NODE_ENV=test jest ./tests/durable/hook/index.test.ts --detectOpenHandles --forceExit --verbose",
36
- "test:durable:interrupt": "NODE_ENV=test jest ./tests/durable/interrupt/index.test.ts --detectOpenHandles --forceExit --verbose",
37
- "test:durable:loopactivity": "NODE_ENV=test jest ./tests/durable/loopactivity/index.test.ts --detectOpenHandles --forceExit --verbose",
38
- "test:durable:nested": "NODE_ENV=test jest ./tests/durable/nested/index.test.ts --detectOpenHandles --forceExit --verbose",
39
- "test:durable:retry": "NODE_ENV=test jest ./tests/durable/retry/index.test.ts --detectOpenHandles --forceExit --verbose",
40
- "test:durable:sleep": "NODE_ENV=test jest ./tests/durable/sleep/index.test.ts --detectOpenHandles --forceExit --verbose",
41
- "test:durable:signal": "NODE_ENV=test jest ./tests/durable/signal/index.test.ts --detectOpenHandles --forceExit --verbose",
42
- "test:durable:unknown": "NODE_ENV=test jest ./tests/durable/unknown/index.test.ts --detectOpenHandles --forceExit --verbose",
29
+ "test:meshflow": "NODE_ENV=test jest ./tests/meshflow/*/index.test.ts --detectOpenHandles --forceExit --verbose",
30
+ "test:meshflow:basic": "NODE_ENV=test jest ./tests/meshflow/basic/index.test.ts --detectOpenHandles --forceExit --verbose",
31
+ "test:meshflow:collision": "NODE_ENV=test jest ./tests/meshflow/collision/index.test.ts --detectOpenHandles --forceExit --verbose",
32
+ "test:meshflow:fatal": "NODE_ENV=test jest ./tests/meshflow/fatal/index.test.ts --detectOpenHandles --forceExit --verbose",
33
+ "test:meshflow:goodbye": "NODE_ENV=test jest ./tests/meshflow/goodbye/index.test.ts --detectOpenHandles --forceExit --verbose",
34
+ "test:meshflow:hello": "HMSH_IS_CLUSTER=true NODE_ENV=test jest ./tests/meshflow/helloworld/index.test.ts --detectOpenHandles --forceExit --verbose",
35
+ "test:meshflow:hook": "NODE_ENV=test jest ./tests/meshflow/hook/index.test.ts --detectOpenHandles --forceExit --verbose",
36
+ "test:meshflow:interrupt": "NODE_ENV=test jest ./tests/meshflow/interrupt/index.test.ts --detectOpenHandles --forceExit --verbose",
37
+ "test:meshflow:loopactivity": "NODE_ENV=test jest ./tests/meshflow/loopactivity/index.test.ts --detectOpenHandles --forceExit --verbose",
38
+ "test:meshflow:nested": "NODE_ENV=test jest ./tests/meshflow/nested/index.test.ts --detectOpenHandles --forceExit --verbose",
39
+ "test:meshflow:retry": "NODE_ENV=test jest ./tests/meshflow/retry/index.test.ts --detectOpenHandles --forceExit --verbose",
40
+ "test:meshflow:sleep": "NODE_ENV=test jest ./tests/meshflow/sleep/index.test.ts --detectOpenHandles --forceExit --verbose",
41
+ "test:meshflow:signal": "NODE_ENV=test jest ./tests/meshflow/signal/index.test.ts --detectOpenHandles --forceExit --verbose",
42
+ "test:meshflow:unknown": "NODE_ENV=test jest ./tests/meshflow/unknown/index.test.ts --detectOpenHandles --forceExit --verbose",
43
43
  "test:emit": "NODE_ENV=test jest ./tests/functional/emit/index.test.ts --detectOpenHandles --forceExit --verbose",
44
44
  "test:pending": "NODE_ENV=test jest ./tests/functional/pending/index.test.ts --detectOpenHandles --forceExit --verbose",
45
45
  "test:functional": "NODE_ENV=test jest ./tests/functional/*/index.test.ts --detectOpenHandles --forceExit --verbose",
@@ -63,6 +63,8 @@
63
63
  "test:sub:ioredis": "NODE_ENV=test jest ./tests/functional/sub/clients/ioredis.test.ts --detectOpenHandles --forceExit --verbose",
64
64
  "test:sub:redis": "NODE_ENV=test jest ./tests/functional/sub/clients/redis.test.ts --detectOpenHandles --forceExit --verbose",
65
65
  "test:trigger": "NODE_ENV=test jest ./tests/unit/services/activities/trigger.test.ts --detectOpenHandles --forceExit --verbose",
66
+ "test:meshdata": "NODE_ENV=test HMSH_IS_CLUSTER=true jest ./tests/meshdata/index.test.ts --forceExit --verbose --detectOpenHandles",
67
+ "test:meshcall": "NODE_ENV=test HMSH_LOGLEVEL=debug jest ./tests/meshcall/index.test.ts --forceExit --verbose --detectOpenHandles",
66
68
  "test:unit": "NODE_ENV=test jest ./tests/unit/*/*/index.test.ts --detectOpenHandles --forceExit --verbose"
67
69
  },
68
70
  "keywords": [
@@ -102,6 +104,7 @@
102
104
  "ts-jest": "^29.0.5",
103
105
  "ts-node": "^10.9.1",
104
106
  "ts-node-dev": "^2.0.0",
107
+ "typedoc": "^0.26.4",
105
108
  "typescript": "^5.0.4"
106
109
  },
107
110
  "peerDependencies": {
@@ -7,9 +7,6 @@ import { JobState, JobStatus } from '../../types/job';
7
7
  import { MultiResponseFlags, RedisClient, RedisMulti } from '../../types/redis';
8
8
  import { StringAnyType } from '../../types/serializer';
9
9
  import { StreamCode, StreamData, StreamStatus } from '../../types/stream';
10
- /**
11
- * The base class for all activities
12
- */
13
10
  declare class Activity {
14
11
  config: ActivityType;
15
12
  data: ActivityData;
@@ -26,19 +23,8 @@ declare class Activity {
26
23
  adjacentIndex: number;
27
24
  constructor(config: ActivityType, data: ActivityData, metadata: ActivityMetadata, hook: ActivityData | null, engine: EngineService, context?: JobState);
28
25
  setLeg(leg: ActivityLeg): void;
29
- /**
30
- * A job is assumed to be complete when its status (a semaphore)
31
- * reaches `0`. A different threshold can be set in the
32
- * activity YAML, in support of Dynamic Activation Control.
33
- */
34
26
  mapStatusThreshold(): number;
35
- /**
36
- * Upon entering leg 1 of a duplexed activity
37
- */
38
27
  verifyEntry(): Promise<void>;
39
- /**
40
- * Upon entering leg 2 of a duplexed activity
41
- */
42
28
  verifyReentry(): Promise<number>;
43
29
  processEvent(status?: StreamStatus, code?: StreamCode, type?: 'hook' | 'output'): Promise<void>;
44
30
  processPending(type: 'hook' | 'output'): Promise<MultiResponseFlags>;
@@ -50,14 +36,7 @@ declare class Activity {
50
36
  mapInputData(): void;
51
37
  mapOutputData(): void;
52
38
  registerTimeout(): Promise<void>;
53
- /**
54
- * Any StreamMessage with a status of ERROR is bound to the activity
55
- */
56
39
  bindActivityError(data: Record<string, unknown>): void;
57
- /**
58
- * unhandled activity errors (activities that return an ERROR StreamMessage
59
- * status and have no adjacent children to transition to) are bound to the job
60
- */
61
40
  bindJobError(data: Record<string, unknown>): void;
62
41
  getTriggerConfig(): Promise<ActivityType>;
63
42
  getJobStatus(): null | number;
@@ -72,12 +51,6 @@ declare class Activity {
72
51
  bindJobMetadataPaths(): string[];
73
52
  bindActivityMetadataPaths(): string[];
74
53
  getState(): Promise<void>;
75
- /**
76
- * if the job is created/deleted/created with the same key,
77
- * the 'gid' ensures no stale messages (such as sleep delays)
78
- * enter the workstream. Any message with a mismatched gid
79
- * belongs to a prior job and can safely be ignored/dropped.
80
- */
81
54
  assertGenerationalId(jobGID: string, msgGID?: string): void;
82
55
  initDimensionalAddress(dad: string): void;
83
56
  initSelf(context: StringAnyType): JobState;
@@ -87,10 +60,6 @@ declare class Activity {
87
60
  resolveAdjacentDad(): string;
88
61
  filterAdjacent(): Promise<StreamData[]>;
89
62
  transition(adjacencyList: StreamData[], jobStatus: JobStatus): Promise<string[]>;
90
- /**
91
- * A job with a vale < -100_000_000 is considered interrupted,
92
- * as the interruption event decrements the job status by 1billion.
93
- */
94
63
  jobWasInterrupted(jobStatus: JobStatus): boolean;
95
64
  }
96
65
  export { Activity, ActivityType };
@@ -10,9 +10,6 @@ const pipe_1 = require("../pipe");
10
10
  const serializer_1 = require("../serializer");
11
11
  const telemetry_1 = require("../telemetry");
12
12
  const stream_1 = require("../../types/stream");
13
- /**
14
- * The base class for all activities
15
- */
16
13
  class Activity {
17
14
  constructor(config, data, metadata, hook, engine, context) {
18
15
  this.status = stream_1.StreamStatus.SUCCESS;
@@ -30,11 +27,6 @@ class Activity {
30
27
  setLeg(leg) {
31
28
  this.leg = leg;
32
29
  }
33
- /**
34
- * A job is assumed to be complete when its status (a semaphore)
35
- * reaches `0`. A different threshold can be set in the
36
- * activity YAML, in support of Dynamic Activation Control.
37
- */
38
30
  mapStatusThreshold() {
39
31
  if (this.config.statusThreshold !== undefined) {
40
32
  const threshold = pipe_1.Pipe.resolve(this.config.statusThreshold, this.context);
@@ -44,9 +36,6 @@ class Activity {
44
36
  }
45
37
  return 0;
46
38
  }
47
- /**
48
- * Upon entering leg 1 of a duplexed activity
49
- */
50
39
  async verifyEntry() {
51
40
  this.setLeg(1);
52
41
  await this.getState();
@@ -57,7 +46,6 @@ class Activity {
57
46
  catch (error) {
58
47
  if (threshold > 0) {
59
48
  if (this.context.metadata.js === threshold) {
60
- //conclude job EXACTLY ONCE
61
49
  const status = await this.setStatus(-threshold);
62
50
  if (Number(status) === 0) {
63
51
  await this.engine.runJobCompletionTasks(this.context);
@@ -70,9 +58,6 @@ class Activity {
70
58
  }
71
59
  await collator_1.CollatorService.notarizeEntry(this);
72
60
  }
73
- /**
74
- * Upon entering leg 2 of a duplexed activity
75
- */
76
61
  async verifyReentry() {
77
62
  const guid = this.context.metadata.guid;
78
63
  this.setLeg(2);
@@ -80,7 +65,6 @@ class Activity {
80
65
  collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
81
66
  return await collator_1.CollatorService.notarizeReentry(this, guid);
82
67
  }
83
- //******** DUPLEX RE-ENTRY POINT ********//
84
68
  async processEvent(status = stream_1.StreamStatus.SUCCESS, code = 200, type = 'output') {
85
69
  this.setLeg(2);
86
70
  const jid = this.context.metadata.jid;
@@ -186,7 +170,6 @@ class Activity {
186
170
  telemetry.mapActivityAttributes();
187
171
  const jobStatus = this.resolveStatus(multiResponse);
188
172
  const attrs = { 'app.job.jss': jobStatus };
189
- //adjacencyList membership has already been set at this point (according to activity status)
190
173
  const messageIds = await this.transition(this.adjacencyList, jobStatus);
191
174
  if (messageIds?.length) {
192
175
  attrs['app.activity.mids'] = messageIds.join(',');
@@ -209,10 +192,6 @@ class Activity {
209
192
  if (output) {
210
193
  for (const key in output) {
211
194
  const f1 = key.indexOf('[');
212
- //keys with array notation suffix `somekey[]` represent
213
- //dynamically-keyed mappings whose `value` must be moved to the output.
214
- //The `value` must be an object with keys appropriate to the
215
- //notation type: `somekey[0] (array)`, `somekey[-] (mark)`, OR `somekey[_] (search)`
216
195
  if (f1 > -1) {
217
196
  const amount = key.substring(f1 + 1).split(']')[0];
218
197
  if (!isNaN(Number(amount))) {
@@ -239,7 +218,6 @@ class Activity {
239
218
  }
240
219
  }
241
220
  mapOutputData() {
242
- //activity YAML may include output map data that produces/extends activity output data.
243
221
  if (this.config.output?.maps) {
244
222
  const mapper = new mapper_1.MapperService((0, utils_1.deepCopy)(this.config.output.maps), this.context);
245
223
  const actOutData = mapper.mapRules();
@@ -249,21 +227,12 @@ class Activity {
249
227
  }
250
228
  }
251
229
  async registerTimeout() {
252
- //set timeout in support of hook and/or duplex
253
230
  }
254
- /**
255
- * Any StreamMessage with a status of ERROR is bound to the activity
256
- */
257
231
  bindActivityError(data) {
258
232
  const md = this.context[this.metadata.aid].output.metadata;
259
233
  md.err = JSON.stringify(this.data);
260
- //(temporary...useful for mapping error parts in the app.yaml)
261
234
  md.$error = { ...data, is_stream_error: true };
262
235
  }
263
- /**
264
- * unhandled activity errors (activities that return an ERROR StreamMessage
265
- * status and have no adjacent children to transition to) are bound to the job
266
- */
267
236
  bindJobError(data) {
268
237
  this.context.metadata.err = JSON.stringify({
269
238
  ...data,
@@ -281,7 +250,6 @@ class Activity {
281
250
  return await this.store.setStatus(amount, this.context.metadata.jid, appId, multi);
282
251
  }
283
252
  authorizeEntry(state) {
284
- //pre-authorize activity state to allow entry for adjacent activities
285
253
  return (this.adjacencyList?.map((streamData) => {
286
254
  const { metadata: { aid }, } = streamData;
287
255
  state[`${aid}/output/metadata/as`] = collator_1.CollatorService.getSeed();
@@ -301,7 +269,6 @@ class Activity {
301
269
  const presets = this.authorizeEntry(state);
302
270
  this.bindDimensionalAddress(state);
303
271
  this.bindActivityState(state);
304
- //symbolNames holds symkeys
305
272
  const symbolNames = [
306
273
  `$${this.config.subscribes}`,
307
274
  this.metadata.aid,
@@ -311,7 +278,6 @@ class Activity {
311
278
  return await this.store.setState(state, this.getJobStatus(), jobId, symbolNames, dIds, multi);
312
279
  }
313
280
  bindJobMetadata() {
314
- //both legs of the most recently run activity (1 and 2) modify ju (job_updated)
315
281
  this.context.metadata.ju = (0, utils_1.formatISODate)(new Date());
316
282
  }
317
283
  bindActivityMetadata() {
@@ -398,7 +364,6 @@ class Activity {
398
364
  telemetry_1.TelemetryService.addTargetTelemetryPaths(consumes, this.config, this.metadata, this.leg);
399
365
  const { dad, jid } = this.context.metadata;
400
366
  const dIds = collator_1.CollatorService.getDimensionsById([...this.config.ancestors, this.metadata.aid], dad || '');
401
- //`state` is a unidimensional hash; context is a tree
402
367
  const [state, _status] = await this.store.getState(jid, consumes, dIds);
403
368
  this.context = (0, utils_1.restoreHierarchy)(state);
404
369
  this.assertGenerationalId(this.context?.metadata?.gid, gid);
@@ -406,12 +371,6 @@ class Activity {
406
371
  this.initSelf(this.context);
407
372
  this.initPolicies(this.context);
408
373
  }
409
- /**
410
- * if the job is created/deleted/created with the same key,
411
- * the 'gid' ensures no stale messages (such as sleep delays)
412
- * enter the workstream. Any message with a mismatched gid
413
- * belongs to a prior job and can safely be ignored/dropped.
414
- */
415
374
  assertGenerationalId(jobGID, msgGID) {
416
375
  if (msgGID !== jobGID) {
417
376
  throw new errors_1.GenerationalError(jobGID, msgGID, this.context?.metadata?.jid ?? '', this.context?.metadata?.aid ?? '', this.context?.metadata?.dad ?? '');
@@ -438,10 +397,9 @@ class Activity {
438
397
  if (!self.output.metadata) {
439
398
  self.output.metadata = {};
440
399
  }
441
- //prebind the updated timestamp (mappings need the time)
442
400
  self.output.metadata.au = (0, utils_1.formatISODate)(new Date());
443
401
  context['$self'] = self;
444
- context['$job'] = context; //NEVER call STRINGIFY! (now circular)
402
+ context['$job'] = context;
445
403
  return context;
446
404
  }
447
405
  initPolicies(context) {
@@ -454,20 +412,17 @@ class Activity {
454
412
  resolveDad() {
455
413
  let dad = this.metadata.dad;
456
414
  if (this.adjacentIndex > 0) {
457
- //if adjacent index > 0 the activity is cycling; replace last index with cycle index
458
415
  dad = `${dad.substring(0, dad.lastIndexOf(','))},${this.adjacentIndex}`;
459
416
  }
460
417
  return dad;
461
418
  }
462
419
  resolveAdjacentDad() {
463
- //concat self and child dimension (all children (leg 1) begin life at 0)
464
420
  return `${this.resolveDad()}${collator_1.CollatorService.getDimensionalSeed(0)}`;
465
421
  }
466
422
  async filterAdjacent() {
467
423
  const adjacencyList = [];
468
424
  const transitions = await this.store.getTransitions(await this.engine.getVID());
469
425
  const transition = transitions[`.${this.metadata.aid}`];
470
- //resolve the dimensional address for adjacent children
471
426
  const adjacentDad = this.resolveAdjacentDad();
472
427
  if (transition) {
473
428
  for (const toActivityId in transition) {
@@ -514,10 +469,6 @@ class Activity {
514
469
  }
515
470
  return mIds;
516
471
  }
517
- /**
518
- * A job with a vale < -100_000_000 is considered interrupted,
519
- * as the interruption event decrements the job status by 1billion.
520
- */
521
472
  jobWasInterrupted(jobStatus) {
522
473
  return jobStatus < -100000000;
523
474
  }
@@ -12,7 +12,6 @@ class Await extends activity_1.Activity {
12
12
  constructor(config, data, metadata, hook, engine, context) {
13
13
  super(config, data, metadata, hook, engine, context);
14
14
  }
15
- //******** INITIAL ENTRY POINT (A) ********//
16
15
  async process() {
17
16
  this.logger.debug('await-process', {
18
17
  jid: this.context.metadata.jid,
@@ -25,15 +24,12 @@ class Await extends activity_1.Activity {
25
24
  telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
26
25
  telemetry.startActivitySpan(this.leg);
27
26
  this.mapInputData();
28
- //save state and authorize reentry
29
27
  const multi = this.store.getMulti();
30
- //todo: await this.registerTimeout();
31
28
  const messageId = await this.execActivity(multi);
32
29
  await collator_1.CollatorService.authorizeReentry(this, multi);
33
30
  await this.setState(multi);
34
31
  await this.setStatus(0, multi);
35
32
  const multiResponse = (await multi.exec());
36
- //telemetry
37
33
  telemetry.mapActivityAttributes();
38
34
  const jobStatus = this.resolveStatus(multiResponse);
39
35
  telemetry.setActivityAttributes({
@@ -7,13 +7,6 @@ declare class Cycle extends Activity {
7
7
  config: CycleActivity;
8
8
  constructor(config: ActivityType, data: ActivityData, metadata: ActivityMetadata, hook: ActivityData | null, engine: EngineService, context?: JobState);
9
9
  process(): Promise<string>;
10
- /**
11
- * Trigger the target ancestor to execute in a cycle,
12
- * without violating the constraints of the DAG. Immutable
13
- * `individual activity state` will execute in a new dimensional
14
- * thread while `shared job state` can change. This
15
- * pattern allows for retries without violating the DAG.
16
- */
17
10
  cycleAncestorActivity(multi: RedisMulti): Promise<string>;
18
11
  }
19
12
  export { Cycle };
@@ -10,7 +10,6 @@ class Cycle extends activity_1.Activity {
10
10
  constructor(config, data, metadata, hook, engine, context) {
11
11
  super(config, data, metadata, hook, engine, context);
12
12
  }
13
- //******** LEG 1 ENTRY ********//
14
13
  async process() {
15
14
  this.logger.debug('cycle-process', {
16
15
  jid: this.context.metadata.jid,
@@ -23,21 +22,18 @@ class Cycle extends activity_1.Activity {
23
22
  telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
24
23
  telemetry.startActivitySpan(this.leg);
25
24
  this.mapInputData();
26
- //set state/status
27
25
  let multi = this.store.getMulti();
28
26
  await this.setState(multi);
29
- await this.setStatus(0, multi); //leg 1 never changes job status
27
+ await this.setStatus(0, multi);
30
28
  const multiResponse = (await multi.exec());
31
29
  telemetry.mapActivityAttributes();
32
30
  const jobStatus = this.resolveStatus(multiResponse);
33
- //cycle the target ancestor
34
31
  multi = this.store.getMulti();
35
32
  const messageId = await this.cycleAncestorActivity(multi);
36
33
  telemetry.setActivityAttributes({
37
34
  'app.activity.mid': messageId,
38
35
  'app.job.jss': jobStatus,
39
36
  });
40
- //exit early (`Cycle` activities only execute Leg 1)
41
37
  await collator_1.CollatorService.notarizeEarlyExit(this, multi);
42
38
  (await multi.exec());
43
39
  return this.context.metadata.aid;
@@ -70,18 +66,7 @@ class Cycle extends activity_1.Activity {
70
66
  });
71
67
  }
72
68
  }
73
- /**
74
- * Trigger the target ancestor to execute in a cycle,
75
- * without violating the constraints of the DAG. Immutable
76
- * `individual activity state` will execute in a new dimensional
77
- * thread while `shared job state` can change. This
78
- * pattern allows for retries without violating the DAG.
79
- */
80
69
  async cycleAncestorActivity(multi) {
81
- //Cycle activity L1 is a standin for the target ancestor L1.
82
- //Input data mapping (mapInputData) allows for the
83
- //next dimensonal thread to execute with different
84
- //input data than the current dimensional thread
85
70
  this.mapInputData();
86
71
  const streamData = {
87
72
  metadata: {
@@ -6,16 +6,10 @@ import { JobState, JobStatus } from '../../types/job';
6
6
  import { RedisMulti } from '../../types/redis';
7
7
  import { StreamCode, StreamStatus } from '../../types/stream';
8
8
  import { Activity } from './activity';
9
- /**
10
- * Supports `signal hook`, `time hook`, and `cycle hook` patterns
11
- */
12
9
  declare class Hook extends Activity {
13
10
  config: HookActivity;
14
11
  constructor(config: ActivityType, data: ActivityData, metadata: ActivityMetadata, hook: ActivityData | null, engine: EngineService, context?: JobState);
15
12
  process(): Promise<string>;
16
- /**
17
- * does this activity use a time-hook or web-hook
18
- */
19
13
  doesHook(): boolean;
20
14
  doHook(telemetry: TelemetryService): Promise<void>;
21
15
  doPassThrough(telemetry: TelemetryService): Promise<void>;
@@ -8,14 +8,10 @@ const task_1 = require("../task");
8
8
  const telemetry_1 = require("../telemetry");
9
9
  const stream_1 = require("../../types/stream");
10
10
  const activity_1 = require("./activity");
11
- /**
12
- * Supports `signal hook`, `time hook`, and `cycle hook` patterns
13
- */
14
11
  class Hook extends activity_1.Activity {
15
12
  constructor(config, data, metadata, hook, engine, context) {
16
13
  super(config, data, metadata, hook, engine, context);
17
14
  }
18
- //******** INITIAL ENTRY POINT (A) ********//
19
15
  async process() {
20
16
  this.logger.debug('hook-process', {
21
17
  jid: this.context.metadata.jid,
@@ -28,11 +24,9 @@ class Hook extends activity_1.Activity {
28
24
  telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
29
25
  telemetry.startActivitySpan(this.leg);
30
26
  if (this.doesHook()) {
31
- //sleep and wait to awaken upon a signal
32
27
  await this.doHook(telemetry);
33
28
  }
34
29
  else {
35
- //end the activity and transition to its children
36
30
  await this.doPassThrough(telemetry);
37
31
  }
38
32
  return this.context.metadata.aid;
@@ -65,9 +59,6 @@ class Hook extends activity_1.Activity {
65
59
  });
66
60
  }
67
61
  }
68
- /**
69
- * does this activity use a time-hook or web-hook
70
- */
71
62
  doesHook() {
72
63
  if (this.config.sleep) {
73
64
  const duration = pipe_1.Pipe.resolve(this.config.sleep, this.context);
@@ -119,7 +110,6 @@ class Hook extends activity_1.Activity {
119
110
  return this.context.metadata.jid;
120
111
  }
121
112
  }
122
- //******** SIGNAL RE-ENTRY POINT ********//
123
113
  async processWebHookEvent(status = stream_1.StreamStatus.SUCCESS, code = 200) {
124
114
  this.logger.debug('hook-process-web-hook-event', {
125
115
  topic: this.config.hook.topic,
@@ -138,8 +128,8 @@ class Hook extends activity_1.Activity {
138
128
  await this.processEvent(status, code, 'hook');
139
129
  if (code === 200) {
140
130
  await taskService.deleteWebHookSignal(this.config.hook.topic, data);
141
- } //else => 202/keep alive
142
- } //else => already resolved
131
+ }
132
+ }
143
133
  }
144
134
  async processTimeHookEvent(jobId) {
145
135
  this.logger.debug('hook-process-time-hook-event', {
@@ -10,7 +10,6 @@ class Interrupt extends activity_1.Activity {
10
10
  constructor(config, data, metadata, hook, engine, context) {
11
11
  super(config, data, metadata, hook, engine, context);
12
12
  }
13
- //******** LEG 1 ENTRY ********//
14
13
  async process() {
15
14
  this.logger.debug('interrupt-process', {
16
15
  jid: this.context.metadata.jid,
@@ -58,14 +57,11 @@ class Interrupt extends activity_1.Activity {
58
57
  }
59
58
  }
60
59
  async interruptSelf(telemetry) {
61
- // Apply final updates to THIS job's state
62
60
  if (this.config.job?.maps) {
63
61
  this.mapJobData();
64
62
  await this.setState();
65
63
  }
66
- // Interrupt THIS job
67
64
  const messageId = await this.interrupt();
68
- // Notarize completion and log
69
65
  telemetry.mapActivityAttributes();
70
66
  const multi = this.store.getMulti();
71
67
  await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
@@ -79,10 +75,8 @@ class Interrupt extends activity_1.Activity {
79
75
  return this.context.metadata.aid;
80
76
  }
81
77
  async interruptAnother(telemetry) {
82
- // Interrupt ANOTHER job
83
78
  const messageId = await this.interrupt();
84
79
  const attrs = { 'app.activity.mid': messageId };
85
- // Apply updates to THIS job's state
86
80
  telemetry.mapActivityAttributes();
87
81
  this.adjacencyList = await this.filterAdjacent();
88
82
  if (this.config.job?.maps || this.config.output?.maps) {
@@ -91,14 +85,12 @@ class Interrupt extends activity_1.Activity {
91
85
  const multi = this.store.getMulti();
92
86
  await this.setState(multi);
93
87
  }
94
- // Notarize completion
95
88
  const multi = this.store.getMulti();
96
89
  await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
97
90
  await this.setStatus(this.adjacencyList.length - 1, multi);
98
91
  const multiResponse = (await multi.exec());
99
92
  const jobStatus = this.resolveStatus(multiResponse);
100
93
  attrs['app.job.jss'] = jobStatus;
101
- // Transition next generation and log
102
94
  const messageIds = await this.transition(this.adjacencyList, jobStatus);
103
95
  if (messageIds.length) {
104
96
  attrs['app.activity.mids'] = messageIds.join(',');