Skip to content

Releases: btravstack/temporal-contract

@temporal-contract/worker@4.0.0

27 Jun 22:47

Choose a tag to compare

Major Changes

  • ebf7683: Upgrade to unthrown 1.0.0.

    unthrown 1.0.0 renames the result constructors to PascalCase: okOk, errErr, defectDefect. All packages are updated, and the unthrown peer-dependency range moves to ^1.

    Breaking for consumers who construct results directly (e.g. in activity implementations): replace ok(value) / err(failure) with Ok(value) / Err(failure) (and ok(value).toAsync() / err(failure).toAsync() at promise boundaries), and bump unthrown to ^1. The result.match({ ok, err, defect }) handler keys are unchanged (they are object keys, not constructors), and matchTags / TaggedError / fromPromise / fromSafePromise / .toAsync() and the result.isOk() / isErr() / isDefect() narrowing are all unchanged.

    See the Migrating from neverthrow guide.

Patch Changes

  • Updated dependencies [ebf7683]
    • @temporal-contract/contract@4.0.0

@temporal-contract/worker@3.0.0

27 Jun 00:01

Choose a tag to compare

Major Changes

  • 8d0750f: Replace neverthrow with unthrown for the Result/error-handling spine across all packages. This is a breaking change to the public API.

    What changed

    • ResultAsync<T, E>AsyncResult<T, E>. Every activity, workflow-context, child-workflow, schedule, and typed-client method that returned a ResultAsync now returns an AsyncResult. The unthrown peer dependency replaces neverthrow.
    • No okAsync / errAsync. Lift a synchronous Result with .toAsync() instead: ok(value).toAsync(), err(failure).toAsync(). Promise boundaries use fromPromise(promise, qualify) / fromSafePromise(promise).
    • Narrow before accessing the payload. Both the result.isOk() / isErr() / isDefect() methods and the matching free functions isOk(result) / isErr(result) / isDefect(result) (imported from unthrown) are type guards; the codebase uses the methods. Narrow before touching .value / .error / .cause.
    • New defect channel. Unanticipated throws (a thrown exception the code did not model) now surface on unthrown's third defect channel — inspected via result.isDefect() / result.cause and re-thrown at the edge — rather than as a typed err. Deliberate boundary classification (e.g. mapping a Temporal SDK rejection to WorkflowExecutionNotFoundError) still produces a modeled err. result.match({ ok, err, defect }) folds all three.
    • WorkflowScopeError removed. Non-cancellation errors thrown inside cancellableScope / nonCancellableScope are unmodeled failures and now ride the defect channel. The scopes' error union narrows to WorkflowCancelledError.
    • The client's "unexpected" RuntimeClientError wrap is gone. An unanticipated rejection in a client operation now surfaces as a defect, not a manufactured RuntimeClientError. RuntimeClientError is still produced by deliberate boundary classification.
    • Error classes use TaggedError. The worker WorkerError hierarchy and the entire client TypedClientError hierarchy are now built with unthrown's TaggedError, each carrying a _tag discriminant (foldable with matchTags). The _tag is package-namespaced — e.g. "@temporal-contract/WorkflowExecutionNotFoundError" — so it never collides with a consumer's own tags; each error's .name stays the bare class name for readable logs. ChildWorkflowCancelledError is now a sibling of ChildWorkflowError (distinct _tag) rather than a subclass — discriminate on _tag / instanceof ChildWorkflowCancelledError instead of relying on instanceof ChildWorkflowError matching cancellation. The worker's ValidationError subclasses are unchanged — they still extend Temporal's ApplicationFailure for terminal-failure semantics.

    See the Migrating from neverthrow guide.

Patch Changes

  • Updated dependencies [8d0750f]
    • @temporal-contract/contract@3.0.0

@temporal-contract/testing@4.0.0

27 Jun 22:47

Choose a tag to compare

Major Changes

  • ebf7683: Upgrade to unthrown 1.0.0.

    unthrown 1.0.0 renames the result constructors to PascalCase: okOk, errErr, defectDefect. All packages are updated, and the unthrown peer-dependency range moves to ^1.

    Breaking for consumers who construct results directly (e.g. in activity implementations): replace ok(value) / err(failure) with Ok(value) / Err(failure) (and ok(value).toAsync() / err(failure).toAsync() at promise boundaries), and bump unthrown to ^1. The result.match({ ok, err, defect }) handler keys are unchanged (they are object keys, not constructors), and matchTags / TaggedError / fromPromise / fromSafePromise / .toAsync() and the result.isOk() / isErr() / isDefect() narrowing are all unchanged.

    See the Migrating from neverthrow guide.

