@temporal-contract/client 1.0.0 → 2.0.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,6 +1,6 @@
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
4
  let _temporalio_client = require("@temporalio/client");
5
5
  //#region src/errors.ts
6
6
  /**
@@ -192,21 +192,19 @@ var UpdateValidationError = class extends TypedClientError {
192
192
  * In-package modules and tests import it directly via relative path.
193
193
  */
194
194
  /**
195
- * Wrap an async result-producing function in a `Future`, catching any
195
+ * Wrap an async result-producing function in a `ResultAsync`, catching any
196
196
  * unhandled rejection as a `RuntimeClientError("unexpected", error)`.
197
197
  *
198
198
  * 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.
199
+ * an `err(...)` for them; the catch here is a safety net for thrown
200
+ * exceptions the work didn't anticipate.
201
201
  *
202
202
  * Used by `client.ts` (workflow operations) and `schedule.ts` (schedule
203
203
  * operations) so the unexpected-rejection shape is identical across the
204
204
  * typed client surface.
205
205
  */
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
- });
206
+ function makeResultAsync(work) {
207
+ return new neverthrow.ResultAsync(work().catch((e) => (0, neverthrow.err)(new RuntimeClientError("unexpected", e))));
210
208
  }
211
209
  /**
212
210
  * Map a thrown error from `client.workflow.start` / `signalWithStart` into
@@ -275,9 +273,9 @@ var TypedScheduleClient = class {
275
273
  create(workflowName, options) {
276
274
  const work = async () => {
277
275
  const definition = this.contract.workflows[workflowName];
278
- if (!definition) return _swan_io_boxed.Result.Error(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows)));
276
+ if (!definition) return (0, neverthrow.err)(new WorkflowNotFoundError(String(workflowName), Object.keys(this.contract.workflows)));
279
277
  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));
278
+ if (inputResult.issues) return (0, neverthrow.err)(new WorkflowValidationError(String(workflowName), "input", inputResult.issues));
281
279
  try {
282
280
  const overrides = options.action ?? {};
283
281
  const action = {
@@ -294,20 +292,19 @@ var TypedScheduleClient = class {
294
292
  ...overrides.staticDetails !== void 0 ? { staticDetails: overrides.staticDetails } : {},
295
293
  ...overrides.staticSummary !== void 0 ? { staticSummary: overrides.staticSummary } : {}
296
294
  };
297
- const handle = await this.scheduleClient.create({
295
+ return (0, neverthrow.ok)(wrapScheduleHandle(await this.scheduleClient.create({
298
296
  scheduleId: options.scheduleId,
299
297
  spec: options.spec,
300
298
  action,
301
299
  ...options.policies !== void 0 ? { policies: options.policies } : {},
302
300
  ...options.state !== void 0 ? { state: options.state } : {},
303
301
  ...options.memo !== void 0 ? { memo: options.memo } : {}
304
- });
305
- return _swan_io_boxed.Result.Ok(wrapScheduleHandle(handle));
302
+ })));
306
303
  } catch (error) {
307
- return _swan_io_boxed.Result.Error(new RuntimeClientError("schedule.create", error));
304
+ return (0, neverthrow.err)(new RuntimeClientError("schedule.create", error));
308
305
  }
309
306
  };
310
- return makeFuture(work);
307
+ return makeResultAsync(work);
311
308
  }
312
309
  /**
313
310
  * Get a typed handle to an existing schedule. Does not validate that the
@@ -321,11 +318,11 @@ var TypedScheduleClient = class {
321
318
  function wrapScheduleHandle(handle) {
322
319
  return {
323
320
  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))
321
+ pause: (note) => neverthrow.ResultAsync.fromPromise(handle.pause(note), (error) => new RuntimeClientError("schedule.pause", error)).map(() => void 0),
322
+ unpause: (note) => neverthrow.ResultAsync.fromPromise(handle.unpause(note), (error) => new RuntimeClientError("schedule.unpause", error)).map(() => void 0),
323
+ trigger: (overlap) => neverthrow.ResultAsync.fromPromise(handle.trigger(overlap), (error) => new RuntimeClientError("schedule.trigger", error)).map(() => void 0),
324
+ delete: () => neverthrow.ResultAsync.fromPromise(handle.delete(), (error) => new RuntimeClientError("schedule.delete", error)).map(() => void 0),
325
+ describe: () => neverthrow.ResultAsync.fromPromise(handle.describe(), (error) => new RuntimeClientError("schedule.describe", error))
329
326
  };
330
327
  }
331
328
  //#endregion
@@ -355,7 +352,7 @@ function toTypedSearchAttributes(workflowDef, values) {
355
352
  return pairs.length > 0 ? new _temporalio_common.TypedSearchAttributes(pairs) : void 0;
356
353
  }
357
354
  /**
358
- * Typed Temporal client with Result/Future pattern based on a contract
355
+ * Typed Temporal client with neverthrow Result/ResultAsync pattern based on a contract
359
356
  *
360
357
  * Provides type-safe methods to start and execute workflows
361
358
  * defined in the contract, with explicit error handling using Result pattern.
@@ -379,10 +376,10 @@ var TypedClient = class TypedClient {
379
376
  * args: { orderId: "sweep" },
380
377
  * });
381
378
  *
382
- * result.match({
383
- * Ok: async (handle) => { await handle.pause("maintenance"); },
384
- * Error: (error) => console.error("schedule create failed", error),
385
- * });
379
+ * result.match(
380
+ * async (handle) => { await handle.pause("maintenance"); },
381
+ * (error) => console.error("schedule create failed", error),
382
+ * );
386
383
  * ```
387
384
  */
