From 0bca086d89ff8dd89fe8de646af410064afcf5ee Mon Sep 17 00:00:00 2001 From: James Watkins-Harvey Date: Tue, 26 Sep 2023 17:31:06 -0400 Subject: [PATCH] Fix multiple issues --- packages/activity/src/index.ts | 31 +++++++++++++-------- packages/common/src/type-helpers.ts | 8 ++++-- packages/worker/src/workflow/reusable-vm.ts | 3 +- packages/workflow/src/workflow.ts | 2 +- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/activity/src/index.ts b/packages/activity/src/index.ts index 9c2f65c57..1822a7880 100644 --- a/packages/activity/src/index.ts +++ b/packages/activity/src/index.ts @@ -71,9 +71,9 @@ import 'abort-controller/polyfill'; // eslint-disable-line import/no-unassigned-import import { AsyncLocalStorage } from 'node:async_hooks'; -import { Logger, Duration, deepFreeze } from '@temporalio/common'; +import { Logger, Duration } from '@temporalio/common'; import { msToNumber } from '@temporalio/common/lib/time'; -import { SymbolBasedInstanceOfError } from '@temporalio/common/lib/type-helpers'; +import { SymbolBasedInstanceOfError, deepFreeze } from '@temporalio/common/lib/type-helpers'; export { ActivityFunction, @@ -278,7 +278,7 @@ export class Context { // Note that we don't freeze the context object itself, because some users add properties to it (generally from // interceptors). We even had samples promoting that practice. We should probably deprecate that at some point, but // lets give us some time before we do. - this.info = deepFreeze(info); + this.info = deepFreeze(info) as Info; this.cancelled = cancelled; this.cancellationSignal = cancellationSignal; @@ -357,7 +357,9 @@ export const log: Logger = new Proxy({} as Logger, { * @param ms Sleep duration: number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string} * @returns A Promise that either resolves when `ms` is reached or rejects when the Activity is cancelled */ -export const sleep = Context.current().sleep; +export function sleep(ms: Duration): Promise { + return Context.current().sleep(ms); +} /** * Send a {@link https://docs.temporal.io/concepts/what-is-an-activity-heartbeat | heartbeat} from an Activity. @@ -372,21 +374,26 @@ export const sleep = Context.current().sleep; * * This is a shortcut for `Context.current().heatbeat(ms)` (see {@link Context.heartbeat}). */ -export const heartbeat = Context.current().heartbeat; +export function heartbeat(details?: unknown): void { + Context.current().heartbeat(details); +} /** - * A Promise that fails with a {@link CancelledFailure} when cancellation of this activity is requested. The promise - * is guaranteed to never successfully resolve. Await this promise in an Activity to get notified of cancellation. + * Return a Promise that fails with a {@link CancelledFailure} when cancellation of this activity is requested. The + * promise is guaranteed to never successfully resolve. Await this promise in an Activity to get notified of + * cancellation. * * Note that to get notified of cancellation, an activity must _also_ do {@link Context.heartbeat}. * * This is a shortcut for `Context.current().cancelled` (see {@link Context.cancelled}). */ -export const cancelled = Context.current().cancelled; +export function cancelled(): Promise { + return Context.current().cancelled; +} /** - * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} that can be used to react to - * Activity cancellation. + * Return an {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | `AbortSignal`} that can be used to + * react to Activity cancellation. * * This can be passed in to libraries such as * {@link https://www.npmjs.com/package/node-fetch#request-cancellation-with-abortsignal | fetch} to abort an @@ -398,4 +405,6 @@ export const cancelled = Context.current().cancelled; * * This is a shortcut for `Context.current().cancellationSignal` (see {@link Context.cancellationSignal}). */ -export const cancellationSignal = Context.current().cancellationSignal; +export function cancellationSignal(): AbortSignal { + return Context.current().cancellationSignal; +} diff --git a/packages/common/src/type-helpers.ts b/packages/common/src/type-helpers.ts index e60eee72b..56a838d4d 100644 --- a/packages/common/src/type-helpers.ts +++ b/packages/common/src/type-helpers.ts @@ -184,10 +184,14 @@ function deepClonePolyfill(object: T): T { } if (Array.isArray(object)) { - return object.map((item) => deepClone(item)) as T; + return object.map((item) => deepClonePolyfill(item)) as T; + } + + if (object instanceof Date) { + return new Date(object) as T; } const clone: any = Object.assign({}, object); - Object.keys(clone).forEach((key) => (clone[key] = deepClone(clone[key]))); + Object.keys(clone).forEach((key) => (clone[key] = deepClonePolyfill(clone[key]))); return clone as T; } diff --git a/packages/worker/src/workflow/reusable-vm.ts b/packages/worker/src/workflow/reusable-vm.ts index 50e601574..e36141cd1 100644 --- a/packages/worker/src/workflow/reusable-vm.ts +++ b/packages/worker/src/workflow/reusable-vm.ts @@ -3,7 +3,8 @@ import { URL, URLSearchParams } from 'node:url'; import { AsyncLocalStorage } from 'node:async_hooks'; import vm from 'node:vm'; import * as internals from '@temporalio/workflow/lib/worker-interface'; -import { deepFreeze, IllegalStateError } from '@temporalio/common'; +import { IllegalStateError } from '@temporalio/common'; +import { deepFreeze } from '@temporalio/common/lib/type-helpers'; import { getTimeOfDay } from '@temporalio/core-bridge'; import { timeOfDayToBigint } from '../logger'; import { Workflow, WorkflowCreateOptions, WorkflowCreator } from './interface'; diff --git a/packages/workflow/src/workflow.ts b/packages/workflow/src/workflow.ts index 80716d0ec..0da8f71ff 100644 --- a/packages/workflow/src/workflow.ts +++ b/packages/workflow/src/workflow.ts @@ -19,7 +19,7 @@ import { } from '@temporalio/common'; import { versioningIntentToProto } from '@temporalio/common/lib/versioning-intent-enum'; import { Duration, msOptionalToTs, msToNumber, msToTs, tsToMs } from '@temporalio/common/lib/time'; -import { deepFreeze, deepClone, DeepReadonly } from '@temporalio/common/src/type-helpers'; +import { deepFreeze, deepClone, DeepReadonly } from '@temporalio/common/lib/type-helpers'; import { composeInterceptors } from '@temporalio/common/lib/interceptors'; import { CancellationScope, registerSleepImplementation } from './cancellation-scope'; import {