@temporal-contract/testing@3.0.0

27 Jun 00:01

Choose a tag to compare

Major Changes

  • 8d0750f: Replace neverthrow with unthrown for the Result/error-handling spine across all packages. This is a breaking change to the public API.

    What changed

    • ResultAsync<T, E>AsyncResult<T, E>. Every activity, workflow-context, child-workflow, schedule, and typed-client method that returned a ResultAsync now returns an AsyncResult. The unthrown peer dependency replaces neverthrow.
    • No okAsync / errAsync. Lift a synchronous Result with .toAsync() instead: ok(value).toAsync(), err(failure).toAsync(). Promise boundaries use fromPromise(promise, qualify) / fromSafePromise(promise).
    • Narrow before accessing the payload. Both the result.isOk() / isErr() / isDefect() methods and the matching free functions isOk(result) / isErr(result) / isDefect(result) (imported from unthrown) are type guards; the codebase uses the methods. Narrow before touching .value / .error / .cause.
    • New defect channel. Unanticipated throws (a thrown exception the code did not model) now surface on unthrown's third defect channel — inspected via result.isDefect() / result.cause and re-thrown at the edge — rather than as a typed err. Deliberate boundary classification (e.g. mapping a Temporal SDK rejection to WorkflowExecutionNotFoundError) still produces a modeled err. result.match({ ok, err, defect }) folds all three.
    • WorkflowScopeError removed. Non-cancellation errors thrown inside cancellableScope / nonCancellableScope are unmodeled failures and now ride the defect channel. The scopes' error union narrows to WorkflowCancelledError.
    • The client's "unexpected" RuntimeClientError wrap is gone. An unanticipated rejection in a client operation now surfaces as a defect, not a manufactured RuntimeClientError. RuntimeClientError is still produced by deliberate boundary classification.
    • Error classes use TaggedError. The worker WorkerError hierarchy and the entire client TypedClientError hierarchy are now built with unthrown's TaggedError, each carrying a _tag discriminant (foldable with matchTags). The _tag is package-namespaced — e.g. "@temporal-contract/WorkflowExecutionNotFoundError" — so it never collides with a consumer's own tags; each error's .name stays the bare class name for readable logs. ChildWorkflowCancelledError is now a sibling of ChildWorkflowError (distinct _tag) rather than a subclass — discriminate on _tag / instanceof ChildWorkflowCancelledError instead of relying on instanceof ChildWorkflowError matching cancellation. The worker's ValidationError subclasses are unchanged — they still extend Temporal's ApplicationFailure for terminal-failure semantics.

    See the Migrating from neverthrow guide.

@temporal-contract/contract@4.0.0

27 Jun 22:48

Choose a tag to compare

Major Changes

  • ebf7683: Upgrade to unthrown 1.0.0.

    unthrown 1.0.0 renames the result constructors to PascalCase: okOk, errErr, defectDefect. All packages are updated, and the unthrown peer-dependency range moves to ^1.

    Breaking for consumers who construct results directly (e.g. in activity implementations): replace ok(value) / err(failure) with Ok(value) / Err(failure) (and ok(value).toAsync() / err(failure).toAsync() at promise boundaries), and bump unthrown to ^1. The result.match({ ok, err, defect }) handler keys are unchanged (they are object keys, not constructors), and matchTags / TaggedError / fromPromise / fromSafePromise / .toAsync() and the result.isOk() / isErr() / isDefect() narrowing are all unchanged.

    See the Migrating from neverthrow guide.

@temporal-contract/contract@3.0.0

27 Jun 00:01

Choose a tag to compare

