@hotmeshio/hotmesh 0.13.0 → 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.
- package/README.md +18 -22
- package/build/modules/enums.d.ts +60 -5
- package/build/modules/enums.js +62 -7
- package/build/modules/errors.d.ts +15 -3
- package/build/modules/errors.js +17 -2
- package/build/package.json +6 -1
- package/build/services/activities/activity/context.d.ts +22 -0
- package/build/services/activities/activity/context.js +76 -0
- package/build/services/activities/activity/index.d.ts +116 -0
- package/build/services/activities/activity/index.js +299 -0
- package/build/services/activities/activity/mapping.d.ts +12 -0
- package/build/services/activities/activity/mapping.js +63 -0
- package/build/services/activities/activity/process.d.ts +28 -0
- package/build/services/activities/activity/process.js +100 -0
- package/build/services/activities/activity/protocol.d.ts +39 -0
- package/build/services/activities/activity/protocol.js +151 -0
- package/build/services/activities/activity/state.d.ts +40 -0
- package/build/services/activities/activity/state.js +143 -0
- package/build/services/activities/activity/transition.d.ts +23 -0
- package/build/services/activities/activity/transition.js +71 -0
- package/build/services/activities/activity/verify.d.ts +22 -0
- package/build/services/activities/activity/verify.js +85 -0
- package/build/services/activities/await.d.ts +1 -4
- package/build/services/activities/await.js +2 -36
- package/build/services/activities/cycle.d.ts +1 -11
- package/build/services/activities/cycle.js +3 -46
- package/build/services/activities/hook.d.ts +2 -11
- package/build/services/activities/hook.js +30 -50
- package/build/services/activities/interrupt.d.ts +2 -4
- package/build/services/activities/interrupt.js +4 -38
- package/build/services/activities/signal.d.ts +1 -11
- package/build/services/activities/signal.js +3 -48
- package/build/services/activities/trigger.d.ts +1 -3
- package/build/services/activities/trigger.js +0 -3
- package/build/services/activities/worker.d.ts +3 -6
- package/build/services/activities/worker.js +4 -40
- package/build/services/connector/factory.d.ts +6 -0
- package/build/services/connector/factory.js +24 -0
- package/build/services/durable/activity.d.ts +1 -1
- package/build/services/durable/activity.js +2 -2
- package/build/services/durable/client.d.ts +24 -29
- package/build/services/durable/client.js +24 -29
- package/build/services/durable/connection.d.ts +13 -7
- package/build/services/durable/connection.js +13 -7
- package/build/services/durable/handle.d.ts +58 -40
- package/build/services/durable/handle.js +60 -40
- package/build/services/durable/index.d.ts +148 -286
- package/build/services/durable/index.js +157 -292
- package/build/services/durable/interceptor.d.ts +43 -33
- package/build/services/durable/interceptor.js +59 -39
- package/build/services/durable/schemas/factory.d.ts +1 -1
- package/build/services/durable/schemas/factory.js +168 -38
- package/build/services/durable/telemetry.d.ts +80 -0
- package/build/services/durable/telemetry.js +137 -0
- package/build/services/durable/worker.d.ts +100 -21
- package/build/services/durable/worker.js +304 -63
- package/build/services/durable/workflow/all.d.ts +1 -1
- package/build/services/durable/workflow/all.js +1 -1
- package/build/services/durable/workflow/cancellationScope.d.ts +104 -0
- package/build/services/durable/workflow/cancellationScope.js +139 -0
- package/build/services/durable/workflow/common.d.ts +5 -4
- package/build/services/durable/workflow/common.js +6 -1
- package/build/services/durable/workflow/{waitFor.d.ts → condition.d.ts} +9 -8
- package/build/services/durable/workflow/{waitFor.js → condition.js} +44 -11
- package/build/services/durable/workflow/continueAsNew.d.ts +65 -0
- package/build/services/durable/workflow/continueAsNew.js +92 -0
- package/build/services/durable/workflow/didRun.d.ts +1 -1
- package/build/services/durable/workflow/didRun.js +3 -3
- package/build/services/durable/workflow/enrich.d.ts +5 -0
- package/build/services/durable/workflow/enrich.js +5 -0
- package/build/services/durable/workflow/entityMethods.d.ts +7 -0
- package/build/services/durable/workflow/entityMethods.js +7 -0
- package/build/services/durable/workflow/execHook.js +3 -3
- package/build/services/durable/workflow/execHookBatch.js +2 -2
- package/build/services/durable/workflow/{execChild.d.ts → executeChild.d.ts} +4 -40
- package/build/services/durable/workflow/{execChild.js → executeChild.js} +36 -45
- package/build/services/durable/workflow/hook.d.ts +1 -1
- package/build/services/durable/workflow/hook.js +4 -3
- package/build/services/durable/workflow/index.d.ts +45 -50
- package/build/services/durable/workflow/index.js +46 -51
- package/build/services/durable/workflow/interruption.d.ts +7 -6
- package/build/services/durable/workflow/interruption.js +11 -7
- package/build/services/durable/workflow/patched.d.ts +72 -0
- package/build/services/durable/workflow/patched.js +110 -0
- package/build/services/durable/workflow/proxyActivities.d.ts +7 -7
- package/build/services/durable/workflow/proxyActivities.js +50 -15
- package/build/services/durable/workflow/searchMethods.d.ts +7 -0
- package/build/services/durable/workflow/searchMethods.js +7 -0
- package/build/services/durable/workflow/signal.d.ts +4 -4
- package/build/services/durable/workflow/signal.js +4 -4
- package/build/services/durable/workflow/{sleepFor.d.ts → sleep.d.ts} +7 -7
- package/build/services/durable/workflow/{sleepFor.js → sleep.js} +39 -10
- package/build/services/durable/workflow/terminate.d.ts +55 -0
- package/build/services/durable/workflow/{interrupt.js → terminate.js} +21 -21
- package/build/services/durable/workflow/trace.js +2 -2
- package/build/services/durable/workflow/uuid4.d.ts +14 -0
- package/build/services/durable/workflow/uuid4.js +39 -0
- package/build/services/durable/workflow/{context.d.ts → workflowInfo.d.ts} +5 -5
- package/build/services/durable/workflow/{context.js → workflowInfo.js} +7 -7
- package/build/services/engine/compiler.d.ts +19 -0
- package/build/services/engine/compiler.js +20 -0
- package/build/services/engine/completion.d.ts +46 -0
- package/build/services/engine/completion.js +145 -0
- package/build/services/engine/dispatch.d.ts +24 -0
- package/build/services/engine/dispatch.js +98 -0
- package/build/services/engine/index.d.ts +49 -81
- package/build/services/engine/index.js +175 -573
- package/build/services/engine/init.d.ts +42 -0
- package/build/services/engine/init.js +74 -0
- package/build/services/engine/pubsub.d.ts +50 -0
- package/build/services/engine/pubsub.js +118 -0
- package/build/services/engine/reporting.d.ts +20 -0
- package/build/services/engine/reporting.js +38 -0
- package/build/services/engine/schema.d.ts +23 -0
- package/build/services/engine/schema.js +62 -0
- package/build/services/engine/signal.d.ts +57 -0
- package/build/services/engine/signal.js +117 -0
- package/build/services/engine/state.d.ts +35 -0
- package/build/services/engine/state.js +61 -0
- package/build/services/engine/version.d.ts +31 -0
- package/build/services/engine/version.js +73 -0
- package/build/services/hotmesh/deployment.d.ts +21 -0
- package/build/services/hotmesh/deployment.js +25 -0
- package/build/services/hotmesh/index.d.ts +141 -532
- package/build/services/hotmesh/index.js +222 -673
- package/build/services/hotmesh/init.d.ts +42 -0
- package/build/services/hotmesh/init.js +93 -0
- package/build/services/hotmesh/jobs.d.ts +67 -0
- package/build/services/hotmesh/jobs.js +99 -0
- package/build/services/hotmesh/pubsub.d.ts +38 -0
- package/build/services/hotmesh/pubsub.js +54 -0
- package/build/services/hotmesh/quorum.d.ts +30 -0
- package/build/services/hotmesh/quorum.js +62 -0
- package/build/services/hotmesh/validation.d.ts +6 -0
- package/build/services/hotmesh/validation.js +28 -0
- package/build/services/quorum/index.js +1 -0
- package/build/services/router/consumption/index.d.ts +11 -5
- package/build/services/router/consumption/index.js +24 -17
- package/build/services/router/error-handling/index.d.ts +2 -2
- package/build/services/router/error-handling/index.js +14 -14
- package/build/services/router/index.d.ts +1 -1
- package/build/services/router/index.js +2 -2
- package/build/services/serializer/index.d.ts +22 -0
- package/build/services/serializer/index.js +39 -1
- package/build/services/store/index.d.ts +1 -0
- package/build/services/store/providers/postgres/exporter-sql.d.ts +2 -2
- package/build/services/store/providers/postgres/exporter-sql.js +4 -4
- package/build/services/store/providers/postgres/kvtables.js +7 -6
- package/build/services/store/providers/postgres/kvtypes/hash/basic.js +67 -52
- package/build/services/store/providers/postgres/kvtypes/hash/jsonb.js +87 -72
- package/build/services/store/providers/postgres/kvtypes/hash/udata.js +106 -79
- package/build/services/store/providers/postgres/kvtypes/hash/utils.d.ts +16 -0
- package/build/services/store/providers/postgres/kvtypes/hash/utils.js +29 -16
- package/build/services/store/providers/postgres/postgres.d.ts +1 -0
- package/build/services/store/providers/postgres/postgres.js +14 -4
- package/build/services/stream/factory.d.ts +3 -1
- package/build/services/stream/factory.js +2 -2
- package/build/services/stream/index.d.ts +1 -0
- package/build/services/stream/providers/nats/nats.d.ts +1 -0
- package/build/services/stream/providers/nats/nats.js +1 -0
- package/build/services/stream/providers/postgres/credentials.d.ts +56 -0
- package/build/services/stream/providers/postgres/credentials.js +129 -0
- package/build/services/stream/providers/postgres/kvtables.js +18 -0
- package/build/services/stream/providers/postgres/messages.js +7 -7
- package/build/services/stream/providers/postgres/notifications.js +16 -2
- package/build/services/stream/providers/postgres/postgres.d.ts +7 -0
- package/build/services/stream/providers/postgres/postgres.js +35 -4
- package/build/services/stream/providers/postgres/procedures.d.ts +21 -0
- package/build/services/stream/providers/postgres/procedures.js +213 -0
- package/build/services/stream/providers/postgres/secured.d.ts +34 -0
- package/build/services/stream/providers/postgres/secured.js +146 -0
- package/build/services/stream/providers/postgres/stats.d.ts +1 -0
- package/build/services/stream/providers/postgres/stats.js +1 -0
- package/build/services/stream/registry.d.ts +1 -1
- package/build/services/stream/registry.js +5 -2
- package/build/services/telemetry/index.d.ts +10 -1
- package/build/services/telemetry/index.js +40 -7
- package/build/services/worker/credentials.d.ts +51 -0
- package/build/services/worker/credentials.js +87 -0
- package/build/services/worker/index.d.ts +2 -2
- package/build/services/worker/index.js +7 -6
- package/build/types/codec.d.ts +84 -0
- package/build/types/codec.js +2 -0
- package/build/types/durable.d.ts +104 -28
- package/build/types/error.d.ts +10 -1
- package/build/types/hotmesh.d.ts +67 -4
- package/build/types/index.d.ts +2 -1
- package/build/types/provider.d.ts +2 -2
- package/build/types/quorum.d.ts +35 -1
- package/build/types/stream.d.ts +12 -6
- package/package.json +6 -1
- package/build/services/activities/activity.d.ts +0 -192
- package/build/services/activities/activity.js +0 -786
- package/build/services/durable/workflow/interrupt.d.ts +0 -55
|
@@ -31,6 +31,11 @@ import { StringStringType } from './common';
|
|
|
31
31
|
* }
|
|
32
32
|
* ```
|
|
33
33
|
*
|
|
34
|
+
* **Not available with `workerCredentials`.** This is a convenience
|
|
35
|
+
* wrapper around `search().set()` and inherits the same restriction:
|
|
36
|
+
* it writes directly to tables, bypassing the stored procedures that
|
|
37
|
+
* scoped worker roles are restricted to.
|
|
38
|
+
*
|
|
34
39
|
* @param {StringStringType} fields - Key-value fields to write to the workflow record.
|
|
35
40
|
* @returns {Promise<boolean>} `true` when enrichment is completed.
|
|
36
41
|
*/
|
|
@@ -34,6 +34,11 @@ const searchMethods_1 = require("./searchMethods");
|
|
|
34
34
|
* }
|
|
35
35
|
* ```
|
|
36
36
|
*
|
|
37
|
+
* **Not available with `workerCredentials`.** This is a convenience
|
|
38
|
+
* wrapper around `search().set()` and inherits the same restriction:
|
|
39
|
+
* it writes directly to tables, bypassing the stored procedures that
|
|
40
|
+
* scoped worker roles are restricted to.
|
|
41
|
+
*
|
|
37
42
|
* @param {StringStringType} fields - Key-value fields to write to the workflow record.
|
|
38
43
|
* @returns {Promise<boolean>} `true` when enrichment is completed.
|
|
39
44
|
*/
|
|
@@ -56,6 +56,13 @@ import { Entity } from './common';
|
|
|
56
56
|
* }
|
|
57
57
|
* ```
|
|
58
58
|
*
|
|
59
|
+
* **Not available with `workerCredentials`.** This method writes directly
|
|
60
|
+
* to the `jobs` table (JSONB `context` column), bypassing the SECURITY
|
|
61
|
+
* DEFINER stored procedures that scoped worker roles are restricted to.
|
|
62
|
+
* Workers connecting with `workerCredentials` will receive a permission
|
|
63
|
+
* error. Use `entity()` only in workflows running with full database
|
|
64
|
+
* credentials.
|
|
65
|
+
*
|
|
59
66
|
* @returns {Promise<Entity>} An entity session scoped to the current workflow job.
|
|
60
67
|
*/
|
|
61
68
|
export declare function entity(): Promise<Entity>;
|
|
@@ -59,6 +59,13 @@ const common_1 = require("./common");
|
|
|
59
59
|
* }
|
|
60
60
|
* ```
|
|
61
61
|
*
|
|
62
|
+
* **Not available with `workerCredentials`.** This method writes directly
|
|
63
|
+
* to the `jobs` table (JSONB `context` column), bypassing the SECURITY
|
|
64
|
+
* DEFINER stored procedures that scoped worker roles are restricted to.
|
|
65
|
+
* Workers connecting with `workerCredentials` will receive a permission
|
|
66
|
+
* error. Use `entity()` only in workflows running with full database
|
|
67
|
+
* credentials.
|
|
68
|
+
*
|
|
62
69
|
* @returns {Promise<Entity>} An entity session scoped to the current workflow job.
|
|
63
70
|
*/
|
|
64
71
|
async function entity() {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.execHook = void 0;
|
|
4
4
|
const hook_1 = require("./hook");
|
|
5
|
-
const
|
|
5
|
+
const condition_1 = require("./condition");
|
|
6
6
|
const interruption_1 = require("./interruption");
|
|
7
7
|
/**
|
|
8
8
|
* Combines `hook()` + `waitFor()` into a single call: spawns a hook
|
|
@@ -85,8 +85,8 @@ async function execHook(options) {
|
|
|
85
85
|
};
|
|
86
86
|
// Execute the hook with the signal information
|
|
87
87
|
await (0, hook_1.hook)(hookOptions);
|
|
88
|
-
// Wait for the signal response and return it
|
|
89
|
-
return await (0,
|
|
88
|
+
// Wait for the signal response and return it (no timeout, so never returns false)
|
|
89
|
+
return await (0, condition_1.condition)(options.signalId);
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
92
|
if ((0, interruption_1.didInterrupt)(error)) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.execHookBatch = void 0;
|
|
4
4
|
const hook_1 = require("./hook");
|
|
5
|
-
const
|
|
5
|
+
const condition_1 = require("./condition");
|
|
6
6
|
/**
|
|
7
7
|
* Executes multiple hooks in parallel and awaits all their signal responses,
|
|
8
8
|
* returning a keyed object of results. This is the recommended way to run
|
|
@@ -122,7 +122,7 @@ async function execHookBatch(hookConfigs) {
|
|
|
122
122
|
// STEP 2: Await all waitFor operations
|
|
123
123
|
// This ensures all waitFor registrations happen in the same call stack
|
|
124
124
|
// before any DurableWaitForError is thrown (via setImmediate mechanism)
|
|
125
|
-
const results = await Promise.all(processedConfigs.map(config => (0,
|
|
125
|
+
const results = await Promise.all(processedConfigs.map(config => (0, condition_1.condition)(config.options.signalId)));
|
|
126
126
|
// STEP 3: Return results as a keyed object
|
|
127
127
|
return Object.fromEntries(processedConfigs.map((config, i) => [config.key, results[i]]));
|
|
128
128
|
}
|
|
@@ -23,7 +23,7 @@ import { WorkflowOptions } from './common';
|
|
|
23
23
|
*
|
|
24
24
|
* // Spawn a child workflow and await its result
|
|
25
25
|
* export async function parentWorkflow(orderId: string): Promise<string> {
|
|
26
|
-
* const result = await Durable.workflow.
|
|
26
|
+
* const result = await Durable.workflow.executeChild<{ status: string }>({
|
|
27
27
|
* taskQueue: 'payments',
|
|
28
28
|
* workflowName: 'processPayment',
|
|
29
29
|
* args: [orderId, 99.99],
|
|
@@ -41,7 +41,7 @@ import { WorkflowOptions } from './common';
|
|
|
41
41
|
* export async function batchWorkflow(items: string[]): Promise<string[]> {
|
|
42
42
|
* const results = await Promise.all(
|
|
43
43
|
* items.map((item) =>
|
|
44
|
-
* Durable.workflow.
|
|
44
|
+
* Durable.workflow.executeChild<string>({
|
|
45
45
|
* taskQueue: 'processors',
|
|
46
46
|
* workflowName: 'processItem',
|
|
47
47
|
* args: [item],
|
|
@@ -54,7 +54,7 @@ import { WorkflowOptions } from './common';
|
|
|
54
54
|
*
|
|
55
55
|
* ```typescript
|
|
56
56
|
* // Entity-based child (uses entity name as task queue)
|
|
57
|
-
* const user = await Durable.workflow.
|
|
57
|
+
* const user = await Durable.workflow.executeChild<UserRecord>({
|
|
58
58
|
* entity: 'user',
|
|
59
59
|
* args: [{ name: 'Alice', email: 'alice@example.com' }],
|
|
60
60
|
* workflowId: 'user-alice', // deterministic ID
|
|
@@ -66,41 +66,5 @@ import { WorkflowOptions } from './common';
|
|
|
66
66
|
* @param {WorkflowOptions} options - Child workflow configuration.
|
|
67
67
|
* @returns {Promise<T>} The child workflow's return value.
|
|
68
68
|
*/
|
|
69
|
-
export declare function
|
|
70
|
-
/**
|
|
71
|
-
* Alias for {@link execChild}.
|
|
72
|
-
*/
|
|
73
|
-
export declare const executeChild: typeof execChild;
|
|
74
|
-
/**
|
|
75
|
-
* Spawns a child workflow in fire-and-forget mode. The parent workflow
|
|
76
|
-
* continues immediately without waiting for the child to complete.
|
|
77
|
-
* Returns the child's job ID for later reference (e.g., to interrupt
|
|
78
|
-
* or query the child).
|
|
79
|
-
*
|
|
80
|
-
* This is a convenience wrapper around `execChild` with `await: false`.
|
|
81
|
-
*
|
|
82
|
-
* ## Example
|
|
83
|
-
*
|
|
84
|
-
* ```typescript
|
|
85
|
-
* import { Durable } from '@hotmeshio/hotmesh';
|
|
86
|
-
*
|
|
87
|
-
* export async function dispatchWorkflow(taskId: string): Promise<string> {
|
|
88
|
-
* // Fire-and-forget: start the child and continue immediately
|
|
89
|
-
* const childJobId = await Durable.workflow.startChild({
|
|
90
|
-
* taskQueue: 'background',
|
|
91
|
-
* workflowName: 'longRunningTask',
|
|
92
|
-
* args: [taskId],
|
|
93
|
-
* });
|
|
94
|
-
*
|
|
95
|
-
* // Optionally store the child ID for monitoring
|
|
96
|
-
* const search = await Durable.workflow.search();
|
|
97
|
-
* await search.set({ childJobId });
|
|
98
|
-
*
|
|
99
|
-
* return childJobId;
|
|
100
|
-
* }
|
|
101
|
-
* ```
|
|
102
|
-
*
|
|
103
|
-
* @param {WorkflowOptions} options - Child workflow configuration.
|
|
104
|
-
* @returns {Promise<string>} The child workflow's job ID.
|
|
105
|
-
*/
|
|
69
|
+
export declare function executeChild<T>(options: WorkflowOptions): Promise<T>;
|
|
106
70
|
export declare function startChild(options: WorkflowOptions): Promise<string>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.startChild = exports.executeChild =
|
|
3
|
+
exports.startChild = exports.executeChild = void 0;
|
|
4
4
|
const common_1 = require("./common");
|
|
5
|
-
const
|
|
5
|
+
const cancellationScope_1 = require("./cancellationScope");
|
|
6
|
+
const workflowInfo_1 = require("./workflowInfo");
|
|
6
7
|
const didRun_1 = require("./didRun");
|
|
7
8
|
/**
|
|
8
9
|
* Constructs the payload necessary to spawn a child workflow.
|
|
@@ -32,6 +33,7 @@ function getChildInterruptPayload(context, options, execIndex) {
|
|
|
32
33
|
await: options?.await ?? true,
|
|
33
34
|
backoffCoefficient: options?.config?.backoffCoefficient ?? common_1.HMSH_DURABLE_EXP_BACKOFF,
|
|
34
35
|
index: execIndex,
|
|
36
|
+
initialInterval: (0, common_1.s)(options?.config?.initialInterval ?? `${common_1.HMSH_DURABLE_INITIAL_INTERVAL}s`),
|
|
35
37
|
maximumAttempts: options?.config?.maximumAttempts ?? common_1.HMSH_DURABLE_MAX_ATTEMPTS,
|
|
36
38
|
maximumInterval: (0, common_1.s)(options?.config?.maximumInterval ?? common_1.HMSH_DURABLE_MAX_INTERVAL),
|
|
37
39
|
originJobId: originJobId ?? workflowId,
|
|
@@ -71,7 +73,7 @@ function getChildInterruptPayload(context, options, execIndex) {
|
|
|
71
73
|
*
|
|
72
74
|
* // Spawn a child workflow and await its result
|
|
73
75
|
* export async function parentWorkflow(orderId: string): Promise<string> {
|
|
74
|
-
* const result = await Durable.workflow.
|
|
76
|
+
* const result = await Durable.workflow.executeChild<{ status: string }>({
|
|
75
77
|
* taskQueue: 'payments',
|
|
76
78
|
* workflowName: 'processPayment',
|
|
77
79
|
* args: [orderId, 99.99],
|
|
@@ -89,7 +91,7 @@ function getChildInterruptPayload(context, options, execIndex) {
|
|
|
89
91
|
* export async function batchWorkflow(items: string[]): Promise<string[]> {
|
|
90
92
|
* const results = await Promise.all(
|
|
91
93
|
* items.map((item) =>
|
|
92
|
-
* Durable.workflow.
|
|
94
|
+
* Durable.workflow.executeChild<string>({
|
|
93
95
|
* taskQueue: 'processors',
|
|
94
96
|
* workflowName: 'processItem',
|
|
95
97
|
* args: [item],
|
|
@@ -102,7 +104,7 @@ function getChildInterruptPayload(context, options, execIndex) {
|
|
|
102
104
|
*
|
|
103
105
|
* ```typescript
|
|
104
106
|
* // Entity-based child (uses entity name as task queue)
|
|
105
|
-
* const user = await Durable.workflow.
|
|
107
|
+
* const user = await Durable.workflow.executeChild<UserRecord>({
|
|
106
108
|
* entity: 'user',
|
|
107
109
|
* args: [{ name: 'Alice', email: 'alice@example.com' }],
|
|
108
110
|
* workflowId: 'user-alice', // deterministic ID
|
|
@@ -114,13 +116,26 @@ function getChildInterruptPayload(context, options, execIndex) {
|
|
|
114
116
|
* @param {WorkflowOptions} options - Child workflow configuration.
|
|
115
117
|
* @returns {Promise<T>} The child workflow's return value.
|
|
116
118
|
*/
|
|
117
|
-
async function
|
|
119
|
+
async function executeChild(options) {
|
|
118
120
|
const isStartChild = options.await === false;
|
|
119
121
|
const prefix = isStartChild ? 'start' : 'child';
|
|
120
122
|
const [didRunAlready, execIndex, result] = await (0, didRun_1.didRun)(prefix);
|
|
121
|
-
|
|
123
|
+
(0, cancellationScope_1.checkCancellation)();
|
|
124
|
+
const context = (0, workflowInfo_1.workflowInfo)();
|
|
122
125
|
const { canRetry, interruptionRegistry } = context;
|
|
123
126
|
if (didRunAlready) {
|
|
127
|
+
// Emit RETURN span in debug mode
|
|
128
|
+
if (common_1.DurableTelemetryService.isVerbose() && result) {
|
|
129
|
+
const { workflowTrace, workflowSpan } = context;
|
|
130
|
+
if (workflowTrace && workflowSpan && result.ac && result.au) {
|
|
131
|
+
const workflowName = options.workflowName || options.entity || 'unknown';
|
|
132
|
+
common_1.DurableTelemetryService.emitDurationSpan(workflowTrace, workflowSpan, `RETURN/${prefix}/${workflowName}/${execIndex}`, common_1.DurableTelemetryService.parseTimestamp(result.ac), common_1.DurableTelemetryService.parseTimestamp(result.au), {
|
|
133
|
+
'durable.operation.type': prefix,
|
|
134
|
+
'durable.workflow.name': workflowName,
|
|
135
|
+
'durable.exec.index': execIndex,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
124
139
|
if (result?.$error && (!result.$error.is_stream_error || !canRetry)) {
|
|
125
140
|
if (options?.config?.throwOnError !== false) {
|
|
126
141
|
const code = result.$error.code;
|
|
@@ -145,6 +160,18 @@ async function execChild(options) {
|
|
|
145
160
|
return result.data;
|
|
146
161
|
}
|
|
147
162
|
}
|
|
163
|
+
// Emit DISPATCH span in debug mode
|
|
164
|
+
if (common_1.DurableTelemetryService.isVerbose()) {
|
|
165
|
+
const { workflowTrace, workflowSpan } = context;
|
|
166
|
+
if (workflowTrace && workflowSpan) {
|
|
167
|
+
const workflowName = options.workflowName || options.entity || 'unknown';
|
|
168
|
+
common_1.DurableTelemetryService.emitPointSpan(workflowTrace, workflowSpan, `DISPATCH/${prefix}/${workflowName}/${execIndex}`, {
|
|
169
|
+
'durable.operation.type': prefix,
|
|
170
|
+
'durable.workflow.name': workflowName,
|
|
171
|
+
'durable.exec.index': execIndex,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
148
175
|
const interruptionMessage = getChildInterruptPayload(context, options, execIndex);
|
|
149
176
|
interruptionRegistry.push({
|
|
150
177
|
code: common_1.HMSH_CODE_DURABLE_CHILD,
|
|
@@ -154,44 +181,8 @@ async function execChild(options) {
|
|
|
154
181
|
await (0, common_1.sleepImmediate)();
|
|
155
182
|
throw new common_1.DurableChildError(interruptionMessage);
|
|
156
183
|
}
|
|
157
|
-
exports.
|
|
158
|
-
/**
|
|
159
|
-
* Alias for {@link execChild}.
|
|
160
|
-
*/
|
|
161
|
-
exports.executeChild = execChild;
|
|
162
|
-
/**
|
|
163
|
-
* Spawns a child workflow in fire-and-forget mode. The parent workflow
|
|
164
|
-
* continues immediately without waiting for the child to complete.
|
|
165
|
-
* Returns the child's job ID for later reference (e.g., to interrupt
|
|
166
|
-
* or query the child).
|
|
167
|
-
*
|
|
168
|
-
* This is a convenience wrapper around `execChild` with `await: false`.
|
|
169
|
-
*
|
|
170
|
-
* ## Example
|
|
171
|
-
*
|
|
172
|
-
* ```typescript
|
|
173
|
-
* import { Durable } from '@hotmeshio/hotmesh';
|
|
174
|
-
*
|
|
175
|
-
* export async function dispatchWorkflow(taskId: string): Promise<string> {
|
|
176
|
-
* // Fire-and-forget: start the child and continue immediately
|
|
177
|
-
* const childJobId = await Durable.workflow.startChild({
|
|
178
|
-
* taskQueue: 'background',
|
|
179
|
-
* workflowName: 'longRunningTask',
|
|
180
|
-
* args: [taskId],
|
|
181
|
-
* });
|
|
182
|
-
*
|
|
183
|
-
* // Optionally store the child ID for monitoring
|
|
184
|
-
* const search = await Durable.workflow.search();
|
|
185
|
-
* await search.set({ childJobId });
|
|
186
|
-
*
|
|
187
|
-
* return childJobId;
|
|
188
|
-
* }
|
|
189
|
-
* ```
|
|
190
|
-
*
|
|
191
|
-
* @param {WorkflowOptions} options - Child workflow configuration.
|
|
192
|
-
* @returns {Promise<string>} The child workflow's job ID.
|
|
193
|
-
*/
|
|
184
|
+
exports.executeChild = executeChild;
|
|
194
185
|
async function startChild(options) {
|
|
195
|
-
return
|
|
186
|
+
return executeChild({ ...options, await: false });
|
|
196
187
|
}
|
|
197
188
|
exports.startChild = startChild;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.hook = void 0;
|
|
4
4
|
const common_1 = require("./common");
|
|
5
|
-
const
|
|
5
|
+
const workflowInfo_1 = require("./workflowInfo");
|
|
6
6
|
const isSideEffectAllowed_1 = require("./isSideEffectAllowed");
|
|
7
7
|
/**
|
|
8
8
|
* Spawns a hook execution against an existing workflow job. The hook runs
|
|
@@ -55,7 +55,7 @@ const isSideEffectAllowed_1 = require("./isSideEffectAllowed");
|
|
|
55
55
|
* });
|
|
56
56
|
*
|
|
57
57
|
* // Manually wait for the hook to signal back
|
|
58
|
-
* return await Durable.workflow.
|
|
58
|
+
* return await Durable.workflow.condition<string>(signalId);
|
|
59
59
|
* }
|
|
60
60
|
* ```
|
|
61
61
|
*
|
|
@@ -77,7 +77,7 @@ const isSideEffectAllowed_1 = require("./isSideEffectAllowed");
|
|
|
77
77
|
* @returns {Promise<string>} The resulting hook/stream ID.
|
|
78
78
|
*/
|
|
79
79
|
async function hook(options) {
|
|
80
|
-
const { workflowId, connection, namespace, workflowTopic } = (0,
|
|
80
|
+
const { workflowId, connection, namespace, workflowTopic } = (0, workflowInfo_1.workflowInfo)();
|
|
81
81
|
const hotMeshClient = await common_1.WorkerService.getHotMesh(workflowTopic, {
|
|
82
82
|
connection,
|
|
83
83
|
namespace,
|
|
@@ -120,6 +120,7 @@ async function hook(options) {
|
|
|
120
120
|
taskQueue: hookTaskQueue,
|
|
121
121
|
workflowName: hookWorkflowName,
|
|
122
122
|
backoffCoefficient: options.config?.backoffCoefficient || common_1.HMSH_DURABLE_EXP_BACKOFF,
|
|
123
|
+
initialInterval: (0, common_1.s)(options?.config?.initialInterval ?? `${common_1.HMSH_DURABLE_INITIAL_INTERVAL}s`),
|
|
123
124
|
maximumAttempts: options.config?.maximumAttempts || common_1.HMSH_DURABLE_MAX_ATTEMPTS,
|
|
124
125
|
maximumInterval: (0, common_1.s)(options?.config?.maximumInterval ?? common_1.HMSH_DURABLE_MAX_INTERVAL),
|
|
125
126
|
};
|
|
@@ -1,63 +1,58 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { workflowInfo } from './workflowInfo';
|
|
2
2
|
import { didRun } from './didRun';
|
|
3
3
|
import { isSideEffectAllowed } from './isSideEffectAllowed';
|
|
4
4
|
import { trace } from './trace';
|
|
5
5
|
import { enrich } from './enrich';
|
|
6
6
|
import { emit } from './emit';
|
|
7
|
-
import {
|
|
7
|
+
import { executeChild, startChild } from './executeChild';
|
|
8
8
|
import { execHook } from './execHook';
|
|
9
9
|
import { execHookBatch } from './execHookBatch';
|
|
10
10
|
import { proxyActivities } from './proxyActivities';
|
|
11
11
|
import { search } from './searchMethods';
|
|
12
12
|
import { random } from './random';
|
|
13
|
+
import { uuid4 } from './uuid4';
|
|
13
14
|
import { signal } from './signal';
|
|
14
15
|
import { hook } from './hook';
|
|
15
|
-
import {
|
|
16
|
+
import { terminate } from './terminate';
|
|
16
17
|
import { didInterrupt } from './interruption';
|
|
17
18
|
import { all } from './all';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
19
|
+
import { sleep } from './sleep';
|
|
20
|
+
import { condition } from './condition';
|
|
21
|
+
import { continueAsNew } from './continueAsNew';
|
|
22
|
+
import { patched, deprecatePatch } from './patched';
|
|
23
|
+
import { CancellationScope, CancelledFailure, isCancellation } from './cancellationScope';
|
|
20
24
|
import { HotMesh } from './common';
|
|
21
25
|
import { entity } from './entityMethods';
|
|
22
26
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
+
* In-workflow API surface, exposed as `Durable.workflow`. Every method
|
|
28
|
+
* is called **inside** a workflow function and participates in
|
|
29
|
+
* deterministic replay — results are persisted and returned instantly
|
|
30
|
+
* on recovery without re-executing side effects.
|
|
27
31
|
*
|
|
28
|
-
* ##
|
|
32
|
+
* ## Primitives
|
|
29
33
|
*
|
|
30
34
|
* | Method | Purpose |
|
|
31
35
|
* |--------|---------|
|
|
32
|
-
* | {@link proxyActivities} |
|
|
33
|
-
* | {@link
|
|
34
|
-
* | {@link
|
|
35
|
-
* | {@link signal} |
|
|
36
|
-
* | {@link
|
|
37
|
-
* | {@link startChild} |
|
|
38
|
-
* | {@link
|
|
39
|
-
* | {@link
|
|
40
|
-
* | {@link
|
|
41
|
-
* | {@link
|
|
42
|
-
*
|
|
43
|
-
* ## Data & Observability
|
|
44
|
-
*
|
|
45
|
-
* | Method | Purpose |
|
|
46
|
-
* |--------|---------|
|
|
47
|
-
* | {@link search} | Read/write flat HASH key-value data |
|
|
48
|
-
* | {@link enrich} | One-shot HASH enrichment |
|
|
49
|
-
* | {@link entity} | Structured JSONB document storage |
|
|
50
|
-
* | {@link emit} | Publish events to the event bus |
|
|
51
|
-
* | {@link trace} | Emit OpenTelemetry trace spans |
|
|
36
|
+
* | {@link proxyActivities} | Execute activities with automatic retry |
|
|
37
|
+
* | {@link sleep} | Durable timer (survives restarts) |
|
|
38
|
+
* | {@link condition} | Pause until a named signal arrives (optional timeout) |
|
|
39
|
+
* | {@link signal} | Deliver data to a waiting `condition` |
|
|
40
|
+
* | {@link executeChild} | Spawn a child workflow and await its result |
|
|
41
|
+
* | {@link startChild} | Fire-and-forget child workflow |
|
|
42
|
+
* | {@link continueAsNew} | Restart with new args (resets history) |
|
|
43
|
+
* | {@link patched} / {@link deprecatePatch} | Safe versioning for in-flight code changes |
|
|
44
|
+
* | {@link CancellationScope} | Shield cleanup code from cancellation |
|
|
45
|
+
* | {@link isCancellation} | Detect `CancelledFailure` errors |
|
|
52
46
|
*
|
|
53
47
|
* ## Utilities
|
|
54
48
|
*
|
|
55
49
|
* | Method | Purpose |
|
|
56
50
|
* |--------|---------|
|
|
57
|
-
* | {@link
|
|
51
|
+
* | {@link workflowInfo} | Access workflow ID, namespace, replay state |
|
|
58
52
|
* | {@link random} | Deterministic pseudo-random numbers |
|
|
53
|
+
* | {@link uuid4} | Deterministic UUID v4 generation |
|
|
59
54
|
* | {@link all} | Workflow-safe `Promise.all` |
|
|
60
|
-
* | {@link didInterrupt} |
|
|
55
|
+
* | {@link didInterrupt} | Detect engine control-flow errors |
|
|
61
56
|
*
|
|
62
57
|
* ## Example
|
|
63
58
|
*
|
|
@@ -66,26 +61,20 @@ import { entity } from './entityMethods';
|
|
|
66
61
|
* import * as activities from './activities';
|
|
67
62
|
*
|
|
68
63
|
* export async function orderWorkflow(orderId: string): Promise<string> {
|
|
69
|
-
* // Proxy activities for durable execution
|
|
70
64
|
* const { validateOrder, processPayment, sendReceipt } =
|
|
71
65
|
* Durable.workflow.proxyActivities<typeof activities>({
|
|
72
66
|
* activities,
|
|
73
|
-
*
|
|
67
|
+
* retry: { maximumAttempts: 3 },
|
|
74
68
|
* });
|
|
75
69
|
*
|
|
76
70
|
* await validateOrder(orderId);
|
|
77
|
-
*
|
|
78
|
-
* // Durable sleep (survives restarts)
|
|
79
|
-
* await Durable.workflow.sleepFor('5 seconds');
|
|
80
|
-
*
|
|
71
|
+
* await Durable.workflow.sleep('5 seconds');
|
|
81
72
|
* const receipt = await processPayment(orderId);
|
|
82
73
|
*
|
|
83
|
-
* //
|
|
84
|
-
* await Durable.workflow.
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* const approval = await Durable.workflow.waitFor<{ ok: boolean }>('approve');
|
|
88
|
-
* if (!approval.ok) return 'cancelled';
|
|
74
|
+
* // Wait for external approval signal (with 1-hour timeout)
|
|
75
|
+
* const approval = await Durable.workflow.condition<{ ok: boolean }>('approve', '1 hour');
|
|
76
|
+
* if (!approval) return 'timed-out';
|
|
77
|
+
* if (!approval.ok) return 'rejected';
|
|
89
78
|
*
|
|
90
79
|
* await sendReceipt(orderId, receipt);
|
|
91
80
|
* return receipt;
|
|
@@ -99,14 +88,13 @@ export declare class WorkflowService {
|
|
|
99
88
|
* all methods are static.
|
|
100
89
|
*/
|
|
101
90
|
private constructor();
|
|
102
|
-
static
|
|
91
|
+
static workflowInfo: typeof workflowInfo;
|
|
103
92
|
static didRun: typeof didRun;
|
|
104
93
|
static isSideEffectAllowed: typeof isSideEffectAllowed;
|
|
105
94
|
static trace: typeof trace;
|
|
106
95
|
static enrich: typeof enrich;
|
|
107
96
|
static emit: typeof emit;
|
|
108
|
-
static
|
|
109
|
-
static executeChild: typeof execChild;
|
|
97
|
+
static executeChild: typeof executeChild;
|
|
110
98
|
static startChild: typeof startChild;
|
|
111
99
|
static execHook: typeof execHook;
|
|
112
100
|
static execHookBatch: typeof execHookBatch;
|
|
@@ -114,13 +102,20 @@ export declare class WorkflowService {
|
|
|
114
102
|
static search: typeof search;
|
|
115
103
|
static entity: typeof entity;
|
|
116
104
|
static random: typeof random;
|
|
105
|
+
static uuid4: typeof uuid4;
|
|
117
106
|
static signal: typeof signal;
|
|
118
107
|
static hook: typeof hook;
|
|
119
108
|
static didInterrupt: typeof didInterrupt;
|
|
120
|
-
static
|
|
109
|
+
static terminate: typeof terminate;
|
|
121
110
|
static all: typeof all;
|
|
122
|
-
static
|
|
123
|
-
static
|
|
111
|
+
static sleep: typeof sleep;
|
|
112
|
+
static condition: typeof condition;
|
|
113
|
+
static continueAsNew: typeof continueAsNew;
|
|
114
|
+
static patched: typeof patched;
|
|
115
|
+
static deprecatePatch: typeof deprecatePatch;
|
|
116
|
+
static CancellationScope: typeof CancellationScope;
|
|
117
|
+
static CancelledFailure: typeof CancelledFailure;
|
|
118
|
+
static isCancellation: typeof isCancellation;
|
|
124
119
|
/**
|
|
125
120
|
* Return a handle to the HotMesh client hosting the workflow execution.
|
|
126
121
|
* @returns {Promise<HotMesh>} The HotMesh client instance.
|