@temporal-contract/client 1.0.0 → 2.1.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/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _temporalio_common = require("@temporalio/common");
3
- let _swan_io_boxed = require("@swan-io/boxed");
3
+ let neverthrow = require("neverthrow");
4
+ let _temporal_contract_contract = require("@temporal-contract/contract");
4
5
  let _temporalio_client = require("@temporalio/client");
6
+ let _temporal_contract_contract_result_async = require("@temporal-contract/contract/result-async");
5
7
  //#region src/errors.ts
6
8
  /**
7
9
  * Base class for all typed client errors with boxed pattern
@@ -77,11 +79,17 @@ var WorkflowExecutionNotFoundError = class extends TypedClientError {
77
79
  * on a workflow's result and the workflow completes with a failure —
78
80
  * Temporal's `WorkflowFailedError`.
79
81
  *
80
- * `cause` is the *unwrapped* underlying failure (typically an
82
+ * `cause` is the *unwrapped* underlying {@link TemporalFailure} (typically an
81
83
  * `ApplicationFailure`, `CancelledFailure`, `TerminatedFailure`, or
82
84
  * `TimeoutFailure`) lifted from Temporal's wrapper, so callers can branch
83
85
  * on the failure category in one step (`err.cause instanceof
84
- * ApplicationFailure`) instead of unwrapping twice via the SDK wrapper.
86
+ * ApplicationFailure`) instead of unwrapping twice via the SDK wrapper. The
87
+ * SDK declares `WorkflowFailedError.cause` as the wider `Error | undefined`
88
+ * (since `cause` lives on `Error`), but the runtime guarantee — driven by
89
+ * Temporal's wire format — is that it is always a `TemporalFailure` subclass
90
+ * when the wrapper is surfaced. `classifyResultError` narrows that wider
91
+ * static type to the public {@link TemporalFailure} union with a cast, so
92
+ * consumers see the precise leaf-failure typing instead of a bare `Error`.
85
93
  *
86
94
  * Returned from `executeWorkflow` and `handle.result()`.
87
95
  */
@@ -94,57 +102,11 @@ var WorkflowFailedError = class extends TypedClientError {
94
102
  }
95
103
  };
96
104
  /**
97
- * Pattern for string keys safe to render with dot notation. A "safe" key is a
98
- * JavaScript identifier (letters/digits/underscore/$, not starting with a
99
- * digit). Anything else — keys containing dots, spaces, leading digits, the
100
- * empty string, the literal string `"0"` etc. — gets bracket-quoted so the
101
- * path is unambiguous.
102
- *
103
- * This helper is intentionally duplicated with the worker package so each
104
- * entry point is self-contained; keep the two copies in sync.
105
- */
106
- const SAFE_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
107
- /**
108
- * Render a Standard Schema {@link StandardSchemaV1.Issue} into a human-readable
109
- * string that includes the failing field's path.
110
- *
111
- * Example output:
112
- * - `at items[0].quantity: Expected number, received undefined`
113
- * - `at customerId: Expected string, received undefined`
114
- * - `at user["first name"]: Expected string, received undefined`
115
- * - `Validation error` *(no path)*
116
- *
117
- * Path segments come either as bare `PropertyKey` values or as
118
- * `{ key: PropertyKey }` objects (per the spec); both are normalized.
119
- * - Numeric keys → `[N]`
120
- * - String keys that are valid JS identifiers → bare (first) or `.key`
121
- * - String keys that aren't valid identifiers → `["..."]` with JSON-style
122
- * escaping (handles dots, spaces, leading digits, the empty string, the
123
- * literal string `"0"`, embedded quotes, etc.)
124
- * - Symbol / other `PropertyKey` → `[Symbol(name)]`
125
- */
126
- function formatIssue(issue) {
127
- if (issue.path === void 0 || issue.path.length === 0) return issue.message;
128
- let path = "";
129
- for (let i = 0; i < issue.path.length; i++) {
130
- const segment = issue.path[i];
131
- const key = segment !== null && typeof segment === "object" && "key" in segment ? segment.key : segment;
132
- if (typeof key === "number") path += `[${key}]`;
133
- else if (typeof key === "string" && SAFE_IDENTIFIER.test(key)) path += i === 0 ? key : `.${key}`;
134
- else if (typeof key === "string") path += `[${JSON.stringify(key)}]`;
135
- else path += `[${String(key)}]`;
136
- }
137
- return `at ${path}: ${issue.message}`;
138
- }
139
- function summarizeIssues(issues) {
140
- return issues.map(formatIssue).join("; ");
141
- }
142
- /**
143
105
  * Thrown when workflow input or output validation fails
144
106
  */
