@temporal-contract/client 0.0.4 → 0.0.6
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/dist/index.cjs +81 -113
- package/dist/index.d.cts +113 -33
- package/dist/index.d.mts +113 -33
- package/dist/index.mjs +82 -89
- package/package.json +23 -19
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
let
|
|
2
|
-
let __swan_io_boxed = require("@swan-io/boxed");
|
|
1
|
+
let _temporal_contract_boxed = require("@temporal-contract/boxed");
|
|
3
2
|
|
|
4
3
|
//#region src/errors.ts
|
|
5
4
|
/**
|
|
@@ -13,6 +12,16 @@ var TypedClientError = class extends Error {
|
|
|
13
12
|
}
|
|
14
13
|
};
|
|
15
14
|
/**
|
|
15
|
+
* Generic runtime failure wrapper when no specific error type applies
|
|
16
|
+
*/
|
|
17
|
+
var RuntimeClientError = class extends TypedClientError {
|
|
18
|
+
constructor(operation, cause) {
|
|
19
|
+
super(`Operation "${operation}" failed: ${cause instanceof Error ? cause.message : String(cause ?? "unknown error")}`);
|
|
20
|
+
this.operation = operation;
|
|
21
|
+
this.cause = cause;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
16
25
|
* Thrown when a workflow is not found in the contract
|
|
17
26
|
*/
|
|
18
27
|
var WorkflowNotFoundError = class extends TypedClientError {
|
|
@@ -93,7 +102,7 @@ var TypedClient = class TypedClient {
|
|
|
93
102
|
* const result = await client.executeWorkflow('processOrder', {
|
|
94
103
|
* workflowId: 'order-123',
|
|
95
104
|
* args: { ... },
|
|
96
|
-
* })
|
|
105
|
+
* });
|
|
97
106
|
*
|
|
98
107
|
* result.match({
|
|
99
108
|
* Ok: (output) => console.log('Success:', output),
|
|
@@ -101,8 +110,8 @@ var TypedClient = class TypedClient {
|
|
|
101
110
|
* });
|
|
102
111
|
* ```
|
|
103
112
|
*/
|
|
104
|
-
static create(contract,
|
|
105
|
-
return new TypedClient(contract,
|
|
113
|
+
static create(contract, client) {
|
|
114
|
+
return new TypedClient(contract, client);
|
|
106
115
|
}
|
|
107
116
|
/**
|
|
108
117
|
* Start a workflow and return a typed handle with Future pattern
|
|
@@ -114,11 +123,11 @@ var TypedClient = class TypedClient {
|
|
|
114
123
|
* args: { orderId: 'ORD-123' },
|
|
115
124
|
* workflowExecutionTimeout: '1 day',
|
|
116
125
|
* retry: { maximumAttempts: 3 },
|
|
117
|
-
* })
|
|
126
|
+
* });
|
|
118
127
|
*
|
|
119
128
|
* handleResult.match({
|
|
120
129
|
* Ok: async (handle) => {
|
|
121
|
-
* const result = await handle.result()
|
|
130
|
+
* const result = await handle.result();
|
|
122
131
|
* // ... handle result
|
|
123
132
|
* },
|
|
124
133
|
* Error: (error) => console.error('Failed to start:', error),
|
|
@@ -126,16 +135,16 @@ var TypedClient = class TypedClient {
|
|
|
126
135
|
* ```
|
|
127
136
|
*/
|
|
128
137
|
startWorkflow(workflowName, { args, ...temporalOptions }) {
|
|
129
|
-
return
|
|
130
|
-
const definition = this.contract.workflows[workflowName];
|
|
131
|
-
if (!definition) {
|
|
132
|
-
resolve(__swan_io_boxed.Result.Error(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows))));
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
138
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
135
139
|
(async () => {
|
|
140
|
+
const definition = this.contract.workflows[workflowName];
|
|
141
|
+
if (!definition) {
|
|
142
|
+
resolve(_temporal_contract_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract)));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
136
145
|
const inputResult = await definition.input["~standard"].validate(args);
|
|
137
146
|
if (inputResult.issues) {
|
|
138
|
-
resolve(
|
|
147
|
+
resolve(_temporal_contract_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues)));
|
|
139
148
|
return;
|
|
140
149
|
}
|
|
141
150
|
const validatedInput = inputResult.value;
|
|
@@ -146,9 +155,9 @@ var TypedClient = class TypedClient {
|
|
|
146
155
|
args: [validatedInput]
|
|
147
156
|
});
|
|
148
157
|
const typedHandle = this.createTypedHandle(handle, definition);
|
|
149
|
-
resolve(
|
|
158
|
+
resolve(_temporal_contract_boxed.Result.Ok(typedHandle));
|
|
150
159
|
} catch (error) {
|
|
151
|
-
resolve(
|
|
160
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("startWorkflow", error)));
|
|
152
161
|
}
|
|
153
162
|
})();
|
|
154
163
|
});
|
|
@@ -163,7 +172,7 @@ var TypedClient = class TypedClient {
|
|
|
163
172
|
* args: { orderId: 'ORD-123' },
|
|
164
173
|
* workflowExecutionTimeout: '1 day',
|
|
165
174
|
* retry: { maximumAttempts: 3 },
|
|
166
|
-
* })
|
|
175
|
+
* });
|
|
167
176
|
*
|
|
168
177
|
* result.match({
|
|
169
178
|
* Ok: (output) => console.log('Order processed:', output.status),
|
|
@@ -172,16 +181,16 @@ var TypedClient = class TypedClient {
|
|
|
172
181
|
* ```
|
|
173
182
|
*/
|
|
174
183
|
executeWorkflow(workflowName, { args, ...temporalOptions }) {
|
|
175
|
-
return
|
|
176
|
-
const definition = this.contract.workflows[workflowName];
|
|
177
|
-
if (!definition) {
|
|
178
|
-
resolve(__swan_io_boxed.Result.Error(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows))));
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
184
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
181
185
|
(async () => {
|
|
186
|
+
const definition = this.contract.workflows[workflowName];
|
|
187
|
+
if (!definition) {
|
|
188
|
+
resolve(_temporal_contract_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract)));
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
182
191
|
const inputResult = await definition.input["~standard"].validate(args);
|
|
183
192
|
if (inputResult.issues) {
|
|
184
|
-
resolve(
|
|
193
|
+
resolve(_temporal_contract_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues)));
|
|
185
194
|
return;
|
|
186
195
|
}
|
|
187
196
|
const validatedInput = inputResult.value;
|
|
@@ -193,12 +202,12 @@ var TypedClient = class TypedClient {
|
|
|
193
202
|
});
|
|
194
203
|
const outputResult = await definition.output["~standard"].validate(result);
|
|
195
204
|
if (outputResult.issues) {
|
|
196
|
-
resolve(
|
|
205
|
+
resolve(_temporal_contract_boxed.Result.Error(createWorkflowValidationError(workflowName, "output", outputResult.issues)));
|
|
197
206
|
return;
|
|
198
207
|
}
|
|
199
|
-
resolve(
|
|
208
|
+
resolve(_temporal_contract_boxed.Result.Ok(outputResult.value));
|
|
200
209
|
} catch (error) {
|
|
201
|
-
resolve(
|
|
210
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("executeWorkflow", error)));
|
|
202
211
|
}
|
|
203
212
|
})();
|
|
204
213
|
});
|
|
@@ -208,10 +217,10 @@ var TypedClient = class TypedClient {
|
|
|
208
217
|
*
|
|
209
218
|
* @example
|
|
210
219
|
* ```ts
|
|
211
|
-
* const handleResult = await client.getHandle('processOrder', 'order-123')
|
|
220
|
+
* const handleResult = await client.getHandle('processOrder', 'order-123');
|
|
212
221
|
* handleResult.match({
|
|
213
222
|
* Ok: async (handle) => {
|
|
214
|
-
* const result = await handle.result()
|
|
223
|
+
* const result = await handle.result();
|
|
215
224
|
* // ... handle result
|
|
216
225
|
* },
|
|
217
226
|
* Error: (error) => console.error('Failed to get handle:', error),
|
|
@@ -219,178 +228,137 @@ var TypedClient = class TypedClient {
|
|
|
219
228
|
* ```
|
|
220
229
|
*/
|
|
221
230
|
getHandle(workflowName, workflowId) {
|
|
222
|
-
return
|
|
231
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
223
232
|
const definition = this.contract.workflows[workflowName];
|
|
224
233
|
if (!definition) {
|
|
225
|
-
resolve(
|
|
234
|
+
resolve(_temporal_contract_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract)));
|
|
226
235
|
return;
|
|
227
236
|
}
|
|
228
237
|
try {
|
|
229
238
|
const handle = this.client.workflow.getHandle(workflowId);
|
|
230
239
|
const typedHandle = this.createTypedHandle(handle, definition);
|
|
231
|
-
resolve(
|
|
240
|
+
resolve(_temporal_contract_boxed.Result.Ok(typedHandle));
|
|
232
241
|
} catch (error) {
|
|
233
|
-
resolve(
|
|
242
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("getHandle", error)));
|
|
234
243
|
}
|
|
235
244
|
});
|
|
236
245
|
}
|
|
237
|
-
createTypedHandle(
|
|
246
|
+
createTypedHandle(workflowHandle, definition) {
|
|
238
247
|
const queries = {};
|
|
239
248
|
for (const [queryName, queryDef] of Object.entries(definition.queries ?? {})) queries[queryName] = (args) => {
|
|
240
|
-
return
|
|
249
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
241
250
|
(async () => {
|
|
242
251
|
const inputResult = await queryDef.input["~standard"].validate(args);
|
|
243
252
|
if (inputResult.issues) {
|
|
244
|
-
resolve(
|
|
253
|
+
resolve(_temporal_contract_boxed.Result.Error(new QueryValidationError(queryName, "input", inputResult.issues)));
|
|
245
254
|
return;
|
|
246
255
|
}
|
|
247
256
|
try {
|
|
248
|
-
const result = await
|
|
257
|
+
const result = await workflowHandle.query(queryName, inputResult.value);
|
|
249
258
|
const outputResult = await queryDef.output["~standard"].validate(result);
|
|
250
259
|
if (outputResult.issues) {
|
|
251
|
-
resolve(
|
|
260
|
+
resolve(_temporal_contract_boxed.Result.Error(new QueryValidationError(queryName, "output", outputResult.issues)));
|
|
252
261
|
return;
|
|
253
262
|
}
|
|
254
|
-
resolve(
|
|
263
|
+
resolve(_temporal_contract_boxed.Result.Ok(outputResult.value));
|
|
255
264
|
} catch (error) {
|
|
256
|
-
resolve(
|
|
265
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("query", error)));
|
|
257
266
|
}
|
|
258
267
|
})();
|
|
259
268
|
});
|
|
260
269
|
};
|
|
261
270
|
const signals = {};
|
|
262
271
|
for (const [signalName, signalDef] of Object.entries(definition.signals ?? {})) signals[signalName] = (args) => {
|
|
263
|
-
return
|
|
272
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
264
273
|
(async () => {
|
|
265
274
|
const inputResult = await signalDef.input["~standard"].validate(args);
|
|
266
275
|
if (inputResult.issues) {
|
|
267
|
-
resolve(
|
|
276
|
+
resolve(_temporal_contract_boxed.Result.Error(new SignalValidationError(signalName, inputResult.issues)));
|
|
268
277
|
return;
|
|
269
278
|
}
|
|
270
279
|
try {
|
|
271
|
-
await
|
|
272
|
-
resolve(
|
|
280
|
+
await workflowHandle.signal(signalName, inputResult.value);
|
|
281
|
+
resolve(_temporal_contract_boxed.Result.Ok(void 0));
|
|
273
282
|
} catch (error) {
|
|
274
|
-
resolve(
|
|
283
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("signal", error)));
|
|
275
284
|
}
|
|
276
285
|
})();
|
|
277
286
|
});
|
|
278
287
|
};
|
|
279
288
|
const updates = {};
|
|
280
289
|
for (const [updateName, updateDef] of Object.entries(definition.updates ?? {})) updates[updateName] = (args) => {
|
|
281
|
-
return
|
|
290
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
282
291
|
(async () => {
|
|
283
292
|
const inputResult = await updateDef.input["~standard"].validate(args);
|
|
284
293
|
if (inputResult.issues) {
|
|
285
|
-
resolve(
|
|
294
|
+
resolve(_temporal_contract_boxed.Result.Error(new UpdateValidationError(updateName, "input", inputResult.issues)));
|
|
286
295
|
return;
|
|
287
296
|
}
|
|
288
297
|
try {
|
|
289
|
-
const result = await
|
|
298
|
+
const result = await workflowHandle.executeUpdate(updateName, { args: [inputResult.value] });
|
|
290
299
|
const outputResult = await updateDef.output["~standard"].validate(result);
|
|
291
300
|
if (outputResult.issues) {
|
|
292
|
-
resolve(
|
|
301
|
+
resolve(_temporal_contract_boxed.Result.Error(new UpdateValidationError(updateName, "output", outputResult.issues)));
|
|
293
302
|
return;
|
|
294
303
|
}
|
|
295
|
-
resolve(
|
|
304
|
+
resolve(_temporal_contract_boxed.Result.Ok(outputResult.value));
|
|
296
305
|
} catch (error) {
|
|
297
|
-
resolve(
|
|
306
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("update", error)));
|
|
298
307
|
}
|
|
299
308
|
})();
|
|
300
309
|
});
|
|
301
310
|
};
|
|
302
311
|
return {
|
|
303
|
-
workflowId:
|
|
312
|
+
workflowId: workflowHandle.workflowId,
|
|
304
313
|
queries,
|
|
305
314
|
signals,
|
|
306
315
|
updates,
|
|
307
316
|
result: () => {
|
|
308
|
-
return
|
|
317
|
+
return _temporal_contract_boxed.Future.make((resolve) => {
|
|
309
318
|
(async () => {
|
|
310
319
|
try {
|
|
311
|
-
const result = await
|
|
320
|
+
const result = await workflowHandle.result();
|
|
312
321
|
const outputResult = await definition.output["~standard"].validate(result);
|
|
313
322
|
if (outputResult.issues) {
|
|
314
|
-
resolve(
|
|
323
|
+
resolve(_temporal_contract_boxed.Result.Error(new WorkflowValidationError(workflowHandle.workflowId, "output", outputResult.issues)));
|
|
315
324
|
return;
|
|
316
325
|
}
|
|
317
|
-
resolve(
|
|
326
|
+
resolve(_temporal_contract_boxed.Result.Ok(outputResult.value));
|
|
318
327
|
} catch (error) {
|
|
319
|
-
resolve(
|
|
328
|
+
resolve(_temporal_contract_boxed.Result.Error(createRuntimeClientError("result", error)));
|
|
320
329
|
}
|
|
321
330
|
})();
|
|
322
331
|
});
|
|
323
332
|
},
|
|
324
333
|
terminate: (reason) => {
|
|
325
|
-
return
|
|
326
|
-
(async () => {
|
|
327
|
-
try {
|
|
328
|
-
await handle.terminate(reason);
|
|
329
|
-
resolve(__swan_io_boxed.Result.Ok(void 0));
|
|
330
|
-
} catch (error) {
|
|
331
|
-
resolve(__swan_io_boxed.Result.Error(new TypedClientError(`Terminate failed: ${error instanceof Error ? error.message : String(error)}`)));
|
|
332
|
-
}
|
|
333
|
-
})();
|
|
334
|
-
});
|
|
334
|
+
return _temporal_contract_boxed.Future.fromPromise(workflowHandle.terminate(reason)).mapError((error) => createRuntimeClientError("terminate", error)).mapOk(() => void 0);
|
|
335
335
|
},
|
|
336
336
|
cancel: () => {
|
|
337
|
-
return
|
|
338
|
-
(async () => {
|
|
339
|
-
try {
|
|
340
|
-
await handle.cancel();
|
|
341
|
-
resolve(__swan_io_boxed.Result.Ok(void 0));
|
|
342
|
-
} catch (error) {
|
|
343
|
-
resolve(__swan_io_boxed.Result.Error(new TypedClientError(`Cancel failed: ${error instanceof Error ? error.message : String(error)}`)));
|
|
344
|
-
}
|
|
345
|
-
})();
|
|
346
|
-
});
|
|
337
|
+
return _temporal_contract_boxed.Future.fromPromise(workflowHandle.cancel()).mapError((error) => createRuntimeClientError("cancel", error)).mapOk(() => void 0);
|
|
347
338
|
},
|
|
348
339
|
describe: () => {
|
|
349
|
-
return
|
|
350
|
-
(async () => {
|
|
351
|
-
try {
|
|
352
|
-
const description = await handle.describe();
|
|
353
|
-
resolve(__swan_io_boxed.Result.Ok(description));
|
|
354
|
-
} catch (error) {
|
|
355
|
-
resolve(__swan_io_boxed.Result.Error(new TypedClientError(`Describe failed: ${error instanceof Error ? error.message : String(error)}`)));
|
|
356
|
-
}
|
|
357
|
-
})();
|
|
358
|
-
});
|
|
340
|
+
return _temporal_contract_boxed.Future.fromPromise(workflowHandle.describe()).mapError((error) => createRuntimeClientError("describe", error));
|
|
359
341
|
},
|
|
360
|
-
fetchHistory: () =>
|
|
342
|
+
fetchHistory: () => {
|
|
343
|
+
return _temporal_contract_boxed.Future.fromPromise(workflowHandle.fetchHistory()).mapError((error) => createRuntimeClientError("fetchHistory", error));
|
|
344
|
+
}
|
|
361
345
|
};
|
|
362
346
|
}
|
|
363
347
|
};
|
|
348
|
+
function createRuntimeClientError(operation, error) {
|
|
349
|
+
return new RuntimeClientError(operation, error);
|
|
350
|
+
}
|
|
351
|
+
function createWorkflowNotFoundError(workflowName, contract) {
|
|
352
|
+
return new WorkflowNotFoundError(String(workflowName), Object.keys(contract.workflows));
|
|
353
|
+
}
|
|
354
|
+
function createWorkflowValidationError(workflowName, direction, issues) {
|
|
355
|
+
return new WorkflowValidationError(String(workflowName), direction, issues);
|
|
356
|
+
}
|
|
364
357
|
|
|
365
358
|
//#endregion
|
|
366
|
-
Object.defineProperty(exports, 'AsyncData', {
|
|
367
|
-
enumerable: true,
|
|
368
|
-
get: function () {
|
|
369
|
-
return __swan_io_boxed.AsyncData;
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
Object.defineProperty(exports, 'Future', {
|
|
373
|
-
enumerable: true,
|
|
374
|
-
get: function () {
|
|
375
|
-
return __swan_io_boxed.Future;
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
Object.defineProperty(exports, 'Option', {
|
|
379
|
-
enumerable: true,
|
|
380
|
-
get: function () {
|
|
381
|
-
return __swan_io_boxed.Option;
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
359
|
exports.QueryValidationError = QueryValidationError;
|
|
385
|
-
Object.defineProperty(exports, 'Result', {
|
|
386
|
-
enumerable: true,
|
|
387
|
-
get: function () {
|
|
388
|
-
return __swan_io_boxed.Result;
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
360
|
exports.SignalValidationError = SignalValidationError;
|
|
392
361
|
exports.TypedClient = TypedClient;
|
|
393
|
-
exports.TypedClientError = TypedClientError;
|
|
394
362
|
exports.UpdateValidationError = UpdateValidationError;
|
|
395
363
|
exports.WorkflowNotFoundError = WorkflowNotFoundError;
|
|
396
364
|
exports.WorkflowValidationError = WorkflowValidationError;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,100 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { AsyncData, Future, Future as Future$1, Option, Result, Result as Result$1 } from "@swan-io/boxed";
|
|
1
|
+
import { Client, WorkflowHandle, WorkflowStartOptions } from "@temporalio/client";
|
|
2
|
+
import { ActivityDefinition, AnySchema, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkflowDefinition } from "@temporal-contract/contract";
|
|
4
3
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
import { Future, Result } from "@temporal-contract/boxed";
|
|
5
5
|
|
|
6
|
+
//#region src/types.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Infer input type from a definition (client perspective)
|
|
10
|
+
* Client sends the input type (before input schema parsing/transformation)
|
|
11
|
+
*/
|
|
12
|
+
type ClientInferInput<T extends {
|
|
13
|
+
input: AnySchema;
|
|
14
|
+
}> = StandardSchemaV1.InferInput<T["input"]>;
|
|
15
|
+
/**
|
|
16
|
+
* Infer output type from a definition (client perspective)
|
|
17
|
+
* Client receives the output type (after output schema parsing/transformation)
|
|
18
|
+
*/
|
|
19
|
+
type ClientInferOutput<T extends {
|
|
20
|
+
output: AnySchema;
|
|
21
|
+
}> = StandardSchemaV1.InferOutput<T["output"]>;
|
|
22
|
+
/**
|
|
23
|
+
* CLIENT PERSPECTIVE
|
|
24
|
+
* Client sends z.output and receives z.input
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Infer workflow function signature from client perspective
|
|
28
|
+
* Client sends z.output and receives z.input
|
|
29
|
+
*/
|
|
30
|
+
type ClientInferWorkflow<TWorkflow extends WorkflowDefinition> = (args: ClientInferInput<TWorkflow>) => Promise<ClientInferOutput<TWorkflow>>;
|
|
31
|
+
/**
|
|
32
|
+
* Infer activity function signature from client perspective
|
|
33
|
+
* Client sends z.output and receives z.input
|
|
34
|
+
*/
|
|
35
|
+
type ClientInferActivity<TActivity extends ActivityDefinition> = (args: ClientInferInput<TActivity>) => Promise<ClientInferOutput<TActivity>>;
|
|
36
|
+
/**
|
|
37
|
+
* Infer signal handler signature from client perspective
|
|
38
|
+
* Client sends z.output and returns Future<Result<void, Error>>
|
|
39
|
+
*/
|
|
40
|
+
type ClientInferSignal<TSignal extends SignalDefinition> = (args: ClientInferInput<TSignal>) => Future<Result<void, Error>>;
|
|
41
|
+
/**
|
|
42
|
+
* Infer query handler signature from client perspective
|
|
43
|
+
* Client sends z.output and receives z.input wrapped in Future<Result<T, Error>>
|
|
44
|
+
*/
|
|
45
|
+
type ClientInferQuery<TQuery extends QueryDefinition> = (args: ClientInferInput<TQuery>) => Future<Result<ClientInferOutput<TQuery>, Error>>;
|
|
46
|
+
/**
|
|
47
|
+
* Infer update handler signature from client perspective
|
|
48
|
+
* Client sends z.output and receives z.input wrapped in Future<Result<T, Error>>
|
|
49
|
+
*/
|
|
50
|
+
type ClientInferUpdate<TUpdate extends UpdateDefinition> = (args: ClientInferInput<TUpdate>) => Future<Result<ClientInferOutput<TUpdate>, Error>>;
|
|
51
|
+
/**
|
|
52
|
+
* CLIENT PERSPECTIVE - Contract-level types
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* Infer all workflows from a contract (client perspective)
|
|
56
|
+
*/
|
|
57
|
+
type ClientInferWorkflows<TContract extends ContractDefinition> = { [K in keyof TContract["workflows"]]: ClientInferWorkflow<TContract["workflows"][K]> };
|
|
58
|
+
/**
|
|
59
|
+
* Infer all activities from a contract (client perspective)
|
|
60
|
+
*/
|
|
61
|
+
type ClientInferActivities<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof TContract["activities"]]: ClientInferActivity<TContract["activities"][K]> } : {};
|
|
62
|
+
/**
|
|
63
|
+
* Infer activities from a workflow definition (client perspective)
|
|
64
|
+
*/
|
|
65
|
+
type ClientInferWorkflowActivities<T extends WorkflowDefinition> = T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: ClientInferActivity<T["activities"][K]> } : {};
|
|
66
|
+
/**
|
|
67
|
+
* Infer signals from a workflow definition (client perspective)
|
|
68
|
+
*/
|
|
69
|
+
type ClientInferWorkflowSignals<T extends WorkflowDefinition> = T["signals"] extends Record<string, SignalDefinition> ? { [K in keyof T["signals"]]: ClientInferSignal<T["signals"][K]> } : {};
|
|
70
|
+
/**
|
|
71
|
+
* Infer queries from a workflow definition (client perspective)
|
|
72
|
+
*/
|
|
73
|
+
type ClientInferWorkflowQueries<T extends WorkflowDefinition> = T["queries"] extends Record<string, QueryDefinition> ? { [K in keyof T["queries"]]: ClientInferQuery<T["queries"][K]> } : {};
|
|
74
|
+
/**
|
|
75
|
+
* Infer updates from a workflow definition (client perspective)
|
|
76
|
+
*/
|
|
77
|
+
type ClientInferWorkflowUpdates<T extends WorkflowDefinition> = T["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof T["updates"]]: ClientInferUpdate<T["updates"][K]> } : {};
|
|
78
|
+
/**
|
|
79
|
+
* Infer all activities available in a workflow context (client perspective)
|
|
80
|
+
* Combines workflow-specific activities with global activities
|
|
81
|
+
*/
|
|
82
|
+
type ClientInferWorkflowContextActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = ClientInferWorkflowActivities<TContract["workflows"][TWorkflowName]> & ClientInferActivities<TContract>;
|
|
83
|
+
//#endregion
|
|
6
84
|
//#region src/errors.d.ts
|
|
7
85
|
/**
|
|
8
86
|
* Base class for all typed client errors with boxed pattern
|
|
9
87
|
*/
|
|
10
|
-
declare class TypedClientError extends Error {
|
|
11
|
-
constructor(message: string);
|
|
88
|
+
declare abstract class TypedClientError extends Error {
|
|
89
|
+
protected constructor(message: string);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generic runtime failure wrapper when no specific error type applies
|
|
93
|
+
*/
|
|
94
|
+
declare class RuntimeClientError extends TypedClientError {
|
|
95
|
+
readonly operation: string;
|
|
96
|
+
readonly cause?: unknown | undefined;
|
|
97
|
+
constructor(operation: string, cause?: unknown | undefined);
|
|
12
98
|
}
|
|
13
99
|
/**
|
|
14
100
|
* Thrown when a workflow is not found in the contract
|
|
@@ -55,11 +141,9 @@ declare class UpdateValidationError extends TypedClientError {
|
|
|
55
141
|
}
|
|
56
142
|
//#endregion
|
|
57
143
|
//#region src/client.d.ts
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
*/
|
|
62
|
-
type TypedWorkflowStartOptions = Pick<WorkflowStartOptions, "workflowId" | "workflowIdReusePolicy" | "workflowExecutionTimeout" | "workflowRunTimeout" | "workflowTaskTimeout" | "retry" | "memo" | "searchAttributes" | "cronSchedule"> & Pick<WorkflowOptions, "workflowId">;
|
|
144
|
+
type TypedWorkflowStartOptions<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = Omit<WorkflowStartOptions, "taskQueue" | "args"> & {
|
|
145
|
+
args: ClientInferInput<TContract["workflows"][TWorkflowName]>;
|
|
146
|
+
};
|
|
63
147
|
/**
|
|
64
148
|
* Typed workflow handle with validated results using Result/Future pattern
|
|
65
149
|
*/
|
|
@@ -69,37 +153,37 @@ interface TypedWorkflowHandle<TWorkflow extends WorkflowDefinition> {
|
|
|
69
153
|
* Type-safe queries based on workflow definition with Result pattern
|
|
70
154
|
* Each query returns Future<Result<T, Error>> instead of Promise<T>
|
|
71
155
|
*/
|
|
72
|
-
queries: { [K in keyof ClientInferWorkflowQueries<TWorkflow>]: ClientInferWorkflowQueries<TWorkflow>[K] extends ((...args: infer Args) =>
|
|
156
|
+
queries: { [K in keyof ClientInferWorkflowQueries<TWorkflow>]: ClientInferWorkflowQueries<TWorkflow>[K] extends ((...args: infer Args) => Future<Result<infer R, Error>>) ? (...args: Args) => Future<Result<R, QueryValidationError | RuntimeClientError>> : never };
|
|
73
157
|
/**
|
|
74
158
|
* Type-safe signals based on workflow definition with Result pattern
|
|
75
159
|
* Each signal returns Future<Result<void, Error>> instead of Promise<void>
|
|
76
160
|
*/
|
|
77
|
-
signals: { [K in keyof ClientInferWorkflowSignals<TWorkflow>]: ClientInferWorkflowSignals<TWorkflow>[K] extends ((...args: infer Args) =>
|
|
161
|
+
signals: { [K in keyof ClientInferWorkflowSignals<TWorkflow>]: ClientInferWorkflowSignals<TWorkflow>[K] extends ((...args: infer Args) => Future<Result<void, Error>>) ? (...args: Args) => Future<Result<void, SignalValidationError | RuntimeClientError>> : never };
|
|
78
162
|
/**
|
|
79
163
|
* Type-safe updates based on workflow definition with Result pattern
|
|
80
164
|
* Each update returns Future<Result<T, Error>> instead of Promise<T>
|
|
81
165
|
*/
|
|
82
|
-
updates: { [K in keyof ClientInferWorkflowUpdates<TWorkflow>]: ClientInferWorkflowUpdates<TWorkflow>[K] extends ((...args: infer Args) =>
|
|
166
|
+
updates: { [K in keyof ClientInferWorkflowUpdates<TWorkflow>]: ClientInferWorkflowUpdates<TWorkflow>[K] extends ((...args: infer Args) => Future<Result<infer R, Error>>) ? (...args: Args) => Future<Result<R, UpdateValidationError | RuntimeClientError>> : never };
|
|
83
167
|
/**
|
|
84
168
|
* Get workflow result with Result pattern
|
|
85
169
|
*/
|
|
86
|
-
result: () => Future
|
|
170
|
+
result: () => Future<Result<ClientInferOutput<TWorkflow>, WorkflowValidationError | RuntimeClientError>>;
|
|
87
171
|
/**
|
|
88
172
|
* Terminate workflow with Result pattern
|
|
89
173
|
*/
|
|
90
|
-
terminate: (reason?: string) => Future
|
|
174
|
+
terminate: (reason?: string) => Future<Result<void, RuntimeClientError>>;
|
|
91
175
|
/**
|
|
92
176
|
* Cancel workflow with Result pattern
|
|
93
177
|
*/
|
|
94
|
-
cancel: () => Future
|
|
178
|
+
cancel: () => Future<Result<void, RuntimeClientError>>;
|
|
95
179
|
/**
|
|
96
180
|
* Get workflow execution description including status and metadata
|
|
97
181
|
*/
|
|
98
|
-
describe: () => Future
|
|
182
|
+
describe: () => Future<Result<Awaited<ReturnType<WorkflowHandle["describe"]>>, RuntimeClientError>>;
|
|
99
183
|
/**
|
|
100
184
|
* Fetch the workflow execution history
|
|
101
185
|
*/
|
|
102
|
-
fetchHistory: () => ReturnType<WorkflowHandle["fetchHistory"]
|
|
186
|
+
fetchHistory: () => Future<Result<Awaited<ReturnType<WorkflowHandle["fetchHistory"]>>, RuntimeClientError>>;
|
|
103
187
|
}
|
|
104
188
|
/**
|
|
105
189
|
* Typed Temporal client with Result/Future pattern based on a contract
|
|
@@ -125,7 +209,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
125
209
|
* const result = await client.executeWorkflow('processOrder', {
|
|
126
210
|
* workflowId: 'order-123',
|
|
127
211
|
* args: { ... },
|
|
128
|
-
* })
|
|
212
|
+
* });
|
|
129
213
|
*
|
|
130
214
|
* result.match({
|
|
131
215
|
* Ok: (output) => console.log('Success:', output),
|
|
@@ -133,7 +217,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
133
217
|
* });
|
|
134
218
|
* ```
|
|
135
219
|
*/
|
|
136
|
-
static create<TContract extends ContractDefinition>(contract: TContract,
|
|
220
|
+
static create<TContract extends ContractDefinition>(contract: TContract, client: Client): TypedClient<TContract>;
|
|
137
221
|
/**
|
|
138
222
|
* Start a workflow and return a typed handle with Future pattern
|
|
139
223
|
*
|
|
@@ -144,11 +228,11 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
144
228
|
* args: { orderId: 'ORD-123' },
|
|
145
229
|
* workflowExecutionTimeout: '1 day',
|
|
146
230
|
* retry: { maximumAttempts: 3 },
|
|
147
|
-
* })
|
|
231
|
+
* });
|
|
148
232
|
*
|
|
149
233
|
* handleResult.match({
|
|
150
234
|
* Ok: async (handle) => {
|
|
151
|
-
* const result = await handle.result()
|
|
235
|
+
* const result = await handle.result();
|
|
152
236
|
* // ... handle result
|
|
153
237
|
* },
|
|
154
238
|
* Error: (error) => console.error('Failed to start:', error),
|
|
@@ -158,9 +242,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
158
242
|
startWorkflow<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, {
|
|
159
243
|
args,
|
|
160
244
|
...temporalOptions
|
|
161
|
-
}: TypedWorkflowStartOptions
|
|
162
|
-
args: ClientInferInput<TContract["workflows"][TWorkflowName]>;
|
|
163
|
-
}): Future$1<Result$1<TypedWorkflowHandle<TContract["workflows"][TWorkflowName]>, TypedClientError>>;
|
|
245
|
+
}: TypedWorkflowStartOptions<TContract, TWorkflowName>): Future<Result<TypedWorkflowHandle<TContract["workflows"][TWorkflowName]>, WorkflowNotFoundError | WorkflowValidationError | RuntimeClientError>>;
|
|
164
246
|
/**
|
|
165
247
|
* Execute a workflow (start and wait for result) with Future/Result pattern
|
|
166
248
|
*
|
|
@@ -171,7 +253,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
171
253
|
* args: { orderId: 'ORD-123' },
|
|
172
254
|
* workflowExecutionTimeout: '1 day',
|
|
173
255
|
* retry: { maximumAttempts: 3 },
|
|
174
|
-
* })
|
|
256
|
+
* });
|
|
175
257
|
*
|
|
176
258
|
* result.match({
|
|
177
259
|
* Ok: (output) => console.log('Order processed:', output.status),
|
|
@@ -182,26 +264,24 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
182
264
|
executeWorkflow<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, {
|
|
183
265
|
args,
|
|
184
266
|
...temporalOptions
|
|
185
|
-
}: TypedWorkflowStartOptions
|
|
186
|
-
args: ClientInferInput<TContract["workflows"][TWorkflowName]>;
|
|
187
|
-
}): Future$1<Result$1<ClientInferOutput<TContract["workflows"][TWorkflowName]>, TypedClientError>>;
|
|
267
|
+
}: TypedWorkflowStartOptions<TContract, TWorkflowName>): Future<Result<ClientInferOutput<TContract["workflows"][TWorkflowName]>, WorkflowNotFoundError | WorkflowValidationError | RuntimeClientError>>;
|
|
188
268
|
/**
|
|
189
269
|
* Get a handle to an existing workflow with Future/Result pattern
|
|
190
270
|
*
|
|
191
271
|
* @example
|
|
192
272
|
* ```ts
|
|
193
|
-
* const handleResult = await client.getHandle('processOrder', 'order-123')
|
|
273
|
+
* const handleResult = await client.getHandle('processOrder', 'order-123');
|
|
194
274
|
* handleResult.match({
|
|
195
275
|
* Ok: async (handle) => {
|
|
196
|
-
* const result = await handle.result()
|
|
276
|
+
* const result = await handle.result();
|
|
197
277
|
* // ... handle result
|
|
198
278
|
* },
|
|
199
279
|
* Error: (error) => console.error('Failed to get handle:', error),
|
|
200
280
|
* });
|
|
201
281
|
* ```
|
|
202
282
|
*/
|
|
203
|
-
getHandle<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, workflowId: string): Future
|
|
283
|
+
getHandle<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, workflowId: string): Future<Result<TypedWorkflowHandle<TContract["workflows"][TWorkflowName]>, WorkflowNotFoundError | RuntimeClientError>>;
|
|
204
284
|
private createTypedHandle;
|
|
205
285
|
}
|
|
206
286
|
//#endregion
|
|
207
|
-
export {
|
|
287
|
+
export { type ClientInferActivities, type ClientInferActivity, type ClientInferInput, type ClientInferOutput, type ClientInferQuery, type ClientInferSignal, type ClientInferUpdate, type ClientInferWorkflow, type ClientInferWorkflowActivities, type ClientInferWorkflowContextActivities, type ClientInferWorkflowQueries, type ClientInferWorkflowSignals, type ClientInferWorkflowUpdates, type ClientInferWorkflows, QueryValidationError, SignalValidationError, TypedClient, type TypedWorkflowHandle, type TypedWorkflowStartOptions, UpdateValidationError, WorkflowNotFoundError, WorkflowValidationError };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,100 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Future, Result } from "@temporal-contract/boxed";
|
|
2
|
+
import { Client, WorkflowHandle, WorkflowStartOptions } from "@temporalio/client";
|
|
3
|
+
import { ActivityDefinition, AnySchema, ContractDefinition, QueryDefinition, SignalDefinition, UpdateDefinition, WorkflowDefinition } from "@temporal-contract/contract";
|
|
4
4
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
5
|
|
|
6
|
+
//#region src/types.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Infer input type from a definition (client perspective)
|
|
10
|
+
* Client sends the input type (before input schema parsing/transformation)
|
|
11
|
+
*/
|
|
12
|
+
type ClientInferInput<T extends {
|
|
13
|
+
input: AnySchema;
|
|
14
|
+
}> = StandardSchemaV1.InferInput<T["input"]>;
|
|
15
|
+
/**
|
|
16
|
+
* Infer output type from a definition (client perspective)
|
|
17
|
+
* Client receives the output type (after output schema parsing/transformation)
|
|
18
|
+
*/
|
|
19
|
+
type ClientInferOutput<T extends {
|
|
20
|
+
output: AnySchema;
|
|
21
|
+
}> = StandardSchemaV1.InferOutput<T["output"]>;
|
|
22
|
+
/**
|
|
23
|
+
* CLIENT PERSPECTIVE
|
|
24
|
+
* Client sends z.output and receives z.input
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Infer workflow function signature from client perspective
|
|
28
|
+
* Client sends z.output and receives z.input
|
|
29
|
+
*/
|
|
30
|
+
type ClientInferWorkflow<TWorkflow extends WorkflowDefinition> = (args: ClientInferInput<TWorkflow>) => Promise<ClientInferOutput<TWorkflow>>;
|
|
31
|
+
/**
|
|
32
|
+
* Infer activity function signature from client perspective
|
|
33
|
+
* Client sends z.output and receives z.input
|
|
34
|
+
*/
|
|
35
|
+
type ClientInferActivity<TActivity extends ActivityDefinition> = (args: ClientInferInput<TActivity>) => Promise<ClientInferOutput<TActivity>>;
|
|
36
|
+
/**
|
|
37
|
+
* Infer signal handler signature from client perspective
|
|
38
|
+
* Client sends z.output and returns Future<Result<void, Error>>
|
|
39
|
+
*/
|
|
40
|
+
type ClientInferSignal<TSignal extends SignalDefinition> = (args: ClientInferInput<TSignal>) => Future<Result<void, Error>>;
|
|
41
|
+
/**
|
|
42
|
+
* Infer query handler signature from client perspective
|
|
43
|
+
* Client sends z.output and receives z.input wrapped in Future<Result<T, Error>>
|
|
44
|
+
*/
|
|
45
|
+
type ClientInferQuery<TQuery extends QueryDefinition> = (args: ClientInferInput<TQuery>) => Future<Result<ClientInferOutput<TQuery>, Error>>;
|
|
46
|
+
/**
|
|
47
|
+
* Infer update handler signature from client perspective
|
|
48
|
+
* Client sends z.output and receives z.input wrapped in Future<Result<T, Error>>
|
|
49
|
+
*/
|
|
50
|
+
type ClientInferUpdate<TUpdate extends UpdateDefinition> = (args: ClientInferInput<TUpdate>) => Future<Result<ClientInferOutput<TUpdate>, Error>>;
|
|
51
|
+
/**
|
|
52
|
+
* CLIENT PERSPECTIVE - Contract-level types
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* Infer all workflows from a contract (client perspective)
|
|
56
|
+
*/
|
|
57
|
+
type ClientInferWorkflows<TContract extends ContractDefinition> = { [K in keyof TContract["workflows"]]: ClientInferWorkflow<TContract["workflows"][K]> };
|
|
58
|
+
/**
|
|
59
|
+
* Infer all activities from a contract (client perspective)
|
|
60
|
+
*/
|
|
61
|
+
type ClientInferActivities<TContract extends ContractDefinition> = TContract["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof TContract["activities"]]: ClientInferActivity<TContract["activities"][K]> } : {};
|
|
62
|
+
/**
|
|
63
|
+
* Infer activities from a workflow definition (client perspective)
|
|
64
|
+
*/
|
|
65
|
+
type ClientInferWorkflowActivities<T extends WorkflowDefinition> = T["activities"] extends Record<string, ActivityDefinition> ? { [K in keyof T["activities"]]: ClientInferActivity<T["activities"][K]> } : {};
|
|
66
|
+
/**
|
|
67
|
+
* Infer signals from a workflow definition (client perspective)
|
|
68
|
+
*/
|
|
69
|
+
type ClientInferWorkflowSignals<T extends WorkflowDefinition> = T["signals"] extends Record<string, SignalDefinition> ? { [K in keyof T["signals"]]: ClientInferSignal<T["signals"][K]> } : {};
|
|
70
|
+
/**
|
|
71
|
+
* Infer queries from a workflow definition (client perspective)
|
|
72
|
+
*/
|
|
73
|
+
type ClientInferWorkflowQueries<T extends WorkflowDefinition> = T["queries"] extends Record<string, QueryDefinition> ? { [K in keyof T["queries"]]: ClientInferQuery<T["queries"][K]> } : {};
|
|
74
|
+
/**
|
|
75
|
+
* Infer updates from a workflow definition (client perspective)
|
|
76
|
+
*/
|
|
77
|
+
type ClientInferWorkflowUpdates<T extends WorkflowDefinition> = T["updates"] extends Record<string, UpdateDefinition> ? { [K in keyof T["updates"]]: ClientInferUpdate<T["updates"][K]> } : {};
|
|
78
|
+
/**
|
|
79
|
+
* Infer all activities available in a workflow context (client perspective)
|
|
80
|
+
* Combines workflow-specific activities with global activities
|
|
81
|
+
*/
|
|
82
|
+
type ClientInferWorkflowContextActivities<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = ClientInferWorkflowActivities<TContract["workflows"][TWorkflowName]> & ClientInferActivities<TContract>;
|
|
83
|
+
//#endregion
|
|
6
84
|
//#region src/errors.d.ts
|
|
7
85
|
/**
|
|
8
86
|
* Base class for all typed client errors with boxed pattern
|
|
9
87
|
*/
|
|
10
|
-
declare class TypedClientError extends Error {
|
|
11
|
-
constructor(message: string);
|
|
88
|
+
declare abstract class TypedClientError extends Error {
|
|
89
|
+
protected constructor(message: string);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generic runtime failure wrapper when no specific error type applies
|
|
93
|
+
*/
|
|
94
|
+
declare class RuntimeClientError extends TypedClientError {
|
|
95
|
+
readonly operation: string;
|
|
96
|
+
readonly cause?: unknown | undefined;
|
|
97
|
+
constructor(operation: string, cause?: unknown | undefined);
|
|
12
98
|
}
|
|
13
99
|
/**
|
|
14
100
|
* Thrown when a workflow is not found in the contract
|
|
@@ -55,11 +141,9 @@ declare class UpdateValidationError extends TypedClientError {
|
|
|
55
141
|
}
|
|
56
142
|
//#endregion
|
|
57
143
|
//#region src/client.d.ts
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
*/
|
|
62
|
-
type TypedWorkflowStartOptions = Pick<WorkflowStartOptions, "workflowId" | "workflowIdReusePolicy" | "workflowExecutionTimeout" | "workflowRunTimeout" | "workflowTaskTimeout" | "retry" | "memo" | "searchAttributes" | "cronSchedule"> & Pick<WorkflowOptions, "workflowId">;
|
|
144
|
+
type TypedWorkflowStartOptions<TContract extends ContractDefinition, TWorkflowName extends keyof TContract["workflows"]> = Omit<WorkflowStartOptions, "taskQueue" | "args"> & {
|
|
145
|
+
args: ClientInferInput<TContract["workflows"][TWorkflowName]>;
|
|
146
|
+
};
|
|
63
147
|
/**
|
|
64
148
|
* Typed workflow handle with validated results using Result/Future pattern
|
|
65
149
|
*/
|
|
@@ -69,37 +153,37 @@ interface TypedWorkflowHandle<TWorkflow extends WorkflowDefinition> {
|
|
|
69
153
|
* Type-safe queries based on workflow definition with Result pattern
|
|
70
154
|
* Each query returns Future<Result<T, Error>> instead of Promise<T>
|
|
71
155
|
*/
|
|
72
|
-
queries: { [K in keyof ClientInferWorkflowQueries<TWorkflow>]: ClientInferWorkflowQueries<TWorkflow>[K] extends ((...args: infer Args) =>
|
|
156
|
+
queries: { [K in keyof ClientInferWorkflowQueries<TWorkflow>]: ClientInferWorkflowQueries<TWorkflow>[K] extends ((...args: infer Args) => Future<Result<infer R, Error>>) ? (...args: Args) => Future<Result<R, QueryValidationError | RuntimeClientError>> : never };
|
|
73
157
|
/**
|
|
74
158
|
* Type-safe signals based on workflow definition with Result pattern
|
|
75
159
|
* Each signal returns Future<Result<void, Error>> instead of Promise<void>
|
|
76
160
|
*/
|
|
77
|
-
signals: { [K in keyof ClientInferWorkflowSignals<TWorkflow>]: ClientInferWorkflowSignals<TWorkflow>[K] extends ((...args: infer Args) =>
|
|
161
|
+
signals: { [K in keyof ClientInferWorkflowSignals<TWorkflow>]: ClientInferWorkflowSignals<TWorkflow>[K] extends ((...args: infer Args) => Future<Result<void, Error>>) ? (...args: Args) => Future<Result<void, SignalValidationError | RuntimeClientError>> : never };
|
|
78
162
|
/**
|
|
79
163
|
* Type-safe updates based on workflow definition with Result pattern
|
|
80
164
|
* Each update returns Future<Result<T, Error>> instead of Promise<T>
|
|
81
165
|
*/
|
|
82
|
-
updates: { [K in keyof ClientInferWorkflowUpdates<TWorkflow>]: ClientInferWorkflowUpdates<TWorkflow>[K] extends ((...args: infer Args) =>
|
|
166
|
+
updates: { [K in keyof ClientInferWorkflowUpdates<TWorkflow>]: ClientInferWorkflowUpdates<TWorkflow>[K] extends ((...args: infer Args) => Future<Result<infer R, Error>>) ? (...args: Args) => Future<Result<R, UpdateValidationError | RuntimeClientError>> : never };
|
|
83
167
|
/**
|
|
84
168
|
* Get workflow result with Result pattern
|
|
85
169
|
*/
|
|
86
|
-
result: () => Future
|
|
170
|
+
result: () => Future<Result<ClientInferOutput<TWorkflow>, WorkflowValidationError | RuntimeClientError>>;
|
|
87
171
|
/**
|
|
88
172
|
* Terminate workflow with Result pattern
|
|
89
173
|
*/
|
|
90
|
-
terminate: (reason?: string) => Future
|
|
174
|
+
terminate: (reason?: string) => Future<Result<void, RuntimeClientError>>;
|
|
91
175
|
/**
|
|
92
176
|
* Cancel workflow with Result pattern
|
|
93
177
|
*/
|
|
94
|
-
cancel: () => Future
|
|
178
|
+
cancel: () => Future<Result<void, RuntimeClientError>>;
|
|
95
179
|
/**
|
|
96
180
|
* Get workflow execution description including status and metadata
|
|
97
181
|
*/
|
|
98
|
-
describe: () => Future
|
|
182
|
+
describe: () => Future<Result<Awaited<ReturnType<WorkflowHandle["describe"]>>, RuntimeClientError>>;
|
|
99
183
|
/**
|
|
100
184
|
* Fetch the workflow execution history
|
|
101
185
|
*/
|
|
102
|
-
fetchHistory: () => ReturnType<WorkflowHandle["fetchHistory"]
|
|
186
|
+
fetchHistory: () => Future<Result<Awaited<ReturnType<WorkflowHandle["fetchHistory"]>>, RuntimeClientError>>;
|
|
103
187
|
}
|
|
104
188
|
/**
|
|
105
189
|
* Typed Temporal client with Result/Future pattern based on a contract
|
|
@@ -125,7 +209,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
125
209
|
* const result = await client.executeWorkflow('processOrder', {
|
|
126
210
|
* workflowId: 'order-123',
|
|
127
211
|
* args: { ... },
|
|
128
|
-
* })
|
|
212
|
+
* });
|
|
129
213
|
*
|
|
130
214
|
* result.match({
|
|
131
215
|
* Ok: (output) => console.log('Success:', output),
|
|
@@ -133,7 +217,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
133
217
|
* });
|
|
134
218
|
* ```
|
|
135
219
|
*/
|
|
136
|
-
static create<TContract extends ContractDefinition>(contract: TContract,
|
|
220
|
+
static create<TContract extends ContractDefinition>(contract: TContract, client: Client): TypedClient<TContract>;
|
|
137
221
|
/**
|
|
138
222
|
* Start a workflow and return a typed handle with Future pattern
|
|
139
223
|
*
|
|
@@ -144,11 +228,11 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
144
228
|
* args: { orderId: 'ORD-123' },
|
|
145
229
|
* workflowExecutionTimeout: '1 day',
|
|
146
230
|
* retry: { maximumAttempts: 3 },
|
|
147
|
-
* })
|
|
231
|
+
* });
|
|
148
232
|
*
|
|
149
233
|
* handleResult.match({
|
|
150
234
|
* Ok: async (handle) => {
|
|
151
|
-
* const result = await handle.result()
|
|
235
|
+
* const result = await handle.result();
|
|
152
236
|
* // ... handle result
|
|
153
237
|
* },
|
|
154
238
|
* Error: (error) => console.error('Failed to start:', error),
|
|
@@ -158,9 +242,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
158
242
|
startWorkflow<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, {
|
|
159
243
|
args,
|
|
160
244
|
...temporalOptions
|
|
161
|
-
}: TypedWorkflowStartOptions
|
|
162
|
-
args: ClientInferInput<TContract["workflows"][TWorkflowName]>;
|
|
163
|
-
}): Future$1<Result$1<TypedWorkflowHandle<TContract["workflows"][TWorkflowName]>, TypedClientError>>;
|
|
245
|
+
}: TypedWorkflowStartOptions<TContract, TWorkflowName>): Future<Result<TypedWorkflowHandle<TContract["workflows"][TWorkflowName]>, WorkflowNotFoundError | WorkflowValidationError | RuntimeClientError>>;
|
|
164
246
|
/**
|
|
165
247
|
* Execute a workflow (start and wait for result) with Future/Result pattern
|
|
166
248
|
*
|
|
@@ -171,7 +253,7 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
171
253
|
* args: { orderId: 'ORD-123' },
|
|
172
254
|
* workflowExecutionTimeout: '1 day',
|
|
173
255
|
* retry: { maximumAttempts: 3 },
|
|
174
|
-
* })
|
|
256
|
+
* });
|
|
175
257
|
*
|
|
176
258
|
* result.match({
|
|
177
259
|
* Ok: (output) => console.log('Order processed:', output.status),
|
|
@@ -182,26 +264,24 @@ declare class TypedClient<TContract extends ContractDefinition> {
|
|
|
182
264
|
executeWorkflow<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, {
|
|
183
265
|
args,
|
|
184
266
|
...temporalOptions
|
|
185
|
-
}: TypedWorkflowStartOptions
|
|
186
|
-
args: ClientInferInput<TContract["workflows"][TWorkflowName]>;
|
|
187
|
-
}): Future$1<Result$1<ClientInferOutput<TContract["workflows"][TWorkflowName]>, TypedClientError>>;
|
|
267
|
+
}: TypedWorkflowStartOptions<TContract, TWorkflowName>): Future<Result<ClientInferOutput<TContract["workflows"][TWorkflowName]>, WorkflowNotFoundError | WorkflowValidationError | RuntimeClientError>>;
|
|
188
268
|
/**
|
|
189
269
|
* Get a handle to an existing workflow with Future/Result pattern
|
|
190
270
|
*
|
|
191
271
|
* @example
|
|
192
272
|
* ```ts
|
|
193
|
-
* const handleResult = await client.getHandle('processOrder', 'order-123')
|
|
273
|
+
* const handleResult = await client.getHandle('processOrder', 'order-123');
|
|
194
274
|
* handleResult.match({
|
|
195
275
|
* Ok: async (handle) => {
|
|
196
|
-
* const result = await handle.result()
|
|
276
|
+
* const result = await handle.result();
|
|
197
277
|
* // ... handle result
|
|
198
278
|
* },
|
|
199
279
|
* Error: (error) => console.error('Failed to get handle:', error),
|
|
200
280
|
* });
|
|
201
281
|
* ```
|
|
202
282
|
*/
|
|
203
|
-
getHandle<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, workflowId: string): Future
|
|
283
|
+
getHandle<TWorkflowName extends keyof TContract["workflows"]>(workflowName: TWorkflowName, workflowId: string): Future<Result<TypedWorkflowHandle<TContract["workflows"][TWorkflowName]>, WorkflowNotFoundError | RuntimeClientError>>;
|
|
204
284
|
private createTypedHandle;
|
|
205
285
|
}
|
|
206
286
|
//#endregion
|
|
207
|
-
export {
|
|
287
|
+
export { type ClientInferActivities, type ClientInferActivity, type ClientInferInput, type ClientInferOutput, type ClientInferQuery, type ClientInferSignal, type ClientInferUpdate, type ClientInferWorkflow, type ClientInferWorkflowActivities, type ClientInferWorkflowContextActivities, type ClientInferWorkflowQueries, type ClientInferWorkflowSignals, type ClientInferWorkflowUpdates, type ClientInferWorkflows, QueryValidationError, SignalValidationError, TypedClient, type TypedWorkflowHandle, type TypedWorkflowStartOptions, UpdateValidationError, WorkflowNotFoundError, WorkflowValidationError };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AsyncData, Future, Future as Future$1, Option, Result, Result as Result$1 } from "@swan-io/boxed";
|
|
1
|
+
import { Future, Result } from "@temporal-contract/boxed";
|
|
3
2
|
|
|
4
3
|
//#region src/errors.ts
|
|
5
4
|
/**
|
|
@@ -13,6 +12,16 @@ var TypedClientError = class extends Error {
|
|
|
13
12
|
}
|
|
14
13
|
};
|
|
15
14
|
/**
|
|
15
|
+
* Generic runtime failure wrapper when no specific error type applies
|
|
16
|
+
*/
|
|
17
|
+
var RuntimeClientError = class extends TypedClientError {
|
|
18
|
+
constructor(operation, cause) {
|
|
19
|
+
super(`Operation "${operation}" failed: ${cause instanceof Error ? cause.message : String(cause ?? "unknown error")}`);
|
|
20
|
+
this.operation = operation;
|
|
21
|
+
this.cause = cause;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
16
25
|
* Thrown when a workflow is not found in the contract
|
|
17
26
|
*/
|
|
18
27
|
var WorkflowNotFoundError = class extends TypedClientError {
|
|
@@ -93,7 +102,7 @@ var TypedClient = class TypedClient {
|
|
|
93
102
|
* const result = await client.executeWorkflow('processOrder', {
|
|
94
103
|
* workflowId: 'order-123',
|
|
95
104
|
* args: { ... },
|
|
96
|
-
* })
|
|
105
|
+
* });
|
|
97
106
|
*
|
|
98
107
|
* result.match({
|
|
99
108
|
* Ok: (output) => console.log('Success:', output),
|
|
@@ -101,8 +110,8 @@ var TypedClient = class TypedClient {
|
|
|
101
110
|
* });
|
|
102
111
|
* ```
|
|
103
112
|
*/
|
|
104
|
-
static create(contract,
|
|
105
|
-
return new TypedClient(contract,
|
|
113
|
+
static create(contract, client) {
|
|
114
|
+
return new TypedClient(contract, client);
|
|
106
115
|
}
|
|
107
116
|
/**
|
|
108
117
|
* Start a workflow and return a typed handle with Future pattern
|
|
@@ -114,11 +123,11 @@ var TypedClient = class TypedClient {
|
|
|
114
123
|
* args: { orderId: 'ORD-123' },
|
|
115
124
|
* workflowExecutionTimeout: '1 day',
|
|
116
125
|
* retry: { maximumAttempts: 3 },
|
|
117
|
-
* })
|
|
126
|
+
* });
|
|
118
127
|
*
|
|
119
128
|
* handleResult.match({
|
|
120
129
|
* Ok: async (handle) => {
|
|
121
|
-
* const result = await handle.result()
|
|
130
|
+
* const result = await handle.result();
|
|
122
131
|
* // ... handle result
|
|
123
132
|
* },
|
|
124
133
|
* Error: (error) => console.error('Failed to start:', error),
|
|
@@ -126,16 +135,16 @@ var TypedClient = class TypedClient {
|
|
|
126
135
|
* ```
|
|
127
136
|
*/
|
|
128
137
|
startWorkflow(workflowName, { args, ...temporalOptions }) {
|
|
129
|
-
return Future
|
|
130
|
-
const definition = this.contract.workflows[workflowName];
|
|
131
|
-
if (!definition) {
|
|
132
|
-
resolve(Result$1.Error(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows))));
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
138
|
+
return Future.make((resolve) => {
|
|
135
139
|
(async () => {
|
|
140
|
+
const definition = this.contract.workflows[workflowName];
|
|
141
|
+
if (!definition) {
|
|
142
|
+
resolve(Result.Error(createWorkflowNotFoundError(workflowName, this.contract)));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
136
145
|
const inputResult = await definition.input["~standard"].validate(args);
|
|
137
146
|
if (inputResult.issues) {
|
|
138
|
-
resolve(Result
|
|
147
|
+
resolve(Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues)));
|
|
139
148
|
return;
|
|
140
149
|
}
|
|
141
150
|
const validatedInput = inputResult.value;
|
|
@@ -146,9 +155,9 @@ var TypedClient = class TypedClient {
|
|
|
146
155
|
args: [validatedInput]
|
|
147
156
|
});
|
|
148
157
|
const typedHandle = this.createTypedHandle(handle, definition);
|
|
149
|
-
resolve(Result
|
|
158
|
+
resolve(Result.Ok(typedHandle));
|
|
150
159
|
} catch (error) {
|
|
151
|
-
resolve(Result
|
|
160
|
+
resolve(Result.Error(createRuntimeClientError("startWorkflow", error)));
|
|
152
161
|
}
|
|
153
162
|
})();
|
|
154
163
|
});
|
|
@@ -163,7 +172,7 @@ var TypedClient = class TypedClient {
|
|
|
163
172
|
* args: { orderId: 'ORD-123' },
|
|
164
173
|
* workflowExecutionTimeout: '1 day',
|
|
165
174
|
* retry: { maximumAttempts: 3 },
|
|
166
|
-
* })
|
|
175
|
+
* });
|
|
167
176
|
*
|
|
168
177
|
* result.match({
|
|
169
178
|
* Ok: (output) => console.log('Order processed:', output.status),
|
|
@@ -172,16 +181,16 @@ var TypedClient = class TypedClient {
|
|
|
172
181
|
* ```
|
|
173
182
|
*/
|
|
174
183
|
executeWorkflow(workflowName, { args, ...temporalOptions }) {
|
|
175
|
-
return Future
|
|
176
|
-
const definition = this.contract.workflows[workflowName];
|
|
177
|
-
if (!definition) {
|
|
178
|
-
resolve(Result$1.Error(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows))));
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
184
|
+
return Future.make((resolve) => {
|
|
181
185
|
(async () => {
|
|
186
|
+
const definition = this.contract.workflows[workflowName];
|
|
187
|
+
if (!definition) {
|
|
188
|
+
resolve(Result.Error(createWorkflowNotFoundError(workflowName, this.contract)));
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
182
191
|
const inputResult = await definition.input["~standard"].validate(args);
|
|
183
192
|
if (inputResult.issues) {
|
|
184
|
-
resolve(Result
|
|
193
|
+
resolve(Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues)));
|
|
185
194
|
return;
|
|
186
195
|
}
|
|
187
196
|
const validatedInput = inputResult.value;
|
|
@@ -193,12 +202,12 @@ var TypedClient = class TypedClient {
|
|
|
193
202
|
});
|
|
194
203
|
const outputResult = await definition.output["~standard"].validate(result);
|
|
195
204
|
if (outputResult.issues) {
|
|
196
|
-
resolve(Result
|
|
205
|
+
resolve(Result.Error(createWorkflowValidationError(workflowName, "output", outputResult.issues)));
|
|
197
206
|
return;
|
|
198
207
|
}
|
|
199
|
-
resolve(Result
|
|
208
|
+
resolve(Result.Ok(outputResult.value));
|
|
200
209
|
} catch (error) {
|
|
201
|
-
resolve(Result
|
|
210
|
+
resolve(Result.Error(createRuntimeClientError("executeWorkflow", error)));
|
|
202
211
|
}
|
|
203
212
|
})();
|
|
204
213
|
});
|
|
@@ -208,10 +217,10 @@ var TypedClient = class TypedClient {
|
|
|
208
217
|
*
|
|
209
218
|
* @example
|
|
210
219
|
* ```ts
|
|
211
|
-
* const handleResult = await client.getHandle('processOrder', 'order-123')
|
|
220
|
+
* const handleResult = await client.getHandle('processOrder', 'order-123');
|
|
212
221
|
* handleResult.match({
|
|
213
222
|
* Ok: async (handle) => {
|
|
214
|
-
* const result = await handle.result()
|
|
223
|
+
* const result = await handle.result();
|
|
215
224
|
* // ... handle result
|
|
216
225
|
* },
|
|
217
226
|
* Error: (error) => console.error('Failed to get handle:', error),
|
|
@@ -219,148 +228,132 @@ var TypedClient = class TypedClient {
|
|
|
219
228
|
* ```
|
|
220
229
|
*/
|
|
221
230
|
getHandle(workflowName, workflowId) {
|
|
222
|
-
return Future
|
|
231
|
+
return Future.make((resolve) => {
|
|
223
232
|
const definition = this.contract.workflows[workflowName];
|
|
224
233
|
if (!definition) {
|
|
225
|
-
resolve(Result
|
|
234
|
+
resolve(Result.Error(createWorkflowNotFoundError(workflowName, this.contract)));
|
|
226
235
|
return;
|
|
227
236
|
}
|
|
228
237
|
try {
|
|
229
238
|
const handle = this.client.workflow.getHandle(workflowId);
|
|
230
239
|
const typedHandle = this.createTypedHandle(handle, definition);
|
|
231
|
-
resolve(Result
|
|
240
|
+
resolve(Result.Ok(typedHandle));
|
|
232
241
|
} catch (error) {
|
|
233
|
-
resolve(Result
|
|
242
|
+
resolve(Result.Error(createRuntimeClientError("getHandle", error)));
|
|
234
243
|
}
|
|
235
244
|
});
|
|
236
245
|
}
|
|
237
|
-
createTypedHandle(
|
|
246
|
+
createTypedHandle(workflowHandle, definition) {
|
|
238
247
|
const queries = {};
|
|
239
248
|
for (const [queryName, queryDef] of Object.entries(definition.queries ?? {})) queries[queryName] = (args) => {
|
|
240
|
-
return Future
|
|
249
|
+
return Future.make((resolve) => {
|
|
241
250
|
(async () => {
|
|
242
251
|
const inputResult = await queryDef.input["~standard"].validate(args);
|
|
243
252
|
if (inputResult.issues) {
|
|
244
|
-
resolve(Result
|
|
253
|
+
resolve(Result.Error(new QueryValidationError(queryName, "input", inputResult.issues)));
|
|
245
254
|
return;
|
|
246
255
|
}
|
|
247
256
|
try {
|
|
248
|
-
const result = await
|
|
257
|
+
const result = await workflowHandle.query(queryName, inputResult.value);
|
|
249
258
|
const outputResult = await queryDef.output["~standard"].validate(result);
|
|
250
259
|
if (outputResult.issues) {
|
|
251
|
-
resolve(Result
|
|
260
|
+
resolve(Result.Error(new QueryValidationError(queryName, "output", outputResult.issues)));
|
|
252
261
|
return;
|
|
253
262
|
}
|
|
254
|
-
resolve(Result
|
|
263
|
+
resolve(Result.Ok(outputResult.value));
|
|
255
264
|
} catch (error) {
|
|
256
|
-
resolve(Result
|
|
265
|
+
resolve(Result.Error(createRuntimeClientError("query", error)));
|
|
257
266
|
}
|
|
258
267
|
})();
|
|
259
268
|
});
|
|
260
269
|
};
|
|
261
270
|
const signals = {};
|
|
262
271
|
for (const [signalName, signalDef] of Object.entries(definition.signals ?? {})) signals[signalName] = (args) => {
|
|
263
|
-
return Future
|
|
272
|
+
return Future.make((resolve) => {
|
|
264
273
|
(async () => {
|
|
265
274
|
const inputResult = await signalDef.input["~standard"].validate(args);
|
|
266
275
|
if (inputResult.issues) {
|
|
267
|
-
resolve(Result
|
|
276
|
+
resolve(Result.Error(new SignalValidationError(signalName, inputResult.issues)));
|
|
268
277
|
return;
|
|
269
278
|
}
|
|
270
279
|
try {
|
|
271
|
-
await
|
|
272
|
-
resolve(Result
|
|
280
|
+
await workflowHandle.signal(signalName, inputResult.value);
|
|
281
|
+
resolve(Result.Ok(void 0));
|
|
273
282
|
} catch (error) {
|
|
274
|
-
resolve(Result
|
|
283
|
+
resolve(Result.Error(createRuntimeClientError("signal", error)));
|
|
275
284
|
}
|
|
276
285
|
})();
|
|
277
286
|
});
|
|
278
287
|
};
|
|
279
288
|
const updates = {};
|
|
280
289
|
for (const [updateName, updateDef] of Object.entries(definition.updates ?? {})) updates[updateName] = (args) => {
|
|
281
|
-
return Future
|
|
290
|
+
return Future.make((resolve) => {
|
|
282
291
|
(async () => {
|
|
283
292
|
const inputResult = await updateDef.input["~standard"].validate(args);
|
|
284
293
|
if (inputResult.issues) {
|
|
285
|
-
resolve(Result
|
|
294
|
+
resolve(Result.Error(new UpdateValidationError(updateName, "input", inputResult.issues)));
|
|
286
295
|
return;
|
|
287
296
|
}
|
|
288
297
|
try {
|
|
289
|
-
const result = await
|
|
298
|
+
const result = await workflowHandle.executeUpdate(updateName, { args: [inputResult.value] });
|
|
290
299
|
const outputResult = await updateDef.output["~standard"].validate(result);
|
|
291
300
|
if (outputResult.issues) {
|
|
292
|
-
resolve(Result
|
|
301
|
+
resolve(Result.Error(new UpdateValidationError(updateName, "output", outputResult.issues)));
|
|
293
302
|
return;
|
|
294
303
|
}
|
|
295
|
-
resolve(Result
|
|
304
|
+
resolve(Result.Ok(outputResult.value));
|
|
296
305
|
} catch (error) {
|
|
297
|
-
resolve(Result
|
|
306
|
+
resolve(Result.Error(createRuntimeClientError("update", error)));
|
|
298
307
|
}
|
|
299
308
|
})();
|
|
300
309
|
});
|
|
301
310
|
};
|
|
302
311
|
return {
|
|
303
|
-
workflowId:
|
|
312
|
+
workflowId: workflowHandle.workflowId,
|
|
304
313
|
queries,
|
|
305
314
|
signals,
|
|
306
315
|
updates,
|
|
307
316
|
result: () => {
|
|
308
|
-
return Future
|
|
317
|
+
return Future.make((resolve) => {
|
|
309
318
|
(async () => {
|
|
310
319
|
try {
|
|
311
|
-
const result = await
|
|
320
|
+
const result = await workflowHandle.result();
|
|
312
321
|
const outputResult = await definition.output["~standard"].validate(result);
|
|
313
322
|
if (outputResult.issues) {
|
|
314
|
-
resolve(Result
|
|
323
|
+
resolve(Result.Error(new WorkflowValidationError(workflowHandle.workflowId, "output", outputResult.issues)));
|
|
315
324
|
return;
|
|
316
325
|
}
|
|
317
|
-
resolve(Result
|
|
326
|
+
resolve(Result.Ok(outputResult.value));
|
|
318
327
|
} catch (error) {
|
|
319
|
-
resolve(Result
|
|
328
|
+
resolve(Result.Error(createRuntimeClientError("result", error)));
|
|
320
329
|
}
|
|
321
330
|
})();
|
|
322
331
|
});
|
|
323
332
|
},
|
|
324
333
|
terminate: (reason) => {
|
|
325
|
-
return Future
|
|
326
|
-
(async () => {
|
|
327
|
-
try {
|
|
328
|
-
await handle.terminate(reason);
|
|
329
|
-
resolve(Result$1.Ok(void 0));
|
|
330
|
-
} catch (error) {
|
|
331
|
-
resolve(Result$1.Error(new TypedClientError(`Terminate failed: ${error instanceof Error ? error.message : String(error)}`)));
|
|
332
|
-
}
|
|
333
|
-
})();
|
|
334
|
-
});
|
|
334
|
+
return Future.fromPromise(workflowHandle.terminate(reason)).mapError((error) => createRuntimeClientError("terminate", error)).mapOk(() => void 0);
|
|
335
335
|
},
|
|
336
336
|
cancel: () => {
|
|
337
|
-
return Future
|
|
338
|
-
(async () => {
|
|
339
|
-
try {
|
|
340
|
-
await handle.cancel();
|
|
341
|
-
resolve(Result$1.Ok(void 0));
|
|
342
|
-
} catch (error) {
|
|
343
|
-
resolve(Result$1.Error(new TypedClientError(`Cancel failed: ${error instanceof Error ? error.message : String(error)}`)));
|
|
344
|
-
}
|
|
345
|
-
})();
|
|
346
|
-
});
|
|
337
|
+
return Future.fromPromise(workflowHandle.cancel()).mapError((error) => createRuntimeClientError("cancel", error)).mapOk(() => void 0);
|
|
347
338
|
},
|
|
348
339
|
describe: () => {
|
|
349
|
-
return Future
|
|
350
|
-
(async () => {
|
|
351
|
-
try {
|
|
352
|
-
const description = await handle.describe();
|
|
353
|
-
resolve(Result$1.Ok(description));
|
|
354
|
-
} catch (error) {
|
|
355
|
-
resolve(Result$1.Error(new TypedClientError(`Describe failed: ${error instanceof Error ? error.message : String(error)}`)));
|
|
356
|
-
}
|
|
357
|
-
})();
|
|
358
|
-
});
|
|
340
|
+
return Future.fromPromise(workflowHandle.describe()).mapError((error) => createRuntimeClientError("describe", error));
|
|
359
341
|
},
|
|
360
|
-
fetchHistory: () =>
|
|
342
|
+
fetchHistory: () => {
|
|
343
|
+
return Future.fromPromise(workflowHandle.fetchHistory()).mapError((error) => createRuntimeClientError("fetchHistory", error));
|
|
344
|
+
}
|
|
361
345
|
};
|
|
362
346
|
}
|
|
363
347
|
};
|
|
348
|
+
function createRuntimeClientError(operation, error) {
|
|
349
|
+
return new RuntimeClientError(operation, error);
|
|
350
|
+
}
|
|
351
|
+
function createWorkflowNotFoundError(workflowName, contract) {
|
|
352
|
+
return new WorkflowNotFoundError(String(workflowName), Object.keys(contract.workflows));
|
|
353
|
+
}
|
|
354
|
+
function createWorkflowValidationError(workflowName, direction, issues) {
|
|
355
|
+
return new WorkflowValidationError(String(workflowName), direction, issues);
|
|
356
|
+
}
|
|
364
357
|
|
|
365
358
|
//#endregion
|
|
366
|
-
export {
|
|
359
|
+
export { QueryValidationError, SignalValidationError, TypedClient, UpdateValidationError, WorkflowNotFoundError, WorkflowValidationError };
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporal-contract/client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Client utilities with Result/Future pattern for consuming temporal-contract workflows",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"temporal",
|
|
7
|
-
"typescript",
|
|
8
|
-
"contract",
|
|
9
6
|
"client",
|
|
7
|
+
"contract",
|
|
8
|
+
"future",
|
|
10
9
|
"result",
|
|
11
|
-
"
|
|
10
|
+
"temporal",
|
|
11
|
+
"typescript"
|
|
12
12
|
],
|
|
13
13
|
"homepage": "https://github.com/btravers/temporal-contract#readme",
|
|
14
14
|
"bugs": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"directory": "packages/client"
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
|
-
"author": "Benoit TRAVERS <benoit.travers.
|
|
23
|
+
"author": "Benoit TRAVERS <benoit.travers.fr@gmail.com>",
|
|
24
24
|
"type": "module",
|
|
25
25
|
"exports": {
|
|
26
26
|
".": {
|
|
@@ -42,28 +42,32 @@
|
|
|
42
42
|
"dist"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@standard-schema/spec": "1.
|
|
46
|
-
"@
|
|
47
|
-
"@temporal-contract/contract": "0.0.
|
|
45
|
+
"@standard-schema/spec": "1.1.0",
|
|
46
|
+
"@temporal-contract/boxed": "0.0.6",
|
|
47
|
+
"@temporal-contract/contract": "0.0.6"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@temporalio/client": "1.
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"
|
|
50
|
+
"@temporalio/client": "1.14.0",
|
|
51
|
+
"@temporalio/worker": "1.14.0",
|
|
52
|
+
"@temporalio/workflow": "1.14.0",
|
|
53
|
+
"@types/node": "25.0.3",
|
|
54
|
+
"@vitest/coverage-v8": "4.0.16",
|
|
55
|
+
"tsdown": "0.18.1",
|
|
54
56
|
"typescript": "5.9.3",
|
|
55
|
-
"vitest": "4.0.
|
|
56
|
-
"zod": "4.1
|
|
57
|
-
"@temporal-contract/
|
|
57
|
+
"vitest": "4.0.16",
|
|
58
|
+
"zod": "4.2.1",
|
|
59
|
+
"@temporal-contract/testing": "0.0.6",
|
|
60
|
+
"@temporal-contract/tsconfig": "0.0.6"
|
|
58
61
|
},
|
|
59
62
|
"peerDependencies": {
|
|
60
|
-
"@temporalio/client": "
|
|
63
|
+
"@temporalio/client": "^1"
|
|
61
64
|
},
|
|
62
65
|
"scripts": {
|
|
63
66
|
"build": "tsdown src/index.ts --format cjs,esm --dts --clean",
|
|
64
67
|
"dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
|
|
65
|
-
"test": "vitest run",
|
|
66
|
-
"test:
|
|
68
|
+
"test": "vitest run --project unit",
|
|
69
|
+
"test:integration": "vitest run --project integration",
|
|
70
|
+
"test:watch": "vitest --project unit",
|
|
67
71
|
"typecheck": "tsc --noEmit"
|
|
68
72
|
}
|
|
69
73
|
}
|