388
385
  schedule;
@@ -393,7 +390,7 @@ var TypedClient = class TypedClient {
393
390
  this.schedule = new TypedScheduleClient(contract, client.schedule);
394
391
  }
395
392
  /**
396
- * Create a typed Temporal client with boxed pattern from a contract
393
+ * Create a typed Temporal client with neverthrow pattern from a contract
397
394
  *
398
395
  * @example
399
396
  * ```ts
@@ -406,17 +403,17 @@ var TypedClient = class TypedClient {
406
403
  * args: { ... },
407
404
  * });
408
405
  *
409
- * result.match({
410
- * Ok: (output) => console.log('Success:', output),
411
- * Error: (error) => console.error('Failed:', error),
412
- * });
406
+ * result.match(
407
+ * (output) => console.log('Success:', output),
408
+ * (error) => console.error('Failed:', error),
409
+ * );
413
410
  * ```
414
411
  */
415
412
  static create(contract, client) {
416
413
  return new TypedClient(contract, client);
417
414
  }
418
415
  /**
419
- * Start a workflow and return a typed handle with Future pattern
416
+ * Start a workflow and return a typed handle with ResultAsync pattern
420
417
  *
421
418
  * @example
422
419
  * ```ts
@@ -427,21 +424,21 @@ var TypedClient = class TypedClient {
427
424
  * retry: { maximumAttempts: 3 },
428
425
  * });
429
426
  *
430
- * handleResult.match({
431
- * Ok: async (handle) => {
427
+ * handleResult.match(
428
+ * async (handle) => {
432
429
  * const result = await handle.result();
433
430
  * // ... handle result
434
431
  * },
435
- * Error: (error) => console.error('Failed to start:', error),
436
- * });
432
+ * (error) => console.error('Failed to start:', error),
433
+ * );
437
434
  * ```
438
435
  */
