@temporalio/workflow 1.14.2-canary-release-testing.0 → 1.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporalio/workflow",
3
- "version": "1.14.2-canary-release-testing.0",
3
+ "version": "1.15.0",
4
4
  "description": "Temporal.io SDK Workflow sub-package",
5
5
  "keywords": [
6
6
  "temporal",
@@ -22,8 +22,8 @@
22
22
  "types": "lib/index.d.ts",
23
23
  "dependencies": {
24
24
  "nexus-rpc": "^0.0.1",
25
- "@temporalio/common": "1.14.2-canary-release-testing.0",
26
- "@temporalio/proto": "1.14.2-canary-release-testing.0"
25
+ "@temporalio/common": "1.15.0",
26
+ "@temporalio/proto": "1.15.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "source-map": "^0.7.4"
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "engines": {
35
- "node": ">= 18.0.0"
35
+ "node": ">= 20.0.0"
36
36
  },
37
37
  "files": [
38
38
  "src",
@@ -35,7 +35,7 @@ export interface CancellationScopeOptions {
35
35
 
36
36
  /**
37
37
  * Cancellation Scopes provide the mechanic by which a Workflow may gracefully handle incoming requests for cancellation
38
- * (e.g. in response to {@link WorkflowHandle.cancel} or through the UI or CLI), as well as request cancelation of
38
+ * (e.g. in response to {@link WorkflowHandle.cancel} or through the UI or CLI), as well as request cancellation of
39
39
  * cancellable operations it owns (e.g. Activities, Timers, Child Workflows, etc).
40
40
  *
41
41
  * Cancellation Scopes form a tree, with the Workflow's main function running in the root scope of that tree.
@@ -57,7 +57,7 @@ export interface CancellationScopeOptions {
57
57
  * ```ts
58
58
  * async function myWorkflow(...): Promise<void> {
59
59
  * try {
60
- * // This activity runs in the root cancellation scope. Therefore, a cancelation request on
60
+ * // This activity runs in the root cancellation scope. Therefore, a cancellation request on
61
61
  * // the Workflow execution (e.g. through the UI or CLI) automatically propagates to this
62
62
  * // activity. Assuming that the activity properly handle the cancellation request, then the
63
63
  * // call below will throw an `ActivityFailure` exception, with `cause` sets to an
package/src/flags.ts CHANGED
@@ -114,7 +114,7 @@ type AltConditionFn = (ctx: { info: WorkflowInfo; sdkVersion?: string }) => bool
114
114
 
115
115
  function buildIdSdkVersionMatches(version: RegExp): AltConditionFn {
116
116
  const regex = new RegExp(`^@temporalio/worker@(${version.source})[+]`);
117
- return ({ info }) => info.currentBuildId != null && regex.test(info.currentBuildId); // eslint-disable-line deprecation/deprecation
117
+ return ({ info }) => info.currentBuildId != null && regex.test(info.currentBuildId); // eslint-disable-line @typescript-eslint/no-deprecated
118
118
  }
119
119
 
120
120
  type SemVer = {
@@ -11,7 +11,7 @@ declare global {
11
11
  // bundles with different versions of the SDK, but in this specific case, there's really no
12
12
  // user-side value in renaming this, so making a breaking change for that would not be justified.
13
13
  //
14
- // eslint-disable-next-line no-var
14
+
15
15
  var __TEMPORAL__: {
16
16
  api: typeof import('./worker-interface.ts');
17
17
  importWorkflows: () => Record<string, Workflow>;
@@ -19,11 +19,11 @@ declare global {
19
19
  };
20
20
 
21
21
  // Destructors to be called when the shared sandbox is destroyed.
22
- // eslint-disable-next-line no-var
22
+
23
23
  var __temporal_globalSandboxDestructors: (() => void)[] | undefined;
24
24
 
25
25
  // FIXME: Rename to lowercase syntax before 1.15.0.
26
- // eslint-disable-next-line no-var
26
+
27
27
  var __TEMPORAL_ACTIVATOR__: Activator | undefined;
28
28
  }
29
29
 
@@ -42,7 +42,7 @@ export function overrideGlobals(): void {
42
42
 
43
43
  global.Date.prototype = OriginalDate.prototype;
44
44
 
45
- const timeoutCancelationScopes = new Map<number, CancellationScope>();
45
+ const timeoutCancellationScopes = new Map<number, CancellationScope>();
46
46
 
47
47
  /**
48
48
  * @param ms sleep duration - number of milliseconds. If given a negative number, value will be set to 1.
@@ -57,15 +57,15 @@ export function overrideGlobals(): void {
57
57
  const sleepPromise = timerScope.run(() => sleep(ms));
58
58
  sleepPromise.then(
59
59
  () => {
60
- timeoutCancelationScopes.delete(seq);
60
+ timeoutCancellationScopes.delete(seq);
61
61
  cb(...args);
62
62
  },
63
63
  () => {
64
- timeoutCancelationScopes.delete(seq);
64
+ timeoutCancellationScopes.delete(seq);
65
65
  }
66
66
  );
67
67
  untrackPromise(sleepPromise);
68
- timeoutCancelationScopes.set(seq, timerScope);
68
+ timeoutCancellationScopes.set(seq, timerScope);
69
69
  return seq;
70
70
  } else {
71
71
  const seq = activator.nextSeqs.timer++;
@@ -88,9 +88,9 @@ export function overrideGlobals(): void {
88
88
 
89
89
  global.clearTimeout = function (handle: number): void {
90
90
  const activator = getActivator();
91
- const timerScope = timeoutCancelationScopes.get(handle);
91
+ const timerScope = timeoutCancellationScopes.get(handle);
92
92
  if (timerScope) {
93
- timeoutCancelationScopes.delete(handle);
93
+ timeoutCancellationScopes.delete(handle);
94
94
  timerScope.cancel();
95
95
  } else {
96
96
  activator.nextSeqs.timer++; // Shouldn't increase seq number, but that's the legacy behavior
package/src/index.ts CHANGED
@@ -60,8 +60,8 @@ export {
60
60
  PayloadConverter,
61
61
  RetryPolicy,
62
62
  rootCause,
63
- SearchAttributes, // eslint-disable-line deprecation/deprecation
64
- SearchAttributeValue, // eslint-disable-line deprecation/deprecation
63
+ SearchAttributes, // eslint-disable-line @typescript-eslint/no-deprecated
64
+ SearchAttributeValue, // eslint-disable-line @typescript-eslint/no-deprecated
65
65
  ServerFailure,
66
66
  TemporalFailure,
67
67
  TerminatedFailure,
@@ -70,7 +70,7 @@ export {
70
70
  export * from '@temporalio/common/lib/errors';
71
71
  export {
72
72
  ActivityFunction,
73
- ActivityInterface, // eslint-disable-line deprecation/deprecation
73
+ ActivityInterface, // eslint-disable-line @typescript-eslint/no-deprecated
74
74
  Payload,
75
75
  QueryDefinition,
76
76
  SignalDefinition,
@@ -108,8 +108,13 @@ export { Trigger } from './trigger';
108
108
  export * from './workflow';
109
109
  export { ChildWorkflowHandle, ExternalWorkflowHandle } from './workflow-handle';
110
110
  export { metricMeter } from './metrics';
111
-
112
- export { createNexusClient, NexusClientOptions, NexusClient, NexusOperationHandle } from './nexus';
111
+ export {
112
+ createNexusClient,
113
+ NexusClientOptions,
114
+ NexusClient,
115
+ NexusOperationHandle,
116
+ NexusOperationCancellationType,
117
+ } from './nexus';
113
118
 
114
119
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
115
120
  // Deprecated APIs
@@ -121,6 +126,6 @@ export {
121
126
  * exported by the `@temporalio/workflow` package. To capture log messages emitted
122
127
  * by Workflow code, set the {@link Runtime.logger} property.
123
128
  */
124
- // eslint-disable-next-line deprecation/deprecation
129
+
125
130
  LoggerSinksDeprecated as LoggerSinks,
126
131
  } from './logs';
@@ -15,7 +15,8 @@ import {
15
15
  WorkflowExecution,
16
16
  } from '@temporalio/common';
17
17
  import type { coresdk } from '@temporalio/proto';
18
- import { ChildWorkflowOptionsWithDefaults, ContinueAsNewOptions } from './interfaces';
18
+ import type { ChildWorkflowOptionsWithDefaults, ContinueAsNewOptions } from './interfaces';
19
+ import type { NexusOperationCancellationType } from './nexus';
19
20
 
20
21
  export { Next, Headers };
21
22
 
@@ -288,6 +289,22 @@ export interface StartNexusOperationOptions {
288
289
  */
289
290
  readonly scheduleToCloseTimeout?: Duration;
290
291
 
292
+ /**
293
+ * Determines:
294
+ * - whether cancellation requests should be propagated from the Workflow to the Nexus Operation
295
+ * - whether and when should the Operation's cancellation be reported back to the Workflow
296
+ * (i.e. at which moment should the operation's result promise fail with a `NexusOperationFailure`,
297
+ * with `cause` set to a `CancelledFailure`).
298
+ *
299
+ * Note that this setting only applies to cancellation originating from an external request for the
300
+ * Workflow itself, or from internal cancellation of the `CancellationScope` in which the
301
+ * Operation call was made.
302
+ *
303
+ * @default WAIT_CANCELLATION_COMPLETED
304
+ */
305
+ // MAINTENANCE: Keep this typedoc in sync with the `NexusOperationCancellationType` enum
306
+ readonly cancellationType?: NexusOperationCancellationType;
307
+
291
308
  /**
292
309
  * A fixed, single-line summary for this Nexus Operation that may appear in the UI/CLI.
293
310
  * This can be in single-line Temporal markdown format.
package/src/interfaces.ts CHANGED
@@ -45,7 +45,7 @@ export interface WorkflowInfo {
45
45
  * This value may change during the lifetime of an Execution.
46
46
  * @deprecated Use {@link typedSearchAttributes} instead.
47
47
  */
48
- readonly searchAttributes: SearchAttributes; // eslint-disable-line deprecation/deprecation
48
+ readonly searchAttributes: SearchAttributes; // eslint-disable-line @typescript-eslint/no-deprecated
49
49
 
50
50
  /**
51
51
  * Indexed information attached to the Workflow Execution, exposed through an interface.
@@ -208,8 +208,6 @@ export interface WorkflowInfo {
208
208
  * executing this task for the first time and has a Deployment Version set, then its ID will be
209
209
  * used. This value may change over the lifetime of the workflow run, but is deterministic and
210
210
  * safe to use for branching.
211
- *
212
- * @experimental Deployment based versioning is experimental and may change in the future.
213
211
  */
214
212
  readonly currentDeploymentVersion?: WorkerDeploymentVersion;
215
213
 
@@ -235,7 +233,22 @@ export interface UnsafeWorkflowInfo {
235
233
  */
236
234
  readonly now: () => number;
237
235
 
236
+ /**
237
+ * Whether the workflow is currently replaying.
238
+ */
238
239
  readonly isReplaying: boolean;
240
+
241
+ /**
242
+ * Whether the workflow is currently replaying history events.
243
+ *
244
+ * This is similar to {@link isReplaying}, but returns `false` during query handlers and update
245
+ * validators, which are live read-only operations that should not be considered as replaying
246
+ * history events.
247
+ *
248
+ * When this property is true, workflow log messages are suppressed and sinks defined with
249
+ * callDuringReplay=false won't get processed.
250
+ */
251
+ readonly isReplayingHistoryEvents: boolean;
239
252
  }
240
253
 
241
254
  /**
@@ -304,7 +317,7 @@ export interface ContinueAsNewOptions {
304
317
  * Searchable attributes to attach to next Workflow run
305
318
  * @deprecated Use {@link typedSearchAttributes} instead.
306
319
  */
307
- searchAttributes?: SearchAttributes; // eslint-disable-line deprecation/deprecation
320
+ searchAttributes?: SearchAttributes; // eslint-disable-line @typescript-eslint/no-deprecated
308
321
  /**
309
322
  * Specifies additional indexed information to attach to the Workflow Execution. More info:
310
323
  * https://docs.temporal.io/docs/typescript/search-attributes
@@ -322,48 +335,74 @@ export interface ContinueAsNewOptions {
322
335
  *
323
336
  * @default 'COMPATIBLE'
324
337
  *
325
- * @deprecated In favor of the new Worker Deployment API.
326
- * @experimental The Worker Versioning API is still being designed. Major changes are expected.
338
+ * @deprecated Worker Versioning is now deprecated. Please use the Worker Deployment API instead: https://docs.temporal.io/worker-deployments
327
339
  */
328
- versioningIntent?: VersioningIntent; // eslint-disable-line deprecation/deprecation
340
+ versioningIntent?: VersioningIntent; // eslint-disable-line @typescript-eslint/no-deprecated
329
341
  }
330
342
 
331
343
  /**
332
- * Specifies:
333
- * - whether cancellation requests are sent to the Child
334
- * - whether and when a {@link CanceledFailure} is thrown from {@link executeChild} or
335
- * {@link ChildWorkflowHandle.result}
344
+ * Determines:
345
+ * - whether cancellation requests should be propagated from the Parent Workflow to the Child, and
346
+ * - whether and when should the Child's cancellation be reported back to the Parent Workflow
347
+ * (i.e. at which moment should the {@link executeChild}'s or {@link ChildWorkflowHandle.result}'s
348
+ * promise fail with a `ChildWorkflowFailure`, with `cause` set to a `CancelledFailure`).
349
+ *
350
+ * Note that this setting only applies to cancellation originating from an external request for the
351
+ * Parent Workflow itself, or from internal cancellation of the `CancellationScope` in which the
352
+ * Child Workflow call was made. Eventual Cancellation of a Child Workflow on completion of the
353
+ * Parent Workflow is controlled by the {@link ParentClosePolicy} setting.
336
354
  *
337
- * @default {@link ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED}
355
+ * @default ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED
338
356
  */
339
- export type ChildWorkflowCancellationType =
340
- (typeof ChildWorkflowCancellationType)[keyof typeof ChildWorkflowCancellationType];
357
+ // MAINTENANCE: Keep this typedoc in sync with the `ChildWorkflowOptions.cancellationType` field
341
358
  export const ChildWorkflowCancellationType = {
342
359
  /**
343
- * Don't send a cancellation request to the Child.
360
+ * Do not propagate cancellation requests to the Child, and immediately report cancellation
361
+ * to the caller.
344
362
  */
345
363
  ABANDON: 'ABANDON',
346
364
 
347
365
  /**
348
- * Send a cancellation request to the Child. Immediately throw the error.
366
+ * Propagate cancellation request from the Parent Workflow to the Child, yet _immediately_ report
367
+ * cancellation to the caller, i.e. without waiting for the server to confirm the cancellation
368
+ * request.
369
+ *
370
+ * Note that this cancellation type provides no guarantee, from the Parent-side, that the
371
+ * cancellation request will actually be atomically added to the Child workflow's history.
372
+ * In particular, the Child may complete (either successfully or uncessfully) before the
373
+ * cancellation is delivered, resulting in a situation where the Parent workflow thinks its child
374
+ * was cancelled, but the child actually completed successfully.
375
+ *
376
+ * To guarantee that the Child will eventually be notified of the cancellation request,
377
+ * use {@link WAIT_CANCELLATION_REQUESTED}.
349
378
  */
350
379
  TRY_CANCEL: 'TRY_CANCEL',
351
380
 
352
381
  /**
353
- * Send a cancellation request to the Child. The Child may respect cancellation, in which case an error will be thrown
354
- * when cancellation has completed, and {@link isCancellation}(error) will be true. On the other hand, the Child may
355
- * ignore the cancellation request, in which case an error might be thrown with a different cause, or the Child may
356
- * complete successfully.
382
+ * Propagate cancellation request from the Parent Workflow to the Child, then wait for the server
383
+ * to confirm that the Child Workflow cancellation request was recorded in its history.
357
384
  *
358
- * @default
385
+ * This cancellation type guarantees that the Child will eventually be notified of the
386
+ * cancellation request (that is, unless the Child terminates inbetween due to unexpected causes).
359
387
  */
360
- WAIT_CANCELLATION_COMPLETED: 'WAIT_CANCELLATION_COMPLETED',
388
+ WAIT_CANCELLATION_REQUESTED: 'WAIT_CANCELLATION_REQUESTED',
361
389
 
362
390
  /**
363
- * Send a cancellation request to the Child. Throw the error once the Server receives the Child cancellation request.
391
+ * Propagate cancellation request from the Parent Workflow to the Child, then wait for completion
392
+ * of the Child Workflow.
393
+ *
394
+ * The Child may respect cancellation, in which case the Parent's `executeChild` or
395
+ * `ChildWorkflowHandle.result` promise will fail with a `ChildWorkflowFailure`, with `cause`
396
+ * set to a `CancelledFailure`. On the other hand, the Child may ignore the cancellation request,
397
+ * in which case the corresponding promise will either resolve with a result (if Child completed
398
+ * successfully) or reject with a different cause (if Child completed uncessfully).
399
+ *
400
+ * @default
364
401
  */
365
- WAIT_CANCELLATION_REQUESTED: 'WAIT_CANCELLATION_REQUESTED',
402
+ WAIT_CANCELLATION_COMPLETED: 'WAIT_CANCELLATION_COMPLETED',
366
403
  } as const;
404
+ export type ChildWorkflowCancellationType =
405
+ (typeof ChildWorkflowCancellationType)[keyof typeof ChildWorkflowCancellationType];
367
406
 
368
407
  // ts-prune-ignore-next
369
408
  export const [encodeChildWorkflowCancellationType, decodeChildWorkflowCancellationType] = makeProtoEnumConverters<
@@ -387,7 +426,6 @@ export const [encodeChildWorkflowCancellationType, decodeChildWorkflowCancellati
387
426
  *
388
427
  * @see {@link https://docs.temporal.io/concepts/what-is-a-parent-close-policy/ | Parent Close Policy}
389
428
  */
390
- export type ParentClosePolicy = (typeof ParentClosePolicy)[keyof typeof ParentClosePolicy];
391
429
  export const ParentClosePolicy = {
392
430
  /**
393
431
  * When the Parent is Closed, the Child is Terminated.
@@ -413,29 +451,30 @@ export const ParentClosePolicy = {
413
451
  *
414
452
  * @deprecated Either leave property `undefined`, or set an explicit policy instead.
415
453
  */
416
- PARENT_CLOSE_POLICY_UNSPECIFIED: undefined, // eslint-disable-line deprecation/deprecation
454
+ PARENT_CLOSE_POLICY_UNSPECIFIED: undefined,
417
455
 
418
456
  /**
419
457
  * When the Parent is Closed, the Child is Terminated.
420
458
  *
421
459
  * @deprecated Use {@link ParentClosePolicy.TERMINATE} instead.
422
460
  */
423
- PARENT_CLOSE_POLICY_TERMINATE: 'TERMINATE', // eslint-disable-line deprecation/deprecation
461
+ PARENT_CLOSE_POLICY_TERMINATE: 'TERMINATE',
424
462
 
425
463
  /**
426
464
  * When the Parent is Closed, nothing is done to the Child.
427
465
  *
428
466
  * @deprecated Use {@link ParentClosePolicy.ABANDON} instead.
429
467
  */
430
- PARENT_CLOSE_POLICY_ABANDON: 'ABANDON', // eslint-disable-line deprecation/deprecation
468
+ PARENT_CLOSE_POLICY_ABANDON: 'ABANDON',
431
469
 
432
470
  /**
433
471
  * When the Parent is Closed, the Child is Cancelled.
434
472
  *
435
473
  * @deprecated Use {@link ParentClosePolicy.REQUEST_CANCEL} instead.
436
474
  */
437
- PARENT_CLOSE_POLICY_REQUEST_CANCEL: 'REQUEST_CANCEL', // eslint-disable-line deprecation/deprecation
475
+ PARENT_CLOSE_POLICY_REQUEST_CANCEL: 'REQUEST_CANCEL',
438
476
  } as const;
477
+ export type ParentClosePolicy = (typeof ParentClosePolicy)[keyof typeof ParentClosePolicy];
439
478
 
440
479
  // ts-prune-ignore-next
441
480
  export const [encodeParentClosePolicy, decodeParentClosePolicy] = makeProtoEnumConverters<
@@ -471,19 +510,26 @@ export interface ChildWorkflowOptions extends Omit<CommonWorkflowOptions, 'workf
471
510
  taskQueue?: string;
472
511
 
473
512
  /**
474
- * Specifies:
475
- * - whether cancellation requests are sent to the Child
476
- * - whether and when an error is thrown from {@link executeChild} or
477
- * {@link ChildWorkflowHandle.result}
513
+ * Determines:
514
+ * - whether cancellation requests should be propagated from the Parent Workflow to the Child, and
515
+ * - whether and when should the Child's cancellation be reported back to the Parent Workflow
516
+ * (i.e. at which moment should the {@link executeChild}'s or {@link ChildWorkflowHandle.result}'s
517
+ * promise fail with a `ChildWorkflowFailure`, with `cause` set to a `CancelledFailure`).
518
+ *
519
+ * Note that this setting only applies to cancellation originating from an external request for the
520
+ * Parent Workflow itself, or from internal cancellation of the `CancellationScope` in which the
521
+ * Child Workflow call was made. Eventual Cancellation of a Child Workflow on completion of the
522
+ * Parent Workflow is controlled by the {@link ParentClosePolicy} setting.
478
523
  *
479
- * @default {@link ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED}
524
+ * @default ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED
480
525
  */
526
+ // MAINTENANCE: Keep this typedoc in sync with the `ChildWorkflowCancellationType` enum
481
527
  cancellationType?: ChildWorkflowCancellationType;
482
528
 
483
529
  /**
484
530
  * Specifies how the Child reacts to the Parent Workflow reaching a Closed state.
485
531
  *
486
- * @default {@link ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE}
532
+ * @default ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE
487
533
  */
488
534
  parentClosePolicy?: ParentClosePolicy;
489
535
 
@@ -493,10 +539,9 @@ export interface ChildWorkflowOptions extends Omit<CommonWorkflowOptions, 'workf
493
539
  *
494
540
  * @default 'COMPATIBLE'
495
541
  *
496
- * @deprecated In favor of the new Worker Deployment API.
497
- * @experimental The Worker Versioning API is still being designed. Major changes are expected.
542
+ * @deprecated Worker Versioning is now deprecated. Please use the Worker Deployment API instead: https://docs.temporal.io/worker-deployments
498
543
  */
499
- versioningIntent?: VersioningIntent; // eslint-disable-line deprecation/deprecation
544
+ versioningIntent?: VersioningIntent; // eslint-disable-line @typescript-eslint/no-deprecated
500
545
  }
501
546
 
502
547
  export type RequiredChildWorkflowOptions = Required<Pick<ChildWorkflowOptions, 'workflowId' | 'cancellationType'>> & {
@@ -581,6 +626,7 @@ export interface WorkflowCreateOptionsInternal extends WorkflowCreateOptions {
581
626
  sourceMap: RawSourceMap;
582
627
  registeredActivityNames: Set<string>;
583
628
  getTimeOfDay(): bigint;
629
+ stackTracesEnabled: boolean;
584
630
  }
585
631
 
586
632
  /**
package/src/internals.ts CHANGED
@@ -457,6 +457,8 @@ export class Activator implements ActivationHandler {
457
457
 
458
458
  public readonly workflowSandboxDestructors: (() => void)[] = [];
459
459
 
460
+ protected readonly stackTracesEnabled: boolean;
461
+
460
462
  constructor({
461
463
  info,
462
464
  now,
@@ -465,6 +467,7 @@ export class Activator implements ActivationHandler {
465
467
  getTimeOfDay,
466
468
  randomnessSeed,
467
469
  registeredActivityNames,
470
+ stackTracesEnabled,
468
471
  }: WorkflowCreateOptionsInternal) {
469
472
  this.getTimeOfDay = getTimeOfDay;
470
473
  this.info = info;
@@ -473,6 +476,7 @@ export class Activator implements ActivationHandler {
473
476
  this.sourceMap = sourceMap;
474
477
  this.random = alea(randomnessSeed);
475
478
  this.registeredActivityNames = registeredActivityNames;
479
+ this.stackTracesEnabled = stackTracesEnabled;
476
480
  }
477
481
 
478
482
  /**
@@ -483,6 +487,9 @@ export class Activator implements ActivationHandler {
483
487
  }
484
488
 
485
489
  protected getStackTraces(): Stack[] {
490
+ if (!this.stackTracesEnabled) {
491
+ throw new IllegalStateError('Workflow stack traces are not enabled on this worker');
492
+ }
486
493
  const { childToParent, promiseToStack } = this.promiseStackStore;
487
494
  const internalNodes = [...childToParent.values()].reduce((acc, curr) => {
488
495
  for (const p of curr) {
@@ -858,12 +865,26 @@ export class Activator implements ActivationHandler {
858
865
  let input: UpdateInput;
859
866
  try {
860
867
  if (runValidator && entry.validator) {
861
- const validate = composeInterceptors(
862
- interceptors,
863
- 'validateUpdate',
864
- this.validateUpdateNextHandler.bind(this, entry.validator)
865
- );
866
- validate(makeInput());
868
+ // Temporarily mark as not replaying history events during validator execution
869
+ // so that logging is permitted. Validators are live read-only operations.
870
+ const wasReplayingHistoryEvents = this.info.unsafe.isReplayingHistoryEvents;
871
+ this.mutateWorkflowInfo((info) => ({
872
+ ...info,
873
+ unsafe: { ...info.unsafe, isReplayingHistoryEvents: false },
874
+ }));
875
+ try {
876
+ const validate = composeInterceptors(
877
+ interceptors,
878
+ 'validateUpdate',
879
+ this.validateUpdateNextHandler.bind(this, entry.validator)
880
+ );
881
+ validate(makeInput());
882
+ } finally {
883
+ this.mutateWorkflowInfo((info) => ({
884
+ ...info,
885
+ unsafe: { ...info.unsafe, isReplayingHistoryEvents: wasReplayingHistoryEvents },
886
+ }));
887
+ }
867
888
  }
868
889
  input = makeInput();
869
890
  } catch (error) {
@@ -930,7 +951,6 @@ export class Activator implements ActivationHandler {
930
951
  const update = this.bufferedUpdates.shift();
931
952
  if (update) {
932
953
  this.rejectUpdate(
933
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
934
954
  update.protocolInstanceId!,
935
955
  ApplicationFailure.nonRetryable(`No registered handler for update: ${update.name}`)
936
956
  );
@@ -997,7 +1017,7 @@ export class Activator implements ActivationHandler {
997
1017
  while (bufferedSignals.length) {
998
1018
  if (this.defaultSignalHandler) {
999
1019
  // We have a default signal handler, so all signals are dispatchable
1000
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1020
+
1001
1021
  this.signalWorkflow(bufferedSignals.shift()!);
1002
1022
  } else {
1003
1023
  const foundIndex = bufferedSignals.findIndex((signal) => this.signalHandlers.has(signal.signalName as string));
package/src/metrics.ts CHANGED
@@ -48,6 +48,9 @@ class WorkflowMetricMeterImpl implements MetricMeter {
48
48
  }
49
49
 
50
50
  class WorkflowMetricCounter implements MetricCounter {
51
+ public readonly kind = 'counter';
52
+ public readonly valueType = 'int';
53
+
51
54
  constructor(
52
55
  public readonly name: string,
53
56
  public readonly unit: string | undefined,
@@ -70,6 +73,8 @@ class WorkflowMetricCounter implements MetricCounter {
70
73
  }
71
74
 
72
75
  class WorkflowMetricHistogram implements MetricHistogram {
76
+ public readonly kind = 'histogram';
77
+
73
78
  constructor(
74
79
  public readonly name: string,
75
80
  public readonly valueType: NumericMetricValueType,
@@ -93,6 +98,8 @@ class WorkflowMetricHistogram implements MetricHistogram {
93
98
  }
94
99
 
95
100
  class WorkflowMetricGauge implements MetricGauge {
101
+ public readonly kind = 'gauge';
102
+
96
103
  constructor(
97
104
  public readonly name: string,
98
105
  public readonly valueType: NumericMetricValueType,