@hotmeshio/hotmesh 0.8.0 → 0.10.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 (164) hide show
  1. package/README.md +178 -43
  2. package/build/index.d.ts +12 -11
  3. package/build/index.js +15 -13
  4. package/build/modules/enums.d.ts +23 -34
  5. package/build/modules/enums.js +26 -38
  6. package/build/modules/errors.d.ts +16 -16
  7. package/build/modules/errors.js +37 -37
  8. package/build/package.json +63 -67
  9. package/build/services/activities/activity.d.ts +58 -7
  10. package/build/services/activities/activity.js +67 -38
  11. package/build/services/activities/await.d.ts +101 -0
  12. package/build/services/activities/await.js +101 -0
  13. package/build/services/activities/cycle.d.ts +82 -0
  14. package/build/services/activities/cycle.js +86 -8
  15. package/build/services/activities/hook.d.ts +139 -1
  16. package/build/services/activities/hook.js +140 -2
  17. package/build/services/activities/interrupt.d.ts +112 -0
  18. package/build/services/activities/interrupt.js +118 -5
  19. package/build/services/activities/signal.d.ts +108 -3
  20. package/build/services/activities/signal.js +113 -8
  21. package/build/services/activities/trigger.d.ts +56 -4
  22. package/build/services/activities/trigger.js +119 -35
  23. package/build/services/activities/worker.d.ts +107 -0
  24. package/build/services/activities/worker.js +107 -0
  25. package/build/services/collator/index.d.ts +3 -15
  26. package/build/services/collator/index.js +7 -34
  27. package/build/services/dba/index.d.ts +171 -0
  28. package/build/services/dba/index.js +280 -0
  29. package/build/services/{memflow → durable}/client.d.ts +3 -3
  30. package/build/services/{memflow → durable}/client.js +15 -15
  31. package/build/services/{memflow → durable}/connection.d.ts +2 -2
  32. package/build/services/{memflow → durable}/connection.js +1 -1
  33. package/build/services/{memflow → durable}/exporter.d.ts +6 -6
  34. package/build/services/{memflow → durable}/exporter.js +2 -2
  35. package/build/services/{memflow → durable}/handle.d.ts +4 -4
  36. package/build/services/{memflow → durable}/handle.js +3 -3
  37. package/build/services/{memflow → durable}/index.d.ts +126 -34
  38. package/build/services/{memflow → durable}/index.js +146 -50
  39. package/build/services/{memflow → durable}/interceptor.d.ts +45 -22
  40. package/build/services/{memflow → durable}/interceptor.js +54 -21
  41. package/build/services/{memflow → durable}/schemas/factory.d.ts +4 -4
  42. package/build/services/{memflow → durable}/schemas/factory.js +5 -5
  43. package/build/services/{memflow → durable}/search.d.ts +1 -1
  44. package/build/services/{memflow → durable}/search.js +4 -4
  45. package/build/services/{memflow → durable}/worker.d.ts +11 -11
  46. package/build/services/{memflow → durable}/worker.js +61 -60
  47. package/build/services/durable/workflow/all.d.ts +32 -0
  48. package/build/services/durable/workflow/all.js +40 -0
  49. package/build/services/{memflow → durable}/workflow/common.d.ts +5 -5
  50. package/build/services/durable/workflow/common.js +47 -0
  51. package/build/services/durable/workflow/context.d.ts +49 -0
  52. package/build/services/durable/workflow/context.js +88 -0
  53. package/build/services/durable/workflow/didRun.d.ts +27 -0
  54. package/build/services/durable/workflow/didRun.js +42 -0
  55. package/build/services/durable/workflow/emit.d.ts +50 -0
  56. package/build/services/durable/workflow/emit.js +68 -0
  57. package/build/services/durable/workflow/enrich.d.ts +37 -0
  58. package/build/services/durable/workflow/enrich.js +45 -0
  59. package/build/services/durable/workflow/entityMethods.d.ts +61 -0
  60. package/build/services/durable/workflow/entityMethods.js +80 -0
  61. package/build/services/durable/workflow/execChild.d.ts +106 -0
  62. package/build/services/durable/workflow/execChild.js +194 -0
  63. package/build/services/durable/workflow/execHook.d.ts +80 -0
  64. package/build/services/durable/workflow/execHook.js +97 -0
  65. package/build/services/durable/workflow/execHookBatch.d.ts +107 -0
  66. package/build/services/durable/workflow/execHookBatch.js +129 -0
  67. package/build/services/durable/workflow/hook.d.ts +74 -0
  68. package/build/services/durable/workflow/hook.js +123 -0
  69. package/build/services/durable/workflow/index.d.ts +129 -0
  70. package/build/services/{memflow → durable}/workflow/index.js +66 -11
  71. package/build/services/durable/workflow/interrupt.d.ts +55 -0
  72. package/build/services/durable/workflow/interrupt.js +70 -0
  73. package/build/services/durable/workflow/interruption.d.ts +61 -0
  74. package/build/services/durable/workflow/interruption.js +76 -0
  75. package/build/services/durable/workflow/isSideEffectAllowed.d.ts +27 -0
  76. package/build/services/{memflow → durable}/workflow/isSideEffectAllowed.js +21 -4
  77. package/build/services/durable/workflow/proxyActivities.d.ts +119 -0
  78. package/build/services/durable/workflow/proxyActivities.js +214 -0
  79. package/build/services/durable/workflow/random.d.ts +36 -0
  80. package/build/services/durable/workflow/random.js +46 -0
  81. package/build/services/durable/workflow/searchMethods.d.ts +53 -0
  82. package/build/services/durable/workflow/searchMethods.js +72 -0
  83. package/build/services/durable/workflow/signal.d.ts +58 -0
  84. package/build/services/durable/workflow/signal.js +79 -0
  85. package/build/services/durable/workflow/sleepFor.d.ts +63 -0
  86. package/build/services/durable/workflow/sleepFor.js +91 -0
  87. package/build/services/durable/workflow/trace.d.ts +47 -0
  88. package/build/services/durable/workflow/trace.js +66 -0
  89. package/build/services/durable/workflow/waitFor.d.ts +66 -0
  90. package/build/services/durable/workflow/waitFor.js +93 -0
  91. package/build/services/engine/index.d.ts +18 -2
  92. package/build/services/engine/index.js +14 -4
  93. package/build/services/exporter/index.d.ts +2 -0
  94. package/build/services/exporter/index.js +1 -0
  95. package/build/services/hotmesh/index.d.ts +471 -236
  96. package/build/services/hotmesh/index.js +473 -238
  97. package/build/services/store/index.d.ts +1 -1
  98. package/build/services/store/providers/postgres/postgres.d.ts +1 -1
  99. package/build/services/store/providers/postgres/postgres.js +4 -3
  100. package/build/services/telemetry/index.js +6 -0
  101. package/build/services/{meshcall → virtual}/index.d.ts +29 -29
  102. package/build/services/{meshcall → virtual}/index.js +49 -49
  103. package/build/services/{meshcall → virtual}/schemas/factory.d.ts +1 -1
  104. package/build/services/{meshcall → virtual}/schemas/factory.js +1 -1
  105. package/build/types/activity.d.ts +1 -1
  106. package/build/types/dba.d.ts +64 -0
  107. package/build/types/{memflow.d.ts → durable.d.ts} +75 -19
  108. package/build/types/error.d.ts +5 -5
  109. package/build/types/exporter.d.ts +1 -1
  110. package/build/types/hotmesh.d.ts +1 -1
  111. package/build/types/index.d.ts +5 -4
  112. package/build/types/job.d.ts +1 -1
  113. package/build/types/quorum.d.ts +2 -2
  114. package/build/types/{meshcall.d.ts → virtual.d.ts} +15 -15
  115. package/build/types/virtual.js +2 -0
  116. package/index.ts +15 -13
  117. package/package.json +63 -67
  118. package/vitest.config.ts +17 -0
  119. package/.claude/settings.local.json +0 -7
  120. package/build/services/memflow/workflow/all.d.ts +0 -7
  121. package/build/services/memflow/workflow/all.js +0 -15
  122. package/build/services/memflow/workflow/common.js +0 -47
  123. package/build/services/memflow/workflow/context.d.ts +0 -6
  124. package/build/services/memflow/workflow/context.js +0 -45
  125. package/build/services/memflow/workflow/didRun.d.ts +0 -7
  126. package/build/services/memflow/workflow/didRun.js +0 -22
  127. package/build/services/memflow/workflow/emit.d.ts +0 -11
  128. package/build/services/memflow/workflow/emit.js +0 -29
  129. package/build/services/memflow/workflow/enrich.d.ts +0 -9
  130. package/build/services/memflow/workflow/enrich.js +0 -17
  131. package/build/services/memflow/workflow/entityMethods.d.ts +0 -14
  132. package/build/services/memflow/workflow/entityMethods.js +0 -33
  133. package/build/services/memflow/workflow/execChild.d.ts +0 -18
  134. package/build/services/memflow/workflow/execChild.js +0 -106
  135. package/build/services/memflow/workflow/execHook.d.ts +0 -65
  136. package/build/services/memflow/workflow/execHook.js +0 -83
  137. package/build/services/memflow/workflow/execHookBatch.d.ts +0 -54
  138. package/build/services/memflow/workflow/execHookBatch.js +0 -77
  139. package/build/services/memflow/workflow/hook.d.ts +0 -9
  140. package/build/services/memflow/workflow/hook.js +0 -58
  141. package/build/services/memflow/workflow/index.d.ts +0 -74
  142. package/build/services/memflow/workflow/interrupt.d.ts +0 -9
  143. package/build/services/memflow/workflow/interrupt.js +0 -24
  144. package/build/services/memflow/workflow/interruption.d.ts +0 -28
  145. package/build/services/memflow/workflow/interruption.js +0 -43
  146. package/build/services/memflow/workflow/isSideEffectAllowed.d.ts +0 -10
  147. package/build/services/memflow/workflow/proxyActivities.d.ts +0 -91
  148. package/build/services/memflow/workflow/proxyActivities.js +0 -176
  149. package/build/services/memflow/workflow/random.d.ts +0 -6
  150. package/build/services/memflow/workflow/random.js +0 -16
  151. package/build/services/memflow/workflow/searchMethods.d.ts +0 -6
  152. package/build/services/memflow/workflow/searchMethods.js +0 -25
  153. package/build/services/memflow/workflow/signal.d.ts +0 -29
  154. package/build/services/memflow/workflow/signal.js +0 -50
  155. package/build/services/memflow/workflow/sleepFor.d.ts +0 -24
  156. package/build/services/memflow/workflow/sleepFor.js +0 -52
  157. package/build/services/memflow/workflow/trace.d.ts +0 -14
  158. package/build/services/memflow/workflow/trace.js +0 -33
  159. package/build/services/memflow/workflow/waitFor.d.ts +0 -29
  160. package/build/services/memflow/workflow/waitFor.js +0 -56
  161. /package/build/services/{memflow → durable}/entity.d.ts +0 -0
  162. /package/build/services/{memflow → durable}/entity.js +0 -0
  163. /package/build/types/{memflow.js → dba.js} +0 -0
  164. /package/build/types/{meshcall.js → durable.js} +0 -0
