@hotmeshio/hotmesh 0.0.55 → 0.0.57

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 (182) hide show
  1. package/README.md +1 -1
  2. package/build/modules/enums.js +1 -10
  3. package/build/modules/key.d.ts +0 -38
  4. package/build/modules/key.js +4 -46
  5. package/build/modules/utils.d.ts +0 -8
  6. package/build/modules/utils.js +0 -14
  7. package/build/package.json +11 -4
  8. package/build/services/activities/activity.d.ts +0 -28
  9. package/build/services/activities/activity.js +1 -46
  10. package/build/services/activities/await.js +0 -4
  11. package/build/services/activities/cycle.d.ts +0 -7
  12. package/build/services/activities/cycle.js +1 -16
  13. package/build/services/activities/hook.d.ts +0 -6
  14. package/build/services/activities/hook.js +2 -12
  15. package/build/services/activities/interrupt.js +0 -8
  16. package/build/services/activities/signal.d.ts +0 -6
  17. package/build/services/activities/signal.js +0 -15
  18. package/build/services/activities/trigger.d.ts +0 -4
  19. package/build/services/activities/trigger.js +1 -7
  20. package/build/services/activities/worker.js +0 -4
  21. package/build/services/collator/index.d.ts +0 -70
  22. package/build/services/collator/index.js +1 -91
  23. package/build/services/compiler/deployer.js +6 -38
  24. package/build/services/compiler/index.d.ts +0 -15
  25. package/build/services/compiler/index.js +0 -20
  26. package/build/services/compiler/validator.d.ts +0 -3
  27. package/build/services/compiler/validator.js +0 -25
  28. package/build/services/connector/clients/ioredis.d.ts +2 -2
  29. package/build/services/connector/clients/ioredis.js +0 -2
  30. package/build/services/connector/clients/redis.d.ts +4 -4
  31. package/build/services/connector/clients/redis.js +1 -3
  32. package/build/services/connector/index.d.ts +1 -1
  33. package/build/services/connector/index.js +0 -2
  34. package/build/services/durable/client.d.ts +1 -26
  35. package/build/services/durable/client.js +0 -56
  36. package/build/services/durable/exporter.d.ts +0 -22
  37. package/build/services/durable/exporter.js +1 -30
  38. package/build/services/durable/handle.d.ts +0 -36
  39. package/build/services/durable/handle.js +0 -46
  40. package/build/services/durable/index.d.ts +0 -4
  41. package/build/services/durable/index.js +0 -4
  42. package/build/services/durable/schemas/factory.d.ts +0 -29
  43. package/build/services/durable/schemas/factory.js +0 -29
  44. package/build/services/durable/search.d.ts +1 -36
  45. package/build/services/durable/search.js +56 -56
  46. package/build/services/durable/worker.js +2 -22
  47. package/build/services/durable/workflow.d.ts +0 -114
  48. package/build/services/durable/workflow.js +1 -141
  49. package/build/services/engine/index.d.ts +1 -6
  50. package/build/services/engine/index.js +1 -43
  51. package/build/services/exporter/index.d.ts +0 -27
  52. package/build/services/exporter/index.js +0 -33
  53. package/build/services/hotmesh/index.d.ts +2 -2
  54. package/build/services/hotmesh/index.js +1 -9
  55. package/build/services/logger/index.js +0 -2
  56. package/build/services/mapper/index.d.ts +0 -14
  57. package/build/services/mapper/index.js +0 -14
  58. package/build/services/pipe/functions/date.d.ts +0 -7
  59. package/build/services/pipe/functions/date.js +0 -7
  60. package/build/services/pipe/functions/math.js +0 -2
  61. package/build/services/pipe/index.d.ts +0 -15
  62. package/build/services/pipe/index.js +2 -23
  63. package/build/services/quorum/index.d.ts +0 -7
  64. package/build/services/quorum/index.js +0 -21
  65. package/build/services/reporter/index.d.ts +0 -5
  66. package/build/services/reporter/index.js +0 -9
  67. package/build/services/router/index.d.ts +0 -9
  68. package/build/services/router/index.js +2 -38
  69. package/build/services/serializer/index.js +7 -26
  70. package/build/services/store/cache.d.ts +0 -18
  71. package/build/services/store/cache.js +0 -18
  72. package/build/services/store/clients/ioredis.d.ts +1 -1
  73. package/build/services/store/clients/ioredis.js +0 -1
  74. package/build/services/store/clients/redis.d.ts +1 -1
  75. package/build/services/store/index.d.ts +0 -55
  76. package/build/services/store/index.js +5 -81
  77. package/build/services/stream/clients/ioredis.d.ts +1 -1
  78. package/build/services/stream/clients/ioredis.js +1 -4
  79. package/build/services/stream/clients/redis.d.ts +1 -1
  80. package/build/services/sub/clients/ioredis.d.ts +1 -1
  81. package/build/services/sub/clients/redis.d.ts +1 -1
  82. package/build/services/task/index.d.ts +0 -9
  83. package/build/services/task/index.js +0 -31
  84. package/build/services/telemetry/index.d.ts +0 -7
  85. package/build/services/telemetry/index.js +1 -13
  86. package/build/services/worker/index.d.ts +0 -4
  87. package/build/services/worker/index.js +2 -6
  88. package/build/types/activity.d.ts +0 -81
  89. package/build/types/durable.d.ts +26 -177
  90. package/build/types/exporter.d.ts +0 -13
  91. package/build/types/hotmesh.d.ts +4 -16
  92. package/build/types/hotmesh.js +0 -3
  93. package/build/types/index.d.ts +4 -6
  94. package/build/types/index.js +4 -3
  95. package/build/types/job.d.ts +1 -86
  96. package/build/types/pipe.d.ts +0 -65
  97. package/build/types/quorum.d.ts +15 -10
  98. package/build/types/redis.d.ts +225 -7
  99. package/build/types/redis.js +9 -0
  100. package/build/types/stream.d.ts +0 -58
  101. package/build/types/stream.js +0 -4
  102. package/package.json +11 -4
  103. package/types/durable.ts +131 -4
  104. package/types/hotmesh.ts +3 -6
  105. package/types/index.ts +23 -10
  106. package/types/job.ts +1 -1
  107. package/types/quorum.ts +22 -0
  108. package/types/redis.ts +267 -18
  109. package/build/types/ioredisclient.d.ts +0 -5
  110. package/build/types/ioredisclient.js +0 -5
  111. package/build/types/redisclient.d.ts +0 -26
  112. package/build/types/redisclient.js +0 -2
  113. package/modules/enums.ts +0 -62
  114. package/modules/errors.ts +0 -280
  115. package/modules/key.ts +0 -101
  116. package/modules/storage.ts +0 -3
  117. package/modules/utils.ts +0 -242
  118. package/services/activities/activity.ts +0 -589
  119. package/services/activities/await.ts +0 -113
  120. package/services/activities/cycle.ts +0 -115
  121. package/services/activities/hook.ts +0 -197
  122. package/services/activities/index.ts +0 -19
  123. package/services/activities/interrupt.ts +0 -172
  124. package/services/activities/signal.ts +0 -148
  125. package/services/activities/trigger.ts +0 -295
  126. package/services/activities/worker.ts +0 -107
  127. package/services/collator/README.md +0 -102
  128. package/services/collator/index.ts +0 -291
  129. package/services/compiler/deployer.ts +0 -504
  130. package/services/compiler/index.ts +0 -98
  131. package/services/compiler/validator.ts +0 -158
  132. package/services/connector/clients/ioredis.ts +0 -57
  133. package/services/connector/clients/redis.ts +0 -72
  134. package/services/connector/index.ts +0 -42
  135. package/services/durable/client.ts +0 -266
  136. package/services/durable/connection.ts +0 -10
  137. package/services/durable/exporter.ts +0 -232
  138. package/services/durable/handle.ts +0 -160
  139. package/services/durable/index.ts +0 -27
  140. package/services/durable/schemas/factory.ts +0 -2358
  141. package/services/durable/search.ts +0 -196
  142. package/services/durable/worker.ts +0 -401
  143. package/services/durable/workflow.ts +0 -557
  144. package/services/engine/index.ts +0 -761
  145. package/services/exporter/index.ts +0 -146
  146. package/services/hotmesh/index.ts +0 -237
  147. package/services/logger/index.ts +0 -79
  148. package/services/mapper/index.ts +0 -89
  149. package/services/pipe/functions/array.ts +0 -78
  150. package/services/pipe/functions/bitwise.ts +0 -27
  151. package/services/pipe/functions/conditional.ts +0 -35
  152. package/services/pipe/functions/date.ts +0 -220
  153. package/services/pipe/functions/index.ts +0 -27
  154. package/services/pipe/functions/json.ts +0 -11
  155. package/services/pipe/functions/logical.ts +0 -11
  156. package/services/pipe/functions/math.ts +0 -217
  157. package/services/pipe/functions/number.ts +0 -75
  158. package/services/pipe/functions/object.ts +0 -98
  159. package/services/pipe/functions/string.ts +0 -86
  160. package/services/pipe/functions/symbol.ts +0 -39
  161. package/services/pipe/functions/unary.ts +0 -19
  162. package/services/pipe/index.ts +0 -216
  163. package/services/quorum/index.ts +0 -319
  164. package/services/reporter/index.ts +0 -387
  165. package/services/router/index.ts +0 -426
  166. package/services/serializer/README.md +0 -10
  167. package/services/serializer/index.ts +0 -285
  168. package/services/store/cache.ts +0 -172
  169. package/services/store/clients/ioredis.ts +0 -145
  170. package/services/store/clients/redis.ts +0 -191
  171. package/services/store/index.ts +0 -1091
  172. package/services/stream/clients/ioredis.ts +0 -157
  173. package/services/stream/clients/redis.ts +0 -158
  174. package/services/stream/index.ts +0 -58
  175. package/services/sub/clients/ioredis.ts +0 -83
  176. package/services/sub/clients/redis.ts +0 -74
  177. package/services/sub/index.ts +0 -25
  178. package/services/task/index.ts +0 -250
  179. package/services/telemetry/index.ts +0 -273
  180. package/services/worker/index.ts +0 -248
  181. package/types/ioredisclient.ts +0 -10
  182. package/types/redisclient.ts +0 -30