Major Changes

  • 8d0750f: Replace neverthrow with unthrown for the Result/error-handling spine across all packages. This is a breaking change to the public API.

    What changed

    • ResultAsync<T, E>AsyncResult<T, E>. Every activity, workflow-context, child-workflow, schedule, and typed-client method that returned a ResultAsync now returns an AsyncResult. The unthrown peer dependency replaces neverthrow.
    • No okAsync / errAsync. Lift a synchronous Result with .toAsync() instead: ok(value).toAsync(), err(failure).toAsync(). Promise boundaries use fromPromise(promise, qualify) / fromSafePromise(promise).
    • Narrow before accessing the payload. Both the result.isOk() / isErr() / isDefect() methods and the matching free functions isOk(result) / isErr(result) / isDefect(result) (imported from unthrown) are type guards; the codebase uses the methods. Narrow before touching .value / .error / .cause.
    • New defect channel. Unanticipated throws (a thrown exception the code did not model) now surface on unthrown's third defect channel — inspected via result.isDefect() / result.cause and re-thrown at the edge — rather than as a typed err. Deliberate boundary classification (e.g. mapping a Temporal SDK rejection to WorkflowExecutionNotFoundError) still produces a modeled err. result.match({ ok, err, defect }) folds all three.
    • WorkflowScopeError removed. Non-cancellation errors thrown inside cancellableScope / nonCancellableScope are unmodeled failures and now ride the defect channel. The scopes' error union narrows to WorkflowCancelledError.
    • The client's "unexpected" RuntimeClientError wrap is gone. An unanticipated rejection in a client operation now surfaces as a defect, not a manufactured RuntimeClientError. RuntimeClientError is still produced by deliberate boundary classification.
    • Error classes use TaggedError. The worker WorkerError hierarchy and the entire client TypedClientError hierarchy are now built with unthrown's TaggedError, each carrying a _tag discriminant (foldable with matchTags). The _tag is package-namespaced — e.g. "@temporal-contract/WorkflowExecutionNotFoundError" — so it never collides with a consumer's own tags; each error's .name stays the bare class name for readable logs. ChildWorkflowCancelledError is now a sibling of ChildWorkflowError (distinct _tag) rather than a subclass — discriminate on _tag / instanceof ChildWorkflowCancelledError instead of relying on instanceof ChildWorkflowError matching cancellation. The worker's ValidationError subclasses are unchanged — they still extend Temporal's ApplicationFailure for terminal-failure semantics.

    See the Migrating from neverthrow guide.

@temporal-contract/client@4.0.0

27 Jun 22:47

Choose a tag to compare

Major Changes

  • ebf7683: Upgrade to unthrown 1.0.0.

    unthrown 1.0.0 renames the result constructors to PascalCase: okOk, errErr, defectDefect. All packages are updated, and the unthrown peer-dependency range moves to ^1.

    Breaking for consumers who construct results directly (e.g. in activity implementations): replace ok(value) / err(failure) with Ok(value) / Err(failure) (and ok(value).toAsync() / err(failure).toAsync() at promise boundaries), and bump unthrown to ^1. The result.match({ ok, err, defect }) handler keys are unchanged (they are object keys, not constructors), and matchTags / TaggedError / fromPromise / fromSafePromise / .toAsync() and the result.isOk() / isErr() / isDefect() narrowing are all unchanged.

    See the Migrating from neverthrow guide.

Patch Changes

  • Updated dependencies [ebf7683]
    • @temporal-contract/contract@4.0.0

@temporal-contract/client@3.0.0

27 Jun 00:01

Choose a tag to compare