@@ -10,178 +10,160 @@ import { StringAnyType, StringStringType } from '../../types/serializer';
10
10
  import { JobStatsInput, GetStatsOptions, IdsResponse, StatsResponse } from '../../types/stats';
11
11
  import { StreamCode, StreamData, StreamDataResponse, StreamStatus } from '../../types/stream';
12
12
  /**
13
- * HotMesh transforms Postgres into a durable workflow orchestration engine capable of running
14
- * fault-tolerant workflows across multiple services and systems.
13
+ * A distributed service mesh that turns Postgres into a durable workflow
14
+ * orchestration engine. Every `HotMesh.init()` call creates a **point of
15
+ * presence** — an engine, a quorum member, and zero or more workers — that
16
+ * collaborates with its peers through Postgres LISTEN/NOTIFY to form a
17
+ * self-coordinating mesh with no external dependencies.
15
18
  *
16
- * ## Key Features
19
+ * ## Service Mesh Architecture
17
20
  *
18
- * - **Fault Tolerance**: Automatic retry with exponential backoff and configurable policies
19
- * - **Distributed Execution**: No single point of failure
20
- * - **YAML-Driven**: Model-driven development with declarative workflow definitions
21
- * - **OpenTelemetry**: Built-in observability and tracing
22
- * - **Durable State**: Workflow state persists across system restarts
23
- * - **Pattern Matching**: Pub/sub with wildcard pattern support
24
- * - **Throttling**: Dynamic flow control and backpressure management
25
- * - **Retry Policies**: PostgreSQL-native retry configuration with exponential backoff
21
+ * Each HotMesh instance joins a **quorum** a real-time pub/sub channel
22
+ * backed by Postgres LISTEN/NOTIFY. The quorum is the mesh's nervous
23
+ * system: version activations, throttle commands, roll calls, and custom
24
+ * user messages all propagate instantly to every connected engine and
25
+ * worker across all processes and servers.
26
26
  *
27
- * ## Architecture
27
+ * ## Quick Start
28
28
  *
29
- * HotMesh consists of several specialized modules:
30
- * - **HotMesh**: Core orchestration engine (this class)
31
- * - **MemFlow**: Temporal.io-compatible workflow framework
32
- * - **MeshCall**: Durable function execution (Temporal-like clone)
33
- *
34
- * ## Lifecycle Overview
35
- *
36
- * 1. **Initialize**: Create HotMesh instance with provider configuration
37
- * 2. **Deploy**: Upload YAML workflow definitions to the backend
38
- * 3. **Activate**: Coordinate quorum to enable the workflow version
39
- * 4. **Execute**: Publish events to trigger workflow execution
40
- * 5. **Monitor**: Track progress via OpenTelemetry and built-in observability
41
- *
42
- * ## Basic Usage
43
- *
44
- * @example
45
29
  * ```typescript
46
30
  * import { HotMesh } from '@hotmeshio/hotmesh';
47
31
  * import { Client as Postgres } from 'pg';
48
32
  *
49
- * // Initialize with Postgres backend
50
33
  * const hotMesh = await HotMesh.init({
51
- * appId: 'my-app',
34
+ * appId: 'myapp',
52
35
  * engine: {
53
36
  * connection: {
54
37
  * class: Postgres,
55
- * options: {
56
- * connectionString: 'postgresql://user:pass@localhost:5432/db'
57
- * }
58
- * }
59
- * }
38
+ * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' },
39
+ * },
40
+ * },
41
+ * workers: [{
42
+ * topic: 'order.process',
43
+ * connection: {
44
+ * class: Postgres,
45
+ * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' },
46
+ * },
47
+ * callback: async (data) => ({
48
+ * metadata: { ...data.metadata },
49
+ * data: { orderId: data.data.id, status: 'fulfilled' },
50
+ * }),
51
+ * }],
60
52
  * });
61
53
  *
62
- * // Deploy workflow definition
54
+ * // Deploy a YAML workflow graph
63
55
  * await hotMesh.deploy(`
64
56
  * app:
65
- * id: my-app
57
+ * id: myapp
66
58
  * version: '1'
67
59
  * graphs:
68
- * - subscribes: order.process
60
+ * - subscribes: order.placed
61
+ * publishes: order.fulfilled
62
+ * expire: 600
63
+ *
69
64
  * activities:
70
- * validate:
71
- * type: worker
72
- * topic: order.validate
73
- * approve:
74
- * type: hook
75
- * topic: order.approve
76
- * fulfill:
65
+ * t1:
66
+ * type: trigger
67
+ * process:
77
68
  * type: worker
78
- * topic: order.fulfill
69
+ * topic: order.process
70
+ * input:
71
+ * schema:
72
+ * type: object
73
+ * properties:
74
+ * id: { type: string }
75
+ * maps:
76
+ * id: '{t1.output.data.id}'
79
77
  * transitions:
80
- * validate:
81
- * - to: approve
82
- * approve:
83
- * - to: fulfill
78
+ * t1:
79
+ * - to: process
84
80
  * `);
85
81
  *
86
- * // Activate the workflow version
87
82
  * await hotMesh.activate('1');
88
83
  *
89
- * // Execute workflow (fire-and-forget)
90
- * const jobId = await hotMesh.pub('order.process', {
91
- * orderId: '12345',
92
- * amount: 99.99
93
- * });
84
+ * // Fire-and-forget
85
+ * const jobId = await hotMesh.pub('order.placed', { id: 'ORD-123' });
94
86
  *
95
- * // Execute workflow and wait for result
96
- * const result = await hotMesh.pubsub('order.process', {
97
- * orderId: '12345',
98
- * amount: 99.99
99
- * });
87
+ * // Request/response (blocks until workflow completes)
88
+ * const result = await hotMesh.pubsub('order.placed', { id: 'ORD-456' });
100
89
  * ```
101
90
  *
102
- * ## Postgres Backend Example
91
+ * ## Quorum: The Mesh Control Plane
103
92
  *
104
- * @example
105
- * ```typescript
106
- * import { HotMesh } from '@hotmeshio/hotmesh';
107
- * import { Client as Postgres } from 'pg';
93
+ * The quorum channel is a broadcast bus available to every mesh member.
94
+ * Use it for operational control, observability, and custom messaging.
108
95
  *
109
- * const hotMesh = await HotMesh.init({
110
- * appId: 'my-app',
111
- * engine: {
112
- * connection: {
113
- * class: Postgres,
114
- * options: {
115
- * connectionString: 'postgresql://user:pass@localhost:5432/db'
116
- * }
117
- * }
96
+ * ```typescript
97
+ * // Roll call — discover every engine and worker in the mesh
98
+ * const members = await hotMesh.rollCall();
99
+ * // => [{ engine_id, worker_topic, throttle, system: { CPULoad, ... } }, ...]
100
+ *
101
+ * // Subscribe to ALL quorum traffic (throttle, activate, pong, job, user)
102
+ * await hotMesh.subQuorum((topic, message) => {
103
+ * switch (message.type) {
104
+ * case 'pong': // roll call response from a mesh member
105
+ * console.log(`Member ${message.guid} on topic ${message.profile?.worker_topic}`);
106
+ * break;
107
+ * case 'throttle': // a throttle command was broadcast
108
+ * console.log(`Throttle ${message.throttle}ms on ${message.topic ?? 'all'}`);
109
+ * break;
110
+ * case 'activate': // a version activation is in progress
111
+ * console.log(`Activating version ${message.until_version}`);
112
+ * break;
113
+ * case 'job': // a workflow completed and published its result
114
+ * console.log(`Job done on ${message.topic}:`, message.job);
115
+ * break;
116
+ * case 'user': // a custom user message
117
+ * console.log(`User event ${message.topic}:`, message.message);
118
+ * break;
118
119
  * }
119
120
  * });
120
- * ```
121
121
  *
122
- * ## Advanced Features
123
- *
124
- * **Pattern Subscriptions**: Listen to multiple workflow topics
125
- * ```typescript
126
- * await hotMesh.psub('order.*', (topic, message) => {
127
- * console.log(`Received ${topic}:`, message);
122
+ * // Publish a custom message to every mesh member
123
+ * await hotMesh.pubQuorum({
124
+ * type: 'user',
125
+ * topic: 'deploy.notify',
126
+ * message: { version: '2.1.0', deployer: 'ci-pipeline' },
128
127
  * });
129
128
  * ```
130
129
  *
131
- * **Throttling**: Control processing rates
132
- * ```typescript
133
- * // Pause all processing for 5 seconds
134
- * await hotMesh.throttle({ throttle: 5000 });
135
- *
136
- * // Emergency stop (pause indefinitely)
137
- * await hotMesh.throttle({ throttle: -1 });
138
- * ```
130
+ * ## Throttling: Backpressure Across the Mesh
139
131
  *
140
- * **Workflow Interruption**: Gracefully stop running workflows
141
- * ```typescript
142
- * await hotMesh.interrupt('order.process', jobId, {
143
- * reason: 'User cancellation'
144
- * });
145
- * ```
132
+ * Throttle commands propagate instantly to every targeted member via
133
+ * the quorum channel, providing fine-grained flow control.
146
134
  *
147
- * **State Inspection**: Query workflow state and progress
148
135
  * ```typescript
149
- * const state = await hotMesh.getState('order.process', jobId);
150
- * const status = await hotMesh.getStatus(jobId);
151
- * ```
136
+ * // Pause the ENTIRE mesh (emergency stop)
137
+ * await hotMesh.throttle({ throttle: -1 });
152
138
  *
153
- * ## Distributed Coordination
139
+ * // Resume the entire mesh
140
+ * await hotMesh.throttle({ throttle: 0 });
154
141
  *
155
- * HotMesh automatically handles distributed coordination through its quorum system:
142
+ * // Slow a specific worker topic to 1 message per 500ms
143
+ * await hotMesh.throttle({ throttle: 500, topic: 'order.process' });
156
144
  *
157
- * ```typescript
158
- * // Check quorum health
159
- * const members = await hotMesh.rollCall();
145
+ * // Throttle a single engine/worker instance by GUID
146
+ * await hotMesh.throttle({ throttle: 2000, guid: 'abc-123' });
160
147
  *
161
- * // Coordinate version activation across all instances
162
- * await hotMesh.activate('2', 1000); // 1 second delay for consensus
148
+ * // Combine: throttle a specific topic on a specific instance
149
+ * await hotMesh.throttle({ throttle: 1000, guid: 'abc-123', topic: 'order.process' });
163
150
  * ```
164
151
  *
165
- * ## Integration with Higher-Level Modules
152
+ * ## Lifecycle
166
153
  *
167
- * For most use cases, consider using the higher-level modules:
168
- * - **MemFlow**: For Temporal.io-style workflows with TypeScript functions
169
- * - **MeshCall**: For durable function calls and RPC patterns
154
+ * 1. **`init`** Create an engine + workers; join the quorum.
155
+ * 2. **`deploy`** Upload a YAML graph to Postgres (inactive).
156
+ * 3. **`activate`** Coordinate the quorum to switch to the new version.
157
+ * 4. **`pub` / `pubsub`** — Trigger workflow execution.
158
+ * 5. **`stop`** — Leave the quorum and release connections.
170
159
  *
171
- * ## Cleanup
160
+ * ## Higher-Level Modules
172
161
  *
173
- * Always clean up resources when shutting down:
174
- * ```typescript
175
- * // Stop this instance
176
- * hotMesh.stop();
162
+ * For most use cases, prefer the higher-level wrappers:
163
+ * - **Durable** — Temporal-style durable workflow functions.
164
+ * - **Virtual** Virtual network functions and idempotent RPC.
177
165
  *
178
- * // Stop all instances (typically in signal handlers)
179
- * await HotMesh.stop();
180
- * ```
181
- *
182
- * @see {@link https://docs.hotmesh.io/} - Complete documentation
183
- * @see {@link https://github.com/hotmeshio/samples-typescript} - Examples and tutorials
184
- * @see {@link https://zenodo.org/records/12168558} - White paper on the architecture
166
+ * @see {@link https://hotmeshio.github.io/sdk-typescript/} - API reference
185
167
  */
