@temporalio/workflow 1.4.4 → 1.5.1

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/src/workflow.ts CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  EnhancedStackTrace,
36
36
  WorkflowInfo,
37
37
  } from './interfaces';
38
- import { LocalActivityDoBackoff, state } from './internals';
38
+ import { LocalActivityDoBackoff, getActivator } from './internals';
39
39
  import { Sinks } from './sinks';
40
40
  import { untrackPromise } from './stack-helpers';
41
41
  import { ChildWorkflowHandle, ExternalWorkflowHandle } from './workflow-handle';
@@ -62,6 +62,7 @@ export function addDefaultWorkflowOptions<T extends Workflow>(
62
62
  * Push a startTimer command into state accumulator and register completion
63
63
  */
64
64
  function timerNextHandler(input: TimerInput) {
65
+ const activator = getActivator();
65
66
  return new Promise<void>((resolve, reject) => {
66
67
  const scope = CancellationScope.current();
67
68
  if (scope.consideredCancelled) {
@@ -71,10 +72,10 @@ function timerNextHandler(input: TimerInput) {
71
72
  if (scope.cancellable) {
72
73
  untrackPromise(
73
74
  scope.cancelRequested.catch((err) => {
74
- if (!state.completions.timer.delete(input.seq)) {
75
+ if (!activator.completions.timer.delete(input.seq)) {
75
76
  return; // Already resolved or never scheduled
76
77
  }
77
- state.pushCommand({
78
+ activator.pushCommand({
78
79
  cancelTimer: {
79
80
  seq: input.seq,
80
81
  },
@@ -83,13 +84,13 @@ function timerNextHandler(input: TimerInput) {
83
84
  })
84
85
  );
85
86
  }
86
- state.pushCommand({
87
+ activator.pushCommand({
87
88
  startTimer: {
88
89
  seq: input.seq,
89
90
  startToFireTimeout: msToTs(input.durationMs),
90
91
  },
91
92
  });
92
- state.completions.timer.set(input.seq, {
93
+ activator.completions.timer.set(input.seq, {
93
94
  resolve,
94
95
  reject,
95
96
  });
@@ -105,11 +106,12 @@ function timerNextHandler(input: TimerInput) {
105
106
  * If given a negative number or 0, value will be set to 1.
106
107
  */
107
108
  export function sleep(ms: number | string): Promise<void> {
108
- const seq = state.nextSeqs.timer++;
109
+ const activator = getActivator();
110
+ const seq = activator.nextSeqs.timer++;
109
111
 
110
112
  const durationMs = Math.max(1, msToNumber(ms));
111
113
 
112
- const execute = composeInterceptors(state.interceptors.outbound, 'startTimer', timerNextHandler);
114
+ const execute = composeInterceptors(activator.interceptors.outbound, 'startTimer', timerNextHandler);
113
115
 
114
116
  return execute({
115
117
  durationMs,
@@ -132,9 +134,10 @@ const validateLocalActivityOptions = validateActivityOptions;
132
134
  * Returns `false` if the current scope is already cancelled.
133
135
  */
134
136
  /**
135
- * Push a scheduleActivity command into state accumulator and register completion
137
+ * Push a scheduleActivity command into activator accumulator and register completion
136
138
  */
137
139
  function scheduleActivityNextHandler({ options, args, headers, seq, activityType }: ActivityInput): Promise<unknown> {
140
+ const activator = getActivator();
138
141
  validateActivityOptions(options);
139
142
  return new Promise((resolve, reject) => {
140
143
  const scope = CancellationScope.current();
@@ -145,10 +148,10 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
145
148
  if (scope.cancellable) {
146
149
  untrackPromise(
147
150
  scope.cancelRequested.catch(() => {
148
- if (!state.completions.activity.has(seq)) {
151
+ if (!activator.completions.activity.has(seq)) {
149
152
  return; // Already resolved or never scheduled
150
153
  }
151
- state.pushCommand({
154
+ activator.pushCommand({
152
155
  requestCancelActivity: {
153
156
  seq,
154
157
  },
@@ -156,14 +159,14 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
156
159
  })
157
160
  );
158
161
  }
159
- state.pushCommand({
162
+ activator.pushCommand({
160
163
  scheduleActivity: {
161
164
  seq,
162
165
  activityId: options.activityId ?? `${seq}`,
163
166
  activityType,
164
- arguments: toPayloads(state.payloadConverter, ...args),
167
+ arguments: toPayloads(activator.payloadConverter, ...args),
165
168
  retryPolicy: options.retry ? compileRetryPolicy(options.retry) : undefined,
166
- taskQueue: options.taskQueue || state.info?.taskQueue,
169
+ taskQueue: options.taskQueue || activator.info?.taskQueue,
167
170
  heartbeatTimeout: msOptionalToTs(options.heartbeatTimeout),
168
171
  scheduleToCloseTimeout: msOptionalToTs(options.scheduleToCloseTimeout),
169
172
  startToCloseTimeout: msOptionalToTs(options.startToCloseTimeout),
@@ -173,7 +176,7 @@ function scheduleActivityNextHandler({ options, args, headers, seq, activityType
173
176
  doNotEagerlyExecute: !(options.allowEagerDispatch ?? true),
174
177
  },
175
178
  });
176
- state.completions.activity.set(seq, {
179
+ activator.completions.activity.set(seq, {
177
180
  resolve,
178
181
  reject,
179
182
  });
@@ -192,6 +195,7 @@ async function scheduleLocalActivityNextHandler({
192
195
  attempt,
193
196
  originalScheduleTime,
194
197
  }: LocalActivityInput): Promise<unknown> {
198
+ const activator = getActivator();
195
199
  validateLocalActivityOptions(options);
196
200
 
197
201
  return new Promise((resolve, reject) => {
@@ -203,10 +207,10 @@ async function scheduleLocalActivityNextHandler({
203
207
  if (scope.cancellable) {
204
208
  untrackPromise(
205
209
  scope.cancelRequested.catch(() => {
206
- if (!state.completions.activity.has(seq)) {
210
+ if (!activator.completions.activity.has(seq)) {
207
211
  return; // Already resolved or never scheduled
208
212
  }
209
- state.pushCommand({
213
+ activator.pushCommand({
210
214
  requestCancelLocalActivity: {
211
215
  seq,
212
216
  },
@@ -214,7 +218,7 @@ async function scheduleLocalActivityNextHandler({
214
218
  })
215
219
  );
216
220
  }
217
- state.pushCommand({
221
+ activator.pushCommand({
218
222
  scheduleLocalActivity: {
219
223
  seq,
220
224
  attempt,
@@ -222,7 +226,7 @@ async function scheduleLocalActivityNextHandler({
222
226
  // Intentionally not exposing activityId as an option
223
227
  activityId: `${seq}`,
224
228
  activityType,
225
- arguments: toPayloads(state.payloadConverter, ...args),
229
+ arguments: toPayloads(activator.payloadConverter, ...args),
226
230
  retryPolicy: options.retry ? compileRetryPolicy(options.retry) : undefined,
227
231
  scheduleToCloseTimeout: msOptionalToTs(options.scheduleToCloseTimeout),
228
232
  startToCloseTimeout: msOptionalToTs(options.startToCloseTimeout),
@@ -232,7 +236,7 @@ async function scheduleLocalActivityNextHandler({
232
236
  cancellationType: options.cancellationType,
233
237
  },
234
238
  });
235
- state.completions.activity.set(seq, {
239
+ activator.completions.activity.set(seq, {
236
240
  resolve,
237
241
  reject,
238
242
  });
@@ -244,11 +248,12 @@ async function scheduleLocalActivityNextHandler({
244
248
  * @hidden
245
249
  */
246
250
  export function scheduleActivity<R>(activityType: string, args: any[], options: ActivityOptions): Promise<R> {
251
+ const activator = getActivator();
247
252
  if (options === undefined) {
248
253
  throw new TypeError('Got empty activity options');
249
254
  }
250
- const seq = state.nextSeqs.activity++;
251
- const execute = composeInterceptors(state.interceptors.outbound, 'scheduleActivity', scheduleActivityNextHandler);
255
+ const seq = activator.nextSeqs.activity++;
256
+ const execute = composeInterceptors(activator.interceptors.outbound, 'scheduleActivity', scheduleActivityNextHandler);
252
257
 
253
258
  return execute({
254
259
  activityType,
@@ -268,6 +273,7 @@ export async function scheduleLocalActivity<R>(
268
273
  args: any[],
269
274
  options: LocalActivityOptions
270
275
  ): Promise<R> {
276
+ const activator = getActivator();
271
277
  if (options === undefined) {
272
278
  throw new TypeError('Got empty activity options');
273
279
  }
@@ -276,9 +282,9 @@ export async function scheduleLocalActivity<R>(
276
282
  let originalScheduleTime = undefined;
277
283
 
278
284
  for (;;) {
279
- const seq = state.nextSeqs.activity++;
285
+ const seq = activator.nextSeqs.activity++;
280
286
  const execute = composeInterceptors(
281
- state.interceptors.outbound,
287
+ activator.interceptors.outbound,
282
288
  'scheduleLocalActivity',
283
289
  scheduleLocalActivityNextHandler
284
290
  );
@@ -314,6 +320,7 @@ function startChildWorkflowExecutionNextHandler({
314
320
  workflowType,
315
321
  seq,
316
322
  }: StartChildWorkflowExecutionInput): Promise<[Promise<string>, Promise<unknown>]> {
323
+ const activator = getActivator();
317
324
  const workflowId = options.workflowId ?? uuid4();
318
325
  const startPromise = new Promise<string>((resolve, reject) => {
319
326
  const scope = CancellationScope.current();
@@ -324,10 +331,10 @@ function startChildWorkflowExecutionNextHandler({
324
331
  if (scope.cancellable) {
325
332
  untrackPromise(
326
333
  scope.cancelRequested.catch(() => {
327
- const complete = !state.completions.childWorkflowComplete.has(seq);
334
+ const complete = !activator.completions.childWorkflowComplete.has(seq);
328
335
 
329
336
  if (!complete) {
330
- state.pushCommand({
337
+ activator.pushCommand({
331
338
  cancelChildWorkflowExecution: { childWorkflowSeq: seq },
332
339
  });
333
340
  }
@@ -335,14 +342,14 @@ function startChildWorkflowExecutionNextHandler({
335
342
  })
336
343
  );
337
344
  }
338
- state.pushCommand({
345
+ activator.pushCommand({
339
346
  startChildWorkflowExecution: {
340
347
  seq,
341
348
  workflowId,
342
349
  workflowType,
343
- input: toPayloads(state.payloadConverter, ...options.args),
350
+ input: toPayloads(activator.payloadConverter, ...options.args),
344
351
  retryPolicy: options.retry ? compileRetryPolicy(options.retry) : undefined,
345
- taskQueue: options.taskQueue || state.info?.taskQueue,
352
+ taskQueue: options.taskQueue || activator.info?.taskQueue,
346
353
  workflowExecutionTimeout: msOptionalToTs(options.workflowExecutionTimeout),
347
354
  workflowRunTimeout: msOptionalToTs(options.workflowRunTimeout),
348
355
  workflowTaskTimeout: msOptionalToTs(options.workflowTaskTimeout),
@@ -355,10 +362,10 @@ function startChildWorkflowExecutionNextHandler({
355
362
  searchAttributes: options.searchAttributes
356
363
  ? mapToPayloads(searchAttributePayloadConverter, options.searchAttributes)
357
364
  : undefined,
358
- memo: options.memo && mapToPayloads(state.payloadConverter, options.memo),
365
+ memo: options.memo && mapToPayloads(activator.payloadConverter, options.memo),
359
366
  },
360
367
  });
361
- state.completions.childWorkflowStart.set(seq, {
368
+ activator.completions.childWorkflowStart.set(seq, {
362
369
  resolve,
363
370
  reject,
364
371
  });
@@ -369,7 +376,7 @@ function startChildWorkflowExecutionNextHandler({
369
376
  const completePromise = new Promise((resolve, reject) => {
370
377
  // Chain start Promise rejection to the complete Promise.
371
378
  untrackPromise(startPromise.catch(reject));
372
- state.completions.childWorkflowComplete.set(seq, {
379
+ activator.completions.childWorkflowComplete.set(seq, {
373
380
  resolve,
374
381
  reject,
375
382
  });
@@ -384,10 +391,8 @@ function startChildWorkflowExecutionNextHandler({
384
391
  }
385
392
 
386
393
  function signalWorkflowNextHandler({ seq, signalName, args, target, headers }: SignalWorkflowInput) {
394
+ const activator = getActivator();
387
395
  return new Promise<any>((resolve, reject) => {
388
- if (state.info === undefined) {
389
- throw new IllegalStateError('Workflow uninitialized');
390
- }
391
396
  const scope = CancellationScope.current();
392
397
  if (scope.consideredCancelled) {
393
398
  untrackPromise(scope.cancelRequested.catch(reject));
@@ -397,23 +402,23 @@ function signalWorkflowNextHandler({ seq, signalName, args, target, headers }: S
397
402
  if (scope.cancellable) {
398
403
  untrackPromise(
399
404
  scope.cancelRequested.catch(() => {
400
- if (!state.completions.signalWorkflow.has(seq)) {
405
+ if (!activator.completions.signalWorkflow.has(seq)) {
401
406
  return;
402
407
  }
403
- state.pushCommand({ cancelSignalWorkflow: { seq } });
408
+ activator.pushCommand({ cancelSignalWorkflow: { seq } });
404
409
  })
405
410
  );
406
411
  }
407
- state.pushCommand({
412
+ activator.pushCommand({
408
413
  signalExternalWorkflowExecution: {
409
414
  seq,
410
- args: toPayloads(state.payloadConverter, ...args),
415
+ args: toPayloads(activator.payloadConverter, ...args),
411
416
  headers,
412
417
  signalName,
413
418
  ...(target.type === 'external'
414
419
  ? {
415
420
  workflowExecution: {
416
- namespace: state.info.namespace,
421
+ namespace: activator.info.namespace,
417
422
  ...target.workflowExecution,
418
423
  },
419
424
  }
@@ -423,7 +428,7 @@ function signalWorkflowNextHandler({ seq, signalName, args, target, headers }: S
423
428
  },
424
429
  });
425
430
 
426
- state.completions.signalWorkflow.set(seq, { resolve, reject });
431
+ activator.completions.signalWorkflow.set(seq, { resolve, reject });
427
432
  });
428
433
  }
429
434
 
@@ -564,15 +569,12 @@ const EXTERNAL_WF_CANCEL_PATCH = '__temporal_internal_connect_external_handle_ca
564
569
  * It takes a Workflow ID and optional run ID.
565
570
  */
566
571
  export function getExternalWorkflowHandle(workflowId: string, runId?: string): ExternalWorkflowHandle {
572
+ const activator = getActivator();
567
573
  return {
568
574
  workflowId,
569
575
  runId,
570
576
  cancel() {
571
577
  return new Promise<void>((resolve, reject) => {
572
- if (state.info === undefined) {
573
- throw new IllegalStateError('Uninitialized workflow');
574
- }
575
-
576
578
  // Connect this cancel operation to the current cancellation scope.
577
579
  // This is behavior was introduced after v0.22.0 and is incompatible
578
580
  // with histories generated with previous SDK versions and thus requires
@@ -596,27 +598,27 @@ export function getExternalWorkflowHandle(workflowId: string, runId?: string): E
596
598
  }
597
599
  }
598
600
 
599
- const seq = state.nextSeqs.cancelWorkflow++;
600
- state.pushCommand({
601
+ const seq = activator.nextSeqs.cancelWorkflow++;
602
+ activator.pushCommand({
601
603
  requestCancelExternalWorkflowExecution: {
602
604
  seq,
603
605
  workflowExecution: {
604
- namespace: state.info.namespace,
606
+ namespace: activator.info.namespace,
605
607
  workflowId,
606
608
  runId,
607
609
  },
608
610
  },
609
611
  });
610
- state.completions.cancelWorkflow.set(seq, { resolve, reject });
612
+ activator.completions.cancelWorkflow.set(seq, { resolve, reject });
611
613
  });
612
614
  },
613
615
  signal<Args extends any[]>(def: SignalDefinition<Args> | string, ...args: Args): Promise<void> {
614
616
  return composeInterceptors(
615
- state.interceptors.outbound,
617
+ activator.interceptors.outbound,
616
618
  'signalWorkflow',
617
619
  signalWorkflowNextHandler
618
620
  )({
619
- seq: state.nextSeqs.signalWorkflow++,
621
+ seq: activator.nextSeqs.signalWorkflow++,
620
622
  signalName: typeof def === 'string' ? def : def.name,
621
623
  args,
622
624
  target: {
@@ -689,15 +691,16 @@ export async function startChild<T extends Workflow>(
689
691
  workflowTypeOrFunc: string | T,
690
692
  options?: WithWorkflowArgs<T, ChildWorkflowOptions>
691
693
  ): Promise<ChildWorkflowHandle<T>> {
694
+ const activator = getActivator();
692
695
  const optionsWithDefaults = addDefaultWorkflowOptions(options ?? {});
693
696
  const workflowType = typeof workflowTypeOrFunc === 'string' ? workflowTypeOrFunc : workflowTypeOrFunc.name;
694
697
  const execute = composeInterceptors(
695
- state.interceptors.outbound,
698
+ activator.interceptors.outbound,
696
699
  'startChildWorkflowExecution',
697
700
  startChildWorkflowExecutionNextHandler
698
701
  );
699
702
  const [started, completed] = await execute({
700
- seq: state.nextSeqs.childWorkflow++,
703
+ seq: activator.nextSeqs.childWorkflow++,
701
704
  options: optionsWithDefaults,
702
705
  headers: {},
703
706
  workflowType,
@@ -712,11 +715,11 @@ export async function startChild<T extends Workflow>(
712
715
  },
713
716
  async signal<Args extends any[]>(def: SignalDefinition<Args> | string, ...args: Args): Promise<void> {
714
717
  return composeInterceptors(
715
- state.interceptors.outbound,
718
+ activator.interceptors.outbound,
716
719
  'signalWorkflow',
717
720
  signalWorkflowNextHandler
718
721
  )({
719
- seq: state.nextSeqs.signalWorkflow++,
722
+ seq: activator.nextSeqs.signalWorkflow++,
720
723
  signalName: typeof def === 'string' ? def : def.name,
721
724
  args,
722
725
  target: {
@@ -787,15 +790,16 @@ export async function executeChild<T extends Workflow>(
787
790
  workflowTypeOrFunc: string | T,
788
791
  options?: WithWorkflowArgs<T, ChildWorkflowOptions>
789
792
  ): Promise<WorkflowResultType<T>> {
793
+ const activator = getActivator();
790
794
  const optionsWithDefaults = addDefaultWorkflowOptions(options ?? {});
791
795
  const workflowType = typeof workflowTypeOrFunc === 'string' ? workflowTypeOrFunc : workflowTypeOrFunc.name;
792
796
  const execute = composeInterceptors(
793
- state.interceptors.outbound,
797
+ activator.interceptors.outbound,
794
798
  'startChildWorkflowExecution',
795
799
  startChildWorkflowExecutionNextHandler
796
800
  );
797
801
  const execPromise = execute({
798
- seq: state.nextSeqs.childWorkflow++,
802
+ seq: activator.nextSeqs.childWorkflow++,
799
803
  options: optionsWithDefaults,
800
804
  headers: {},
801
805
  workflowType,
@@ -832,10 +836,7 @@ export async function executeChild<T extends Workflow>(
832
836
  * }
833
837
  */
834
838
  export function workflowInfo(): WorkflowInfo {
835
- if (state.info === undefined) {
836
- throw new IllegalStateError('Workflow uninitialized');
837
- }
838
- return state.info;
839
+ return getActivator().info;
839
840
  }
840
841
 
841
842
  /**
@@ -843,7 +844,7 @@ export function workflowInfo(): WorkflowInfo {
843
844
  */
844
845
  export function inWorkflowContext(): boolean {
845
846
  try {
846
- workflowInfo();
847
+ getActivator();
847
848
  return true;
848
849
  } catch (err: any) {
849
850
  // Use string comparison in case multiple versions of @temporalio/common are
@@ -896,7 +897,8 @@ export function proxySinks<T extends Sinks>(): T {
896
897
  {
897
898
  get(_, fnName) {
898
899
  return (...args: any[]) => {
899
- state.sinkCalls.push({
900
+ const activator = getActivator();
901
+ activator.sinkCalls.push({
900
902
  ifaceName: ifaceName as string,
901
903
  fnName: fnName as string,
902
904
  args,
@@ -920,6 +922,7 @@ export function proxySinks<T extends Sinks>(): T {
920
922
  export function makeContinueAsNewFunc<F extends Workflow>(
921
923
  options?: ContinueAsNewOptions
922
924
  ): (...args: Parameters<F>) => Promise<never> {
925
+ const activator = getActivator();
923
926
  const info = workflowInfo();
924
927
  const { workflowType, taskQueue, ...rest } = options ?? {};
925
928
  const requiredOptions = {
@@ -929,14 +932,14 @@ export function makeContinueAsNewFunc<F extends Workflow>(
929
932
  };
930
933
 
931
934
  return (...args: Parameters<F>): Promise<never> => {
932
- const fn = composeInterceptors(state.interceptors.outbound, 'continueAsNew', async (input) => {
935
+ const fn = composeInterceptors(activator.interceptors.outbound, 'continueAsNew', async (input) => {
933
936
  const { headers, args, options } = input;
934
937
  throw new ContinueAsNew({
935
938
  workflowType: options.workflowType,
936
- arguments: toPayloads(state.payloadConverter, ...args),
939
+ arguments: toPayloads(activator.payloadConverter, ...args),
937
940
  headers,
938
941
  taskQueue: options.taskQueue,
939
- memo: options.memo,
942
+ memo: options.memo && mapToPayloads(activator.payloadConverter, options.memo),
940
943
  searchAttributes: options.searchAttributes
941
944
  ? mapToPayloads(searchAttributePayloadConverter, options.searchAttributes)
942
945
  : undefined,
@@ -1043,23 +1046,21 @@ export function deprecatePatch(patchId: string): void {
1043
1046
  }
1044
1047
 
1045
1048
  function patchInternal(patchId: string, deprecated: boolean): boolean {
1049
+ const activator = getActivator();
1046
1050
  // Patch operation does not support interception at the moment, if it did,
1047
1051
  // this would be the place to start the interception chain
1048
1052
 
1049
- if (state.workflow === undefined) {
1053
+ if (activator.workflow === undefined) {
1050
1054
  throw new IllegalStateError('Patches cannot be used before Workflow starts');
1051
1055
  }
1052
- if (state.info === undefined) {
1053
- throw new IllegalStateError('Workflow uninitialized');
1054
- }
1055
- const usePatch = !state.info.unsafe.isReplaying || state.knownPresentPatches.has(patchId);
1056
+ const usePatch = !activator.info.unsafe.isReplaying || activator.knownPresentPatches.has(patchId);
1056
1057
  // Avoid sending commands for patches core already knows about.
1057
1058
  // This optimization enables development of automatic patching tools.
1058
- if (usePatch && !state.sentPatches.has(patchId)) {
1059
- state.pushCommand({
1059
+ if (usePatch && !activator.sentPatches.has(patchId)) {
1060
+ activator.pushCommand({
1060
1061
  setPatchMarker: { patchId, deprecated },
1061
1062
  });
1062
- state.sentPatches.add(patchId);
1063
+ activator.sentPatches.add(patchId);
1063
1064
  }
1064
1065
  return usePatch;
1065
1066
  }
@@ -1079,7 +1080,11 @@ export function condition(fn: () => boolean, timeout: number | string): Promise<
1079
1080
  export function condition(fn: () => boolean): Promise<void>;
1080
1081
 
1081
1082
  export async function condition(fn: () => boolean, timeout?: number | string): Promise<void | boolean> {
1082
- if (timeout) {
1083
+ // Prior to 1.5.0, `condition(fn, 0)` was treated as equivalent to `condition(fn, undefined)`
1084
+ if (timeout === 0 && !getActivator().checkInternalPatchAtLeast(1)) {
1085
+ return conditionInner(fn);
1086
+ }
1087
+ if (typeof timeout === 'number' || typeof timeout === 'string') {
1083
1088
  return CancellationScope.cancellable(async () => {
1084
1089
  try {
1085
1090
  return await Promise.race([sleep(timeout).then(() => false), conditionInner(fn).then(() => true)]);
@@ -1092,6 +1097,7 @@ export async function condition(fn: () => boolean, timeout?: number | string): P
1092
1097
  }
1093
1098
 
1094
1099
  function conditionInner(fn: () => boolean): Promise<void> {
1100
+ const activator = getActivator();
1095
1101
  return new Promise((resolve, reject) => {
1096
1102
  const scope = CancellationScope.current();
1097
1103
  if (scope.consideredCancelled) {
@@ -1099,11 +1105,11 @@ function conditionInner(fn: () => boolean): Promise<void> {
1099
1105
  return;
1100
1106
  }
1101
1107
 
1102
- const seq = state.nextSeqs.condition++;
1108
+ const seq = activator.nextSeqs.condition++;
1103
1109
  if (scope.cancellable) {
1104
1110
  untrackPromise(
1105
1111
  scope.cancelRequested.catch((err) => {
1106
- state.blockedConditions.delete(seq);
1112
+ activator.blockedConditions.delete(seq);
1107
1113
  reject(err);
1108
1114
  })
1109
1115
  );
@@ -1115,7 +1121,7 @@ function conditionInner(fn: () => boolean): Promise<void> {
1115
1121
  return;
1116
1122
  }
1117
1123
 
1118
- state.blockedConditions.set(seq, { fn, resolve });
1124
+ activator.blockedConditions.set(seq, { fn, resolve });
1119
1125
  });
1120
1126
  }
1121
1127
 
@@ -1170,17 +1176,18 @@ export function setHandler<Ret, Args extends any[], T extends SignalDefinition<A
1170
1176
  def: T,
1171
1177
  handler: Handler<Ret, Args, T> | undefined
1172
1178
  ): void {
1179
+ const activator = getActivator();
1173
1180
  if (def.type === 'signal') {
1174
- state.signalHandlers.set(def.name, handler as any);
1175
- const bufferedSignals = state.bufferedSignals.get(def.name);
1181
+ activator.signalHandlers.set(def.name, handler as any);
1182
+ const bufferedSignals = activator.bufferedSignals.get(def.name);
1176
1183
  if (bufferedSignals !== undefined && handler !== undefined) {
1177
- state.bufferedSignals.delete(def.name);
1184
+ activator.bufferedSignals.delete(def.name);
1178
1185
  for (const signal of bufferedSignals) {
1179
- state.activator.signalWorkflow(signal);
1186
+ activator.signalWorkflow(signal);
1180
1187
  }
1181
1188
  }
1182
1189
  } else if (def.type === 'query') {
1183
- state.queryHandlers.set(def.name, handler as any);
1190
+ activator.queryHandlers.set(def.name, handler as any);
1184
1191
  } else {
1185
1192
  throw new TypeError(`Invalid definition type: ${(def as any).type}`);
1186
1193
  }
@@ -1216,22 +1223,20 @@ export function setHandler<Ret, Args extends any[], T extends SignalDefinition<A
1216
1223
  * @param searchAttributes The Record to merge. Use a value of `[]` to clear a Search Attribute.
1217
1224
  */
1218
1225
  export function upsertSearchAttributes(searchAttributes: SearchAttributes): void {
1219
- if (!state.info) {
1220
- throw new IllegalStateError('`state.info` should be defined');
1221
- }
1226
+ const activator = getActivator();
1222
1227
 
1223
- const mergedSearchAttributes = { ...state.info.searchAttributes, ...searchAttributes };
1228
+ const mergedSearchAttributes = { ...activator.info.searchAttributes, ...searchAttributes };
1224
1229
  if (!mergedSearchAttributes) {
1225
1230
  throw new Error('searchAttributes must be a non-null SearchAttributes');
1226
1231
  }
1227
1232
 
1228
- state.pushCommand({
1233
+ activator.pushCommand({
1229
1234
  upsertWorkflowSearchAttributes: {
1230
1235
  searchAttributes: mapToPayloads(searchAttributePayloadConverter, searchAttributes),
1231
1236
  },
1232
1237
  });
1233
1238
 
1234
- state.info.searchAttributes = mergedSearchAttributes;
1239
+ activator.info.searchAttributes = mergedSearchAttributes;
1235
1240
  }
1236
1241
 
1237
1242
  export const stackTraceQuery = defineQuery<string>('__stack_trace');