145
107
  var WorkflowValidationError = class extends TypedClientError {
146
108
  constructor(workflowName, direction, issues) {
147
- super(`Validation failed for workflow "${workflowName}" ${direction}: ${summarizeIssues(issues)}`);
109
+ super(`Validation failed for workflow "${workflowName}" ${direction}: ${(0, _temporal_contract_contract.summarizeIssues)(issues)}`);
148
110
  this.workflowName = workflowName;
149
111
  this.direction = direction;
150
112
  this.issues = issues;
@@ -155,7 +117,7 @@ var WorkflowValidationError = class extends TypedClientError {
155
117
  */
156
118
  var QueryValidationError = class extends TypedClientError {
157
119
  constructor(queryName, direction, issues) {
158
- super(`Validation failed for query "${queryName}" ${direction}: ${summarizeIssues(issues)}`);
120
+ super(`Validation failed for query "${queryName}" ${direction}: ${(0, _temporal_contract_contract.summarizeIssues)(issues)}`);
159
121
  this.queryName = queryName;
160
122
  this.direction = direction;
161
123
  this.issues = issues;
@@ -166,7 +128,7 @@ var QueryValidationError = class extends TypedClientError {
166
128
  */
167
129
  var SignalValidationError = class extends TypedClientError {
168
130
  constructor(signalName, issues) {
169
- super(`Validation failed for signal "${signalName}": ${summarizeIssues(issues)}`);
131
+ super(`Validation failed for signal "${signalName}": ${(0, _temporal_contract_contract.summarizeIssues)(issues)}`);
170
132
  this.signalName = signalName;
171
133
  this.issues = issues;
172
134
  }
@@ -176,7 +138,7 @@ var SignalValidationError = class extends TypedClientError {
176
138
  */
177
139
  var UpdateValidationError = class extends TypedClientError {
178
140
  constructor(updateName, direction, issues) {
179
- super(`Validation failed for update "${updateName}" ${direction}: ${summarizeIssues(issues)}`);
141
+ super(`Validation failed for update "${updateName}" ${direction}: ${(0, _temporal_contract_contract.summarizeIssues)(issues)}`);
180
142
  this.updateName = updateName;
181
143
  this.direction = direction;
182
144
  this.issues = issues;
@@ -192,21 +154,21 @@ var UpdateValidationError = class extends TypedClientError {
192
154
  * In-package modules and tests import it directly via relative path.
193
155
  */
194
156
  /**
195
- * Wrap an async result-producing function in a `Future`, catching any
157
+ * Wrap an async result-producing function in a `ResultAsync`, catching any
196
158
  * unhandled rejection as a `RuntimeClientError("unexpected", error)`.
197
159
  *
198
160
  * The work function is expected to handle its own domain errors and return
199
- * a `Result.Error(...)` for them; the catch here is a safety net for
200
- * thrown exceptions the work didn't anticipate.
161
+ * an `err(...)` for them; the catch here is a safety net for thrown
162
+ * exceptions the work didn't anticipate.
201
163
  *
202
164
  * Used by `client.ts` (workflow operations) and `schedule.ts` (schedule
203
165
  * operations) so the unexpected-rejection shape is identical across the
204
- * typed client surface.
166
+ * typed client surface. Delegates to `_internal_makeResultAsync` from
167
+ * `@temporal-contract/contract` so the same wrapper is shared between the
168
+ * client and worker packages.
205
169
  */
206
- function makeFuture(work) {
207
- return _swan_io_boxed.Future.make((resolve) => {
208
- work().then(resolve).catch((e) => resolve(_swan_io_boxed.Result.Error(new RuntimeClientError("unexpected", e))));
209
- });
170
+ function makeResultAsync(work) {
171
+ return (0, _temporal_contract_contract_result_async._internal_makeResultAsync)(work, (e) => new RuntimeClientError("unexpected", e));
210
172
  }
211
173
  /**
212
174
  * Map a thrown error from `client.workflow.start` / `signalWithStart` into
@@ -275,9 +237,9 @@ var TypedScheduleClient = class {
275
237
  create(workflowName, options) {
276
238
  const work = async () => {
277
239
  const definition = this.contract.workflows[workflowName];
278
- if (!definition) return _swan_io_boxed.Result.Error(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows)));
240
+ if (!definition) return (0, neverthrow.err)(new WorkflowNotFoundError(workflowName, Object.keys(this.contract.workflows)));
279
241
  const inputResult = await definition.input["~standard"].validate(options.args);
280
- if (inputResult.issues) return _swan_io_boxed.Result.Error(new WorkflowValidationError(String(workflowName), "input", inputResult.issues));
242
+ if (inputResult.issues) return (0, neverthrow.err)(new WorkflowValidationError(workflowName, "input", inputResult.issues));
281
243
  try {
282
244
  const overrides = options.action ?? {};
283
245
  const action = {
@@ -294,20 +256,19 @@ var TypedScheduleClient = class {
294
256
  ...overrides.staticDetails !== void 0 ? { staticDetails: overrides.staticDetails } : {},
295
257
  ...overrides.staticSummary !== void 0 ? { staticSummary: overrides.staticSummary } : {}
296
258
  };
297
- const handle = await this.scheduleClient.create({
259
+ return (0, neverthrow.ok)(wrapScheduleHandle(await this.scheduleClient.create({
298
260
  scheduleId: options.scheduleId,
299
261
  spec: options.spec,
300
262
  action,
301
263
  ...options.policies !== void 0 ? { policies: options.policies } : {},
302
264
  ...options.state !== void 0 ? { state: options.state } : {},
303
265
  ...options.memo !== void 0 ? { memo: options.memo } : {}
304
- });
305
- return _swan_io_boxed.Result.Ok(wrapScheduleHandle(handle));
266
+ })));
306
267
  } catch (error) {
307
- return _swan_io_boxed.Result.Error(new RuntimeClientError("schedule.create", error));
268
+ return (0, neverthrow.err)(new RuntimeClientError("schedule.create", error));
308
269
  }
309
270
  };
310
- return makeFuture(work);
271
+ return makeResultAsync(work);
311
272
  }
312
273
  /**
313
274
  * Get a typed handle to an existing schedule. Does not validate that the
@@ -321,11 +282,11 @@ var TypedScheduleClient = class {
321
282
  function wrapScheduleHandle(handle) {
322
283
  return {
323
284
  scheduleId: handle.scheduleId,
324
- pause: (note) => _swan_io_boxed.Future.fromPromise(handle.pause(note)).mapError((error) => new RuntimeClientError("schedule.pause", error)).mapOk(() => void 0),
325
- unpause: (note) => _swan_io_boxed.Future.fromPromise(handle.unpause(note)).mapError((error) => new RuntimeClientError("schedule.unpause", error)).mapOk(() => void 0),
326
- trigger: (overlap) => _swan_io_boxed.Future.fromPromise(handle.trigger(overlap)).mapError((error) => new RuntimeClientError("schedule.trigger", error)).mapOk(() => void 0),
327
- delete: () => _swan_io_boxed.Future.fromPromise(handle.delete()).mapError((error) => new RuntimeClientError("schedule.delete", error)).mapOk(() => void 0),
328
- describe: () => _swan_io_boxed.Future.fromPromise(handle.describe()).mapError((error) => new RuntimeClientError("schedule.describe", error))
285
+ pause: (note) => neverthrow.ResultAsync.fromPromise(handle.pause(note), (error) => new RuntimeClientError("schedule.pause", error)).map(() => void 0),
286
+ unpause: (note) => neverthrow.ResultAsync.fromPromise(handle.unpause(note), (error) => new RuntimeClientError("schedule.unpause", error)).map(() => void 0),
287
+ trigger: (overlap) => neverthrow.ResultAsync.fromPromise(handle.trigger(overlap), (error) => new RuntimeClientError("schedule.trigger", error)).map(() => void 0),
288
+ delete: () => neverthrow.ResultAsync.fromPromise(handle.delete(), (error) => new RuntimeClientError("schedule.delete", error)).map(() => void 0),
289
+ describe: () => neverthrow.ResultAsync.fromPromise(handle.describe(), (error) => new RuntimeClientError("schedule.describe", error))
329
290
  };
330
291
  }
331
292
  //#endregion
@@ -355,7 +316,37 @@ function toTypedSearchAttributes(workflowDef, values) {
355
316
  return pairs.length > 0 ? new _temporalio_common.TypedSearchAttributes(pairs) : void 0;
356
317
  }
357
318
  /**
358
- * Typed Temporal client with Result/Future pattern based on a contract
319
+ * Shared pre-call ritual for the three contract-driven entry points that
320
+ * actually start a workflow (`startWorkflow`, `signalWithStart`,
321
+ * `executeWorkflow`):
322
+ *
323
+ * 1. Look up the workflow definition on the contract.
324
+ * 2. Surface a `WorkflowNotFoundError` if absent.
325
+ * 3. Validate `args` against the workflow's input schema.
326
+ * 4. Surface a `WorkflowValidationError` if validation fails.
327
+ * 5. Translate any caller-supplied `searchAttributes` into Temporal's
328
+ * `TypedSearchAttributes` shape (or `undefined`).
329
+ *
330
+ * `getHandle` deliberately keeps its own three-line lookup — it doesn't
331
+ * accept `args` or `searchAttributes`, so it can't share this helper. The
332
+ * call-specific extras (signal validation, post-call output validation,
333
+ * extended error classification) stay at the call site — those are the
334
+ * differentiators that make each method distinct.
335
+ */
336
+ async function resolveDefinitionAndValidateInput(contract, workflowName, args, searchAttributes) {
337
+ const definition = contract.workflows[workflowName];
338
+ if (!definition) return (0, neverthrow.err)(createWorkflowNotFoundError(workflowName, contract));
339
+ const inputResult = await definition.input["~standard"].validate(args);
340
+ if (inputResult.issues) return (0, neverthrow.err)(createWorkflowValidationError(workflowName, "input", inputResult.issues));
341
+ const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
342
+ return (0, neverthrow.ok)({
343
+ definition,
344
+ validatedInput: inputResult.value,
345
+ typedSearchAttributes
346
+ });
347
+ }
348
+ /**
349
+ * Typed Temporal client with neverthrow Result/ResultAsync pattern based on a contract
359
350
  *
360
351
  * Provides type-safe methods to start and execute workflows
361
352
  * defined in the contract, with explicit error handling using Result pattern.
@@ -379,10 +370,10 @@ var TypedClient = class TypedClient {
379
370
  * args: { orderId: "sweep" },
380
371
  * });
381
372
  *
382
- * result.match({
383
- * Ok: async (handle) => { await handle.pause("maintenance"); },
384
- * Error: (error) => console.error("schedule create failed", error),
385
- * });
373
+ * result.match(
374
+ * async (handle) => { await handle.pause("maintenance"); },
375
+ * (error) => console.error("schedule create failed", error),
376
+ * );
386
377
  * ```
387
378
  */
388
379
  schedule;
@@ -393,7 +384,7 @@ var TypedClient = class TypedClient {
393
384
  this.schedule = new TypedScheduleClient(contract, client.schedule);
394
385
  }
395
386
  /**
396
- * Create a typed Temporal client with boxed pattern from a contract
387
+ * Create a typed Temporal client with neverthrow pattern from a contract
397
388
  *
398
389
  * @example
399
390
  * ```ts
@@ -406,17 +397,17 @@ var TypedClient = class TypedClient {
406
397
  * args: { ... },
407
398
  * });
408
399
  *
409
- * result.match({
410
- * Ok: (output) => console.log('Success:', output),
411
- * Error: (error) => console.error('Failed:', error),
412
- * });
400
+ * result.match(
401
+ * (output) => console.log('Success:', output),
402
+ * (error) => console.error('Failed:', error),
403
+ * );
413
404
  * ```
414
405
  */
415
406
  static create(contract, client) {
416
407
  return new TypedClient(contract, client);
417
408
  }
418
409
  /**
419
- * Start a workflow and return a typed handle with Future pattern
410
+ * Start a workflow and return a typed handle with ResultAsync pattern
420
411
  *
421
412
  * @example
422
413
  * ```ts
@@ -427,35 +418,33 @@ var TypedClient = class TypedClient {
427
418
  * retry: { maximumAttempts: 3 },
428
419
  * });
429
420
  *
430
- * handleResult.match({
431
- * Ok: async (handle) => {
421
+ * handleResult.match(
422
+ * async (handle) => {
432
423
  * const result = await handle.result();
433
424
  * // ... handle result
434
425
  * },
435
- * Error: (error) => console.error('Failed to start:', error),
436
- * });
426
+ * (error) => console.error('Failed to start:', error),
427
+ * );
437
428
  * ```
438
429
  */
439
430
  startWorkflow(workflowName, { args, searchAttributes, ...temporalOptions }) {
440
431
  const work = async () => {
441
- const definition = this.contract.workflows[workflowName];
442
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
443
- const inputResult = await definition.input["~standard"].validate(args);
444
- if (inputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues));
445
- const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
432
+ const resolved = await resolveDefinitionAndValidateInput(this.contract, workflowName, args, searchAttributes);
433
+ if (resolved.isErr()) return (0, neverthrow.err)(resolved.error);
434
+ const { definition, validatedInput, typedSearchAttributes } = resolved.value;
446
435
  try {
447
436
  const handle = await this.client.workflow.start(workflowName, {
448
437
  ...temporalOptions,
449
438
  taskQueue: this.contract.taskQueue,
450
- args: [inputResult.value],
439
+ args: [validatedInput],
451
440
  ...typedSearchAttributes ? { typedSearchAttributes } : {}
452
441
  });
453
- return _swan_io_boxed.Result.Ok(this.createTypedHandle(handle, definition));
442
+ return (0, neverthrow.ok)(this.createTypedHandle(handle, definition));
454
443
  } catch (error) {
455
- return _swan_io_boxed.Result.Error(classifyStartError("startWorkflow", error));
444
+ return (0, neverthrow.err)(classifyStartError("startWorkflow", error));
456
445
  }
457
446
  };
458
- return makeFuture(work);
447
+ return makeResultAsync(work);
459
448
  }
460
449
  /**
461
450
  * Send a signal to a workflow, starting it first if it doesn't already exist.
@@ -477,45 +466,42 @@ var TypedClient = class TypedClient {
477
466
  * signalArgs: { reason: 'duplicate' },
478
467
  * });
479
468
  *
480
- * result.match({
481
- * Ok: (handle) => console.log('signaled run', handle.signaledRunId),
482
- * Error: (error) => console.error('signalWithStart failed', error),
483
- * });
469
+ * result.match(
470
+ * (handle) => console.log('signaled run', handle.signaledRunId),
471
+ * (error) => console.error('signalWithStart failed', error),
472
+ * );
484
473
  * ```
485
474
  */
486
475
  signalWithStart(workflowName, { args, signalName, signalArgs, searchAttributes, ...temporalOptions }) {
487
476
  const work = async () => {
488
- const definition = this.contract.workflows[workflowName];
489
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
490
- const inputResult = await definition.input["~standard"].validate(args);
491
- if (inputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues));
477
+ const resolved = await resolveDefinitionAndValidateInput(this.contract, workflowName, args, searchAttributes);
478
+ if (resolved.isErr()) return (0, neverthrow.err)(resolved.error);
479
+ const { definition, validatedInput, typedSearchAttributes } = resolved.value;
492
480
  const signalDef = definition.signals?.[signalName];
493
- if (!signalDef) return _swan_io_boxed.Result.Error(new SignalValidationError(signalName, [{ message: `Signal "${signalName}" is not declared on workflow "${String(workflowName)}".` }]));
481
+ if (!signalDef) return (0, neverthrow.err)(new SignalValidationError(signalName, [{ message: `Signal "${signalName}" is not declared on workflow "${workflowName}".` }]));
494
482
  const signalInputResult = await signalDef.input["~standard"].validate(signalArgs);
495
- if (signalInputResult.issues) return _swan_io_boxed.Result.Error(new SignalValidationError(signalName, signalInputResult.issues));
496
- const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
483
+ if (signalInputResult.issues) return (0, neverthrow.err)(new SignalValidationError(signalName, signalInputResult.issues));
497
484
  try {
498
485
  const handle = await this.client.workflow.signalWithStart(workflowName, {
499
486
  ...temporalOptions,
500
487
  taskQueue: this.contract.taskQueue,
501
- args: [inputResult.value],
488
+ args: [validatedInput],
502
489
  signal: signalName,
503
490
  signalArgs: [signalInputResult.value],
504
491
  ...typedSearchAttributes ? { typedSearchAttributes } : {}
505
492
  });
506
- const typed = this.createTypedHandle(handle, definition);
507
- return _swan_io_boxed.Result.Ok({
508
- ...typed,
493
+ return (0, neverthrow.ok)({
494
+ ...this.createTypedHandle(handle, definition),
509
495
  signaledRunId: handle.signaledRunId
510
496
  });
511
497
  } catch (error) {
512
- return _swan_io_boxed.Result.Error(classifyStartError("signalWithStart", error));
498
+ return (0, neverthrow.err)(classifyStartError("signalWithStart", error));
513
499
  }
514
500
  };
515
- return makeFuture(work);
501
+ return makeResultAsync(work);
516
502
  }
517
503
  /**
518
- * Execute a workflow (start and wait for result) with Future/Result pattern
504
+ * Execute a workflow (start and wait for result) with ResultAsync pattern
519
505
  *
520
506
  * @example
521
507
  * ```ts
@@ -526,65 +512,63 @@ var TypedClient = class TypedClient {
526
512
  * retry: { maximumAttempts: 3 },
527
513
  * });
528
514
  *
529
- * result.match({
530
- * Ok: (output) => console.log('Order processed:', output.status),
531
- * Error: (error) => console.error('Processing failed:', error),
532
- * });
515
+ * result.match(
516
+ * (output) => console.log('Order processed:', output.status),
517
+ * (error) => console.error('Processing failed:', error),
518
+ * );
533
519
  * ```
534
520
  */
535
521
  executeWorkflow(workflowName, { args, searchAttributes, ...temporalOptions }) {
536
522
  const work = async () => {
537
- const definition = this.contract.workflows[workflowName];
538
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
539
- const inputResult = await definition.input["~standard"].validate(args);
540
- if (inputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues));
541
- const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
523
+ const resolved = await resolveDefinitionAndValidateInput(this.contract, workflowName, args, searchAttributes);
524
+ if (resolved.isErr()) return (0, neverthrow.err)(resolved.error);
525
+ const { definition, validatedInput, typedSearchAttributes } = resolved.value;
542
526
  try {
543
527
  const result = await this.client.workflow.execute(workflowName, {
544
528
  ...temporalOptions,
545
529
  taskQueue: this.contract.taskQueue,
546
- args: [inputResult.value],
530
+ args: [validatedInput],
547
531
  ...typedSearchAttributes ? { typedSearchAttributes } : {}
548
532
  });
549
533
  const outputResult = await definition.output["~standard"].validate(result);
550
- if (outputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "output", outputResult.issues));
551
- return _swan_io_boxed.Result.Ok(outputResult.value);
534
+ if (outputResult.issues) return (0, neverthrow.err)(createWorkflowValidationError(workflowName, "output", outputResult.issues));
535
+ return (0, neverthrow.ok)(outputResult.value);
552
536
  } catch (error) {
553
- if (error instanceof _temporalio_client.WorkflowExecutionAlreadyStartedError) return _swan_io_boxed.Result.Error(new WorkflowAlreadyStartedError(error.workflowType, error.workflowId, error));
554
- if (error instanceof _temporalio_client.WorkflowFailedError) return _swan_io_boxed.Result.Error(new WorkflowFailedError(temporalOptions.workflowId, error.cause));
555
- if (error instanceof _temporalio_common.WorkflowNotFoundError) return _swan_io_boxed.Result.Error(new WorkflowExecutionNotFoundError(error.workflowId || temporalOptions.workflowId, error.runId, error));
556
- return _swan_io_boxed.Result.Error(createRuntimeClientError("executeWorkflow", error));
537
+ if (error instanceof _temporalio_client.WorkflowExecutionAlreadyStartedError) return (0, neverthrow.err)(new WorkflowAlreadyStartedError(error.workflowType, error.workflowId, error));
538
+ if (error instanceof _temporalio_client.WorkflowFailedError) return (0, neverthrow.err)(new WorkflowFailedError(temporalOptions.workflowId, error.cause));
539
+ if (error instanceof _temporalio_common.WorkflowNotFoundError) return (0, neverthrow.err)(new WorkflowExecutionNotFoundError(error.workflowId || temporalOptions.workflowId, error.runId, error));
540
+ return (0, neverthrow.err)(createRuntimeClientError("executeWorkflow", error));
557
541
  }
558
542
  };
559
- return makeFuture(work);
543
+ return makeResultAsync(work);
560
544
  }
561
545
  /**
562
- * Get a handle to an existing workflow with Future/Result pattern
546
+ * Get a handle to an existing workflow with ResultAsync pattern
563
547
  *
564
548
  * @example
565
549
  * ```ts
566
550
  * const handleResult = await client.getHandle('processOrder', 'order-123');
567
- * handleResult.match({
568
- * Ok: async (handle) => {
551
+ * handleResult.match(
552
+ * async (handle) => {
569
553
  * const result = await handle.result();
570
554
  * // ... handle result
571
555
  * },
572
- * Error: (error) => console.error('Failed to get handle:', error),
573
- * });
556
+ * (error) => console.error('Failed to get handle:', error),
557
+ * );
574
558
  * ```
575
559
  */
576
560
  getHandle(workflowName, workflowId) {
577
561
  const work = async () => {
578
562
  const definition = this.contract.workflows[workflowName];
579
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
563
+ if (!definition) return (0, neverthrow.err)(createWorkflowNotFoundError(workflowName, this.contract));
580
564
  try {
581
565
  const handle = this.client.workflow.getHandle(workflowId);
582
- return _swan_io_boxed.Result.Ok(this.createTypedHandle(handle, definition));
566
+ return (0, neverthrow.ok)(this.createTypedHandle(handle, definition));
583
567
  } catch (error) {
584
- return _swan_io_boxed.Result.Error(createRuntimeClientError("getHandle", error));
568
+ return (0, neverthrow.err)(createRuntimeClientError("getHandle", error));
585
569
  }
586
570
  };
587
- return makeFuture(work);
571
+ return makeResultAsync(work);
588
572
  }
589
573
  createTypedHandle(workflowHandle, definition) {
590
574
  const queries = buildValidatedProxy({
@@ -623,18 +607,18 @@ var TypedClient = class TypedClient {
623
607
  try {
624
608
  const result = await workflowHandle.result();
625
609
  const outputResult = await definition.output["~standard"].validate(result);
626
- if (outputResult.issues) return _swan_io_boxed.Result.Error(new WorkflowValidationError(workflowHandle.workflowId, "output", outputResult.issues));
627
- return _swan_io_boxed.Result.Ok(outputResult.value);
610
+ if (outputResult.issues) return (0, neverthrow.err)(new WorkflowValidationError(workflowHandle.workflowId, "output", outputResult.issues));
611
+ return (0, neverthrow.ok)(outputResult.value);
628
612
  } catch (error) {
629
- return _swan_io_boxed.Result.Error(classifyResultError("result", error, workflowHandle.workflowId));
613
+ return (0, neverthrow.err)(classifyResultError("result", error, workflowHandle.workflowId));
630
614
  }
631
615
  };
632
- return makeFuture(work);
616
+ return makeResultAsync(work);
633
617
  },
634
- terminate: (reason) => _swan_io_boxed.Future.fromPromise(workflowHandle.terminate(reason)).mapError((error) => classifyHandleError("terminate", error, workflowHandle.workflowId)).mapOk(() => void 0),
635
- cancel: () => _swan_io_boxed.Future.fromPromise(workflowHandle.cancel()).mapError((error) => classifyHandleError("cancel", error, workflowHandle.workflowId)).mapOk(() => void 0),
636
- describe: () => _swan_io_boxed.Future.fromPromise(workflowHandle.describe()).mapError((error) => classifyHandleError("describe", error, workflowHandle.workflowId)),
637
- fetchHistory: () => _swan_io_boxed.Future.fromPromise(workflowHandle.fetchHistory()).mapError((error) => classifyHandleError("fetchHistory", error, workflowHandle.workflowId))
618
+ terminate: (reason) => neverthrow.ResultAsync.fromPromise(workflowHandle.terminate(reason), (error) => classifyHandleError("terminate", error, workflowHandle.workflowId)).map(() => void 0),
619
+ cancel: () => neverthrow.ResultAsync.fromPromise(workflowHandle.cancel(), (error) => classifyHandleError("cancel", error, workflowHandle.workflowId)).map(() => void 0),
620
+ describe: () => neverthrow.ResultAsync.fromPromise(workflowHandle.describe(), (error) => classifyHandleError("describe", error, workflowHandle.workflowId)),
621
+ fetchHistory: () => neverthrow.ResultAsync.fromPromise(workflowHandle.fetchHistory(), (error) => classifyHandleError("fetchHistory", error, workflowHandle.workflowId))
638
622
  };
639
623
  }
640
624
  };
@@ -648,7 +632,7 @@ function createWorkflowValidationError(workflowName, direction, issues) {
648
632
  return new WorkflowValidationError(String(workflowName), direction, issues);
649
633
  }
650
634
  /**
651
- * Build a `{ name: (args) => Future<Result<...>> }` proxy for a contract's
635
+ * Build a `{ name: (args) => ResultAsync<...> }` proxy for a contract's
652
636
  * queries/signals/updates. The three call sites differ only in how they
653
637
  * invoke Temporal and whether they validate output, so the shared
654
638
  * input-validate → invoke → output-validate → wrap-Result pipeline lives
@@ -660,19 +644,19 @@ function buildValidatedProxy({ defs, operation, workflowId, makeValidationError,
660
644
  for (const [name, def] of Object.entries(defs)) proxy[name] = (args) => {
661
645
  const work = async () => {
662
646
  const inputResult = await def.input["~standard"].validate(args);
663
- if (inputResult.issues) return _swan_io_boxed.Result.Error(makeValidationError(name, "input", inputResult.issues));
647
+ if (inputResult.issues) return (0, neverthrow.err)(makeValidationError(name, "input", inputResult.issues));
664
648
  try {
665
649
  const result = await invoke(name, inputResult.value);
666
650
  const outputSchema = validateOutput(def);
667
- if (!outputSchema) return _swan_io_boxed.Result.Ok(result);
651
+ if (!outputSchema) return (0, neverthrow.ok)(result);
668
652
  const outputResult = await outputSchema["~standard"].validate(result);
669
- if (outputResult.issues) return _swan_io_boxed.Result.Error(makeValidationError(name, "output", outputResult.issues));
670
- return _swan_io_boxed.Result.Ok(outputResult.value);
653
+ if (outputResult.issues) return (0, neverthrow.err)(makeValidationError(name, "output", outputResult.issues));
654
+ return (0, neverthrow.ok)(outputResult.value);
671
655
  } catch (error) {
672
- return _swan_io_boxed.Result.Error(classifyHandleError(operation, error, workflowId));
656
+ return (0, neverthrow.err)(classifyHandleError(operation, error, workflowId));
673
657
  }
674
658
  };
675
- return makeFuture(work);
659
+ return makeResultAsync(work);
676
660
  };
677
661
  return proxy;
678
662
  }