@@ -1,291 +0,0 @@
1
- import { CollationError, InactiveJobError } from '../../modules/errors';
2
- import { RedisMulti } from '../../types/redis';
3
- import { CollationFaultType, CollationStage } from '../../types/collator';
4
- import { ActivityDuplex } from '../../types/activity';
5
- import { HotMeshGraph } from '../../types/hotmesh';
6
- import { Activity } from '../activities/activity';
7
- import { Cycle } from '../activities/cycle';
8
-
9
- class CollatorService {
10
-
11
- //max int digit count that supports `hincrby`
12
- static targetLength = 15;
13
-
14
- /**
15
- * Upon re/entry, verify that the job status is active
16
- */
17
- static assertJobActive(status: number, jobId: string, activityId: string): void {
18
- if (status <= 0) {
19
- throw new InactiveJobError(jobId, status, activityId);
20
- }
21
- }
22
-
23
- /**
24
- * returns the dimensional address (dad) for the target; due
25
- * to the nature of the notary system, the dad for leg 2 entry
26
- * must target the `0` index while leg 2 exit must target the
27
- * current index (0)
28
- */
29
- static getDimensionalAddress(activity: Activity, isEntry = false): Record<string, string> {
30
- let dad = activity.context.metadata.dad || activity.metadata.dad;
31
- if (isEntry && dad && activity.leg === 2) {
32
- dad = `${dad.substring(0, dad.lastIndexOf(','))},0`;
33
- }
34
- return CollatorService.getDimensionsById([...activity.config.ancestors, activity.metadata.aid], dad);
35
- }
36
-
37
- /**
38
- * resolves the dimensional address for the
39
- * ancestor in the graph to go back to. this address
40
- * is determined by trimming the last digits from
41
- * the `dad` (including the target).
42
- * the target activity index is then set to `0`, so that
43
- * the origin node can be queried for approval/entry.
44
- */
45
- static resolveReentryDimension(activity: Cycle) {
46
- const targetActivityId = activity.config.ancestor;
47
- const ancestors = activity.config.ancestors;
48
- const ancestorIndex = ancestors.indexOf(targetActivityId);
49
- const dimensions = activity.metadata.dad.split(','); //e.g., `,0,0,1,0`
50
- dimensions.length = ancestorIndex + 1;
51
- dimensions.push('0');
52
- return dimensions.join(',');
53
- }
54
-
55
- static async notarizeEntry(activity: Activity, multi?: RedisMulti): Promise<number> {
56
- //decrement by -100_000_000_000_000
57
- const amount = await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, -100_000_000_000_000, this.getDimensionalAddress(activity), multi);
58
- this.verifyInteger(amount, 1, 'enter');
59
- return amount;
60
- };
61
-
62
- static async authorizeReentry(activity: Activity, multi?: RedisMulti): Promise<number> {
63
- //set second digit to 8, allowing for re-entry
64
- //decrement by -10_000_000_000_000
65
- const amount = await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, -10_000_000_000_000, this.getDimensionalAddress(activity), multi);
66
- return amount;
67
- }
68
-
69
- static async notarizeEarlyExit(activity: Activity, multi?: RedisMulti): Promise<number> {
70
- //decrement the 2nd and 3rd digits to fully deactivate (`cycle` activities use this command to fully exit after leg 1) (should result in `888000000000000`)
71
- return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, -11_000_000_000_000, this.getDimensionalAddress(activity), multi);
72
- };
73
-
74
- static async notarizeEarlyCompletion(activity: Activity, multi?: RedisMulti): Promise<number> {
75
- //initialize both `possible` (1m) and `actualized` (1) zero dimension, while decrementing the 2nd
76
- //3rd digit is optionally kept open if the activity might be used in a cycle
77
- const decrement = activity.config.cycle ? 10_000_000_000_000 : 11_000_000_000_000;
78
- return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, 1_000_001 - decrement, this.getDimensionalAddress(activity), multi);
79
- };
80
-
81
- /**
82
- * verifies both the concrete and synthetic keys for the activity; concrete keys
83
- * exist in the original model and are effectively the 'real' keys. In reality,
84
- * hook activities are atomized during compilation to create a synthetic DAG that
85
- * is used to track the status of the graph in a distributed environment. The
86
- * synthetic key represents different dimensional realities and is used to
87
- * track re-entry overages (it distinguishes between the original and re-entry).
88
- * The essential challenge is: is this a re-entry that is purposeful in
89
- * order to induce cycles, or is the re-entry due to a failure in the system?
90
- */
91
- static async notarizeReentry(activity: Activity, guid: string, multi?: RedisMulti): Promise<number> {
92
- const jid = activity.context.metadata.jid;
93
- const localMulti = multi || activity.store.getMulti();
94
- //increment by 1_000_000 (indicates re-entry and is used to drive the 'dimensional address' for adjacent activities (minus 1))
95
- await activity.store.collate(jid, activity.metadata.aid, 1_000_000, this.getDimensionalAddress(activity, true), localMulti);
96
- await activity.store.collateSynthetic(jid, guid, 1_000_000, localMulti);
97
- const [_amountConcrete, _amountSynthetic] = await localMulti.exec();
98
- const amountConcrete = Array.isArray(_amountConcrete) ? _amountConcrete[1] : _amountConcrete;
99
- const amountSynthetic = Array.isArray(_amountSynthetic) ? _amountSynthetic[1] : _amountSynthetic;
100
- this.verifyInteger(amountConcrete as number, 2, 'enter');
101
- this.verifySyntheticInteger(amountSynthetic as number);
102
- return amountConcrete as number;
103
- };
104
-
105
- static async notarizeContinuation(activity: Activity, multi?: RedisMulti): Promise<number> {
106
- //keep open; actualize the leg2 dimension (+1)
107
- return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, 1, this.getDimensionalAddress(activity), multi);
108
- };
109
-
110
- static async notarizeCompletion(activity: Activity, multi?: RedisMulti): Promise<number> {
111
- //1) ALWAYS actualize leg2 dimension (+1)
112
- //2) IF the activity is used in a cycle, don't close leg 2!
113
- const decrement = activity.config.cycle ? 0 : 1_000_000_000_000;
114
- return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, 1 - decrement, this.getDimensionalAddress(activity), multi);
115
- };
116
-
117
- static getDigitAtIndex(num: number, targetDigitIndex: number): number | null {
118
- const numStr = num.toString();
119
- if (targetDigitIndex < 0 || targetDigitIndex >= numStr.length) {
120
- return null;
121
- }
122
- const digit = parseInt(numStr[targetDigitIndex], 10);
123
- return digit;
124
- }
125
-
126
- static getDimensionalIndex(num: number): number | null {
127
- const numStr = num.toString();
128
- if (numStr.length < 9) {
129
- return null;
130
- }
131
- const extractedStr = numStr.substring(3, 9);
132
- const extractedInt = parseInt(extractedStr, 10);
133
- return extractedInt - 1;
134
- }
135
-
136
- static isDuplicate(num: number, targetDigitIndex: number): boolean {
137
- return this.getDigitAtIndex(num, targetDigitIndex) < 8;
138
- }
139
-
140
- static isInactive(num: number): boolean {
141
- return this.getDigitAtIndex(num, 2) < 9;
142
- }
143
-
144
- static isPrimed(amount: number, leg: ActivityDuplex): boolean {
145
- //activity entry is not allowed if paths not properly pre-set
146
- if (leg == 1) {
147
- return amount != -100_000_000_000_000;
148
- } else {
149
- return this.getDigitAtIndex(amount, 0) < 9 &&
150
- this.getDigitAtIndex(amount, 1) < 9;
151
- }
152
- }
153
-
154
- /**
155
- * During compilation, the graphs are compiled into structures necessary
156
- * for distributed processing; these are referred to as 'synthetic DAGs',
157
- * because they are not part of the original graph, but are used to track
158
- * the status of the graph in a distributed environment. This check ensures
159
- * that the 'synthetic key' is not a duplicate. (which is different than
160
- * saying the 'key' is not a duplicate)
161
- */
162
- static verifySyntheticInteger(amount: number): void {
163
- const samount = amount.toString();
164
- const isCompletedValue = parseInt(samount[samount.length - 1], 10);
165
- if (isCompletedValue > 0) {
166
- //already done error (ack/delete clearly failed; this is a duplicate)
167
- throw new CollationError(amount, 2, 'enter', CollationFaultType.INACTIVE);
168
- } else if (amount >= 2_000_000) {
169
- //duplicate synthetic key (todo: need to resolve/fix this!!)
170
- throw new CollationError(amount, 2, 'enter', CollationFaultType.DUPLICATE);
171
- }
172
- }
173
-
174
- static verifyInteger(amount: number, leg: ActivityDuplex, stage: CollationStage): void {
175
- let faultType: CollationFaultType | undefined;
176
- if (leg === 1 && stage === 'enter') {
177
- if (!this.isPrimed(amount, 1)) {
178
- faultType = CollationFaultType.MISSING;
179
- } else if (this.isDuplicate(amount, 0)) {
180
- faultType = CollationFaultType.DUPLICATE;
181
- } else if (amount != 899_000_000_000_000) {
182
- faultType = CollationFaultType.INVALID;
183
- }
184
- } else if (leg === 1 && stage === 'exit') {
185
- if (amount === -10_000_000_000_000) {
186
- faultType = CollationFaultType.MISSING;
187
- } else if (this.isDuplicate(amount, 1)) {
188
- faultType = CollationFaultType.DUPLICATE;
189
- }
190
- } else if (leg === 2 && stage === 'enter') {
191
- if (!this.isPrimed(amount, 2)) {
192
- faultType = CollationFaultType.FORBIDDEN;
193
- } else if (this.isInactive(amount)) {
194
- faultType = CollationFaultType.INACTIVE;
195
- }
196
- }
197
- if (faultType) {
198
- throw new CollationError(amount, leg, stage, faultType);
199
- }
200
- }
201
-
202
- static getDimensionsById(ancestors: string[], dad: string): Record<string, string> {
203
- //ancestors is an ordered list of all ancestors, starting with the trigger (['t1', 'a1', 'a2'])
204
- //dad is the dimensional address of the ancestors list (',0,5,3')
205
- //loop through the ancestors list and create a map of the ancestor to the dimensional address.
206
- //return { 't1': ',0', 'a1': ',0,5', 'a1': ',0,5,3', $ADJACENT: ',0,5,3,0' };
207
- // `adjacent` is a special key that is used to track the dimensional address of adjacent activities
208
- const map: Record<string, string> = { '$ADJACENT': `${dad},0` };
209
- let dadStr = dad;
210
- ancestors.reverse().forEach((ancestor) => {
211
- map[ancestor] = dadStr;
212
- dadStr = dadStr.substring(0, dadStr.lastIndexOf(','));
213
- });
214
- return map;
215
- }
216
-
217
- /**
218
- * All non-trigger activities are assigned a status seed by their parent
219
- */
220
- static getSeed(): string {
221
- return '999000000000000';
222
- }
223
-
224
- /**
225
- * All trigger activities are assigned a status seed in a completed state
226
- */
227
- static getTriggerSeed(): string {
228
- return '888000001000001';
229
- }
230
-
231
- /**
232
- * entry point for compiler-type activities. This is called by the compiler
233
- * to bind the sorted activity IDs to the trigger activity. These are then used
234
- * at runtime by the activities to track job/activity status.
235
- * @param graphs
236
- */
237
- static compile(graphs: HotMeshGraph[]) {
238
- CollatorService.bindAncestorArray(graphs);
239
- }
240
-
241
- /**
242
- * binds the ancestor array to each activity.
243
- * Used in conjunction with the dimensional
244
- * address (dad). If dad is `,0,1,0,0` and the
245
- * ancestor array is `['t1', 'a1', 'a2']` for
246
- * activity 'a3', then the SAVED DAD
247
- * will always have the trailing
248
- * 0's removed. This ensures that the addressing
249
- * remains consistent even if the graph changes.
250
- * id DAD SAVED DAD
251
- * * t1 => ,0 => [empty]
252
- * * a1 => ,0,1 => ,0,1
253
- * * a2 => ,0,1,0 => ,0,1
254
- * * a3 => ,0,1,0,0 => ,0,1
255
- *
256
- */
257
- static bindAncestorArray(graphs: HotMeshGraph[]) {
258
- graphs.forEach((graph) => {
259
- const ancestors: Record<string, string[]> = {};
260
- const startingNode = Object.keys(graph.activities).find(
261
- (activity) => graph.activities[activity].type === 'trigger'
262
- );
263
- if (!startingNode) {
264
- throw new Error('collator-trigger-activity-not-found');
265
- }
266
- const dfs = (node: string, parentList: string[]) => {
267
- ancestors[node] = parentList;
268
- graph.activities[node]['ancestors'] = parentList;
269
- const transitions = graph.transitions?.[node] || [];
270
- transitions.forEach((transition) => {
271
- dfs(transition.to, [...parentList, node]);
272
- });
273
- };
274
- // Start the DFS traversal
275
- dfs(startingNode, []);
276
- });
277
- }
278
-
279
- /**
280
- * All activities exist on a dimensional plane. Zero
281
- * is the default. A value of
282
- * `AxY,0,0,0,0,1,0,0` would reflect that
283
- * an ancestor activity was dimensionalized beyond
284
- * the default.
285
- */
286
- static getDimensionalSeed(index = 0): string {
287
- return `,${index}`;
288
- }
289
- }
290
-
291
- export { CollatorService };