Skip to content

Releases: temporalio/sdk-typescript

v1.9.3

23 Feb 23:20
Compare
Choose a tag to compare

Bug fixes

  • Fix deprecated patch removal when no subsequent command (temporalio/sdk-core#671).
  • Fix incorrect ordering of a query execution that could happen if new workflow tasks came in while there were buffered queries (temporalio/sdk-core#673).
  • Fix a possibility of sending local activity marker after the Workflow Task Complete command (temporalio/sdk-core#678).
  • Wait for activity completes to reach server before shutdown (temporalio/sdk-core#681).
  • Update protobuf definitions to work with the new EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_REQUESTED event (temporalio/sdk-core#677).
  • Fix a regression regarding gRPC incoming message limit due to a behavior change in tonic 0.9.0.

Documentation

  • Avoid doctype reexports canonicalization issue (#1354)

Miscellaneous Tasks

  • Add test for module property mutation isolation (#1356)

v1.9.1

08 Feb 00:10
4d87689
Compare
Choose a tag to compare

Bug Fixes

  • [worker] Fix prometheus and otel regressions (#1345)
  • Fix devDependencies in some of the SDK packages where file URLs were used instead of version numbers.

Documentation

  • Add note on custom conveters and bundleWorkflowCode (#1338)
  • Fix sort order + snipsync examples issue (#1341)
  • [worker] Update webpack error doc link in worker/bundler.ts (#1344)
  • Explain the purpose of updateId (#1318)

Features

  • [worker] Add a workflow metadata query (#1319)

v1.9.0

12 Jan 17:25
Compare
Choose a tag to compare

Important updates

  • The reuseV8Context worker option is now enabled by default. This major optimization of the Workflow sandboxing runtime significantly reduces RAM and CPU usage, without compromising the safety of the deterministic sandbox. You may still revert to the legacy execution model by adding reuseV8Context: false to your worker options.

    Note that support for the legacy, non-reuseV8Context execution model may be removed at some point in the future. Please reach out if you find any issue that requires disabling reuseV8Context.

  • Support for Node.js 14 and Node.js 16 will soon be dropped. Node.js 14 officially reached end-of-life on April 30th, 2023, and Node.js 16 reached end-of-life on September 11th, 2023 (see Node.js release schedule).

    This has since then caused a rippling effect, as more and more libraries in the NPM ecosystem are progressively dropping support for both of those older targets. Given that challenges to maintaining compatibility with these outdated Node.js releases will only continue to grow, it is evident that we will soon need to follow suit in discontinuing support for Node.js 14 and 16 in the Temporal TypeScript SDK.

    For those reasons:

    • TS SDK v1.9 will be the last minor release to support Node.js 14.
    • TS SDK v1.10 could possibly be the last minor release to support Node.js 16. Note that this also implies that GLIBC 2.27 will no longer be supported from that point on, since Node.js 18+ won’t compile on GLIBC older than 2.28.

    We strongly encourage everyone to take immediate action in updating their deployments to supported versions of Node.js to ensure continued compatibility and receive the latest features and security updates.

New & Noteworthy

Support for Workflow Update (experimental)

  • Introduced Workflow Update APIs, both on Workflow side and Client side (#1277, #1312 and #1320). Kudos to @dandavison πŸ™.

    ⚠️ The Workflow Update feature is currently in pre-release stage. Related APIs are considered experimental and may change in the near future. This feature requires Temporal Server version 1.21 or later, and must be enabled through configuration.

    Here are some examples to get started:

    // An Update is defined similarly to Query and Signal. The second type parameter (input) is optional
    const myUpdate = wf.defineUpdate<string, [string]>('myUpdate');
    
    // A handler is a sync or async function; the optional validator is always sync.
    wf.setHandler(myUpdate, handler, { validator });
    
    // `await wfHandle.executeUpdate` to start an update and block until it completes or fails.
    // The signature resembles `WorkflowClient.start` in that the arguments are supplied
    // in the optional options object
    // (as opposed to the variadic signatures of wfHandle.query and wfHandle.signal)
    // An error is thrown if the RPC times out (we do not poll for this call)
    // or if the validator rejects, or the handler throws ApplicationFailure.
    const updateResult = await handle.executeUpdate(myUpdate, { args: ['a'] });
    
    // `startUpdate` to block until Accepted and obtain a handle to the Update. Signature the same as `executeUpdate`.
    const updateHandle = await handle.startUpdate(myUpdate, { args: ['a'] });
    // Blocking call to fetch result, with polling.
    // Validation failures or ApplicationFailure in the handler would throw here.
    const updateResult = await updateHandle.result();
    

Major overhaul of logging support

This release features a major overhaul of Workflow logging, Activity logging support, and Core log forwarding support.

These changes add up to better DX, notably by promoting clear usage patterns that work out of the box, removing the need to use insufficiently documented features, and removing some requirements that were error-prone and a recurring source of support questions.

Workflow Logging

  • Calling appendDefaultInterceptors() when registering custom interceptors is no longer required in order for Workflow logger support to work properly. appendDefaultInterceptors() is now deprecated and behave as a no-op in most cases (i.e. except when a custom logger is supplied in order to redirect log emitted by activities) (#1290).

  • Similarly, calling defaultSink() when registering custom sinks is no longer required for Workflow logging to work properly (#1283). SDK's logger sink is now forcibly injected. Registering a custom logger sink named defaultWorkerLogger is still supported, but discouraged and deprecated.

  • Attributes from the current Workflow are now automatically included as metadata on every log entries emitted using the Workflow context logger, and some key events of the Workflow's lifecycle are now automatically logged (at DEBUG level for most messages; WARN for failures) (#1290).

  • WorkflowLogInterceptor has been deprecated (#1290).

Activity Logging

  • Attributes from the current Activity context are now automatically included as metadata on every log entries emitted using the Activity context logger, and some key events of the Activity's lifecycle are now automatically logged (at DEBUG level for most messages; WARN for failures) (#1284).

  • Logged Activity attributes can be customized by registering an ActivityOutboundCallsInterceptor that intercepts the getLogAttributes() method (#1284).

  • ActivityInboundLogInterceptor has been deprecated; registering such an interceptor with a custom logger still works, but will prevent the use of the newly introduced getLogAttributes() interceptor. The same is true about modifying the context logger directly (e.g. context.log = myCustomLogger) (#1284).

Core Logging

  • Log entries forwarded from Core to TS now retain metadata (#1225).

  • Reduce the default Core log level to WARN and non Core Rust logs to ERROR (#1270).

Improvements to Activity-related APIs

  • πŸ’₯ BREAKING: Non-local activities may now receive cancellation for schedule-to-close and start-to-close timeouts, without heartbeating. Heartbeating is still required to receive server sent cancellations.

  • All APIs provided through Context.current() can now be accessed directly from the @temporalio/activity import (#1252). Also, thanks to @SergeiMeza for fixing a related issue that would occur when heartbeat and sleep functions were destructured out of Context.current() (#1249) πŸ™.

    Instead of this:

    import { Context } from `@temporalio/activity`;
    // ...
    Context.current().sleep('5 minutes');
    

    you can now do:

    import { sleep } from `@temporalio/activity`;
    // ...
    sleep('5 minutes');
    
  • ActivityInboundCallsInterceptorFactory has been deprecated. Activity Interceptors should now be instantiated using an ActivityInterceptorsFactory (#1284).

  • MockActivityEnvironment now accept a list of activity interceptors, and more closely match an actual activity execution (#1284).

Improvements to Client-related APIs

  • Allow specifying gRPC CallCredentials on Client connection. Also, fixed the fact that ConnectionOptions.credentials was completely ignored (#1261).

  • Client and Connection classes now expose a withAbortSignal() method. This can be used to cancel all ongoing connections started within a function's scope (#1272).

    Example:

    const ctrl = new AbortController();
    setTimeout(() => ctrl.abort(), 10_000);
    // πŸ‘‡ throws if incomplete by the timeout.
    await conn.withAbortSignal(ctrl.signal, () => { /* make client or direct grpc calls */);
    
  • Add startDelay option to workflow start, execute, and signalWithStart (#1300).

Miscellaneous

  • WorkerOptions now exposes a nonStickyToStickyPollRatio property, which controls the proportion of Workflow Task Pollers assigned to polling from Regular Task Queue vs to polling from Sticky Tasks Queues (#1254).

  • Fixed a bug that could happen if the @temporalio/proto was minimized (#1279).

  • Prevents a Workflow-only Worker from requesting Eager Activity Execution for activities schedules on the same task queue name (#1326).

1.9.0-rc0

08 Dec 18:22
Compare
Choose a tag to compare
1.9.0-rc0 Pre-release
Pre-release

Support for Workflow Update (experimental)

  • Introduced Workflow Update APIs, both on Workflow side and Client side (#1277 and #1312). Kudos to @dandavison πŸ™.

    ⚠️ The Workflow Update feature is currently in Public Preview. Related APIs are considered experimental and may change in the near future. This feature requires Temporal Server version 1.21 or later, and must be enabled through configuration.

    Here are some examples to get started:

    // An Update is defined similarly to Query and Signal. The second type parameter (input) is optional
    const myUpdate = wf.defineUpdate<string, [string]>('myUpdate');
    
    // A handler is a sync or async function; the optional validator is always sync.
    wf.setHandler(myUpdate, handler, { validator });
    
    // `await wfHandle.executeUpdate` to start an update and block until it completes or fails.
    // The signature resembles `WorkflowClient.start` in that the arguments are supplied
    // in the optional options object
    // (as opposed to the variadic signatures of wfHandle.query and wfHandle.signal)
    // An error is thrown if the RPC times out (we do not poll for this call)
    // or if the validator rejects, or the handler throws ApplicationFailure.
    const updateResult = await handle.executeUpdate(myUpdate, { args: ['a'] });
    
    // `startUpdate` to block until Accepted and obtain a handle to the Update.
    // Signature the same as `executeUpdate`.
    const updateHandle = await handle.startUpdate(myUpdate, { args: ['a'] });
    
    // Blocking call to fetch result, with polling.
    // Validation failures or ApplicationFailure in the handler would throw here.
    const updateResult = await updateHandle.result();

Major overhaul of logging support

This release feature a major overhaul of Workflow logging, Activity logging support, and Core log forwarding support.

These changes add up to better DX, notably by promoting clear usage patterns that work out of the box, remove the need to use insufficiently documented features, and remove some requirements that were error-prone and recurring source of support questions.

Workflow Logging

  • Calling appendDefaultInterceptors() when registering custom interceptors is no longer required in order for Workflow logger support to work properly. appendDefaultInterceptors() is now deprecated and behave as a no-op in most cases (i.e. except when a custom logger is supplied in order to redirect log emitted by activities) (#1290).

  • Similarly, calling defaultSink() when registering custom sinks is no longer required for Workflow logging to work properly (#1283). SDK's logger sink is now forcibly injected. Registering a custom logger sink named defaultWorkerLogger is still supported, but discouraged and deprecated.

  • Attributes from the current Workflow are now automatically included as metadata on every log entries emited using the Workflow context logger, and some key events of the Workflow's lifecycle are now automatically logged (at DEBUG level for most messages; WARN for failures) (#1290).

  • WorkflowLogInterceptor has been deprecated (#1290).

Activity Logging

  • Attributes from the current Activity context are now automatically included as metadata on every log entries emited using the Activity context logger, and some key events of the Activity's lifecycle are now automatically logged (at DEBUG level for most messages; WARN for failures) (#1284).

  • Logged Activity attributes can be customized by registering an ActivityOutboundCallsInterceptor that intercepts the getLogAttributes() method (#1284).

  • ActivityInboundLogInterceptor has been deprecated; registering such an interceptor with a custom logger still works, but will prevent the use of the newly introduced getLogAttributes() interceptor. The same is true about modifying the context logger directly (eg. context.log = myCustomLogger) (#1284).

Core Logging

  • Log entries forwarded from Core to TS now retain metadata (#1225).

  • Reduce the default Core log level to WARN and non Core Rust logs to ERROR (#1270).

Improvements to Activity-related APIs

  • πŸ’₯ Remote activities may now receive cancellation for schedule-to-close and start-to-close timeouts, without heartbeating. Heartbeating is still required to receive server sent cancellations.

  • All APIs provided through Context.current() can now be accessed directly from the @temporalio/activity import (#1252). Also, thanks to @SergeiMeza for fixing a related issue that would occur when heartbeat and sleep functions were destructured out of Context.current() (#1249) πŸ™.

    Instead of this:

    import { Context } from `@temporalio/activity`;
    // ...
    Context.current().sleep('5 minutes');
    

    you can now do:

    import { sleep } from `@temporalio/activity`;
    // ...
    sleep('5 minutes');
    
  • ActivityInboundCallsInterceptorFactory has been deprecated. Activity Interceptors should now be instantiated using an ActivityInterceptorsFactory (#1284).

  • MockActivityEnvironment now accept a list of activity interceptors, and more closely match an actual activity execution (#1284).

Improvements to Client-related APIs

  • Allow specifying gRPC CallCredentials on Client connection. Also, fixed the fact that ConnectionOptions.credentials was completely ignored (#1261).

  • Client and Connection classes now expose a withAbortSignal() method. This can be used to cancel all ongoing connections started within a function's scope. (#1272)

    Example:

    const ctrl = new AbortController();
    setTimeout(() => ctrl.abort(), 10_000);
    // πŸ‘‡ throws if incomplete by the timeout.
    await conn.withAbortSignal(ctrl.signal, () => { /* make client or direct grpc calls */);
    
  • Add startDelay to workflow (signal) start options (#1300)

Miscellaneous

  • WorkerOptions now expose a nonStickyToStickyPollRatio property, which control the proportion of Workflow Task Pollers assigned to polling from Regular Task Queue vs to polling from Sticky Tasks Queues. (#1254)

  • Enable reuseV8Context by default (#1310)

  • Fixed a bug that could happen if the @temporalio/proto was minimized (#1279)

v1.8.6

13 Sep 23:00
Compare
Choose a tag to compare

Bug Fixes

  • [worker] Fix a memory leak introduced in v1.8.5 (#1242)

v1.8.5

12 Sep 20:59
Compare
Choose a tag to compare

Features

  • [workflow] Add historySizeInBytes and continueAsNewSuggested to WorkflowInfo (#1223).

  • Remove experimental flags on the following APIs (#1235):

    • Schedules
    • Failure Converters
    • Local Activities
    • Replay Histories

Bug Fixes

  • [workflow] Fix a particular case where isReplaying could be incorrectly false if a query came in right after a cache eviction and there had been a signal in the last workflow task before the cache eviction (#1234). This could notably cause situations where calls to sink functions configured with calledDuringReplay = false would be called more than once for a same code location, as well as situations where patched(...) would return true even though that patch had not been set on the first execution.

  • [workflow] Make ExternalWorkflowHandle.signal signature match that of BaseWorkflowHandle.signal (#1237). Thanks to @gabrielsantosblanchet and @josiah-roberts πŸ™.

  • [worker] Avoid rxjs error while flushing logs on worker shutdown (#1238).

  • Upgrade protobufjs dependencies (#1219). Thanks to @alex-dixon πŸ™.

1.8.4

22 Aug 21:07
Compare
Choose a tag to compare

Bug Fixes

  • [workflow] Fix a particular case where isReplaying would be incorrectly true if a query came in right after a cache eviction (#1211). This could notably cause situations where calls to sink functions not configured with calledDuringReplay = true would not be relayed, as well as situations where patched(...) would return false even though this part of the code was being executed for the first time.

  • [workflow] Avoid errors in Search Attributes Payload Converter if enumerable properties had been added on Array.prototype (#1209).

  • [worker] Validate buildId is set when useVersioning is true (#1207).

1.8.3

17 Aug 00:27
Compare
Choose a tag to compare

Bug Fixes

  • [workflow] Remove accidental import of large protos into workflow library (#1203). This had been causing significant memory usage increases on workflow workers since 1.8.1.
  • [core] Fix removal of deprecated patch call adjacent to other patch (#587)
  • [client] Throw WorkflowExecutionAlreadyStartedError on signalWithStart (#1199 thanks to @satazor πŸ™)

1.8.2

04 Aug 21:15
Compare
Choose a tag to compare

Features

  • [workflow] Add support for URL/URLSearchParams inside the workflow sandbox (#1173)

  • [worker] Export the WorkerStatus interface (#1184).

Bug Fixes

  • Use custom symbol-based implementation of instanceof for all of our custom error classes (#1166). This is a complete rework of the fixes introduced in 1.8.0 and 1.8.1, both of which turned out to be insufficient. instanceof now works correctly both across execution contexts and when running tests with Jest.

    πŸ’₯ The static is function introduced previously on some of our error classes is no longer required, as the instanceof operator itself now behave correctly; these is functions have therefore been removed.

  • [client] Make action.workflowId optional on Schedule update (#1176)

  • [activity] heartbeatTimeoutMs is now correctly set on Activity's Context.current().info. The currentAttemptScheduledTimestampMs property has also been added to that data structure (#1187)

  • [workflow] The Workflow Bundler is now smarter regarding requiring files with incorrect or missing file extensions (#1186). Thanks to @GauBen πŸ™.

  • [workflow] Fix incorrect values of workflowInfo.historyLength and workflowInfo.unsafe.isReplaying as reported in out-of-sandbox log messages, and as argument of sink function implementations (#1181).

  • [workflow] Sink functions configured with callDuringReplay = false are no longer invoked from a replay-only worker (i.e. Worker.runReplayHistories()); it was previously possible for these to get called in some cases on the very last Workflow Task (#1181).

  • [workflow] Encoding and decoding of protobuf JSON payloads is now working in workflow context. This was previously failing, due to the fact that an underlying library depends on the Buffer class, which is not available inside the workflow sandbox (#1170). Thanks to @antlai-temporal πŸ™.

  • [core] Improve warning message on error response to completion (temporalio/sdk-core#581) Thanks to @dandavison πŸ™.

  • [core] Fix abandoned children nondeterminism if they complete (temporalio/sdk-core#580).

1.8.1

04 Aug 21:16
Compare
Choose a tag to compare

Bug Fixes

  • Remove instanceof Error checks from is methods (#1162). This fixes various regressions observed when running Workflow tests with Jest.

  • Add the VersioningIntent parameters on the experimental worker versioning feature (#1156). Also, all values of the ReachabilityType type has been converted to SCREAMING_CASE.

  • [workflow] Make workflows.log()'s attributes argument optional (#1159).

  • [workflow] Attach workflows.log()'s attributes to every workflow log message (#1159).