@hotmeshio/hotmesh 0.7.0 → 0.9.0

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 (138) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/README.md +158 -38
  3. package/build/index.d.ts +1 -3
  4. package/build/index.js +1 -5
  5. package/build/modules/utils.js +3 -31
  6. package/build/package.json +63 -79
  7. package/build/services/activities/activity.d.ts +97 -9
  8. package/build/services/activities/activity.js +323 -86
  9. package/build/services/activities/await.d.ts +101 -0
  10. package/build/services/activities/await.js +103 -2
  11. package/build/services/activities/cycle.d.ts +82 -0
  12. package/build/services/activities/cycle.js +86 -8
  13. package/build/services/activities/hook.d.ts +144 -1
  14. package/build/services/activities/hook.js +162 -21
  15. package/build/services/activities/interrupt.d.ts +112 -0
  16. package/build/services/activities/interrupt.js +134 -29
  17. package/build/services/activities/signal.d.ts +111 -4
  18. package/build/services/activities/signal.js +136 -28
  19. package/build/services/activities/trigger.d.ts +56 -4
  20. package/build/services/activities/trigger.js +119 -35
  21. package/build/services/activities/worker.d.ts +107 -0
  22. package/build/services/activities/worker.js +109 -2
  23. package/build/services/collator/index.d.ts +116 -30
  24. package/build/services/collator/index.js +211 -115
  25. package/build/services/connector/factory.d.ts +1 -1
  26. package/build/services/connector/factory.js +1 -11
  27. package/build/services/engine/index.d.ts +22 -6
  28. package/build/services/engine/index.js +49 -18
  29. package/build/services/exporter/index.d.ts +2 -0
  30. package/build/services/exporter/index.js +1 -0
  31. package/build/services/hotmesh/index.d.ts +471 -236
  32. package/build/services/hotmesh/index.js +473 -238
  33. package/build/services/memflow/client.js +2 -2
  34. package/build/services/memflow/handle.js +1 -1
  35. package/build/services/memflow/index.d.ts +1 -1
  36. package/build/services/memflow/index.js +1 -1
  37. package/build/services/memflow/workflow/all.d.ts +28 -3
  38. package/build/services/memflow/workflow/all.js +28 -3
  39. package/build/services/memflow/workflow/context.d.ts +44 -1
  40. package/build/services/memflow/workflow/context.js +44 -1
  41. package/build/services/memflow/workflow/didRun.d.ts +23 -3
  42. package/build/services/memflow/workflow/didRun.js +23 -3
  43. package/build/services/memflow/workflow/emit.d.ts +43 -4
  44. package/build/services/memflow/workflow/emit.js +43 -4
  45. package/build/services/memflow/workflow/enrich.d.ts +32 -4
  46. package/build/services/memflow/workflow/enrich.js +32 -4
  47. package/build/services/memflow/workflow/entityMethods.d.ts +54 -7
  48. package/build/services/memflow/workflow/entityMethods.js +54 -7
  49. package/build/services/memflow/workflow/execChild.d.ts +96 -8
  50. package/build/services/memflow/workflow/execChild.js +96 -8
  51. package/build/services/memflow/workflow/execHook.d.ts +54 -39
  52. package/build/services/memflow/workflow/execHook.js +52 -38
  53. package/build/services/memflow/workflow/execHookBatch.d.ts +82 -29
  54. package/build/services/memflow/workflow/execHookBatch.js +80 -28
  55. package/build/services/memflow/workflow/hook.d.ts +68 -3
  56. package/build/services/memflow/workflow/hook.js +69 -4
  57. package/build/services/memflow/workflow/index.d.ts +65 -10
  58. package/build/services/memflow/workflow/index.js +65 -10
  59. package/build/services/memflow/workflow/interrupt.d.ts +50 -4
  60. package/build/services/memflow/workflow/interrupt.js +50 -4
  61. package/build/services/memflow/workflow/interruption.d.ts +49 -16
  62. package/build/services/memflow/workflow/interruption.js +49 -16
  63. package/build/services/memflow/workflow/isSideEffectAllowed.d.ts +21 -4
  64. package/build/services/memflow/workflow/isSideEffectAllowed.js +21 -4
  65. package/build/services/memflow/workflow/proxyActivities.d.ts +70 -42
  66. package/build/services/memflow/workflow/proxyActivities.js +70 -42
  67. package/build/services/memflow/workflow/random.d.ts +33 -3
  68. package/build/services/memflow/workflow/random.js +33 -3
  69. package/build/services/memflow/workflow/searchMethods.d.ts +49 -2
  70. package/build/services/memflow/workflow/searchMethods.js +49 -2
  71. package/build/services/memflow/workflow/signal.d.ts +51 -22
  72. package/build/services/memflow/workflow/signal.js +52 -23
  73. package/build/services/memflow/workflow/sleepFor.d.ts +57 -18
  74. package/build/services/memflow/workflow/sleepFor.js +57 -18
  75. package/build/services/memflow/workflow/trace.d.ts +39 -6
  76. package/build/services/memflow/workflow/trace.js +39 -6
  77. package/build/services/memflow/workflow/waitFor.d.ts +55 -18
  78. package/build/services/memflow/workflow/waitFor.js +55 -18
  79. package/build/services/router/consumption/index.js +1 -1
  80. package/build/services/search/factory.js +1 -9
  81. package/build/services/store/factory.js +1 -9
  82. package/build/services/store/index.d.ts +6 -1
  83. package/build/services/store/providers/postgres/kvsql.d.ts +4 -0
  84. package/build/services/store/providers/postgres/kvsql.js +4 -0
  85. package/build/services/store/providers/postgres/kvtransaction.d.ts +2 -0
  86. package/build/services/store/providers/postgres/kvtransaction.js +23 -0
  87. package/build/services/store/providers/postgres/kvtypes/hash/basic.d.ts +51 -0
  88. package/build/services/store/providers/postgres/kvtypes/hash/basic.js +193 -1
  89. package/build/services/store/providers/postgres/kvtypes/hash/index.d.ts +4 -0
  90. package/build/services/store/providers/postgres/kvtypes/hash/index.js +6 -0
  91. package/build/services/store/providers/postgres/postgres.d.ts +21 -1
  92. package/build/services/store/providers/postgres/postgres.js +42 -4
  93. package/build/services/stream/factory.js +1 -17
  94. package/build/services/stream/providers/postgres/scout.js +2 -2
  95. package/build/services/sub/factory.js +1 -9
  96. package/build/services/sub/index.d.ts +1 -1
  97. package/build/services/sub/providers/postgres/postgres.d.ts +1 -1
  98. package/build/services/sub/providers/postgres/postgres.js +25 -10
  99. package/build/services/task/index.d.ts +1 -1
  100. package/build/services/task/index.js +2 -6
  101. package/build/services/telemetry/index.js +6 -0
  102. package/build/types/activity.d.ts +1 -1
  103. package/build/types/hotmesh.d.ts +1 -1
  104. package/build/types/index.d.ts +0 -1
  105. package/build/types/index.js +1 -4
  106. package/build/types/job.d.ts +1 -1
  107. package/build/types/memflow.d.ts +1 -1
  108. package/build/types/provider.d.ts +1 -1
  109. package/build/types/quorum.d.ts +2 -2
  110. package/build/vitest.config.d.ts +2 -0
  111. package/build/vitest.config.js +18 -0
  112. package/index.ts +0 -4
  113. package/package.json +63 -79
  114. package/vitest.config.ts +17 -0
  115. package/build/services/connector/providers/ioredis.d.ts +0 -9
  116. package/build/services/connector/providers/ioredis.js +0 -26
  117. package/build/services/connector/providers/redis.d.ts +0 -9
  118. package/build/services/connector/providers/redis.js +0 -38
  119. package/build/services/search/providers/redis/ioredis.d.ts +0 -23
  120. package/build/services/search/providers/redis/ioredis.js +0 -189
  121. package/build/services/search/providers/redis/redis.d.ts +0 -23
  122. package/build/services/search/providers/redis/redis.js +0 -202
  123. package/build/services/store/providers/redis/_base.d.ts +0 -137
  124. package/build/services/store/providers/redis/_base.js +0 -980
  125. package/build/services/store/providers/redis/ioredis.d.ts +0 -20
  126. package/build/services/store/providers/redis/ioredis.js +0 -190
  127. package/build/services/store/providers/redis/redis.d.ts +0 -18
  128. package/build/services/store/providers/redis/redis.js +0 -199
  129. package/build/services/stream/providers/redis/ioredis.d.ts +0 -61
  130. package/build/services/stream/providers/redis/ioredis.js +0 -272
  131. package/build/services/stream/providers/redis/redis.d.ts +0 -61
  132. package/build/services/stream/providers/redis/redis.js +0 -305
  133. package/build/services/sub/providers/redis/ioredis.d.ts +0 -20
  134. package/build/services/sub/providers/redis/ioredis.js +0 -161
  135. package/build/services/sub/providers/redis/redis.d.ts +0 -18
  136. package/build/services/sub/providers/redis/redis.js +0 -148
  137. package/build/types/redis.d.ts +0 -258
  138. package/build/types/redis.js +0 -11
