@hotmeshio/hotmesh 0.9.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 (96) hide show
  1. package/README.md +38 -23
  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 +23 -22
  9. package/build/services/activities/activity.js +1 -1
  10. package/build/services/dba/index.d.ts +171 -0
  11. package/build/services/dba/index.js +280 -0
  12. package/build/services/{memflow → durable}/client.d.ts +3 -3
  13. package/build/services/{memflow → durable}/client.js +13 -13
  14. package/build/services/{memflow → durable}/connection.d.ts +2 -2
  15. package/build/services/{memflow → durable}/connection.js +1 -1
  16. package/build/services/{memflow → durable}/exporter.d.ts +6 -6
  17. package/build/services/{memflow → durable}/exporter.js +2 -2
  18. package/build/services/{memflow → durable}/handle.d.ts +4 -4
  19. package/build/services/{memflow → durable}/handle.js +2 -2
  20. package/build/services/{memflow → durable}/index.d.ts +125 -33
  21. package/build/services/{memflow → durable}/index.js +145 -49
  22. package/build/services/{memflow → durable}/interceptor.d.ts +45 -22
  23. package/build/services/{memflow → durable}/interceptor.js +54 -21
  24. package/build/services/{memflow → durable}/schemas/factory.d.ts +4 -4
  25. package/build/services/{memflow → durable}/schemas/factory.js +5 -5
  26. package/build/services/{memflow → durable}/search.d.ts +1 -1
  27. package/build/services/{memflow → durable}/search.js +4 -4
  28. package/build/services/{memflow → durable}/worker.d.ts +11 -11
  29. package/build/services/{memflow → durable}/worker.js +61 -60
  30. package/build/services/{memflow → durable}/workflow/all.d.ts +5 -5
  31. package/build/services/{memflow → durable}/workflow/all.js +5 -5
  32. package/build/services/{memflow → durable}/workflow/common.d.ts +5 -5
  33. package/build/services/durable/workflow/common.js +47 -0
  34. package/build/services/{memflow → durable}/workflow/context.d.ts +5 -5
  35. package/build/services/{memflow → durable}/workflow/context.js +5 -5
  36. package/build/services/{memflow → durable}/workflow/emit.d.ts +5 -5
  37. package/build/services/{memflow → durable}/workflow/emit.js +5 -5
  38. package/build/services/{memflow → durable}/workflow/enrich.d.ts +4 -4
  39. package/build/services/{memflow → durable}/workflow/enrich.js +4 -4
  40. package/build/services/{memflow → durable}/workflow/entityMethods.d.ts +4 -4
  41. package/build/services/{memflow → durable}/workflow/entityMethods.js +4 -4
  42. package/build/services/{memflow → durable}/workflow/execChild.d.ts +9 -9
  43. package/build/services/{memflow → durable}/workflow/execChild.js +22 -22
  44. package/build/services/{memflow → durable}/workflow/execHook.d.ts +8 -8
  45. package/build/services/{memflow → durable}/workflow/execHook.js +10 -10
  46. package/build/services/{memflow → durable}/workflow/execHookBatch.d.ts +5 -5
  47. package/build/services/{memflow → durable}/workflow/execHookBatch.js +8 -8
  48. package/build/services/{memflow → durable}/workflow/hook.d.ts +5 -5
  49. package/build/services/{memflow → durable}/workflow/hook.js +11 -11
  50. package/build/services/{memflow → durable}/workflow/index.d.ts +6 -6
  51. package/build/services/{memflow → durable}/workflow/index.js +6 -6
  52. package/build/services/{memflow → durable}/workflow/interrupt.d.ts +7 -7
  53. package/build/services/{memflow → durable}/workflow/interrupt.js +7 -7
  54. package/build/services/{memflow → durable}/workflow/interruption.d.ts +10 -10
  55. package/build/services/{memflow → durable}/workflow/interruption.js +19 -19
  56. package/build/services/{memflow → durable}/workflow/proxyActivities.d.ts +7 -7
  57. package/build/services/{memflow → durable}/workflow/proxyActivities.js +31 -21
  58. package/build/services/{memflow → durable}/workflow/random.d.ts +4 -4
  59. package/build/services/{memflow → durable}/workflow/random.js +4 -4
  60. package/build/services/{memflow → durable}/workflow/searchMethods.d.ts +5 -5
  61. package/build/services/{memflow → durable}/workflow/searchMethods.js +5 -5
  62. package/build/services/{memflow → durable}/workflow/signal.d.ts +8 -8
  63. package/build/services/{memflow → durable}/workflow/signal.js +8 -8
  64. package/build/services/{memflow → durable}/workflow/sleepFor.d.ts +7 -7
  65. package/build/services/{memflow → durable}/workflow/sleepFor.js +10 -10
  66. package/build/services/{memflow → durable}/workflow/trace.d.ts +5 -5
  67. package/build/services/{memflow → durable}/workflow/trace.js +5 -5
  68. package/build/services/{memflow → durable}/workflow/waitFor.d.ts +9 -9
  69. package/build/services/{memflow → durable}/workflow/waitFor.js +12 -12
  70. package/build/services/hotmesh/index.d.ts +3 -3
  71. package/build/services/hotmesh/index.js +3 -3
  72. package/build/services/{meshcall → virtual}/index.d.ts +29 -29
  73. package/build/services/{meshcall → virtual}/index.js +49 -49
  74. package/build/services/{meshcall → virtual}/schemas/factory.d.ts +1 -1
  75. package/build/services/{meshcall → virtual}/schemas/factory.js +1 -1
  76. package/build/types/dba.d.ts +64 -0
  77. package/build/types/{memflow.d.ts → durable.d.ts} +74 -18
  78. package/build/types/error.d.ts +5 -5
  79. package/build/types/exporter.d.ts +1 -1
  80. package/build/types/index.d.ts +5 -4
  81. package/build/types/{meshcall.d.ts → virtual.d.ts} +15 -15
  82. package/build/types/virtual.js +2 -0
  83. package/index.ts +15 -13
  84. package/package.json +23 -22
  85. package/.claude/settings.local.json +0 -8
  86. package/build/services/memflow/workflow/common.js +0 -47
  87. package/build/vitest.config.d.ts +0 -2
  88. package/build/vitest.config.js +0 -18
  89. /package/build/services/{memflow → durable}/entity.d.ts +0 -0
  90. /package/build/services/{memflow → durable}/entity.js +0 -0
  91. /package/build/services/{memflow → durable}/workflow/didRun.d.ts +0 -0
  92. /package/build/services/{memflow → durable}/workflow/didRun.js +0 -0
  93. /package/build/services/{memflow → durable}/workflow/isSideEffectAllowed.d.ts +0 -0
  94. /package/build/services/{memflow → durable}/workflow/isSideEffectAllowed.js +0 -0
  95. /package/build/types/{memflow.js → dba.js} +0 -0
  96. /package/build/types/{meshcall.js → durable.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MemFlow = void 0;
3
+ exports.Durable = void 0;
4
4
  const hotmesh_1 = require("../hotmesh");
5
5
  const utils_1 = require("../../modules/utils");
6
6
  const client_1 = require("./client");
@@ -13,9 +13,9 @@ const handle_1 = require("./handle");
13
13
  const interruption_1 = require("./workflow/interruption");
14
14
  const interceptor_1 = require("./interceptor");
15
15
  /**
16
- * The MemFlow service provides a Temporal-compatible workflow framework backed by
17
- * Postgres. It offers durable execution, entity-based memory management,
18
- * and composable workflows.
16
+ * The Durable service provides a Temporal-compatible workflow framework backed
17
+ * by Postgres. It offers entity-based memory management and composable,
18
+ * fault-tolerant workflows.
19
19
  *
20
20
  * ## Core Features
21
21
  *
@@ -23,7 +23,7 @@ const interceptor_1 = require("./interceptor");
23
23
  * Each workflow has a durable JSONB entity that serves as its memory:
24
24
  * ```typescript
25
25
  * export async function researchAgent(query: string) {
26
- * const agent = await MemFlow.workflow.entity();
26
+ * const agent = await Durable.workflow.entity();
27
27
  *
28
28
  * // Initialize entity state
29
29
  * await agent.set({
@@ -42,14 +42,14 @@ const interceptor_1 = require("./interceptor");
42
42
  * Spawn and coordinate multiple perspectives/phases:
43
43
  * ```typescript
44
44
  * // Launch parallel research perspectives
45
- * await MemFlow.workflow.execHook({
45
+ * await Durable.workflow.execHook({
46
46
  * taskQueue: 'research',
47
47
  * workflowName: 'optimisticView',
48
48
  * args: [query],
49
49
  * signalId: 'optimistic-complete'
50
50
  * });
51
51
  *
52
- * await MemFlow.workflow.execHook({
52
+ * await Durable.workflow.execHook({
53
53
  * taskQueue: 'research',
54
54
  * workflowName: 'skepticalView',
55
55
  * args: [query],
@@ -58,8 +58,8 @@ const interceptor_1 = require("./interceptor");
58
58
  *
59
59
  * // Wait for both perspectives
60
60
  * await Promise.all([
61
- * MemFlow.workflow.waitFor('optimistic-complete'),
62
- * MemFlow.workflow.waitFor('skeptical-complete')
61
+ * Durable.workflow.waitFor('optimistic-complete'),
62
+ * Durable.workflow.waitFor('skeptical-complete')
63
63
  * ]);
64
64
  * ```
65
65
  *
@@ -67,7 +67,7 @@ const interceptor_1 = require("./interceptor");
67
67
  * Define and execute durable activities with automatic retry:
68
68
  * ```typescript
69
69
  * // Default: activities use workflow's task queue
70
- * const activities = MemFlow.workflow.proxyActivities<{
70
+ * const activities = Durable.workflow.proxyActivities<{
71
71
  * analyzeDocument: typeof analyzeDocument;
72
72
  * validateFindings: typeof validateFindings;
73
73
  * }>({
@@ -87,7 +87,7 @@ const interceptor_1 = require("./interceptor");
87
87
  * Register activity workers explicitly before workflows start:
88
88
  * ```typescript
89
89
  * // Register shared activity pool for interceptors
90
- * await MemFlow.registerActivityWorker({
90
+ * await Durable.registerActivityWorker({
91
91
  * connection: {
92
92
  * class: Postgres,
93
93
  * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' }
@@ -96,7 +96,7 @@ const interceptor_1 = require("./interceptor");
96
96
  * }, sharedActivities, 'shared-activities');
97
97
  *
98
98
  * // Register custom activity pool for specific use cases
99
- * await MemFlow.registerActivityWorker({
99
+ * await Durable.registerActivityWorker({
100
100
  * connection: {
101
101
  * class: Postgres,
102
102
  * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' }
@@ -109,7 +109,7 @@ const interceptor_1 = require("./interceptor");
109
109
  * Build complex workflows through composition:
110
110
  * ```typescript
111
111
  * // Start a child workflow
112
- * const childResult = await MemFlow.workflow.execChild({
112
+ * const childResult = await Durable.workflow.execChild({
113
113
  * taskQueue: 'analysis',
114
114
  * workflowName: 'detailedAnalysis',
115
115
  * args: [data],
@@ -121,7 +121,7 @@ const interceptor_1 = require("./interceptor");
121
121
  * });
122
122
  *
123
123
  * // Fire-and-forget child workflow
124
- * await MemFlow.workflow.startChild({
124
+ * await Durable.workflow.startChild({
125
125
  * taskQueue: 'notifications',
126
126
  * workflowName: 'sendUpdates',
127
127
  * args: [updates]
@@ -132,7 +132,7 @@ const interceptor_1 = require("./interceptor");
132
132
  * Add cross-cutting concerns through interceptors that run as durable functions:
133
133
  * ```typescript
134
134
  * // First register shared activity worker for interceptors
135
- * await MemFlow.registerActivityWorker({
135
+ * await Durable.registerActivityWorker({
136
136
  * connection: {
137
137
  * class: Postgres,
138
138
  * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' }
@@ -141,11 +141,11 @@ const interceptor_1 = require("./interceptor");
141
141
  * }, { auditLog }, 'interceptor-activities');
142
142
  *
143
143
  * // Add audit interceptor that uses activities with explicit taskQueue
144
- * MemFlow.registerInterceptor({
144
+ * Durable.registerInterceptor({
145
145
  * async execute(ctx, next) {
146
146
  * try {
147
147
  * // Interceptors use explicit taskQueue to prevent per-workflow queues
148
- * const { auditLog } = MemFlow.workflow.proxyActivities<typeof activities>({
148
+ * const { auditLog } = Durable.workflow.proxyActivities<typeof activities>({
149
149
  * activities: { auditLog },
150
150
  * taskQueue: 'interceptor-activities', // Explicit shared queue
151
151
  * retryPolicy: { maximumAttempts: 3 }
@@ -160,7 +160,7 @@ const interceptor_1 = require("./interceptor");
160
160
  * return result;
161
161
  * } catch (err) {
162
162
  * // CRITICAL: Always check for HotMesh interruptions
163
- * if (MemFlow.didInterrupt(err)) {
163
+ * if (Durable.didInterrupt(err)) {
164
164
  * throw err; // Rethrow for replay system
165
165
  * }
166
166
  * throw err;
@@ -169,15 +169,71 @@ const interceptor_1 = require("./interceptor");
169
169
  * });
170
170
  * ```
171
171
  *
172
+ * ### 7. Activity Interceptors
173
+ * Wrap individual proxied activity calls with cross-cutting logic.
174
+ * Unlike workflow interceptors (which wrap the entire workflow), activity
175
+ * interceptors execute around each `proxyActivities` call. They run inside
176
+ * the workflow's execution context and have access to all Durable workflow
177
+ * methods (`proxyActivities`, `sleepFor`, `waitFor`, `execChild`, etc.).
178
+ * Multiple activity interceptors execute in onion order (first registered
179
+ * is outermost).
180
+ * ```typescript
181
+ * // Simple logging interceptor
182
+ * Durable.registerActivityInterceptor({
183
+ * async execute(activityCtx, workflowCtx, next) {
184
+ * console.log(`Activity ${activityCtx.activityName} starting`);
185
+ * try {
186
+ * const result = await next();
187
+ * console.log(`Activity ${activityCtx.activityName} completed`);
188
+ * return result;
189
+ * } catch (err) {
190
+ * if (Durable.didInterrupt(err)) throw err;
191
+ * console.error(`Activity ${activityCtx.activityName} failed`);
192
+ * throw err;
193
+ * }
194
+ * }
195
+ * });
196
+ *
197
+ * // Interceptor that calls its own proxy activities
198
+ * await Durable.registerActivityWorker({
199
+ * connection: {
200
+ * class: Postgres,
201
+ * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' }
202
+ * },
203
+ * taskQueue: 'audit-activities'
204
+ * }, { auditLog }, 'audit-activities');
205
+ *
206
+ * Durable.registerActivityInterceptor({
207
+ * async execute(activityCtx, workflowCtx, next) {
208
+ * try {
209
+ * const { auditLog } = Durable.workflow.proxyActivities<{
210
+ * auditLog: (id: string, action: string) => Promise<void>;
211
+ * }>({
212
+ * taskQueue: 'audit-activities',
213
+ * retryPolicy: { maximumAttempts: 3 }
214
+ * });
215
+ *
216
+ * await auditLog(workflowCtx.get('workflowId'), `before:${activityCtx.activityName}`);
217
+ * const result = await next();
218
+ * await auditLog(workflowCtx.get('workflowId'), `after:${activityCtx.activityName}`);
219
+ * return result;
220
+ * } catch (err) {
221
+ * if (Durable.didInterrupt(err)) throw err;
222
+ * throw err;
223
+ * }
224
+ * }
225
+ * });
226
+ * ```
227
+ *
172
228
  * ## Basic Usage Example
173
229
  *
174
230
  * ```typescript
175
- * import { Client, Worker, MemFlow } from '@hotmeshio/hotmesh';
231
+ * import { Client, Worker, Durable } from '@hotmeshio/hotmesh';
176
232
  * import { Client as Postgres } from 'pg';
177
233
  * import * as activities from './activities';
178
234
  *
179
235
  * // (Optional) Register shared activity workers for interceptors
180
- * await MemFlow.registerActivityWorker({
236
+ * await Durable.registerActivityWorker({
181
237
  * connection: {
182
238
  * class: Postgres,
183
239
  * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' }
@@ -208,17 +264,17 @@ const interceptor_1 = require("./interceptor");
208
264
  * args: ['input data'],
209
265
  * taskQueue: 'default',
210
266
  * workflowName: 'example',
211
- * workflowId: MemFlow.guid()
267
+ * workflowId: Durable.guid()
212
268
  * });
213
269
  *
214
270
  * // Get result
215
271
  * const result = await handle.result();
216
272
  *
217
273
  * // Cleanup
218
- * await MemFlow.shutdown();
274
+ * await Durable.shutdown();
219
275
  * ```
220
276
  */
221
- class MemFlowClass {
277
+ class DurableClass {
222
278
  /**
223
279
  * @private
224
280
  */
@@ -228,62 +284,102 @@ class MemFlowClass {
228
284
  * @param interceptor The interceptor to register
229
285
  */
230
286
  static registerInterceptor(interceptor) {
231
- MemFlowClass.interceptorService.register(interceptor);
287
+ DurableClass.interceptorService.register(interceptor);
232
288
  }
233
289
  /**
234
- * Clear all registered workflow interceptors
290
+ * Clear all registered interceptors (both workflow and activity)
235
291
  */
236
292
  static clearInterceptors() {
237
- MemFlowClass.interceptorService.clear();
293
+ DurableClass.interceptorService.clear();
294
+ }
295
+ /**
296
+ * Register an activity interceptor that wraps individual proxied
297
+ * activity calls within workflows. Interceptors execute in registration
298
+ * order (first registered is outermost) using the onion pattern.
299
+ *
300
+ * Activity interceptors run inside the workflow's execution context
301
+ * and have access to all Durable workflow methods (`proxyActivities`,
302
+ * `sleepFor`, `waitFor`, `execChild`, etc.). The `activityCtx` parameter
303
+ * provides `activityName`, `args`, and `options` for the call being
304
+ * intercepted. The `workflowCtx` map provides workflow metadata
305
+ * (`workflowId`, `workflowName`, `namespace`, etc.).
306
+ *
307
+ * @param interceptor The activity interceptor to register
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * Durable.registerActivityInterceptor({
312
+ * async execute(activityCtx, workflowCtx, next) {
313
+ * const start = Date.now();
314
+ * try {
315
+ * const result = await next();
316
+ * console.log(`${activityCtx.activityName} took ${Date.now() - start}ms`);
317
+ * return result;
318
+ * } catch (err) {
319
+ * if (Durable.didInterrupt(err)) throw err;
320
+ * throw err;
321
+ * }
322
+ * }
323
+ * });
324
+ * ```
325
+ */
326
+ static registerActivityInterceptor(interceptor) {
327
+ DurableClass.interceptorService.registerActivity(interceptor);
328
+ }
329
+ /**
330
+ * Clear all registered activity interceptors
331
+ */
332
+ static clearActivityInterceptors() {
333
+ DurableClass.interceptorService.clearActivity();
238
334
  }
239
335
  /**
240
336
  * Get the interceptor service instance
241
337
  * @internal
242
338
  */
243
339
  static getInterceptorService() {
244
- return MemFlowClass.interceptorService;
340
+ return DurableClass.interceptorService;
245
341
  }
246
342
  /**
247
343
  * Shutdown everything. All connections, workers, and clients will be closed.
248
344
  * Include in your signal handlers to ensure a clean shutdown.
249
345
  */
250
346
  static async shutdown() {
251
- await MemFlowClass.Client.shutdown();
252
- await MemFlowClass.Worker.shutdown();
347
+ await DurableClass.Client.shutdown();
348
+ await DurableClass.Worker.shutdown();
253
349
  await hotmesh_1.HotMesh.stop();
254
350
  }
255
351
  }
256
- exports.MemFlow = MemFlowClass;
352
+ exports.Durable = DurableClass;
257
353
  /**
258
- * The MemFlow `Client` service is functionally
354
+ * The Durable `Client` service is functionally
259
355
  * equivalent to the Temporal `Client` service.
260
356
  */
261
- MemFlowClass.Client = client_1.ClientService;
357
+ DurableClass.Client = client_1.ClientService;
262
358
  /**
263
- * The MemFlow `Connection` service is functionally
359
+ * The Durable `Connection` service is functionally
264
360
  * equivalent to the Temporal `Connection` service.
265
361
  */
266
- MemFlowClass.Connection = connection_1.ConnectionService;
362
+ DurableClass.Connection = connection_1.ConnectionService;
267
363
  /**
268
364
  * @private
269
365
  */
270
- MemFlowClass.Search = search_1.Search;
366
+ DurableClass.Search = search_1.Search;
271
367
  /**
272
368
  * @private
273
369
  */
274
- MemFlowClass.Entity = entity_1.Entity;
370
+ DurableClass.Entity = entity_1.Entity;
275
371
  /**
276
372
  * The Handle provides methods to interact with a running
277
373
  * workflow. This includes exporting the workflow, sending signals, and
278
374
  * querying the state of the workflow. An instance of the Handle service
279
- * is typically accessed via the MemFlow.Client class (workflow.getHandle).
375
+ * is typically accessed via the Durable.Client class (workflow.getHandle).
280
376
  */
281
- MemFlowClass.Handle = handle_1.WorkflowHandleService;
377
+ DurableClass.Handle = handle_1.WorkflowHandleService;
282
378
  /**
283
- * The MemFlow `Worker` service is functionally
379
+ * The Durable `Worker` service is functionally
284
380
  * equivalent to the Temporal `Worker` service.
285
381
  */
286
- MemFlowClass.Worker = worker_1.WorkerService;
382
+ DurableClass.Worker = worker_1.WorkerService;
287
383
  /**
288
384
  * Register activity workers for a task queue. Activities execute via message queue
289
385
  * and can run on different servers from workflows.
@@ -296,7 +392,7 @@ MemFlowClass.Worker = worker_1.WorkerService;
296
392
  * async sendEmail(to: string, msg: string) { /* ... *\/ }
297
393
  * };
298
394
  *
299
- * await MemFlow.registerActivityWorker({
395
+ * await Durable.registerActivityWorker({
300
396
  * connection: {
301
397
  * class: Postgres,
302
398
  * options: { connectionString: 'postgresql://usr:pwd@localhost:5432/db' }
@@ -306,7 +402,7 @@ MemFlowClass.Worker = worker_1.WorkerService;
306
402
  *
307
403
  * // Workflow worker (can be on different server)
308
404
  * async function orderWorkflow(amount: number) {
309
- * const { processPayment, sendEmail } = MemFlow.workflow.proxyActivities<{
405
+ * const { processPayment, sendEmail } = Durable.workflow.proxyActivities<{
310
406
  * processPayment: (amount: number) => Promise<string>;
311
407
  * sendEmail: (to: string, msg: string) => Promise<void>;
312
408
  * }>({
@@ -319,30 +415,30 @@ MemFlowClass.Worker = worker_1.WorkerService;
319
415
  * return result;
320
416
  * }
321
417
  *
322
- * await MemFlow.Worker.create({
418
+ * await Durable.Worker.create({
323
419
  * connection: { class: Postgres, options: { connectionString: '...' } },
324
420
  * taskQueue: 'orders',
325
421
  * workflow: orderWorkflow
326
422
  * });
327
423
  * ```
328
424
  */
329
- MemFlowClass.registerActivityWorker = worker_1.WorkerService.registerActivityWorker;
425
+ DurableClass.registerActivityWorker = worker_1.WorkerService.registerActivityWorker;
330
426
  /**
331
- * The MemFlow `workflow` service is functionally
427
+ * The Durable `workflow` service is functionally
332
428
  * equivalent to the Temporal `Workflow` service
333
429
  * with additional methods for managing workflows,
334
430
  * including: `execChild`, `waitFor`, `sleep`, etc
335
431
  */
336
- MemFlowClass.workflow = workflow_1.WorkflowService;
432
+ DurableClass.workflow = workflow_1.WorkflowService;
337
433
  /**
338
434
  * Checks if an error is a HotMesh reserved error type that indicates
339
435
  * a workflow interruption rather than a true error condition.
340
436
  *
341
437
  * @see {@link didInterrupt} for detailed documentation
342
438
  */
343
- MemFlowClass.didInterrupt = interruption_1.didInterrupt;
344
- MemFlowClass.interceptorService = new interceptor_1.InterceptorService();
439
+ DurableClass.didInterrupt = interruption_1.didInterrupt;
440
+ DurableClass.interceptorService = new interceptor_1.InterceptorService();
345
441
  /**
346
442
  * Generate a unique identifier for workflow IDs
347
443
  */
348
- MemFlowClass.guid = utils_1.guid;
444
+ DurableClass.guid = utils_1.guid;
@@ -1,4 +1,4 @@
1
- import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
1
+ import { WorkflowInterceptor, InterceptorRegistry, ActivityInterceptor, ActivityInterceptorContext } from '../../types/durable';
2
2
  /**
3
3
  * Service for managing workflow interceptors that wrap workflow execution
4
4
  * in an onion-like pattern. Each interceptor can perform actions before
@@ -49,32 +49,32 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
49
49
  * });
50
50
  * ```
51
51
  *
52
- * ## Durable Interceptors with MemFlow Functions
52
+ * ## Durable Interceptors with Durable Functions
53
53
  *
54
54
  * Interceptors run within the workflow's async local storage context, which means
55
- * they can use MemFlow functions like `sleepFor`, `entity`, `proxyActivities`, etc.
55
+ * they can use Durable functions like `sleepFor`, `entity`, `proxyActivities`, etc.
56
56
  * These interceptors participate in the HotMesh interruption/replay pattern.
57
57
  *
58
58
  * @example
59
59
  * ```typescript
60
- * import { MemFlow } from '@hotmeshio/hotmesh';
60
+ * import { Durable } from '@hotmeshio/hotmesh';
61
61
  *
62
62
  * // Rate limiting interceptor that sleeps before execution
63
63
  * const rateLimitInterceptor: WorkflowInterceptor = {
64
64
  * async execute(ctx, next) {
65
65
  * try {
66
66
  * // This sleep will cause an interruption on first execution
67
- * await MemFlow.workflow.sleepFor('1 second');
67
+ * await Durable.workflow.sleepFor('1 second');
68
68
  *
69
69
  * const result = await next();
70
70
  *
71
71
  * // Another sleep after workflow completes
72
- * await MemFlow.workflow.sleepFor('500 milliseconds');
72
+ * await Durable.workflow.sleepFor('500 milliseconds');
73
73
  *
74
74
  * return result;
75
75
  * } catch (err) {
76
76
  * // CRITICAL: Always check for HotMesh interruptions
77
- * if (MemFlow.didInterrupt(err)) {
77
+ * if (Durable.didInterrupt(err)) {
78
78
  * throw err; // Rethrow interruptions for replay system
79
79
  * }
80
80
  * // Handle actual errors
@@ -88,7 +88,7 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
88
88
  * const auditInterceptor: WorkflowInterceptor = {
89
89
  * async execute(ctx, next) {
90
90
  * try {
91
- * const entity = await MemFlow.workflow.entity();
91
+ * const entity = await Durable.workflow.entity();
92
92
  * await entity.append('auditLog', {
93
93
  * action: 'workflow_started',
94
94
  * timestamp: new Date().toISOString(),
@@ -108,12 +108,12 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
108
108
  *
109
109
  * return result;
110
110
  * } catch (err) {
111
- * if (MemFlow.didInterrupt(err)) {
111
+ * if (Durable.didInterrupt(err)) {
112
112
  * throw err;
113
113
  * }
114
114
  *
115
115
  * // Log failure to entity
116
- * const entity = await MemFlow.workflow.entity();
116
+ * const entity = await Durable.workflow.entity();
117
117
  * await entity.append('auditLog', {
118
118
  * action: 'workflow_failed',
119
119
  * timestamp: new Date().toISOString(),
@@ -126,35 +126,35 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
126
126
  * };
127
127
  *
128
128
  * // Register interceptors
129
- * MemFlow.registerInterceptor(rateLimitInterceptor);
130
- * MemFlow.registerInterceptor(auditInterceptor);
129
+ * Durable.registerInterceptor(rateLimitInterceptor);
130
+ * Durable.registerInterceptor(auditInterceptor);
131
131
  * ```
132
132
  *
133
133
  * ## Execution Pattern with Interruptions
134
134
  *
135
- * When interceptors use MemFlow functions, the workflow will execute multiple times
135
+ * When interceptors use Durable functions, the workflow will execute multiple times
136
136
  * due to the interruption/replay pattern:
137
137
  *
138
- * 1. **First execution**: Interceptor calls `sleepFor` → throws `MemFlowSleepError` → workflow pauses
139
- * 2. **Second execution**: Interceptor sleep replays (skipped), workflow runs → proxy activity throws `MemFlowProxyError` → workflow pauses
140
- * 3. **Third execution**: All previous operations replay, interceptor sleep after workflow → throws `MemFlowSleepError` → workflow pauses
138
+ * 1. **First execution**: Interceptor calls `sleepFor` → throws `DurableSleepError` → workflow pauses
139
+ * 2. **Second execution**: Interceptor sleep replays (skipped), workflow runs → proxy activity throws `DurableProxyError` → workflow pauses
140
+ * 3. **Third execution**: All previous operations replay, interceptor sleep after workflow → throws `DurableSleepError` → workflow pauses
141
141
  * 4. **Fourth execution**: Everything replays successfully, workflow completes
142
142
  *
143
143
  * This pattern ensures deterministic, durable execution across all interceptors and workflow code.
144
144
  *
145
145
  * @example
146
146
  * ```typescript
147
- * // Interceptor with complex MemFlow operations
147
+ * // Interceptor with complex Durable operations
148
148
  * const complexInterceptor: WorkflowInterceptor = {
149
149
  * async execute(ctx, next) {
150
150
  * try {
151
151
  * // Get persistent state
152
- * const entity = await MemFlow.workflow.entity();
152
+ * const entity = await Durable.workflow.entity();
153
153
  * const state = await entity.get() as any;
154
154
  *
155
155
  * // Conditional durable operations
156
156
  * if (!state.preProcessed) {
157
- * await MemFlow.workflow.sleepFor('100 milliseconds');
157
+ * await Durable.workflow.sleepFor('100 milliseconds');
158
158
  * await entity.merge({ preProcessed: true });
159
159
  * }
160
160
  *
@@ -163,7 +163,7 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
163
163
  *
164
164
  * // Post-processing with child workflow
165
165
  * if (!state.postProcessed) {
166
- * await MemFlow.workflow.execChild({
166
+ * await Durable.workflow.execChild({
167
167
  * taskQueue: 'cleanup',
168
168
  * workflowName: 'cleanupWorkflow',
169
169
  * args: [result]
@@ -173,7 +173,7 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
173
173
  *
174
174
  * return result;
175
175
  * } catch (err) {
176
- * if (MemFlow.didInterrupt(err)) {
176
+ * if (Durable.didInterrupt(err)) {
177
177
  * throw err;
178
178
  * }
179
179
  * throw err;
@@ -184,6 +184,7 @@ import { WorkflowInterceptor, InterceptorRegistry } from '../../types/memflow';
184
184
  */
185
185
  export declare class InterceptorService implements InterceptorRegistry {
186
186
  interceptors: WorkflowInterceptor[];
187
+ activityInterceptors: ActivityInterceptor[];
187
188
  /**
188
189
  * Register a new workflow interceptor that will wrap workflow execution.
189
190
  * Interceptors are executed in the order they are registered, with the
@@ -230,7 +231,29 @@ export declare class InterceptorService implements InterceptorRegistry {
230
231
  */
231
232
  executeChain(ctx: Map<string, any>, fn: () => Promise<any>): Promise<any>;
232
233
  /**
233
- * Clear all registered interceptors.
234
+ * Register a new activity interceptor that will wrap individual
235
+ * proxied activity calls. Interceptors are executed in the order
236
+ * they are registered, with the first registered being the outermost wrapper.
237
+ *
238
+ * @param interceptor The activity interceptor to register
239
+ */
240
+ registerActivity(interceptor: ActivityInterceptor): void;
241
+ /**
242
+ * Execute the activity interceptor chain around an activity invocation.
243
+ * Uses the same onion/reduceRight pattern as executeChain.
244
+ *
245
+ * @param activityCtx - Metadata about the activity (name, args, options)
246
+ * @param workflowCtx - The workflow context Map
247
+ * @param fn - The core activity function (registers with interruptionRegistry, sleeps, throws)
248
+ * @returns The result of the activity (from replay or after future execution)
249
+ */
250
+ executeActivityChain(activityCtx: ActivityInterceptorContext, workflowCtx: Map<string, any>, fn: () => Promise<any>): Promise<any>;
251
+ /**
252
+ * Clear all registered activity interceptors.
253
+ */
254
+ clearActivity(): void;
255
+ /**
256
+ * Clear all registered interceptors (both workflow and activity).
234
257
  *
235
258
  * @example
236
259
  * ```typescript