@hotmeshio/hotmesh 0.12.1 → 0.14.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 (202) hide show
  1. package/README.md +18 -22
  2. package/build/modules/enums.d.ts +60 -5
  3. package/build/modules/enums.js +62 -7
  4. package/build/modules/errors.d.ts +15 -2
  5. package/build/modules/errors.js +17 -1
  6. package/build/modules/storage.d.ts +1 -0
  7. package/build/modules/storage.js +2 -1
  8. package/build/package.json +8 -2
  9. package/build/services/activities/activity/context.d.ts +22 -0
  10. package/build/services/activities/activity/context.js +76 -0
  11. package/build/services/activities/activity/index.d.ts +116 -0
  12. package/build/services/activities/activity/index.js +299 -0
  13. package/build/services/activities/activity/mapping.d.ts +12 -0
  14. package/build/services/activities/activity/mapping.js +63 -0
  15. package/build/services/activities/activity/process.d.ts +28 -0
  16. package/build/services/activities/activity/process.js +100 -0
  17. package/build/services/activities/activity/protocol.d.ts +39 -0
  18. package/build/services/activities/activity/protocol.js +151 -0
  19. package/build/services/activities/activity/state.d.ts +40 -0
  20. package/build/services/activities/activity/state.js +143 -0
  21. package/build/services/activities/activity/transition.d.ts +23 -0
  22. package/build/services/activities/activity/transition.js +71 -0
  23. package/build/services/activities/activity/verify.d.ts +22 -0
  24. package/build/services/activities/activity/verify.js +85 -0
  25. package/build/services/activities/await.d.ts +1 -4
  26. package/build/services/activities/await.js +2 -36
  27. package/build/services/activities/cycle.d.ts +1 -11
  28. package/build/services/activities/cycle.js +3 -46
  29. package/build/services/activities/hook.d.ts +2 -11
  30. package/build/services/activities/hook.js +30 -50
  31. package/build/services/activities/interrupt.d.ts +2 -4
  32. package/build/services/activities/interrupt.js +4 -38
  33. package/build/services/activities/signal.d.ts +1 -11
  34. package/build/services/activities/signal.js +3 -48
  35. package/build/services/activities/trigger.d.ts +1 -3
  36. package/build/services/activities/trigger.js +0 -3
  37. package/build/services/activities/worker.d.ts +3 -6
  38. package/build/services/activities/worker.js +4 -40
  39. package/build/services/connector/factory.d.ts +6 -0
  40. package/build/services/connector/factory.js +24 -0
  41. package/build/services/dba/index.d.ts +14 -4
  42. package/build/services/dba/index.js +57 -18
  43. package/build/services/durable/activity.d.ts +30 -0
  44. package/build/services/durable/activity.js +46 -0
  45. package/build/services/durable/client.d.ts +26 -31
  46. package/build/services/durable/client.js +26 -31
  47. package/build/services/durable/connection.d.ts +13 -7
  48. package/build/services/durable/connection.js +13 -7
  49. package/build/services/durable/exporter.d.ts +2 -2
  50. package/build/services/durable/exporter.js +27 -12
  51. package/build/services/durable/handle.d.ts +59 -41
  52. package/build/services/durable/handle.js +61 -41
  53. package/build/services/durable/index.d.ts +152 -283
  54. package/build/services/durable/index.js +161 -289
  55. package/build/services/durable/interceptor.d.ts +43 -33
  56. package/build/services/durable/interceptor.js +59 -39
  57. package/build/services/durable/schemas/factory.d.ts +2 -3
  58. package/build/services/durable/schemas/factory.js +180 -30
  59. package/build/services/durable/telemetry.d.ts +80 -0
  60. package/build/services/durable/telemetry.js +137 -0
  61. package/build/services/durable/worker.d.ts +100 -21
  62. package/build/services/durable/worker.js +314 -60
  63. package/build/services/durable/workflow/all.d.ts +1 -1
  64. package/build/services/durable/workflow/all.js +1 -1
  65. package/build/services/durable/workflow/cancellationScope.d.ts +104 -0
  66. package/build/services/durable/workflow/cancellationScope.js +139 -0
  67. package/build/services/durable/workflow/common.d.ts +5 -4
  68. package/build/services/durable/workflow/common.js +6 -1
  69. package/build/services/durable/workflow/{waitFor.d.ts → condition.d.ts} +9 -8
  70. package/build/services/durable/workflow/{waitFor.js → condition.js} +44 -11
  71. package/build/services/durable/workflow/continueAsNew.d.ts +65 -0
  72. package/build/services/durable/workflow/continueAsNew.js +92 -0
  73. package/build/services/durable/workflow/didRun.d.ts +2 -2
  74. package/build/services/durable/workflow/didRun.js +4 -4
  75. package/build/services/durable/workflow/enrich.d.ts +5 -0
  76. package/build/services/durable/workflow/enrich.js +5 -0
  77. package/build/services/durable/workflow/entityMethods.d.ts +7 -0
  78. package/build/services/durable/workflow/entityMethods.js +7 -0
  79. package/build/services/durable/workflow/execHook.js +3 -3
  80. package/build/services/durable/workflow/execHookBatch.js +2 -2
  81. package/build/services/durable/workflow/{execChild.d.ts → executeChild.d.ts} +4 -40
  82. package/build/services/durable/workflow/{execChild.js → executeChild.js} +36 -45
  83. package/build/services/durable/workflow/hook.d.ts +1 -1
  84. package/build/services/durable/workflow/hook.js +4 -3
  85. package/build/services/durable/workflow/index.d.ts +45 -50
  86. package/build/services/durable/workflow/index.js +46 -51
  87. package/build/services/durable/workflow/interruption.d.ts +7 -6
  88. package/build/services/durable/workflow/interruption.js +11 -7
  89. package/build/services/durable/workflow/patched.d.ts +72 -0
  90. package/build/services/durable/workflow/patched.js +110 -0
  91. package/build/services/durable/workflow/proxyActivities.d.ts +7 -7
  92. package/build/services/durable/workflow/proxyActivities.js +51 -15
  93. package/build/services/durable/workflow/searchMethods.d.ts +7 -0
  94. package/build/services/durable/workflow/searchMethods.js +7 -0
  95. package/build/services/durable/workflow/signal.d.ts +4 -4
  96. package/build/services/durable/workflow/signal.js +4 -4
  97. package/build/services/durable/workflow/{sleepFor.d.ts → sleep.d.ts} +7 -7
  98. package/build/services/durable/workflow/{sleepFor.js → sleep.js} +39 -10
  99. package/build/services/durable/workflow/terminate.d.ts +55 -0
  100. package/build/services/durable/workflow/{interrupt.js → terminate.js} +21 -21
  101. package/build/services/durable/workflow/trace.js +2 -2
  102. package/build/services/durable/workflow/uuid4.d.ts +14 -0
  103. package/build/services/durable/workflow/uuid4.js +39 -0
  104. package/build/services/durable/workflow/{context.d.ts → workflowInfo.d.ts} +5 -5
  105. package/build/services/durable/workflow/{context.js → workflowInfo.js} +7 -7
  106. package/build/services/engine/compiler.d.ts +19 -0
  107. package/build/services/engine/compiler.js +20 -0
  108. package/build/services/engine/completion.d.ts +46 -0
  109. package/build/services/engine/completion.js +145 -0
  110. package/build/services/engine/dispatch.d.ts +24 -0
  111. package/build/services/engine/dispatch.js +98 -0
  112. package/build/services/engine/index.d.ts +49 -81
  113. package/build/services/engine/index.js +175 -573
  114. package/build/services/engine/init.d.ts +42 -0
  115. package/build/services/engine/init.js +74 -0
  116. package/build/services/engine/pubsub.d.ts +50 -0
  117. package/build/services/engine/pubsub.js +118 -0
  118. package/build/services/engine/reporting.d.ts +20 -0
  119. package/build/services/engine/reporting.js +38 -0
  120. package/build/services/engine/schema.d.ts +23 -0
  121. package/build/services/engine/schema.js +62 -0
  122. package/build/services/engine/signal.d.ts +57 -0
  123. package/build/services/engine/signal.js +117 -0
  124. package/build/services/engine/state.d.ts +35 -0
  125. package/build/services/engine/state.js +61 -0
  126. package/build/services/engine/version.d.ts +31 -0
  127. package/build/services/engine/version.js +73 -0
  128. package/build/services/hotmesh/deployment.d.ts +21 -0
  129. package/build/services/hotmesh/deployment.js +25 -0
  130. package/build/services/hotmesh/index.d.ts +142 -533
  131. package/build/services/hotmesh/index.js +223 -674
  132. package/build/services/hotmesh/init.d.ts +42 -0
  133. package/build/services/hotmesh/init.js +93 -0
  134. package/build/services/hotmesh/jobs.d.ts +67 -0
  135. package/build/services/hotmesh/jobs.js +99 -0
  136. package/build/services/hotmesh/pubsub.d.ts +38 -0
  137. package/build/services/hotmesh/pubsub.js +54 -0
  138. package/build/services/hotmesh/quorum.d.ts +30 -0
  139. package/build/services/hotmesh/quorum.js +62 -0
  140. package/build/services/hotmesh/validation.d.ts +6 -0
  141. package/build/services/hotmesh/validation.js +28 -0
  142. package/build/services/quorum/index.js +1 -0
  143. package/build/services/router/consumption/index.d.ts +11 -5
  144. package/build/services/router/consumption/index.js +24 -17
  145. package/build/services/router/error-handling/index.d.ts +2 -2
  146. package/build/services/router/error-handling/index.js +14 -14
  147. package/build/services/router/index.d.ts +1 -1
  148. package/build/services/router/index.js +2 -2
  149. package/build/services/serializer/index.d.ts +22 -0
  150. package/build/services/serializer/index.js +39 -1
  151. package/build/services/store/index.d.ts +1 -0
  152. package/build/services/store/providers/postgres/exporter-sql.d.ts +2 -2
  153. package/build/services/store/providers/postgres/exporter-sql.js +4 -4
  154. package/build/services/store/providers/postgres/kvtables.js +7 -6
  155. package/build/services/store/providers/postgres/kvtypes/hash/basic.js +67 -52
  156. package/build/services/store/providers/postgres/kvtypes/hash/jsonb.js +87 -72
  157. package/build/services/store/providers/postgres/kvtypes/hash/udata.js +106 -79
  158. package/build/services/store/providers/postgres/kvtypes/hash/utils.d.ts +16 -0
  159. package/build/services/store/providers/postgres/kvtypes/hash/utils.js +29 -16
  160. package/build/services/store/providers/postgres/postgres.d.ts +1 -0
  161. package/build/services/store/providers/postgres/postgres.js +14 -4
  162. package/build/services/stream/factory.d.ts +3 -1
  163. package/build/services/stream/factory.js +2 -2
  164. package/build/services/stream/index.d.ts +1 -0
  165. package/build/services/stream/providers/nats/nats.d.ts +1 -0
  166. package/build/services/stream/providers/nats/nats.js +1 -0
  167. package/build/services/stream/providers/postgres/credentials.d.ts +56 -0
  168. package/build/services/stream/providers/postgres/credentials.js +129 -0
  169. package/build/services/stream/providers/postgres/kvtables.js +18 -0
  170. package/build/services/stream/providers/postgres/messages.js +7 -7
  171. package/build/services/stream/providers/postgres/notifications.js +16 -2
  172. package/build/services/stream/providers/postgres/postgres.d.ts +7 -0
  173. package/build/services/stream/providers/postgres/postgres.js +35 -4
  174. package/build/services/stream/providers/postgres/procedures.d.ts +21 -0
  175. package/build/services/stream/providers/postgres/procedures.js +213 -0
  176. package/build/services/stream/providers/postgres/secured.d.ts +34 -0
  177. package/build/services/stream/providers/postgres/secured.js +146 -0
  178. package/build/services/stream/providers/postgres/stats.d.ts +1 -0
  179. package/build/services/stream/providers/postgres/stats.js +1 -0
  180. package/build/services/stream/registry.d.ts +1 -1
  181. package/build/services/stream/registry.js +5 -2
  182. package/build/services/telemetry/index.d.ts +10 -1
  183. package/build/services/telemetry/index.js +40 -7
  184. package/build/services/worker/credentials.d.ts +51 -0
  185. package/build/services/worker/credentials.js +87 -0
  186. package/build/services/worker/index.d.ts +2 -2
  187. package/build/services/worker/index.js +7 -6
  188. package/build/types/codec.d.ts +84 -0
  189. package/build/types/codec.js +2 -0
  190. package/build/types/dba.d.ts +39 -3
  191. package/build/types/durable.d.ts +123 -25
  192. package/build/types/error.d.ts +10 -0
  193. package/build/types/exporter.d.ts +1 -1
  194. package/build/types/hotmesh.d.ts +67 -4
  195. package/build/types/index.d.ts +2 -1
  196. package/build/types/provider.d.ts +2 -2
  197. package/build/types/quorum.d.ts +35 -1
  198. package/build/types/stream.d.ts +12 -6
  199. package/package.json +8 -2
  200. package/build/services/activities/activity.d.ts +0 -192
  201. package/build/services/activities/activity.js +0 -786
  202. package/build/services/durable/workflow/interrupt.d.ts +0 -55