439
436
  startWorkflow(workflowName, { args, searchAttributes, ...temporalOptions }) {
440
437
  const work = async () => {
441
438
  const definition = this.contract.workflows[workflowName];
442
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
439
+ if (!definition) return (0, neverthrow.err)(createWorkflowNotFoundError(workflowName, this.contract));
443
440
  const inputResult = await definition.input["~standard"].validate(args);
444
- if (inputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues));
441
+ if (inputResult.issues) return (0, neverthrow.err)(createWorkflowValidationError(workflowName, "input", inputResult.issues));
445
442
  const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
446
443
  try {
447
444
  const handle = await this.client.workflow.start(workflowName, {
@@ -450,12 +447,12 @@ var TypedClient = class TypedClient {
450
447
  args: [inputResult.value],
451
448
  ...typedSearchAttributes ? { typedSearchAttributes } : {}
452
449
  });
453
- return _swan_io_boxed.Result.Ok(this.createTypedHandle(handle, definition));
450
+ return (0, neverthrow.ok)(this.createTypedHandle(handle, definition));
454
451
  } catch (error) {
455
- return _swan_io_boxed.Result.Error(classifyStartError("startWorkflow", error));
452
+ return (0, neverthrow.err)(classifyStartError("startWorkflow", error));
456
453
  }
457
454
  };
458
- return makeFuture(work);
455
+ return makeResultAsync(work);
459
456
  }
460
457
  /**
461
458
  * Send a signal to a workflow, starting it first if it doesn't already exist.
@@ -477,22 +474,22 @@ var TypedClient = class TypedClient {
477
474
  * signalArgs: { reason: 'duplicate' },
478
475
  * });
479
476
  *
480
- * result.match({
481
- * Ok: (handle) => console.log('signaled run', handle.signaledRunId),
482
- * Error: (error) => console.error('signalWithStart failed', error),
483
- * });
477
+ * result.match(
478
+ * (handle) => console.log('signaled run', handle.signaledRunId),
479
+ * (error) => console.error('signalWithStart failed', error),
480
+ * );
484
481
  * ```
485
482
  */
486
483
  signalWithStart(workflowName, { args, signalName, signalArgs, searchAttributes, ...temporalOptions }) {
487
484
  const work = async () => {
488
485
  const definition = this.contract.workflows[workflowName];
489
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
486
+ if (!definition) return (0, neverthrow.err)(createWorkflowNotFoundError(workflowName, this.contract));
490
487
  const inputResult = await definition.input["~standard"].validate(args);
491
- if (inputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues));
488
+ if (inputResult.issues) return (0, neverthrow.err)(createWorkflowValidationError(workflowName, "input", inputResult.issues));
492
489
  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)}".` }]));
490
+ if (!signalDef) return (0, neverthrow.err)(new SignalValidationError(signalName, [{ message: `Signal "${signalName}" is not declared on workflow "${String(workflowName)}".` }]));
494
491
  const signalInputResult = await signalDef.input["~standard"].validate(signalArgs);
495
- if (signalInputResult.issues) return _swan_io_boxed.Result.Error(new SignalValidationError(signalName, signalInputResult.issues));
492
+ if (signalInputResult.issues) return (0, neverthrow.err)(new SignalValidationError(signalName, signalInputResult.issues));
496
493
  const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