186
168
  declare class HotMesh {
187
169
  namespace: string;
@@ -216,12 +198,19 @@ declare class HotMesh {
216
198
  *
217
199
  * ## Retry Policy Configuration
218
200
  *
219
- * HotMesh supports robust retry policies with exponential backoff for PostgreSQL.
220
- * Configure retry behavior at the stream level for automatic fault tolerance.
201
+ * HotMesh supports retry policies with exponential backoff. Retry behavior
202
+ * can be configured independently on both the `engine` and individual
203
+ * `workers`. They are **not inherited**; each operates at its own level.
204
+ *
205
+ * - **Engine `retryPolicy`**: Stamps messages the engine publishes with
206
+ * retry metadata (stored as Postgres columns). Workers that consume
207
+ * these messages will use the embedded config when handling failures.
208
+ * - **Worker `retryPolicy`**: Used as the fallback when the consumed
209
+ * message does not carry explicit retry metadata.
221
210
  *
222
211
  * @example Basic Configuration
223
212
  * ```typescript
224
- * const config: HotMeshConfig = {
213
+ * const hotMesh = await HotMesh.init({
225
214
  * appId: 'myapp',
226
215
  * engine: {
227
216
  * connection: {
@@ -231,46 +220,49 @@ declare class HotMesh {
231
220
  * }
232
221
  * }
233
222
  * },
234
- * workers [...]
235
- * };
236
- * const hotMesh = await HotMesh.init(config);
223
+ * workers: [...]
224
+ * });
237
225
  * ```
238
226
  *
239
- * @example With Retry Policy (PostgreSQL)
227
+ * @example Engine Retry Policy
240
228
  * ```typescript
241
- * import { HotMesh } from '@hotmeshio/hotmesh';
242
- * import { Client as Postgres } from 'pg';
243
- *
244
229
  * const hotMesh = await HotMesh.init({
245
- * appId: 'my-app',
230
+ * appId: 'myapp',
246
231
  * engine: {
247
232
  * connection: {
248
233
  * class: Postgres,
249
234
  * options: { connectionString: 'postgresql://...' }
250
235
  * },
251
- * // Default retry policy for engine streams
252
236
  * retryPolicy: {
253
- * maximumAttempts: 5, // Retry up to 5 times
254
- * backoffCoefficient: 2, // Exponential: 2^0, 2^1, 2^2...
255
- * maximumInterval: '300s' // Cap delay at 5 minutes
237
+ * maximumAttempts: 5,
238
+ * backoffCoefficient: 2,
239
+ * maximumInterval: '300s'
256
240
  * }
257
- * },
241
+ * }
242
+ * });
243
+ * ```
244
+ *
245
+ * @example Worker Retry Policy
246
+ * ```typescript
247
+ * const hotMesh = await HotMesh.init({
248
+ * appId: 'myapp',
249
+ * engine: { connection },
258
250
  * workers: [{
259
251
  * topic: 'order.process',
260
- * connection: {
261
- * class: Postgres,
262
- * options: { connectionString: 'postgresql://...' }
263
- * },
264
- * // Worker-specific retry policy
252
+ * connection,
265
253
  * retryPolicy: {
266
- * maximumAttempts: 10,
267
- * backoffCoefficient: 1.5,
268
- * maximumInterval: '600s'
254
+ * maximumAttempts: 5,
255
+ * backoffCoefficient: 2,
256
+ * maximumInterval: '30s',
269
257
  * },
270
- * callback: async (data) => {
271
- * // Your business logic here
272
- * // Failures will automatically retry with exponential backoff
273
- * return { status: 'success', data: processedData };
258
+ * callback: async (data: StreamData) => {
259
+ * const result = await doWork(data.data);
260
+ * return {
261
+ * code: 200,
262
+ * status: StreamStatus.SUCCESS,
263
+ * metadata: { ...data.metadata },
264
+ * data: { result },
265
+ * } as StreamDataResponse;
274
266
  * }
275
267
  * }]
276
268
  * });
@@ -289,8 +281,8 @@ declare class HotMesh {
289
281
  */
290
282
  static init(config: HotMeshConfig): Promise<HotMesh>;
291
283
  /**
292
- * returns a guid using the same core guid
293
- * generator used by the HotMesh (nanoid)
284
+ * Generates a unique ID using the same nanoid generator used
285
+ * internally by HotMesh for job IDs and GUIDs.
294
286
  */
295
287
  static guid(): string;
296
288
  /**
@@ -324,96 +316,252 @@ declare class HotMesh {
324
316
  */
325
317
  private applyRetryPolicy;
326
318
  /**
327
- * Starts a workflow
319
+ * Publishes a message to a workflow topic, starting a new job.
320
+ * Returns the job ID immediately (fire-and-forget). Use `pubsub`
321
+ * to block until the workflow completes.
322
+ *
328
323
  * @example
329
324
  * ```typescript
330
- * await hotMesh.pub('a.b.c', { key: 'value' });
325
+ * const jobId = await hotMesh.pub('order.placed', {
326
+ * id: 'ORD-123',
327
+ * amount: 99.99,
328
+ * });
329
+ * console.log(`Started job ${jobId}`);
331
330
  * ```
332
331
  */
333
332
  pub(topic: string, data?: JobData, context?: JobState, extended?: ExtensionType): Promise<string>;
334
333
  /**
335
- * Subscribe (listen) to all output and interim emissions of a single
336
- * workflow topic. NOTE: Postgres does not support patterned
337
- * unsubscription, so this method is not supported for Postgres.
334
+ * Subscribes to all output and interim emissions from a specific
335
+ * workflow topic. The callback fires each time a job on that topic
336
+ * completes or emits an interim result.
338
337
  *
339
338
  * @example
340
339
  * ```typescript
341
- * await hotMesh.psub('a.b.c', (topic, message) => {
342
- * console.log(message);
340
+ * await hotMesh.sub('order.fulfilled', (topic, message) => {
341
+ * console.log(`Order completed:`, message.data);
343
342
  * });
344
343
  * ```
345
344
  */
346
345
  sub(topic: string, callback: JobMessageCallback): Promise<void>;
347
346
  /**
348
- * Stop listening in on a single workflow topic
347
+ * Unsubscribes from a single workflow topic previously registered
348
+ * with `sub()`.
349
349
  */
350
350
  unsub(topic: string): Promise<void>;
351
351
  /**
352
- * Listen to all output and interim emissions of a workflow topic
353
- * matching a wildcard pattern.
352
+ * Subscribes to workflow emissions matching a wildcard pattern.
353
+ * Useful for monitoring an entire domain of workflows at once.
354
+ *
354
355
  * @example
355
356
  * ```typescript
356
- * await hotMesh.psub('a.b.c*', (topic, message) => {
357
- * console.log(message);
357
+ * // Listen to all order-related workflow completions
358
+ * await hotMesh.psub('order.*', (topic, message) => {
359
+ * console.log(`${topic} completed:`, message.data);
358
360
  * });
359
361
  * ```
360
362
  */
361
363
  psub(wild: string, callback: JobMessageCallback): Promise<void>;
362
364
  /**
363
- * Patterned unsubscribe. NOTE: Postgres does not support patterned
364
- * unsubscription, so this method is not supported for Postgres.
365
+ * Unsubscribes from a wildcard pattern previously registered with `psub()`.
365
366
  */
366
367
  punsub(wild: string): Promise<void>;
367
368
  /**
368
- * Starts a workflow and awaits the response
369
+ * Publishes a message to a workflow topic and blocks until the workflow
370
+ * completes, returning the final job output. Internally subscribes to
371
+ * the workflow's `publishes` topic before publishing, then unsubscribes
372
+ * after receiving the result.
373
+ *
369
374
  * @example
370
375
  * ```typescript
371
- * await hotMesh.pubsub('a.b.c', { key: 'value' });
376
+ * const result = await hotMesh.pubsub('order.placed', {
377
+ * id: 'ORD-789',
378
+ * amount: 49.99,
379
+ * });
380
+ * console.log('Order result:', result.data);
372
381
  * ```
373
382
  */
374
383
  pubsub(topic: string, data?: JobData, context?: JobState | null, timeout?: number): Promise<JobOutput>;
375
384
  /**
376
- * Add a transition message to the workstream, resuming leg 2 of a paused
377
- * reentrant activity (e.g., await, worker, hook)
385
+ * Adds a transition message to the workstream, resuming Leg 2 of a
386
+ * paused reentrant activity (e.g., `await`, `worker`, `hook`). This
387
+ * is typically called by the engine internally but is exposed for
388
+ * advanced use cases like custom activity implementations.
378
389
  */
379
390
  add(streamData: StreamData | StreamDataResponse): Promise<string>;
380
391
  /**
381
- * Request a roll call from the quorum (engine and workers)
392
+ * Broadcasts a roll call across the mesh and collects responses from
393
+ * every connected engine and worker. Each member replies with its
394
+ * `QuorumProfile` — including GUID, worker topic, stream depth,
395
+ * throttle rate, and system health (CPU, memory, network).
396
+ *
397
+ * Use this for service discovery, health checks, and capacity planning.
398
+ *
399
+ * @example
400
+ * ```typescript
401
+ * const members = await hotMesh.rollCall();
402
+ * for (const member of members) {
403
+ * console.log(
404
+ * `${member.engine_id} | topic=${member.worker_topic ?? 'engine'} ` +
405
+ * `| throttle=${member.throttle}ms | depth=${member.stream_depth}`,
406
+ * );
407
+ * }
408
+ * ```
382
409
  */
383
410
  rollCall(delay?: number): Promise<QuorumProfile[]>;
384
411
  /**
385
- * Sends a throttle message to the quorum (engine and/or workers)
386
- * to limit the rate of processing. Pass `-1` to throttle indefinitely.
387
- * The value must be a non-negative integer and not exceed `MAX_DELAY` ms.
412
+ * Broadcasts a throttle command to the mesh via the quorum channel.
413
+ * Targeted members insert a delay (in milliseconds) before processing
414
+ * their next stream message, providing instant backpressure control
415
+ * across any combination of engines and workers.
416
+ *
417
+ * Throttling is **stateless** — no data is lost. Messages accumulate
418
+ * in Postgres streams and are processed once the throttle is lifted.
388
419
  *
389
- * When throttling is set, the quorum will pause for the specified time
390
- * before processing the next message. Target specific engines and
391
- * workers by passing a `guid` and/or `topic`. Pass no arguments to
392
- * throttle the entire quorum.
420
+ * ## Targeting
393
421
  *
394
- * In this example, all processing has been paused indefinitely for
395
- * the entire quorum. This is equivalent to an emergency stop.
422
+ * | Option | Effect |
423
+ * |---------|--------|
424
+ * | *(none)* | Throttle the **entire mesh** (all engines + all workers) |
425
+ * | `topic` | Throttle all workers subscribed to this topic |
426
+ * | `guid` | Throttle a single engine or worker instance |
427
+ * | `topic` + `guid` | Throttle a specific topic on a specific instance |
396
428
  *
397
- * HotMesh is a stateless sequence engine, so the throttle can be adjusted up
398
- * and down with no loss of data.
429
+ * ## Special Values
399
430
  *
431
+ * | Value | Effect |
432
+ * |--------|--------|
433
+ * | `0` | Resume normal processing (remove throttle) |
434
+ * | `-1` | Pause indefinitely (emergency stop) |
435
+ * | `500` | 500ms delay between messages |
400
436
  *
401
437
  * @example
402
438
  * ```typescript
439
+ * // Emergency stop: pause the entire mesh
403
440
  * await hotMesh.throttle({ throttle: -1 });
441
+ *
442
+ * // Resume the entire mesh
443
+ * await hotMesh.throttle({ throttle: 0 });
444
+ *
445
+ * // Slow a specific worker topic to 1 msg per second
446
+ * await hotMesh.throttle({ throttle: 1000, topic: 'order.process' });
447
+ *
448
+ * // Throttle a single instance by GUID
449
+ * await hotMesh.throttle({ throttle: 2000, guid: 'abc-123' });
450
+ *
451
+ * // Throttle a specific topic on a specific instance
452
+ * await hotMesh.throttle({
453
+ * throttle: 500,
454
+ * guid: 'abc-123',
455
+ * topic: 'payment.charge',
456
+ * });
404
457
  * ```
405
458
  */
406
459
  throttle(options: ThrottleOptions): Promise<boolean>;
407
460
  /**
408
- * Publish a message to the quorum (engine and/or workers)
461
+ * Publishes a message to every mesh member via the quorum channel
462
+ * (Postgres LISTEN/NOTIFY). Any `QuorumMessage` type can be sent,
463
+ * but the `user` type is the most common for application-level
464
+ * messaging.
465
+ *
466
+ * @example
467
+ * ```typescript
468
+ * // Broadcast a custom event to all mesh members
469
+ * await hotMesh.pubQuorum({
470
+ * type: 'user',
471
+ * topic: 'deploy.notify',
472
+ * message: { version: '2.1.0', deployer: 'ci-pipeline' },
473
+ * });
474
+ *
475
+ * // Broadcast a config-reload signal
476
+ * await hotMesh.pubQuorum({
477
+ * type: 'user',
478
+ * topic: 'config.reload',
479
+ * message: { features: { darkMode: true } },
480
+ * });
481
+ * ```
409
482
  */
410
483
  pubQuorum(quorumMessage: QuorumMessage): Promise<boolean>;
411
484
  /**
412
- * Subscribe to quorum events (engine and workers)
485
+ * Subscribes to the quorum channel, receiving **every** message
486
+ * broadcast across the mesh in real time. This is the primary
487
+ * observability hook into the service mesh — use it to monitor
488
+ * version activations, throttle commands, roll call responses,
489
+ * workflow completions, and custom user events.
490
+ *
491
+ * Messages arrive as typed `QuorumMessage` unions. Switch on
492
+ * `message.type` to handle each:
493
+ *
494
+ * | Type | When it fires |
495
+ * |-------------|---------------|
496
+ * | `pong` | A mesh member responds to a roll call |
497
+ * | `throttle` | A throttle command was broadcast |
498
+ * | `activate` | A version activation is in progress |
499
+ * | `job` | A workflow completed and published its result |
500
+ * | `user` | A custom user message (via `pubQuorum`) |
501
+ * | `ping` | A roll call was initiated |
502
+ * | `work` | A work distribution event |
503
+ * | `cron` | A cron/scheduled event |
504
+ *
505
+ * @example
506
+ * ```typescript
507
+ * // Build a real-time mesh dashboard
508
+ * await hotMesh.subQuorum((topic, message) => {
509
+ * switch (message.type) {
510
+ * case 'pong':
511
+ * dashboard.updateMember(message.guid, {
512
+ * topic: message.profile?.worker_topic,
513
+ * throttle: message.profile?.throttle,
514
+ * depth: message.profile?.stream_depth,
515
+ * cpu: message.profile?.system?.CPULoad,
516
+ * });
517
+ * break;
518
+ *
519
+ * case 'throttle':
520
+ * dashboard.logThrottle(
521
+ * message.throttle,
522
+ * message.topic,
523
+ * message.guid,
524
+ * );
525
+ * break;
526
+ *
527
+ * case 'job':
528
+ * dashboard.logCompletion(message.topic, message.job);
529
+ * break;
530
+ *
531
+ * case 'user':
532
+ * dashboard.logUserEvent(message.topic, message.message);
533
+ * break;
534
+ * }
535
+ * });
536
+ * ```
537
+ *
538
+ * @example
539
+ * ```typescript
540
+ * // React to custom deployment events
541
+ * await hotMesh.subQuorum((topic, message) => {
542
+ * if (message.type === 'user' && message.topic === 'config.reload') {
543
+ * reloadFeatureFlags(message.message);
544
+ * }
545
+ * });
546
+ * ```
547
+ *
548
+ * @example
549
+ * ```typescript
550
+ * // Log all mesh activity for audit
551
+ * await hotMesh.subQuorum((topic, message) => {
552
+ * auditLog.append({
553
+ * timestamp: Date.now(),
554
+ * type: message.type,
555
+ * guid: message.guid,
556
+ * topic: message.topic,
557
+ * payload: message,
558
+ * });
559
+ * });
560
+ * ```
413
561
  */
414
562
  subQuorum(callback: QuorumMessageCallback): Promise<void>;
415
563
  /**
416
- * Unsubscribe from quorum events (engine and workers)
564
+ * Unsubscribes a callback previously registered with `subQuorum()`.
417
565
  */
418
566
  unsubQuorum(callback: QuorumMessageCallback): Promise<void>;
419
567
  /**
@@ -423,37 +571,72 @@ declare class HotMesh {
423
571
  */
424
572
  plan(path: string): Promise<HotMeshManifest>;
425
573
  /**
426
- * When the app YAML descriptor file is ready, the `deploy` function can be called.
427
- * This function is responsible for merging all referenced YAML source
428
- * files and writing the JSON output to the file system and to the provider backend. It
429
- * is also possible to embed the YAML in-line as a string.
574
+ * Deploys a YAML workflow graph to Postgres. Accepts a file path or
575
+ * an inline YAML string. Referenced `$ref` files are resolved and
576
+ * merged. The deployed version is **inactive** until `activate()` is
577
+ * called.
578
+ *
579
+ * @example
580
+ * ```typescript
581
+ * // Deploy from an inline YAML string
582
+ * await hotMesh.deploy(`
583
+ * app:
584
+ * id: myapp
585
+ * version: '2'
586
+ * graphs:
587
+ * - subscribes: order.placed
588
+ * activities:
589
+ * t1:
590
+ * type: trigger
591
+ * process:
592
+ * type: worker
593
+ * topic: order.process
594
+ * transitions:
595
+ * t1:
596
+ * - to: process
597
+ * `);
430
598
  *
431
- * *The version will not be active until activation is explicitly called.*
599
+ * // Deploy from a file path (resolves $ref references)
600
+ * await hotMesh.deploy('./workflows/order.yaml');
601
+ * ```
432
602
  */
433
603
  deploy(pathOrYAML: string): Promise<HotMeshManifest>;
434
604
  /**
435
- * Once the app YAML file is deployed to the provider backend, the `activate` function can be
436
- * called to enable it for the entire quorum at the same moment.
605
+ * Activates a deployed version across the entire mesh. The quorum
606
+ * coordinates a synchronized switch-over:
607
+ *
608
+ * 1. Roll call to verify quorum health.
609
+ * 2. Broadcast `nocache` mode — all engines consult Postgres for the
610
+ * active version on every request.
611
+ * 3. Set the new version as active.
612
+ * 4. Broadcast `cache` mode — engines resume caching.
613
+ *
614
+ * The optional `delay` adds a pause (in ms) for the quorum to reach
615
+ * consensus under heavy traffic. Combine with `throttle()` for
616
+ * zero-downtime version switches.
437
617
  *
438
- * The approach is to establish the coordinated health of the system through series
439
- * of call/response exchanges. Once it is established that the quorum is healthy,
440
- * the quorum is instructed to run their engine in `no-cache` mode, ensuring
441
- * that the provider backend is consulted for the active app version each time a
442
- * call is processed. This ensures that all engines are running the same version
443
- * of the app, switching over at the same moment and then enabling `cache` mode
444
- * to improve performance.
618
+ * @example
619
+ * ```typescript
620
+ * // Simple activation
621
+ * await hotMesh.activate('2');
445
622
  *
446
- * *Add a delay for the quorum to reach consensus if traffic is busy, but
447
- * also consider throttling traffic flow to an acceptable level.*
623
+ * // With consensus delay under heavy traffic
624
+ * await hotMesh.throttle({ throttle: 500 }); // slow the mesh
625
+ * await hotMesh.activate('2', 2000); // activate with 2s consensus window
626
+ * await hotMesh.throttle({ throttle: 0 }); // resume full speed
627
+ * ```
448
628
  */
449
629
  activate(version: string, delay?: number): Promise<boolean>;
450
630
  /**
451
- * Returns the job state as a JSON object, useful
452
- * for understanding dependency chains
631
+ * Exports the full job state as a structured JSON object, including
632
+ * activity data, transitions, and dependency chains. Useful for
633
+ * debugging, auditing, and visualizing workflow execution.
453
634
  */
454
635
  export(jobId: string): Promise<JobExport>;
455
636
  /**
456
- * Returns all data (HGETALL) for a job.
637
+ * Returns all raw key-value pairs for a job's HASH record. This is
638
+ * the lowest-level read — it returns internal engine fields alongside
639
+ * user data. Prefer `getState()` for structured output.
457
640
  */
458
641
  getRaw(jobId: string): Promise<StringStringType>;
459
642
  /**
@@ -462,32 +645,38 @@ declare class HotMesh {
462
645
  */
463
646
  getStats(topic: string, query: JobStatsInput): Promise<StatsResponse>;
464
647
  /**
465
- * Returns the status of a job. This is a numeric
466
- * semaphore value that indicates the job's state.
467
- * Any non-positive value indicates a completed job.
468
- * Jobs with a value of `-1` are pending and will
469
- * automatically be scrubbed after a set period.
470
- * Jobs a value around -1billion have been interrupted
471
- * and will be scrubbed after a set period. Jobs with
472
- * a value of 0 completed normally. Jobs with a
473
- * positive value are still running.
648
+ * Returns the numeric status semaphore for a job.
649
+ *
650
+ * | Value | Meaning |
651
+ * |------------------|---------|
652
+ * | `> 0` | Running (count of open activities) |
653
+ * | `0` | Completed normally |
654
+ * | `-1` | Pending (awaiting activation) |
655
+ * | `< -100,000,000` | Interrupted (abnormal termination) |
474
656
  */
475
657
  getStatus(jobId: string): Promise<JobStatus>;
476
658
  /**
477
- * Returns the job state (data and metadata) for a job.
659
+ * Returns the structured job state (data and metadata) for a job,
660
+ * scoped to the given workflow topic.
661
+ *
662
+ * @example
663
+ * ```typescript
664
+ * const state = await hotMesh.getState('order.placed', jobId);
665
+ * console.log(state.data); // workflow output data
666
+ * console.log(state.metadata); // jid, aid, timestamps, etc.
667
+ * ```
478
668
  */
479
669
  getState(topic: string, jobId: string): Promise<JobOutput>;
480
670
  /**
481
- * Returns searchable/queryable data for a job. In this
482
- * example a literal field is also searched (the colon
483
- * is used to track job status and is a reserved field;
484
- * it can be read but not written).
671
+ * Returns specific searchable fields from a job's HASH record.
672
+ * Pass field names to retrieve; use `":"` to read the reserved
673
+ * status field.
485
674
  *
486
675
  * @example
487
676
  * ```typescript
488
- * const fields = ['fred', 'barney', '":"'];
489
- * const queryState = await hotMesh.getQueryState('123', fields);
490
- * //returns { fred: 'flintstone', barney: 'rubble', ':': '1' }
677
+ * const fields = ['orderId', 'status', '":"'];
678
+ * const data = await hotMesh.getQueryState(jobId, fields);
679
+ * // => { orderId: 'ORD-123', status: 'paid', ':': '0' }
491
680
  * ```
492
681
  */
493
682
  getQueryState(jobId: string, fields: string[]): Promise<StringAnyType>;
@@ -500,35 +689,81 @@ declare class HotMesh {
500
689
  */
501
690
  resolveQuery(topic: string, query: JobStatsInput): Promise<GetStatsOptions>;
502
691
  /**
503
- * Interrupt an active job
692
+ * Interrupts (terminates) an active workflow job. The job's status is
693
+ * set to an error code indicating abnormal termination, and any pending
694
+ * activities or timers are cancelled.
695
+ *
696
+ * @example
697
+ * ```typescript
698
+ * await hotMesh.interrupt('order.placed', jobId, {
699
+ * reason: 'Customer cancelled',
700
+ * descend: true, // also interrupt child workflows
701
+ * });
702
+ * ```
504
703
  */
505
704
  interrupt(topic: string, jobId: string, options?: JobInterruptOptions): Promise<string>;
506
705
  /**
507
- * Immediately deletes (DEL) a completed job from the system.
508
- *
509
- * *Scrubbed jobs must be complete with a non-positive `status` value*
706
+ * Immediately deletes a completed job from the system. The job must
707
+ * have a non-positive status (completed or interrupted). Running jobs
708
+ * must be interrupted first.
510
709
  */
511
710
  scrub(jobId: string): Promise<void>;
512
711
  /**
513
- * Re/entry point for an active job. This is used to resume a paused job
514
- * and close the reentry point or leave it open for subsequent reentry.
515
- * Because `hooks` are public entry points, they include a `topic`
516
- * which is established in the app YAML file.
712
+ * Sends a signal to a paused workflow, resuming its execution.
713
+ * The `topic` must match a hook rule defined in the YAML graph's
714
+ * `hooks` section. The engine locates the exact activity and
715
+ * dimension for reentry based on the hook rule's match conditions.
517
716
  *
518
- * When this method is called, a hook rule will be located to establish
519
- * the exact activity and activity dimension for reentry.
717
+ * Use this to deliver external data (approval decisions, webhook
718
+ * payloads, partner responses) into a workflow that is sleeping
719
+ * on a hook activity or awaiting a `waitFor()` signal.
720
+ *
721
+ * @example
722
+ * ```typescript
723
+ * // Resume a paused approval workflow with external data
724
+ * await hotMesh.signal('order.approval', {
725
+ * id: jobId,
726
+ * approved: true,
727
+ * reviewer: 'manager@example.com',
728
+ * });
729
+ * ```
730
+ *
731
+ * @example
732
+ * ```typescript
733
+ * // Signal a Durable workflow waiting on waitFor('payment-received')
734
+ * await hotMesh.signal(`${appId}.wfs.signal`, {
735
+ * id: 'payment-received',
736
+ * data: { amount: 99.99, currency: 'USD' },
737
+ * });
738
+ * ```
520
739
  */
521
- hook(topic: string, data: JobData, status?: StreamStatus, code?: StreamCode): Promise<string>;
740
+ signal(topic: string, data: JobData, status?: StreamStatus, code?: StreamCode): Promise<string>;
522
741
  /**
742
+ * Fan-out variant of `signal()` that delivers data to **all**
743
+ * paused workflows matching a search query. Useful for resuming
744
+ * a batch of workflows waiting on the same external event.
745
+ *
523
746
  * @private
524
747
  */
525
- hookAll(hookTopic: string, data: JobData, query: JobStatsInput, queryFacets?: string[]): Promise<string[]>;
748
+ signalAll(hookTopic: string, data: JobData, query: JobStatsInput, queryFacets?: string[]): Promise<string[]>;
526
749
  /**
527
- * Stop all points of presence, workers and engines
750
+ * Stops **all** HotMesh instances in the current process — engines,
751
+ * workers, and connections. Typically called in signal handlers
752
+ * (`SIGTERM`, `SIGINT`) for graceful shutdown.
753
+ *
754
+ * @example
755
+ * ```typescript
756
+ * process.on('SIGTERM', async () => {
757
+ * await HotMesh.stop();
758
+ * process.exit(0);
759
+ * });
760
+ * ```
528
761
  */
529
762
  static stop(): Promise<void>;
530
763
  /**
531
- * Stop this point of presence, workers and engines
764
+ * Stops this specific HotMesh instance its engine, quorum
765
+ * membership, and all attached workers. Other instances in the
766
+ * same process are unaffected.
532
767
  */
533
768
  stop(): void;
534
769
  /**