@@ -37,15 +37,47 @@ export interface PruneOptions {
37
37
  jobs?: boolean;
38
38
  /**
39
39
  * If true, hard-deletes expired stream messages older than the
40
- * retention window.
40
+ * retention window from both `engine_streams` and `worker_streams`.
41
+ * Use `engineStreams` / `workerStreams` for independent control.
41
42
  * @default true
42
43
  */
43
44
  streams?: boolean;
45
+ /**
46
+ * Override for `engine_streams` cleanup. When set, takes precedence
47
+ * over `streams` for the engine table. Engine streams contain internal
48
+ * routing messages and can be pruned aggressively.
49
+ * @default undefined (falls back to `streams`)
50
+ */
51
+ engineStreams?: boolean;
52
+ /**
53
+ * Override for `worker_streams` cleanup. When set, takes precedence
54
+ * over `streams` for the worker table. Worker streams contain workflow
55
+ * input arguments and activity payloads needed by the exporter — use
56
+ * a longer retention to preserve export fidelity.
57
+ * @default undefined (falls back to `streams`)
58
+ */
59
+ workerStreams?: boolean;
60
+ /**
61
+ * Retention override for `engine_streams`. When set, uses this interval
62
+ * instead of the global `expire` for engine stream cleanup.
63
+ * @default undefined (falls back to `expire`)
64
+ *
65
+ * @example '24 hours'
66
+ */
67
+ engineStreamsExpire?: string;
68
+ /**
69
+ * Retention override for `worker_streams`. When set, uses this interval
70
+ * instead of the global `expire` for worker stream cleanup.
71
+ * @default undefined (falls back to `expire`)
72
+ *
73
+ * @example '90 days'
74
+ */
75
+ workerStreamsExpire?: string;
44
76
  /**
45
77
  * If true, strips execution-artifact attributes from completed,
46
78
  * un-pruned jobs. Preserves `jdata` (return data), `udata`
47
79
  * (searchable data), and `jmark` (timeline/event history for
48
- * Temporal-compatible export). See `keepHmark` for `hmark`.
80
+ * workflow execution export). See `keepHmark` for `hmark`.
49
81
  * @default false
50
82
  */
51
83
  attributes?: boolean;
@@ -79,8 +111,12 @@ export interface PruneOptions {
79
111
  export interface PruneResult {
80
112
  /** Number of expired job rows hard-deleted */
81
113
  jobs: number;
82
- /** Number of expired stream message rows hard-deleted */
114
+ /** Number of expired stream message rows hard-deleted (engine + worker) */
83
115
  streams: number;
116
+ /** Number of expired engine_streams rows hard-deleted */
117
+ engineStreams: number;
118
+ /** Number of expired worker_streams rows hard-deleted */
119
+ workerStreams: number;
84
120
  /** Number of execution-artifact attribute rows stripped from completed jobs */
85
121
  attributes: number;
86
122
  /** Number of transient (entity IS NULL) job rows hard-deleted */
@@ -9,12 +9,18 @@ import { StreamData, StreamError } from './stream';
9
9
  type WorkflowConfig = {
10
10
  /**
11
11
  * Backoff coefficient for retry mechanism.
12
- * @default 10 (HMSH_DURABLE_EXP_BACKOFF)
12
+ * @default 5 (HMSH_DURABLE_EXP_BACKOFF)
13
13
  */
14
14
  backoffCoefficient?: number;
15
+ /**
16
+ * Initial interval before the first retry attempt.
17
+ * Formula: initialInterval * backoffCoefficient^retryCount, clamped by maximumInterval.
18
+ * @default '1s' (HMSH_DURABLE_INITIAL_INTERVAL)
19
+ */
20
+ initialInterval?: string;
15
21
  /**
16
22
  * Maximum number of attempts for retries.
17
- * @default 5 (HMSH_DURABLE_MAX_ATTEMPTS)
23
+ * @default 50 (HMSH_DURABLE_MAX_ATTEMPTS)
18
24
  */
19
25
  maximumAttempts?: number;
20
26
  /**
@@ -104,6 +110,23 @@ type WorkflowContext = {
104
110
  */
105
111
  expire?: number;
106
112
  };
113
+ /**
114
+ * Context available inside an executing activity function via
115
+ * `Durable.activity.getContext()`. Populated by the activity worker
116
+ * using `activityAsyncLocalStorage`.
117
+ */
118
+ type DurableActivityContext = {
119
+ /** The name of the activity function being executed */
120
+ activityName: string;
121
+ /** The arguments passed to the activity */
122
+ arguments: any[];
123
+ /** Optional metadata provided via `proxyActivities({ headers })` */
124
+ headers: Record<string, any>;
125
+ /** The workflow ID of the parent workflow that dispatched this activity */
126
+ workflowId: string;
127
+ /** The workflow topic of the parent workflow */
128
+ workflowTopic: string;
129
+ };
107
130
  /**
108
131
  * The schema for the full-text-search
109
132
  * @deprecated
@@ -354,6 +377,8 @@ type SignalOptions = {
354
377
  type ActivityWorkflowDataType = {
355
378
  activityName: string;
356
379
  arguments: any[];
380
+ headers?: Record<string, any>;
381
+ startToCloseTimeout?: number;
357
382
  workflowId: string;
358
383
  workflowTopic: string;
359
384
  };
@@ -365,6 +390,7 @@ type WorkflowDataType = {
365
390
  originJobId?: string;
366
391
  canRetry?: boolean;
367
392
  expire?: number;
393
+ continueGeneration?: number;
368
394
  };
369
395
  type Connection = ProviderConfig | ProvidersConfig;
370
396
  type ClientConfig = {
@@ -385,6 +411,14 @@ type WorkerConfig = {
385
411
  taskQueue: string;
386
412
  /** Target function or a record type with a name (string) and reference function */
387
413
  workflow: Function | Record<string | symbol, Function>;
414
+ /**
415
+ * Optional activity functions to register with this worker's task queue.
416
+ * When provided, these activities are registered and served on `{taskQueue}-activity`.
417
+ * Workflows can then call them via `proxyActivities()` without passing activities inline.
418
+ *
419
+ * Workflows can then call them via `proxyActivities()` without passing activities inline.
420
+ */
421
+ activities?: Record<string, Function>;
388
422
  /** Additional options for configuring the worker */
389
423
  options?: WorkerOptions;
390
424
  /** Search options for workflow execution details */
@@ -395,6 +429,19 @@ type WorkerConfig = {
395
429
  * when identifying the point of presence within the mesh.
396
430
  */
397
431
  guid?: string;
432
+ /**
433
+ * Scoped Postgres credentials for database-level worker isolation.
434
+ * When provided, the worker connects as a restricted Postgres role
435
+ * that can only dequeue/ack/respond on its allowed stream names
436
+ * via SECURITY DEFINER stored procedures.
437
+ *
438
+ * Provision credentials via `HotMesh.provisionWorkerRole()` (or
439
+ * the convenience alias `Durable.provisionWorkerRole()`).
440
+ */
441
+ workerCredentials?: {
442
+ user: string;
443
+ password: string;
444
+ };
398
445
  };
399
446
  type FindWhereQuery = {
400
447
  field: string;
@@ -437,10 +484,12 @@ type FindJobsOptions = {
437
484
  type WorkerOptions = {
438
485
  /** Log level: debug, info, warn, error */
439
486
  logLevel?: LogLevel;
440
- /** Maximum number of attempts, default 5 (HMSH_DURABLE_MAX_ATTEMPTS) */
487
+ /** Maximum number of attempts, default 50 (HMSH_DURABLE_MAX_ATTEMPTS) */
441
488
  maximumAttempts?: number;
442
489
  /** Backoff coefficient for retry logic, default 10 (HMSH_DURABLE_EXP_BACKOFF) */
443
490
  backoffCoefficient?: number;
491
+ /** Initial interval before the first retry, default '1s' (HMSH_DURABLE_INITIAL_INTERVAL) */
492
+ initialInterval?: string;
444
493
  /** Maximum interval between retries, default 120s (HMSH_DURABLE_MAX_INTERVAL) */
445
494
  maximumInterval?: string;
446
495
  };
@@ -458,7 +507,7 @@ type ProxyType<ACT> = {
458
507
  type ActivityConfig = {
459
508
  /** place holder setting; unused at this time (re: activity workflow expire configuration) */
460
509
  expire?: number;
461
- /** Start to close timeout for the activity; not yet implemented */
510
+ /** Maximum time an activity can run after starting execution. If exceeded, the activity fails with a timeout error. Accepts duration strings (e.g., '30s', '5m', '1h'). */
462
511
  startToCloseTimeout?: string;
463
512
  /** Configuration for specific activities, type not yet specified */
464
513
  activities?: any;
@@ -481,7 +530,7 @@ type ActivityConfig = {
481
530
  * // Default: uses workflow's task queue (backward compatible)
482
531
  * const activities = Durable.workflow.proxyActivities<typeof activities>({
483
532
  * activities,
484
- * retryPolicy: { maximumAttempts: 3 }
533
+ * retry: { maximumAttempts: 3 }
485
534
  * });
486
535
  * // If workflow taskQueue is "orders", uses "orders-activity"
487
536
  *
@@ -489,18 +538,24 @@ type ActivityConfig = {
489
538
  * const { auditLog } = Durable.workflow.proxyActivities<typeof activities>({
490
539
  * activities: { auditLog },
491
540
  * taskQueue: 'shared-activities', // Uses "shared-activities-activity"
492
- * retryPolicy: { maximumAttempts: 3 }
541
+ * retry: { maximumAttempts: 3 }
493
542
  * });
494
543
  * ```
495
544
  */
496
545
  taskQueue?: string;
546
+ /** Optional metadata to pass alongside activity arguments. This metadata
547
+ * is transported as a dedicated schema field (not inside args) and made
548
+ * available to the activity function via `Durable.activity.getContext()`. */
549
+ headers?: Record<string, any>;
497
550
  /** Retry policy configuration for activities */
498
- retryPolicy?: {
499
- /** Maximum number of retry attempts, default is 5 (HMSH_DURABLE_MAX_ATTEMPTS) */
551
+ retry?: {
552
+ /** Maximum number of retry attempts, default is 50 (HMSH_DURABLE_MAX_ATTEMPTS) */
500
553
  maximumAttempts?: number;
501
- /** Factor by which the retry timeout increases, default is 10 (HMSH_DURABLE_MAX_INTERVAL) */
554
+ /** Factor by which the retry timeout increases, default is 10 (HMSH_DURABLE_EXP_BACKOFF) */
502
555
  backoffCoefficient?: number;
503
- /** Maximum interval between retries, default is '120s' (HMSH_DURABLE_EXP_BACKOFF) */
556
+ /** Initial interval before the first retry. Formula: initialInterval * backoffCoefficient^retryCount, clamped by maximumInterval. Default is '1s' */
557
+ initialInterval?: string;
558
+ /** Maximum interval between retries, default is '120s' (HMSH_DURABLE_MAX_INTERVAL) */
504
559
  maximumInterval?: string;
505
560
  /** Whether to throw an error on failure, default is true */
506
561
  throwOnError?: boolean;
@@ -547,7 +602,7 @@ interface ClientWorkflow {
547
602
  * @example
548
603
  * ```typescript
549
604
  * // Simple logging interceptor
550
- * const loggingInterceptor: WorkflowInterceptor = {
605
+ * const loggingInterceptor: WorkflowInboundCallsInterceptor = {
551
606
  * async execute(ctx, next) {
552
607
  * console.log('Before workflow');
553
608
  * try {
@@ -565,7 +620,7 @@ interface ClientWorkflow {
565
620
  * Durable.registerInterceptor(loggingInterceptor);
566
621
  * ```
567
622
  */
568
- export interface WorkflowInterceptor {
623
+ export interface WorkflowInboundCallsInterceptor {
569
624
  /**
570
625
  * Called before workflow execution to wrap the workflow in custom logic
571
626
  *
@@ -606,27 +661,32 @@ export interface WorkflowInterceptor {
606
661
  */
607
662
  export interface InterceptorRegistry {
608
663
  /**
609
- * Array of registered workflow interceptors that will wrap workflow execution
664
+ * Array of registered inbound interceptors that will wrap workflow execution
610
665
  * in the order they were registered (first registered = outermost wrapper).
611
666
  */
612
- interceptors: WorkflowInterceptor[];
667
+ inbound: WorkflowInboundCallsInterceptor[];
613
668
  /**
614
- * Array of registered activity interceptors that will wrap individual
669
+ * Array of registered outbound interceptors that will wrap individual
615
670
  * proxied activity calls in the order they were registered
616
671
  * (first registered = outermost wrapper).
617
672
  */
618
- activityInterceptors: ActivityInterceptor[];
673
+ outbound: WorkflowOutboundCallsInterceptor[];
674
+ /**
675
+ * Array of registered activity inbound interceptors that wrap the actual
676
+ * activity function execution on the activity worker side.
677
+ */
678
+ activityInbound: ActivityInboundCallsInterceptor[];
619
679
  }
620
680
  /**
621
681
  * Context provided to an activity interceptor, containing metadata
622
682
  * about the proxied activity being invoked.
623
683
  */
624
- export interface ActivityInterceptorContext {
684
+ export interface WorkflowOutboundCallsInterceptorContext {
625
685
  /** The name of the activity function being called */
626
686
  activityName: string;
627
687
  /** The arguments passed to the activity call */
628
688
  args: any[];
629
- /** The activity configuration (retryPolicy, taskQueue, etc.) */
689
+ /** The activity configuration (retry, taskQueue, etc.) */
630
690
  options?: ActivityConfig;
631
691
  }
632
692
  /**
@@ -653,13 +713,13 @@ export interface ActivityInterceptorContext {
653
713
  *
654
714
  * @example
655
715
  * ```typescript
656
- * const auditInterceptor: ActivityInterceptor = {
716
+ * const auditInterceptor: WorkflowOutboundCallsInterceptor = {
657
717
  * async execute(activityCtx, workflowCtx, next) {
658
718
  * const { auditLog } = Durable.workflow.proxyActivities<{
659
719
  * auditLog: (id: string, action: string) => Promise<void>;
660
720
  * }>({
661
721
  * taskQueue: 'shared-audit',
662
- * retryPolicy: { maximumAttempts: 3 },
722
+ * retry: { maximumAttempts: 3 },
663
723
  * });
664
724
  *
665
725
  * await auditLog(workflowCtx.get('workflowId'), `before:${activityCtx.activityName}`);
@@ -669,20 +729,58 @@ export interface ActivityInterceptorContext {
669
729
  * },
670
730
  * };
671
731
  *
672
- * Durable.registerActivityInterceptor(auditInterceptor);
732
+ * Durable.registerWorkflowOutboundCallsInterceptor(auditInterceptor);
673
733
  * ```
674
734
  */
675
- export interface ActivityInterceptor {
735
+ export interface WorkflowOutboundCallsInterceptor {
676
736
  /**
677
737
  * Called around each proxied activity invocation. Code before `next()`
678
738
  * runs in the before phase; code after `next()` runs in the after phase
679
739
  * once the activity result is available on replay.
680
740
  *
681
741
  * @param activityCtx - Metadata about the activity being called (args may be modified)
682
- * @param workflowCtx - The workflow context map (same as WorkflowInterceptor receives)
742
+ * @param workflowCtx - The workflow context map (same as WorkflowInboundCallsInterceptor receives)
683
743
  * @param next - Call to proceed to the next interceptor or the core activity function
684
744
  * @returns The activity result (from replay or after interruption/re-execution)
685
745
  */
686
- execute(activityCtx: ActivityInterceptorContext, workflowCtx: Map<string, any>, next: () => Promise<any>): Promise<any>;
746
+ execute(activityCtx: WorkflowOutboundCallsInterceptorContext, workflowCtx: Map<string, any>, next: () => Promise<any>): Promise<any>;
747
+ }
748
+ /**
749
+ * Interceptor for activity function execution on the activity worker side.
750
+ * Runs inside the activity's `activityAsyncLocalStorage` context, wrapping
751
+ * the actual activity function invocation — not the proxy call in the workflow.
752
+ *
753
+ * Unlike workflow-side interceptors, this runs where the activity actually executes.
754
+ * Use it for cross-cutting concerns like logging, metrics, auth validation,
755
+ * or error enrichment at the point where the activity actually executes.
756
+ *
757
+ * @example
758
+ * ```typescript
759
+ * Durable.registerActivityInboundInterceptor({
760
+ * async execute(activityName, args, next) {
761
+ * console.log(`Activity ${activityName} starting with`, args);
762
+ * const start = Date.now();
763
+ * try {
764
+ * const result = await next();
765
+ * console.log(`Activity ${activityName} completed in ${Date.now() - start}ms`);
766
+ * return result;
767
+ * } catch (err) {
768
+ * console.error(`Activity ${activityName} failed`, err);
769
+ * throw err;
770
+ * }
771
+ * }
772
+ * });
773
+ * ```
774
+ */
775
+ export interface ActivityInboundCallsInterceptor {
776
+ /**
777
+ * Called around the actual activity function execution on the worker.
778
+ *
779
+ * @param activityName - The name of the activity being executed
780
+ * @param args - The arguments passed to the activity
781
+ * @param next - Call to execute the next interceptor or the activity itself
782
+ * @returns The activity function's return value
783
+ */
784
+ execute(activityName: string, args: any[], next: () => Promise<any>): Promise<any>;
687
785
  }
688
- export { ActivityConfig, ActivityWorkflowDataType, ChildResponseType, ClientConfig, ClientWorkflow, ContextType, Connection, FunctionSignature, ProxyResponseType, ProxyType, Registry, SignalOptions, FindJobsOptions, FindOptions, FindWhereOptions, FindWhereQuery, HookOptions, SearchResults, WorkerConfig, WorkflowConfig, WorkerOptions, WorkflowSearchOptions, WorkflowDataType, WorkflowOptions, WorkflowContext, };
786
+ export { ActivityConfig, DurableActivityContext, ActivityWorkflowDataType, ChildResponseType, ClientConfig, ClientWorkflow, ContextType, Connection, FunctionSignature, ProxyResponseType, ProxyType, Registry, SignalOptions, FindJobsOptions, FindOptions, FindWhereOptions, FindWhereQuery, HookOptions, SearchResults, WorkerConfig, WorkflowConfig, WorkerOptions, WorkflowSearchOptions, WorkflowDataType, WorkflowOptions, WorkflowContext, };
@@ -2,6 +2,7 @@ export type DurableChildErrorType = {
2
2
  arguments: string[];
3
3
  await?: boolean;
4
4
  backoffCoefficient?: number;
5
+ initialInterval?: number;
5
6
  index: number;
6
7
  expire?: number;
7
8
  persistent?: boolean;
@@ -29,10 +30,13 @@ export type DurableWaitForAllErrorType = {
29
30
  };
30
31
  export type DurableProxyErrorType = {
31
32
  arguments: string[];
33
+ headers?: Record<string, any>;
32
34
  activityName: string;
33
35
  backoffCoefficient?: number;
36
+ initialInterval?: number;
34
37
  index: number;
35
38
  expire?: number;
39
+ startToCloseTimeout?: number;
36
40
  maximumAttempts?: number;
37
41
  maximumInterval?: number;
38
42
  originJobId: string | null;
@@ -53,3 +57,9 @@ export type DurableSleepErrorType = {
53
57
  workflowDimension: string;
54
58
  workflowId: string;
55
59
  };
60
+ export type DurableContinueAsNewErrorType = {
61
+ arguments: any[];
62
+ index: number;
63
+ workflowDimension: string;
64
+ workflowId: string;
65
+ };
@@ -251,7 +251,7 @@ export interface ExecutionExportOptions {
251
251
  * When true, fetches the full stream message history for this workflow
252
252
  * from the worker_streams table and attaches it as `stream_history`.
253
253
  * This provides raw activity input/output data from the original stream
254
- * messages, enabling Temporal-grade export fidelity.
254
+ * messages, enabling full export fidelity.
255
255
  *
256
256
  * @default false
257
257
  */
@@ -122,7 +122,7 @@ type HotMeshEngine = {
122
122
  * @example
123
123
  * ```typescript
124
124
  * {
125
- * retryPolicy: {
125
+ * retry: {
126
126
  * maximumAttempts: 5,
127
127
  * backoffCoefficient: 2,
128
128
  * maximumInterval: '300s'
@@ -130,8 +130,25 @@ type HotMeshEngine = {
130
130
  * }
131
131
  * ```
132
132
  */
133
- retryPolicy?: import('./stream').RetryPolicy;
133
+ retry?: import('./stream').RetryPolicy;
134
134
  };
135
+ /**
136
+ * Configuration for a HotMesh worker that consumes messages from a
137
+ * Postgres stream topic. Workers can run on the same process as the
138
+ * engine or on entirely separate servers — the only coupling is the
139
+ * shared Postgres database.
140
+ *
141
+ * ## Connection Modes
142
+ *
143
+ * **Standard**: Worker uses the same Postgres credentials as the engine.
144
+ * Set `connection` with admin credentials. Suitable for trusted, co-located workers.
145
+ *
146
+ * **Secured**: Worker connects as a restricted Postgres role with
147
+ * `workerCredentials`. The role can only dequeue/ack/respond on its
148
+ * allowed stream topics via SECURITY DEFINER stored procedures — zero
149
+ * direct table access. Use for untrusted workloads: K8s containers,
150
+ * LLM agents, third-party integrations.
151
+ */
135
152
  type HotMeshWorker = {
136
153
  /**
137
154
  * the topic/task queue that the worker subscribes to (stream_name)
@@ -212,7 +229,7 @@ type HotMeshWorker = {
212
229
  * @example
213
230
  * ```typescript
214
231
  * {
215
- * retryPolicy: {
232
+ * retry: {
216
233
  * maximumAttempts: 5,
217
234
  * backoffCoefficient: 2,
218
235
  * maximumInterval: '300s'
@@ -220,7 +237,53 @@ type HotMeshWorker = {
220
237
  * }
221
238
  * ```
222
239
  */
223
- retryPolicy?: import('./stream').RetryPolicy;
240
+ retry?: import('./stream').RetryPolicy;
241
+ /**
242
+ * Scoped Postgres credentials for database-level worker isolation.
243
+ *
244
+ * When provided, the `user` and `password` in the worker's connection
245
+ * options are overridden with these values, and all stream operations
246
+ * route through SECURITY DEFINER stored procedures that validate
247
+ * `app.allowed_streams` before executing. The worker role has **zero
248
+ * direct table access**.
249
+ *
250
+ * Use this for workers running in untrusted environments: pluggable
251
+ * K8s containers, LLM-driven agents (e.g., MCP tool servers),
252
+ * third-party integrations, or any workload that should be isolated
253
+ * from the engine's database surface.
254
+ *
255
+ * Provision credentials via `HotMesh.provisionWorkerRole()` or by
256
+ * creating a Postgres role with `EXECUTE` on the schema's worker
257
+ * stored procedures and `ALTER ROLE ... SET app.allowed_streams`.
258
+ *
259
+ * **Limitations:** Workflows running under scoped credentials cannot
260
+ * use `Durable.workflow.entity()`, `Durable.workflow.search()`, or
261
+ * `Durable.workflow.enrich()` — these write directly to the `jobs`
262
+ * and `jobs_attributes` tables, which the scoped role has no access
263
+ * to. All other workflow primitives (`proxyActivities`, `sleep`,
264
+ * `condition`, `signal`, `emit`, `executeChild`, etc.) work normally.
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * // Admin provisions scoped credentials (one-time)
269
+ * const cred = await HotMesh.provisionWorkerRole({
270
+ * connection: { class: Postgres, options: adminOptions },
271
+ * streamNames: ['order.process'],
272
+ * });
273
+ *
274
+ * // Worker connects with restricted role
275
+ * workers: [{
276
+ * topic: 'order.process',
277
+ * connection: { class: Postgres, options: { host: 'pg.prod', database: 'db' } },
278
+ * workerCredentials: { user: cred.roleName, password: cred.password },
279
+ * callback: myCallback,
280
+ * }]
281
+ * ```
282
+ */
283
+ workerCredentials?: {
284
+ user: string;
285
+ password: string;
286
+ };
224
287
  };
225
288
  type HotMeshConfig = {
226
289
  appId: string;
@@ -1,9 +1,10 @@
1
1
  export { ActivityType, ActivityDataType, ActivityContext, ActivityData, ActivityDuplex, ActivityLeg, ActivityMetadata, Consumes, AwaitActivity, BaseActivity, CycleActivity, HookActivity, WorkerActivity, InterruptActivity, SignalActivity, TriggerActivity, TriggerActivityStats, } from './activity';
2
2
  export { App, AppVID, AppTransitions, AppSubscriptions } from './app';
3
3
  export { AsyncSignal } from './async';
4
+ export { PayloadCodec } from './codec';
4
5
  export { CacheMode } from './cache';
5
6
  export { CollationFaultType, CollationStage } from './collator';
6
- export { ActivityConfig, ActivityInterceptor, ActivityInterceptorContext, ActivityWorkflowDataType, ChildResponseType, ClientConfig, ClientWorkflow, ContextType, Connection, ProxyResponseType, ProxyType, Registry, SignalOptions, FindJobsOptions, FindOptions, FindWhereOptions, FindWhereQuery, HookOptions, SearchResults, WorkflowConfig, WorkerConfig, WorkerOptions, WorkflowContext, WorkflowSearchOptions, WorkflowSearchSchema, WorkflowDataType, WorkflowOptions, WorkflowInterceptor, InterceptorRegistry, } from './durable';
7
+ export { ActivityConfig, DurableActivityContext, WorkflowOutboundCallsInterceptor, WorkflowOutboundCallsInterceptorContext, ActivityInboundCallsInterceptor, ActivityWorkflowDataType, ChildResponseType, ClientConfig, ClientWorkflow, ContextType, Connection, ProxyResponseType, ProxyType, Registry, SignalOptions, FindJobsOptions, FindOptions, FindWhereOptions, FindWhereQuery, HookOptions, SearchResults, WorkflowConfig, WorkerConfig, WorkerOptions, WorkflowContext, WorkflowSearchOptions, WorkflowSearchSchema, WorkflowDataType, WorkflowOptions, WorkflowInboundCallsInterceptor, InterceptorRegistry, } from './durable';
7
8
  export { PruneOptions, PruneResult, } from './dba';
8
9
  export { DurableChildErrorType, DurableProxyErrorType, DurableSleepErrorType, DurableWaitForAllErrorType, DurableWaitForErrorType, } from './error';
9
10
  export { ActivityAction, ActivityDetail, ActivityInputMap, ActivityTaskCompletedAttributes, ActivityTaskFailedAttributes, ActivityTaskScheduledAttributes, ChildWorkflowExecutionCompletedAttributes, ChildWorkflowExecutionFailedAttributes, ChildWorkflowExecutionStartedAttributes, DependencyExport, DurableJobExport, ExecutionExportOptions, ExportCycles, ExportFields, ExportItem, ExportMode, ExportOptions, ExportTransitions, JobAction, JobActionExport, JobAttributesRow, JobExport, JobRow, JobTimeline, StreamHistoryEntry, TimelineType, TimerFiredAttributes, TimerStartedAttributes, TransitionType, WorkflowEventAttributes, WorkflowEventCategory, WorkflowEventType, WorkflowExecution, WorkflowExecutionCompletedAttributes, WorkflowExecutionEvent, WorkflowExecutionFailedAttributes, WorkflowExecutionSignaledAttributes, WorkflowExecutionStartedAttributes, WorkflowExecutionStatus, WorkflowExecutionSummary, } from './exporter';
@@ -69,7 +69,7 @@ export type ProviderConfig = {
69
69
  * @example
70
70
  * ```typescript
71
71
  * {
72
- * retryPolicy: {
72
+ * retry: {
73
73
  * maximumAttempts: 5,
74
74
  * backoffCoefficient: 2,
75
75
  * maximumInterval: '300s'
@@ -77,7 +77,7 @@ export type ProviderConfig = {
77
77
  * }
78
78
  * ```
79
79
  */
80
- retryPolicy?: import('./stream').RetryPolicy;
80
+ retry?: import('./stream').RetryPolicy;
81
81
  };
82
82
  export type ProvidersConfig = {
83
83
  sub: ProviderConfig;
@@ -16,7 +16,7 @@ export interface NetworkStat {
16
16
  tx_sec: number;
17
17
  ms: number;
18
18
  }
19
- /** reveals: memory, cpu, network */
19
+ /** Host-level resource snapshot collected at pong time. */
20
20
  export interface SystemHealth {
21
21
  TotalMemoryGB: string;
22
22
  FreeMemoryGB: string;
@@ -36,21 +36,55 @@ export type ThrottleOptions = {
36
36
  /** namespace */
37
37
  namespace?: string;
38
38
  };
39
+ /**
40
+ * Snapshot of a single engine or worker instance, returned by
41
+ * `HotMesh.rollCall()`. Each connected instance responds to the
42
+ * quorum PING with its current profile.
43
+ *
44
+ * **Engines** populate `stream` (the engine stream key).
45
+ * **Workers** populate `worker_topic` (the task queue topic) and `stream`.
46
+ *
47
+ * Use `counts` and `error_count` for throughput and health monitoring.
48
+ */
39
49
  export interface QuorumProfile {
50
+ /** Namespace the instance belongs to. */
40
51
  namespace: string;
52
+ /** Application ID (matches `HotMeshConfig.appId`). */
41
53
  app_id: string;
54
+ /** Unique instance GUID (engine or worker). */
42
55
  engine_id: string;
56
+ /** Entity name (if applicable). */
43
57
  entity?: string;
58
+ /** Worker task queue topic. Present only for worker instances. */
44
59
  worker_topic?: string;
60
+ /** Stream key this instance consumes from. */
45
61
  stream?: string;
62
+ /** Number of pending (unprocessed) messages in the stream. */
46
63
  stream_depth?: number;
64
+ /**
65
+ * Cumulative messages processed, keyed by status code.
66
+ * Common codes: `'200'` (success), `'590'` (child workflow),
67
+ * `'591'` (activity dispatch), `'500'` (error).
68
+ */
47
69
  counts?: Record<string, number>;
70
+ /**
71
+ * Consecutive stream consumption errors. `0` = healthy.
72
+ * Non-zero means the consumer is in exponential backoff recovery.
73
+ */
74
+ error_count?: number;
75
+ /** ISO timestamp of when this instance was initialized. */
48
76
  inited?: string;
77
+ /** ISO timestamp of when this profile was generated. */
49
78
  timestamp?: string;
79
+ /** Current throttle delay in ms (`0` = no throttle). */
50
80
  throttle?: number;
81
+ /** Interval (ms) before reclaiming unacknowledged messages. */
51
82
  reclaimDelay?: number;
83
+ /** Max messages to reclaim per cycle. */
52
84
  reclaimCount?: number;
85
+ /** Host-level memory, CPU, and network stats. */
53
86
  system?: SystemHealth;
87
+ /** Stringified worker callback function (only if `signature: true` in rollcall). */
54
88
  signature?: string;
55
89
  }
56
90
  interface QuorumMessageBase {
@@ -5,7 +5,7 @@ import { ProviderTransaction } from './provider';
5
5
  *
6
6
  * @example
7
7
  * ```typescript
8
- * const retryPolicy: RetryPolicy = {
8
+ * const retry: RetryPolicy = {
9
9
  * maximumAttempts: 5,
10
10
  * backoffCoefficient: 2,
11
11
  * maximumInterval: '300s',
@@ -172,7 +172,7 @@ export type RouterConfig = {
172
172
  /** if true, will not process stream messages; default true */
173
173
  readonly?: boolean;
174
174
  /** Retry policy for worker messages. Applied when worker callback throws an error */
175
- retryPolicy?: RetryPolicy;
175
+ retry?: RetryPolicy;
176
176
  };
177
177
  export type StreamProviderType = 'postgres' | 'nats' | 'sqs';
178
178
  export interface StreamConfig {
@@ -195,7 +195,13 @@ export interface StreamConfig {
195
195
  * }
196
196
  * ```
197
197
  */
198
- retryPolicy?: RetryPolicy;
198
+ retry?: RetryPolicy;
199
+ /**
200
+ * When true, worker stream operations use SECURITY DEFINER stored
201
+ * procedures instead of raw SQL. Enabled automatically when the
202
+ * worker connects with scoped `workerCredentials`.
203
+ */
204
+ securedWorker?: boolean;
199
205
  postgres?: {
200
206
  pollInterval?: number;
201
207
  vacuumInterval?: number;
@@ -227,7 +233,7 @@ export interface StreamMessage {
227
233
  * Retry policy configuration for this message.
228
234
  * Populated from database columns when available.
229
235
  */
230
- retryPolicy?: RetryPolicy;
236
+ retry?: RetryPolicy;
231
237
  }
232
238
  export interface StreamMessageMetadata {
233
239
  timestamp?: number;
@@ -265,7 +271,7 @@ export interface PublishMessageConfig {
265
271
  * @example
266
272
  * ```typescript
267
273
  * await streamService.publishMessages('my-topic', [msg], {
268
- * retryPolicy: {
274
+ * retry: {
269
275
  * maximumAttempts: 10,
270
276
  * backoffCoefficient: 2,
271
277
  * maximumInterval: '600s',
@@ -273,7 +279,7 @@ export interface PublishMessageConfig {
273
279
  * });
274
280
  * ```
275
281
  */
276
- retryPolicy?: RetryPolicy;
282
+ retry?: RetryPolicy;
277
283
  }
278
284
  /**
279
285
  * Notification consumer configuration for PostgreSQL stream provider.