497
494
  try {
498
495
  const handle = await this.client.workflow.signalWithStart(workflowName, {
@@ -503,19 +500,18 @@ var TypedClient = class TypedClient {
503
500
  signalArgs: [signalInputResult.value],
504
501
  ...typedSearchAttributes ? { typedSearchAttributes } : {}
505
502
  });
506
- const typed = this.createTypedHandle(handle, definition);
507
- return _swan_io_boxed.Result.Ok({
508
- ...typed,
503
+ return (0, neverthrow.ok)({
504
+ ...this.createTypedHandle(handle, definition),
509
505
  signaledRunId: handle.signaledRunId
510
506
  });
511
507
  } catch (error) {
512
- return _swan_io_boxed.Result.Error(classifyStartError("signalWithStart", error));
508
+ return (0, neverthrow.err)(classifyStartError("signalWithStart", error));
513
509
  }
514
510
  };
515
- return makeFuture(work);
511
+ return makeResultAsync(work);
516
512
  }
517
513
  /**
518
- * Execute a workflow (start and wait for result) with Future/Result pattern
514
+ * Execute a workflow (start and wait for result) with ResultAsync pattern
519
515
  *
520
516
  * @example
521
517
  * ```ts
@@ -526,18 +522,18 @@ var TypedClient = class TypedClient {
526
522
  * retry: { maximumAttempts: 3 },
527
523
  * });
528
524
  *
529
- * result.match({
530
- * Ok: (output) => console.log('Order processed:', output.status),
531
- * Error: (error) => console.error('Processing failed:', error),
532
- * });
525
+ * result.match(
526
+ * (output) => console.log('Order processed:', output.status),
527
+ * (error) => console.error('Processing failed:', error),
528
+ * );
533
529
  * ```
534
530
  */
535
531
  executeWorkflow(workflowName, { args, searchAttributes, ...temporalOptions }) {
536
532
  const work = async () => {
537
533
  const definition = this.contract.workflows[workflowName];
538
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
534
+ if (!definition) return (0, neverthrow.err)(createWorkflowNotFoundError(workflowName, this.contract));
539
535
  const inputResult = await definition.input["~standard"].validate(args);
540
- if (inputResult.issues) return _swan_io_boxed.Result.Error(createWorkflowValidationError(workflowName, "input", inputResult.issues));
536
+ if (inputResult.issues) return (0, neverthrow.err)(createWorkflowValidationError(workflowName, "input", inputResult.issues));
541
537
  const typedSearchAttributes = toTypedSearchAttributes(definition, searchAttributes);
542
538
  try {
543
539
  const result = await this.client.workflow.execute(workflowName, {
@@ -547,44 +543,44 @@ var TypedClient = class TypedClient {
547
543
  ...typedSearchAttributes ? { typedSearchAttributes } : {}
548
544
  });
549
545
  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);
546
+ if (outputResult.issues) return (0, neverthrow.err)(createWorkflowValidationError(workflowName, "output", outputResult.issues));
547
+ return (0, neverthrow.ok)(outputResult.value);
552
548
  } 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));
549
+ if (error instanceof _temporalio_client.WorkflowExecutionAlreadyStartedError) return (0, neverthrow.err)(new WorkflowAlreadyStartedError(error.workflowType, error.workflowId, error));
550
+ if (error instanceof _temporalio_client.WorkflowFailedError) return (0, neverthrow.err)(new WorkflowFailedError(temporalOptions.workflowId, error.cause));
551
+ if (error instanceof _temporalio_common.WorkflowNotFoundError) return (0, neverthrow.err)(new WorkflowExecutionNotFoundError(error.workflowId || temporalOptions.workflowId, error.runId, error));
552
+ return (0, neverthrow.err)(createRuntimeClientError("executeWorkflow", error));
557
553
  }
558
554
  };
559
- return makeFuture(work);
555
+ return makeResultAsync(work);
560
556
  }
561
557
  /**
562
- * Get a handle to an existing workflow with Future/Result pattern
558
+ * Get a handle to an existing workflow with ResultAsync pattern
563
559
  *
564
560
  * @example
565
561
  * ```ts
566
562
  * const handleResult = await client.getHandle('processOrder', 'order-123');
567
- * handleResult.match({
568
- * Ok: async (handle) => {
563
+ * handleResult.match(
564
+ * async (handle) => {
569
565
  * const result = await handle.result();
570
566
  * // ... handle result
571
567
  * },
572
- * Error: (error) => console.error('Failed to get handle:', error),
573
- * });
568
+ * (error) => console.error('Failed to get handle:', error),
569
+ * );
574
570
  * ```
575
571
  */
576
572
  getHandle(workflowName, workflowId) {
577
573
  const work = async () => {
578
574
  const definition = this.contract.workflows[workflowName];
579
- if (!definition) return _swan_io_boxed.Result.Error(createWorkflowNotFoundError(workflowName, this.contract));
575
+ if (!definition) return (0, neverthrow.err)(createWorkflowNotFoundError(workflowName, this.contract));
580
576
  try {
581
577
  const handle = this.client.workflow.getHandle(workflowId);
582
- return _swan_io_boxed.Result.Ok(this.createTypedHandle(handle, definition));
578
+ return (0, neverthrow.ok)(this.createTypedHandle(handle, definition));
583
579
  } catch (error) {
584
- return _swan_io_boxed.Result.Error(createRuntimeClientError("getHandle", error));
580
+ return (0, neverthrow.err)(createRuntimeClientError("getHandle", error));
585
581
  }
586
582
  };
587
- return makeFuture(work);
583
+ return makeResultAsync(work);
588
584
  }