@@ -183,7 +183,7 @@ class EngineService {
183
183
  * @private
184
184
  */
185
185
  async processWebHooks() {
186
- this.taskService.processWebHooks(this.hook.bind(this));
186
+ this.taskService.processWebHooks(this.signal.bind(this));
187
187
  }
188
188
  /**
189
189
  * @private
@@ -381,7 +381,7 @@ class EngineService {
381
381
  /**
382
382
  * @private
383
383
  */
384
- async execAdjacentParent(context, jobOutput, emit = false) {
384
+ async execAdjacentParent(context, jobOutput, emit = false, transaction) {
385
385
  if (this.hasParentJob(context)) {
386
386
  //errors are stringified `StreamError` objects
387
387
  const error = this.resolveError(jobOutput.metadata);
@@ -414,7 +414,7 @@ class EngineService {
414
414
  streamData.status = stream_1.StreamStatus.SUCCESS;
415
415
  streamData.code = enums_1.HMSH_CODE_SUCCESS;
416
416
  }
417
- return (await this.router?.publishMessage(null, streamData));
417
+ return (await this.router?.publishMessage(null, streamData, transaction));
418
418
  }
419
419
  }
420
420
  /**
@@ -457,11 +457,17 @@ class EngineService {
457
457
  //todo: do not allow scrubbing of non-existent or actively running job
458
458
  await this.store.scrub(jobId);
459
459
  }
460
- // ****************** `HOOK` ACTIVITY RE-ENTRY POINT *****************
460
+ // ****************** `SIGNAL` ACTIVITY RE-ENTRY POINT ****************
461
461
  /**
462
+ * Delivers a signal (data payload) to a paused hook activity,
463
+ * resuming its Leg 2 execution. The `topic` must match a hook rule
464
+ * defined in the YAML graph's `hooks` section. The engine locates
465
+ * the target activity and dimension for reentry based on the hook
466
+ * rule's match conditions.
467
+ *
462
468
  * @private
463
469
  */
464
- async hook(topic, data, status = stream_1.StreamStatus.SUCCESS, code = 200) {
470
+ async signal(topic, data, status = stream_1.StreamStatus.SUCCESS, code = 200, transaction) {
465
471
  const hookRule = await this.taskService.getHookRule(topic);
466
472
  const [aid] = await this.getSchema(`.${hookRule.to}`);
467
473
  const streamData = {
@@ -475,7 +481,7 @@ class EngineService {
475
481
  },
476
482
  data,
477
483
  };
478
- return (await this.router?.publishMessage(null, streamData));
484
+ return (await this.router?.publishMessage(null, streamData, transaction));
479
485
  }
480
486
  /**
481
487
  * @private
@@ -503,9 +509,13 @@ class EngineService {
503
509
  await this.router?.publishMessage(null, streamData);
504
510
  }
505
511
  /**
512
+ * Fan-out variant of `signal()` that delivers data to **all**
513
+ * paused workflows matching a search query. Useful for resuming
514
+ * a batch of workflows waiting on the same external event.
515
+ *
506
516
  * @private
507
517
  */
508
- async hookAll(hookTopic, data, keyResolver, queryFacets = []) {
518
+ async signalAll(hookTopic, data, keyResolver, queryFacets = []) {
509
519
  const config = await this.getVID();
510
520
  const hookRule = await this.taskService.getHookRule(hookTopic);
511
521
  if (hookRule) {
@@ -621,7 +631,7 @@ class EngineService {
621
631
  /**
622
632
  * @private
623
633
  */
624
- async pubOneTimeSubs(context, jobOutput, emit = false) {
634
+ async pubOneTimeSubs(context, jobOutput, emit = false, transaction) {
625
635
  //todo: subscriber should query for the job...only publish minimum context needed
626
636
  if (this.hasOneTimeSubscription(context)) {
627
637
  const message = {
@@ -629,7 +639,7 @@ class EngineService {
629
639
  topic: context.metadata.jid,
630
640
  job: (0, utils_1.restoreHierarchy)(jobOutput),
631
641
  };
632
- this.subscribe.publish(key_1.KeyType.QUORUM, message, this.appId, context.metadata.ngn);
642
+ await this.subscribe.publish(key_1.KeyType.QUORUM, message, this.appId, context.metadata.ngn, transaction);
633
643
  }
634
644
  }
635
645
  /**
@@ -644,7 +654,7 @@ class EngineService {
644
654
  /**
645
655
  * @private
646
656
  */
647
- async pubPermSubs(context, jobOutput, emit = false) {
657
+ async pubPermSubs(context, jobOutput, emit = false, transaction) {
648
658
  const topic = await this.getPublishesTopic(context);
649
659
  if (topic) {
650
660
  const message = {
@@ -652,7 +662,7 @@ class EngineService {
652
662
  topic,
653
663
  job: (0, utils_1.restoreHierarchy)(jobOutput),
654
664
  };
655
- this.subscribe.publish(key_1.KeyType.QUORUM, message, this.appId, `${topic}.${context.metadata.jid}`);
665
+ await this.subscribe.publish(key_1.KeyType.QUORUM, message, this.appId, `${topic}.${context.metadata.jid}`, transaction);
656
666
  }
657
667
  }
658
668
  /**
@@ -683,20 +693,41 @@ class EngineService {
683
693
  /**
684
694
  * @private
685
695
  */
686
- async runJobCompletionTasks(context, options = {}) {
696
+ async runJobCompletionTasks(context, options = {}, transaction) {
687
697
  //'emit' indicates the job is still active
688
698
  const isAwait = this.hasParentJob(context, true);
689
699
  const isOneTimeSub = this.hasOneTimeSubscription(context);
690
700
  const topic = await this.getPublishesTopic(context);
691
701
  let msgId;
702
+ let jobOutput;
692
703
  if (isAwait || isOneTimeSub || topic) {
693
- const jobOutput = await this.getState(context.metadata.tpc, context.metadata.jid);
694
- msgId = await this.execAdjacentParent(context, jobOutput, options.emit);
695
- this.pubOneTimeSubs(context, jobOutput, options.emit);
696
- this.pubPermSubs(context, jobOutput, options.emit);
704
+ jobOutput = await this.getState(context.metadata.tpc, context.metadata.jid);
705
+ //only send RESULT to parent for non-severed children (execChild).
706
+ //startChild (px=true) children already sent RESULT at spawn time
707
+ //via Trigger.execAdjacentParent; sending again here would cause
708
+ //a duplicate semaphore decrement in collation workflows.
709
+ if (isAwait) {
710
+ msgId = await this.execAdjacentParent(context, jobOutput, options.emit, transaction);
711
+ }
712
+ if (transaction) {
713
+ //transactional: await to queue NOTIFY in the transaction
714
+ await this.pubOneTimeSubs(context, jobOutput, options.emit, transaction);
715
+ await this.pubPermSubs(context, jobOutput, options.emit, transaction);
716
+ }
717
+ else {
718
+ //non-transactional: fire-and-forget to avoid race with inline
719
+ //trigger processing (callback registered after pub() returns)
720
+ this.pubOneTimeSubs(context, jobOutput, options.emit);
721
+ this.pubPermSubs(context, jobOutput, options.emit);
722
+ }
697
723
  }
698
724
  if (!options.emit) {
699
- this.taskService.registerJobForCleanup(context.metadata.jid, this.resolveExpires(context, options), options);
725
+ if (transaction) {
726
+ await this.taskService.registerJobForCleanup(context.metadata.jid, this.resolveExpires(context, options), options, transaction);
727
+ }
728
+ else {
729
+ this.taskService.registerJobForCleanup(context.metadata.jid, this.resolveExpires(context, options), options);
730
+ }
700
731
  }
701
732
  return msgId;
702
733
  }
@@ -745,7 +776,7 @@ class EngineService {
745
776
  }
746
777
  const [state, status] = output;
747
778
  const stateTree = (0, utils_1.restoreHierarchy)(state);
748
- if (status && stateTree.metadata) {
779
+ if (status != null && stateTree.metadata) {
749
780
  stateTree.metadata.js = status;
750
781
  }
751
782
  return stateTree;
@@ -10,8 +10,10 @@ import { StringStringType, Symbols } from '../../types/serializer';
10
10
  declare class ExporterService {
11
11
  appId: string;
12
12
  logger: ILogger;
13
+ /** @hidden */
13
14
  store: StoreService<ProviderClient, ProviderTransaction>;
14
15
  symbols: Promise<Symbols> | Symbols;
16
+ /** @hidden */
15
17
  constructor(appId: string, store: StoreService<ProviderClient, ProviderTransaction>, logger: ILogger);
16
18
  /**
17
19
  * Convert the job hash into a JobExport object.
@@ -9,6 +9,7 @@ const serializer_1 = require("../serializer");
9
9
  * includes dependency list
10
10
  */
11
11
  class ExporterService {
12
+ /** @hidden */
12
13
  constructor(appId, store, logger) {
13
14
  this.appId = appId;
14
15
  this.logger = logger;