Major Changes

  • 8d0750f: Replace neverthrow with unthrown for the Result/error-handling spine across all packages. This is a breaking change to the public API.

    What changed

    • ResultAsync<T, E>AsyncResult<T, E>. Every activity, workflow-context, child-workflow, schedule, and typed-client method that returned a ResultAsync now returns an AsyncResult. The unthrown peer dependency replaces neverthrow.
    • No okAsync / errAsync. Lift a synchronous Result with .toAsync() instead: ok(value).toAsync(), err(failure).toAsync(). Promise boundaries use fromPromise(promise, qualify) / fromSafePromise(promise).
    • Narrow before accessing the payload. Both the result.isOk() / isErr() / isDefect() methods and the matching free functions isOk(result) / isErr(result) / isDefect(result) (imported from unthrown) are type guards; the codebase uses the methods. Narrow before touching .value / .error / .cause.
    • New defect channel. Unanticipated throws (a thrown exception the code did not model) now surface on unthrown's third defect channel — inspected via result.isDefect() / result.cause and re-thrown at the edge — rather than as a typed err. Deliberate boundary classification (e.g. mapping a Temporal SDK rejection to WorkflowExecutionNotFoundError) still produces a modeled err. result.match({ ok, err, defect }) folds all three.
    • WorkflowScopeError removed. Non-cancellation errors thrown inside cancellableScope / nonCancellableScope are unmodeled failures and now ride the defect channel. The scopes' error union narrows to WorkflowCancelledError.
    • The client's "unexpected" RuntimeClientError wrap is gone. An unanticipated rejection in a client operation now surfaces as a defect, not a manufactured RuntimeClientError. RuntimeClientError is still produced by deliberate boundary classification.
    • Error classes use TaggedError. The worker WorkerError hierarchy and the entire client TypedClientError hierarchy are now built with unthrown's TaggedError, each carrying a _tag discriminant (foldable with matchTags). The _tag is package-namespaced — e.g. "@temporal-contract/WorkflowExecutionNotFoundError" — so it never collides with a consumer's own tags; each error's .name stays the bare class name for readable logs. ChildWorkflowCancelledError is now a sibling of ChildWorkflowError (distinct _tag) rather than a subclass — discriminate on _tag / instanceof ChildWorkflowCancelledError instead of relying on instanceof ChildWorkflowError matching cancellation. The worker's ValidationError subclasses are unchanged — they still extend Temporal's ApplicationFailure for terminal-failure semantics.

    See the Migrating from neverthrow guide.

Patch Changes

  • Updated dependencies [8d0750f]
    • @temporal-contract/contract@3.0.0

@temporal-contract/worker@2.4.0

22 Jun 08:57

Choose a tag to compare

Minor Changes

  • eae7aae: Declare engines.node: ">=22.19.0" on every published package. The floor is set by undici@8 (pulled in transitively by testcontainers via @temporal-contract/testing), which already fails at runtime on Node ≤22.18 — the engines field just surfaces that reality at install time so consumers get a clear signal instead of a stack trace. Also bumps @temporalio/* 1.18.0 → 1.18.1 and testcontainers 12.0.1 → 12.0.2 in the catalog.

  • 2c18aa4: Make contract validation failures fail the execution terminally instead of hanging the workflow.

    Previously, the worker's runtime validation errors (WorkflowInputValidationError, WorkflowOutputValidationError, ActivityInputValidationError, ActivityOutputValidationError, and the signal/query/update equivalents) were plain Errors. The TypeScript SDK classifies a non-TemporalFailure thrown from workflow code as a Workflow Task failure and retries it indefinitely, so a deterministic validation failure produced a silently hung workflow (stuck Running, only a repeating WorkflowTaskFailed event) rather than a failed execution. The same hazard applied at the activity boundary, where Temporal's default retry policy is unlimited. See #251.

    These error classes now extend Temporal's ApplicationFailure with nonRetryable: true. Because contract schemas are static, a validation failure can never pass on retry, so the execution now fails fast and terminally with a WorkflowExecutionFailed event. The concrete error name is preserved as the failure type (e.g. "WorkflowInputValidationError"), so it stays discriminable via failure.type after crossing Temporal's serialization boundary, and the failing field path remains in the human-readable message.

    The error classes keep their names and identity, so existing instanceof WorkflowInputValidationError checks (and the new shared ValidationError base, now exported from @temporal-contract/worker/workflow and /activity) continue to work. If you previously wrapped declareWorkflow(...) to rethrow these as ApplicationFailure.nonRetryable yourself, that workaround is no longer needed.

Patch Changes

  • Updated dependencies [eae7aae]
    • @temporal-contract/contract@2.4.0

@temporal-contract/testing@2.4.0

22 Jun 08:57

Choose a tag to compare

Minor Changes

  • eae7aae: Declare engines.node: ">=22.19.0" on every published package. The floor is set by undici@8 (pulled in transitively by testcontainers via @temporal-contract/testing), which already fails at runtime on Node ≤22.18 — the engines field just surfaces that reality at install time so consumers get a clear signal instead of a stack trace. Also bumps @temporalio/* 1.18.0 → 1.18.1 and testcontainers 12.0.1 → 12.0.2 in the catalog.