589
585
  createTypedHandle(workflowHandle, definition) {
590
586
  const queries = buildValidatedProxy({
@@ -623,18 +619,18 @@ var TypedClient = class TypedClient {
623
619
  try {
624
620
  const result = await workflowHandle.result();
625
621
  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);
622
+ if (outputResult.issues) return (0, neverthrow.err)(new WorkflowValidationError(workflowHandle.workflowId, "output", outputResult.issues));
623
+ return (0, neverthrow.ok)(outputResult.value);
628
624
  } catch (error) {
629
- return _swan_io_boxed.Result.Error(classifyResultError("result", error, workflowHandle.workflowId));
625
+ return (0, neverthrow.err)(classifyResultError("result", error, workflowHandle.workflowId));
630
626
  }
631
627
  };
632
- return makeFuture(work);
628
+ return makeResultAsync(work);
633
629
  },
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))
630
+ terminate: (reason) => neverthrow.ResultAsync.fromPromise(workflowHandle.terminate(reason), (error) => classifyHandleError("terminate", error, workflowHandle.workflowId)).map(() => void 0),
631
+ cancel: () => neverthrow.ResultAsync.fromPromise(workflowHandle.cancel(), (error) => classifyHandleError("cancel", error, workflowHandle.workflowId)).map(() => void 0),
632
+ describe: () => neverthrow.ResultAsync.fromPromise(workflowHandle.describe(), (error) => classifyHandleError("describe", error, workflowHandle.workflowId)),
633
+ fetchHistory: () => neverthrow.ResultAsync.fromPromise(workflowHandle.fetchHistory(), (error) => classifyHandleError("fetchHistory", error, workflowHandle.workflowId))
638
634
  };
639
635
  }
640
636
  };
@@ -648,7 +644,7 @@ function createWorkflowValidationError(workflowName, direction, issues) {
648
644
  return new WorkflowValidationError(String(workflowName), direction, issues);
649
645
  }
650
646
  /**
651
- * Build a `{ name: (args) => Future<Result<...>> }` proxy for a contract's
647
+ * Build a `{ name: (args) => ResultAsync<...> }` proxy for a contract's
652
648
  * queries/signals/updates. The three call sites differ only in how they
653
649
  * invoke Temporal and whether they validate output, so the shared
654
650
  * input-validate → invoke → output-validate → wrap-Result pipeline lives
@@ -660,19 +656,19 @@ function buildValidatedProxy({ defs, operation, workflowId, makeValidationError,
660
656
  for (const [name, def] of Object.entries(defs)) proxy[name] = (args) => {
661
657
  const work = async () => {
662
658
  const inputResult = await def.input["~standard"].validate(args);
663
- if (inputResult.issues) return _swan_io_boxed.Result.Error(makeValidationError(name, "input", inputResult.issues));
659
+ if (inputResult.issues) return (0, neverthrow.err)(makeValidationError(name, "input", inputResult.issues));
664
660
  try {
665
661
  const result = await invoke(name, inputResult.value);
666
662
  const outputSchema = validateOutput(def);
667
- if (!outputSchema) return _swan_io_boxed.Result.Ok(result);
663
+ if (!outputSchema) return (0, neverthrow.ok)(result);
668
664
  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);
665
+ if (outputResult.issues) return (0, neverthrow.err)(makeValidationError(name, "output", outputResult.issues));
666
+ return (0, neverthrow.ok)(outputResult.value);
671
667
  } catch (error) {
672
- return _swan_io_boxed.Result.Error(classifyHandleError(operation, error, workflowId));
668
+ return (0, neverthrow.err)(classifyHandleError(operation, error, workflowId));
673
669
  }
674
670
  };
675
- return makeFuture(work);
671
+ return makeResultAsync(work);
676
672
  };
677
673
  return proxy;
678
674
  }