@temporalio/common 1.8.0 → 1.8.2

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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.assertNever = exports.errorCode = exports.errorMessage = exports.hasOwnProperties = exports.hasOwnProperty = exports.isRecord = exports.checkExtends = void 0;
3
+ exports.SymbolBasedInstanceOfError = exports.assertNever = exports.errorCode = exports.errorMessage = exports.isAbortError = exports.isError = exports.hasOwnProperties = exports.hasOwnProperty = exports.isRecord = exports.checkExtends = void 0;
4
4
  /** Verify that an type _Copy extends _Orig */
5
5
  function checkExtends() {
6
6
  // noop, just type check
@@ -10,7 +10,6 @@ function isRecord(value) {
10
10
  return typeof value === 'object' && value !== null;
11
11
  }
12
12
  exports.isRecord = isRecord;
13
- // ts-prune-ignore-next
14
13
  function hasOwnProperty(record, prop) {
15
14
  return prop in record;
16
15
  }
@@ -19,26 +18,38 @@ function hasOwnProperties(record, props) {
19
18
  return props.every((prop) => prop in record);
20
19
  }
21
20
  exports.hasOwnProperties = hasOwnProperties;
21
+ function isError(error) {
22
+ return (isRecord(error) &&
23
+ typeof error.name === 'string' &&
24
+ typeof error.message === 'string' &&
25
+ (error.stack == null || typeof error.stack === 'string'));
26
+ }
27
+ exports.isError = isError;
28
+ function isAbortError(error) {
29
+ return isError(error) && error.name === 'AbortError';
30
+ }
31
+ exports.isAbortError = isAbortError;
22
32
  /**
23
33
  * Get `error.message` (or `undefined` if not present)
24
34
  */
25
35
  function errorMessage(error) {
26
- if (typeof error === 'string') {
27
- return error;
28
- }
29
- if (error instanceof Error) {
36
+ if (isError(error)) {
30
37
  return error.message;
31
38
  }
39
+ else if (typeof error === 'string') {
40
+ return error;
41
+ }
32
42
  return undefined;
33
43
  }
34
44
  exports.errorMessage = errorMessage;
45
+ function isErrorWithCode(error) {
46
+ return isRecord(error) && typeof error.code === 'string';
47
+ }
35
48
  /**
36
49
  * Get `error.code` (or `undefined` if not present)
37
50
  */
38
51
  function errorCode(error) {
39
- if (typeof error === 'object' &&
40
- error.code !== undefined &&
41
- typeof error.code === 'string') {
52
+ if (isErrorWithCode(error)) {
42
53
  return error.code;
43
54
  }
44
55
  return undefined;
@@ -51,4 +62,54 @@ function assertNever(msg, x) {
51
62
  throw new TypeError(msg + ': ' + x);
52
63
  }
53
64
  exports.assertNever = assertNever;
65
+ /**
66
+ * A decorator to be used on error classes. It adds the 'name' property AND provides a custom
67
+ * 'instanceof' handler that works correctly across execution contexts.
68
+ *
69
+ * ### Details ###
70
+ *
71
+ * According to the EcmaScript's spec, the default behavior of JavaScript's `x instanceof Y` operator is to walk up the
72
+ * prototype chain of object 'x', checking if any constructor in that hierarchy is _exactly the same object_ as the
73
+ * constructor function 'Y'.
74
+ *
75
+ * Unfortunately, it happens in various situations that different constructor function objects get created for what
76
+ * appears to be the very same class. This leads to surprising behavior where `instanceof` returns false though it is
77
+ * known that the object is indeed an instance of that class. One particular case where this happens is when constructor
78
+ * 'Y' belongs to a different realm than the constuctor with which 'x' was instantiated. Another case is when two copies
79
+ * of the same library gets loaded in the same realm.
80
+ *
81
+ * In practice, this tends to cause issues when crossing the workflow-sandboxing boundary (since Node's vm module
82
+ * really creates new execution realms), as well as when running tests using Jest (see https://github.com/jestjs/jest/issues/2549
83
+ * for some details on that one).
84
+ *
85
+ * This function injects a custom 'instanceof' handler into the prototype of 'clazz', which is both cross-realm safe and
86
+ * cross-copies-of-the-same-lib safe. It works by adding a special symbol property to the prototype of 'clazz', and then
87
+ * checking for the presence of that symbol.
88
+ */
89
+ function SymbolBasedInstanceOfError(markerName) {
90
+ return (clazz) => {
91
+ const marker = Symbol.for(`__temporal_is${markerName}`);
92
+ Object.defineProperty(clazz.prototype, 'name', { value: markerName, enumerable: true });
93
+ Object.defineProperty(clazz.prototype, marker, { value: true, enumerable: false });
94
+ Object.defineProperty(clazz, Symbol.hasInstance, {
95
+ // eslint-disable-next-line object-shorthand
96
+ value: function (error) {
97
+ if (this === clazz) {
98
+ return isRecord(error) && error[marker] === true;
99
+ }
100
+ else {
101
+ // 'this' must be a _subclass_ of clazz that doesn't redefined [Symbol.hasInstance], so that it inherited
102
+ // from clazz's [Symbol.hasInstance]. If we don't handle this particular situation, then
103
+ // `x instanceof SubclassOfParent` would return true for any instance of 'Parent', which is clearly wrong.
104
+ //
105
+ // Ideally, it'd be preferable to avoid this case entirely, by making sure that all subclasses of 'clazz'
106
+ // redefine [Symbol.hasInstance], but we can't enforce that. We therefore fallback to the default instanceof
107
+ // behavior (which is NOT cross-realm safe).
108
+ return this.prototype.isPrototypeOf(error); // eslint-disable-line no-prototype-builtins
109
+ }
110
+ },
111
+ });
112
+ };
113
+ }
114
+ exports.SymbolBasedInstanceOfError = SymbolBasedInstanceOfError;
54
115
  //# sourceMappingURL=type-helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"type-helpers.js","sourceRoot":"","sources":["../src/type-helpers.ts"],"names":[],"mappings":";;;AAYA,8CAA8C;AAC9C,SAAgB,YAAY;IAC1B,wBAAwB;AAC1B,CAAC;AAFD,oCAEC;AAID,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAFD,4BAEC;AAED,uBAAuB;AACvB,SAAgB,cAAc,CAC5B,MAAS,EACT,IAAO;IAEP,OAAO,IAAI,IAAI,MAAM,CAAC;AACxB,CAAC;AALD,wCAKC;AAED,SAAgB,gBAAgB,CAC9B,MAAS,EACT,KAAU;IAEV,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC;AAC/C,CAAC;AALD,4CAKC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,OAAO,KAAK,CAAC;KACd;IACD,IAAI,KAAK,YAAY,KAAK,EAAE;QAC1B,OAAO,KAAK,CAAC,OAAO,CAAC;KACtB;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AARD,oCAQC;AAKD;;GAEG;AACH,SAAgB,SAAS,CAAC,KAAc;IACtC,IACE,OAAO,KAAK,KAAK,QAAQ;QACxB,KAAuB,CAAC,IAAI,KAAK,SAAS;QAC3C,OAAQ,KAAuB,CAAC,IAAI,KAAK,QAAQ,EACjD;QACA,OAAQ,KAAuB,CAAC,IAAI,CAAC;KACtC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAVD,8BAUC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,GAAW,EAAE,CAAQ;IAC/C,MAAM,IAAI,SAAS,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC;AAFD,kCAEC"}
1
+ {"version":3,"file":"type-helpers.js","sourceRoot":"","sources":["../src/type-helpers.ts"],"names":[],"mappings":";;;AAYA,8CAA8C;AAC9C,SAAgB,YAAY;IAC1B,wBAAwB;AAC1B,CAAC;AAFD,oCAEC;AAID,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAFD,4BAEC;AAED,SAAgB,cAAc,CAC5B,MAAS,EACT,IAAO;IAEP,OAAO,IAAI,IAAI,MAAM,CAAC;AACxB,CAAC;AALD,wCAKC;AAED,SAAgB,gBAAgB,CAC9B,MAAS,EACT,KAAU;IAEV,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC;AAC/C,CAAC;AALD,4CAKC;AAED,SAAgB,OAAO,CAAC,KAAc;IACpC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CACzD,CAAC;AACJ,CAAC;AAPD,0BAOC;AAED,SAAgB,YAAY,CAAC,KAAc;IACzC,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC;AACvD,CAAC;AAFD,oCAEC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;QAClB,OAAO,KAAK,CAAC,OAAO,CAAC;KACtB;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACpC,OAAO,KAAK,CAAC;KACd;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAPD,oCAOC;AAMD,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,KAAc;IACtC,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE;QAC1B,OAAO,KAAK,CAAC,IAAI,CAAC;KACnB;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAND,8BAMC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,GAAW,EAAE,CAAQ;IAC/C,MAAM,IAAI,SAAS,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC;AAFD,kCAEC;AAOD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,0BAA0B,CAAkB,UAAkB;IAC5E,OAAO,CAAC,KAAe,EAAQ,EAAE;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;QAExD,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACxF,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QACnF,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE;YAC/C,4CAA4C;YAC5C,KAAK,EAAE,UAAqB,KAAa;gBACvC,IAAI,IAAI,KAAK,KAAK,EAAE;oBAClB,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAK,KAAa,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;iBAC3D;qBAAM;oBACL,yGAAyG;oBACzG,wFAAwF;oBACxF,0GAA0G;oBAC1G,EAAE;oBACF,yGAAyG;oBACzG,4GAA4G;oBAC5G,4CAA4C;oBAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,4CAA4C;iBACzF;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAxBD,gEAwBC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Indicates whether the user intends certain commands to be run on a compatible worker Build Id
3
+ * version or not.
4
+ *
5
+ * `COMPATIBLE` indicates that the command should run on a worker with compatible version if
6
+ * possible. It may not be possible if the target task queue does not also have knowledge of the
7
+ * current worker's Build Id.
8
+ *
9
+ * `DEFAULT` indicates that the command should run on the target task queue's current
10
+ * overall-default Build Id.
11
+ *
12
+ * Where this type is accepted optionally, an unset value indicates that the SDK should choose the
13
+ * most sensible default behavior for the type of command, accounting for whether the command will
14
+ * be run on the same task queue as the current worker.
15
+ *
16
+ * @experimental
17
+ */
18
+ export type VersioningIntent = 'COMPATIBLE' | 'DEFAULT';
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=versioning-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versioning-intent.js","sourceRoot":"","sources":["../src/versioning-intent.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporalio/common",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "Common library for code that's used across the Client, Worker, and/or Workflow",
5
5
  "main": "lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -13,7 +13,7 @@
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
15
  "@opentelemetry/api": "^1.4.1",
16
- "@temporalio/proto": "1.8.0",
16
+ "@temporalio/proto": "1.8.2",
17
17
  "long": "^5.2.0",
18
18
  "ms": "^3.0.0-canary.1",
19
19
  "proto3-json-serializer": "^1.0.3",
@@ -35,5 +35,5 @@
35
35
  "src",
36
36
  "lib"
37
37
  ],
38
- "gitHead": "17d16e4dca39513470dd4b6e30d9af06dafd00d6"
38
+ "gitHead": "d85bf54da757741b438f8d39a0e7265b80d4f0d6"
39
39
  }
@@ -2,6 +2,7 @@ import type { coresdk } from '@temporalio/proto';
2
2
  import { RetryPolicy } from './retry-policy';
3
3
  import { checkExtends } from './type-helpers';
4
4
  import { Duration } from './time';
5
+ import { VersioningIntent } from './versioning-intent';
5
6
 
6
7
  // Avoid importing the proto implementation to reduce workflow bundle size
7
8
  // Copied from coresdk.workflow_commands.ActivityCancellationType
@@ -100,6 +101,14 @@ export interface ActivityOptions {
100
101
  * @default true
101
102
  */
102
103
  allowEagerDispatch?: boolean;
104
+
105
+ /**
106
+ * When using the Worker Versioning feature, specifies whether this Activity should run on a
107
+ * worker with a compatible Build Id or not. See {@link VersioningIntent}.
108
+ *
109
+ * @experimental
110
+ */
111
+ versioningIntent?: VersioningIntent;
103
112
  }
104
113
 
105
114
  /**
@@ -12,7 +12,7 @@ import {
12
12
  TimeoutFailure,
13
13
  TimeoutType,
14
14
  } from '../failure';
15
- import { hasOwnProperties, isRecord } from '../type-helpers';
15
+ import { isError } from '../type-helpers';
16
16
  import { arrayFromPayloads, fromPayloadsAtIndex, PayloadConverter, toPayloads } from './payload-converter';
17
17
 
18
18
  /**
@@ -219,7 +219,7 @@ export class DefaultFailureConverter implements FailureConverter {
219
219
  }
220
220
 
221
221
  errorToFailureInner(err: unknown, payloadConverter: PayloadConverter): ProtoFailure {
222
- if (TemporalFailure.is(err)) {
222
+ if (err instanceof TemporalFailure) {
223
223
  if (err.failure) return err.failure;
224
224
  const base = {
225
225
  message: err.message,
@@ -228,7 +228,7 @@ export class DefaultFailureConverter implements FailureConverter {
228
228
  source: FAILURE_SOURCE,
229
229
  };
230
230
 
231
- if (ActivityFailure.is(err)) {
231
+ if (err instanceof ActivityFailure) {
232
232
  return {
233
233
  ...base,
234
234
  activityFailureInfo: {
@@ -237,7 +237,7 @@ export class DefaultFailureConverter implements FailureConverter {
237
237
  },
238
238
  };
239
239
  }
240
- if (ChildWorkflowFailure.is(err)) {
240
+ if (err instanceof ChildWorkflowFailure) {
241
241
  return {
242
242
  ...base,
243
243
  childWorkflowExecutionFailureInfo: {
@@ -247,7 +247,7 @@ export class DefaultFailureConverter implements FailureConverter {
247
247
  },
248
248
  };
249
249
  }
250
- if (ApplicationFailure.is(err)) {
250
+ if (err instanceof ApplicationFailure) {
251
251
  return {
252
252
  ...base,
253
253
  applicationFailureInfo: {
@@ -260,7 +260,7 @@ export class DefaultFailureConverter implements FailureConverter {
260
260
  },
261
261
  };
262
262
  }
263
- if (CancelledFailure.is(err)) {
263
+ if (err instanceof CancelledFailure) {
264
264
  return {
265
265
  ...base,
266
266
  canceledFailureInfo: {
@@ -271,7 +271,7 @@ export class DefaultFailureConverter implements FailureConverter {
271
271
  },
272
272
  };
273
273
  }
274
- if (TimeoutFailure.is(err)) {
274
+ if (err instanceof TimeoutFailure) {
275
275
  return {
276
276
  ...base,
277
277
  timeoutFailureInfo: {
@@ -282,13 +282,13 @@ export class DefaultFailureConverter implements FailureConverter {
282
282
  },
283
283
  };
284
284
  }
285
- if (ServerFailure.is(err)) {
285
+ if (err instanceof ServerFailure) {
286
286
  return {
287
287
  ...base,
288
288
  serverFailureInfo: { nonRetryable: err.nonRetryable },
289
289
  };
290
290
  }
291
- if (TerminatedFailure.is(err)) {
291
+ if (err instanceof TerminatedFailure) {
292
292
  return {
293
293
  ...base,
294
294
  terminatedFailureInfo: {},
@@ -302,12 +302,12 @@ export class DefaultFailureConverter implements FailureConverter {
302
302
  source: FAILURE_SOURCE,
303
303
  };
304
304
 
305
- if (isRecord(err) && hasOwnProperties(err, ['message', 'stack'])) {
305
+ if (isError(err)) {
306
306
  return {
307
307
  ...base,
308
308
  message: String(err.message) ?? '',
309
- stackTrace: cutoffStackTrace(String(err.stack)),
310
- cause: this.optionalErrorToOptionalFailure(err.cause, payloadConverter),
309
+ stackTrace: cutoffStackTrace(err.stack),
310
+ cause: this.optionalErrorToOptionalFailure((err as any).cause, payloadConverter),
311
311
  };
312
312
  }
313
313
 
@@ -260,7 +260,7 @@ export class SearchAttributePayloadConverter implements PayloadConverter {
260
260
  validNonDateTypes = ['string', 'number', 'boolean'];
261
261
 
262
262
  public toPayload(values: unknown): Payload {
263
- if (!(values instanceof Array)) {
263
+ if (!Array.isArray(values)) {
264
264
  throw new ValueError(`SearchAttribute value must be an array`);
265
265
  }
266
266
 
@@ -309,7 +309,7 @@ export class SearchAttributePayloadConverter implements PayloadConverter {
309
309
  }
310
310
 
311
311
  const value = this.jsonConverter.fromPayload(payload);
312
- let arrayWrappedValue = value instanceof Array ? value : [value];
312
+ let arrayWrappedValue = Array.isArray(value) ? value : [value];
313
313
 
314
314
  const searchAttributeType = decode(payload.metadata.type);
315
315
  if (searchAttributeType === 'Datetime') {
@@ -14,6 +14,8 @@ import {
14
14
 
15
15
  import { encodingTypes, METADATA_ENCODING_KEY, METADATA_MESSAGE_TYPE_KEY } from './types';
16
16
 
17
+ const GLOBAL_BUFFER = globalThis.constructor.constructor('return globalThis.Buffer')();
18
+
17
19
  abstract class ProtobufPayloadConverter implements PayloadConverterWithEncoding {
18
20
  protected readonly root: Root | undefined;
19
21
  public abstract encodingType: string;
@@ -121,17 +123,69 @@ export class ProtobufJsonPayloadConverter extends ProtobufPayloadConverter {
121
123
  return undefined;
122
124
  }
123
125
 
124
- const jsonValue = protoJsonSerializer.toProto3JSON(value);
125
-
126
- return this.constructPayload({
127
- messageTypeName: getNamespacedTypeName(value.$type),
128
- message: encode(JSON.stringify(jsonValue)),
129
- });
126
+ const hasBufferChanged = setBufferInGlobal();
127
+ try {
128
+ const jsonValue = protoJsonSerializer.toProto3JSON(value);
129
+
130
+ return this.constructPayload({
131
+ messageTypeName: getNamespacedTypeName(value.$type),
132
+ message: encode(JSON.stringify(jsonValue)),
133
+ });
134
+ } finally {
135
+ resetBufferInGlobal(hasBufferChanged);
136
+ }
130
137
  }
131
138
 
132
139
  public fromPayload<T>(content: Payload): T {
133
- const { messageType, data } = this.validatePayload(content);
134
- return protoJsonSerializer.fromProto3JSON(messageType, JSON.parse(decode(data))) as unknown as T;
140
+ const hasBufferChanged = setBufferInGlobal();
141
+ try {
142
+ const { messageType, data } = this.validatePayload(content);
143
+ const res = protoJsonSerializer.fromProto3JSON(messageType, JSON.parse(decode(data))) as unknown as T;
144
+ if (Buffer.isBuffer(res)) {
145
+ return new Uint8Array(res) as any;
146
+ }
147
+ replaceBuffers(res);
148
+ return res;
149
+ } finally {
150
+ resetBufferInGlobal(hasBufferChanged);
151
+ }
152
+ }
153
+ }
154
+
155
+ function replaceBuffers<X>(obj: X) {
156
+ const replaceBuffersImpl = <Y>(value: any, key: string | number, target: Y) => {
157
+ if (Buffer.isBuffer(value)) {
158
+ // Need to copy. `Buffer` manages a pool slab, internally reused when Buffer objects are GC.
159
+ type T = keyof typeof target;
160
+ target[key as T] = new Uint8Array(value) as any;
161
+ } else {
162
+ replaceBuffers(value);
163
+ }
164
+ };
165
+
166
+ if (obj != null && typeof obj === 'object') {
167
+ // Performance optimization for large arrays
168
+ if (Array.isArray(obj)) {
169
+ obj.forEach(replaceBuffersImpl);
170
+ } else {
171
+ for (const [key, value] of Object.entries(obj)) {
172
+ replaceBuffersImpl(value, key, obj);
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ function setBufferInGlobal(): boolean {
179
+ if (typeof globalThis.Buffer === 'undefined') {
180
+ globalThis.Buffer = GLOBAL_BUFFER;
181
+ return true;
182
+ }
183
+ return false;
184
+ }
185
+
186
+ function resetBufferInGlobal(hasChanged: boolean): void {
187
+ if (hasChanged) {
188
+ delete (globalThis as any).Buffer;
135
189
  }
136
190
  }
137
191
 
package/src/errors.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { TemporalFailure } from './failure';
2
+ import { SymbolBasedInstanceOfError } from './type-helpers';
2
3
 
3
4
  /**
4
5
  * Thrown from code that receives a value that is unexpected or that it's unable to handle.
5
6
  */
7
+ @SymbolBasedInstanceOfError('ValueError')
6
8
  export class ValueError extends Error {
7
- public readonly name: string = 'ValueError';
8
-
9
9
  constructor(message: string | undefined, public readonly cause?: unknown) {
10
10
  super(message ?? undefined);
11
11
  }
@@ -14,18 +14,14 @@ export class ValueError extends Error {
14
14
  /**
15
15
  * Thrown when a Payload Converter is misconfigured.
16
16
  */
17
- export class PayloadConverterError extends ValueError {
18
- public readonly name: string = 'PayloadConverterError';
19
- }
17
+ @SymbolBasedInstanceOfError('PayloadConverterError')
18
+ export class PayloadConverterError extends ValueError {}
20
19
 
21
20
  /**
22
21
  * Used in different parts of the SDK to note that something unexpected has happened.
23
22
  */
24
- export class IllegalStateError extends Error {
25
- public readonly name: string = 'IllegalStateError';
26
- }
27
-
28
- const isWorkflowExecutionAlreadyStartedError = Symbol.for('__temporal_isWorkflowExecutionAlreadyStartedError');
23
+ @SymbolBasedInstanceOfError('IllegalStateError')
24
+ export class IllegalStateError extends Error {}
29
25
 
30
26
  /**
31
27
  * This exception is thrown in the following cases:
@@ -35,27 +31,11 @@ const isWorkflowExecutionAlreadyStartedError = Symbol.for('__temporal_isWorkflow
35
31
  * - There is closed Workflow in the `Completed` state with the same Workflow Id and the {@link WorkflowOptions.workflowIdReusePolicy}
36
32
  * is `WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY`
37
33
  */
34
+ @SymbolBasedInstanceOfError('WorkflowExecutionAlreadyStartedError')
38
35
  export class WorkflowExecutionAlreadyStartedError extends TemporalFailure {
39
- public readonly name: string = 'WorkflowExecutionAlreadyStartedError';
40
-
41
36
  constructor(message: string, public readonly workflowId: string, public readonly workflowType: string) {
42
37
  super(message);
43
38
  }
44
-
45
- /**
46
- * Marker to determine whether an error is an instance of WorkflowExecutionAlreadyStartedError.
47
- */
48
- protected readonly [isWorkflowExecutionAlreadyStartedError] = true;
49
-
50
- /**
51
- * Instanceof check that works when multiple versions of @temporalio/common are installed.
52
- */
53
- static is(error: unknown): error is WorkflowExecutionAlreadyStartedError {
54
- return (
55
- error instanceof WorkflowExecutionAlreadyStartedError ||
56
- (error instanceof Error && (error as any)[isWorkflowExecutionAlreadyStartedError])
57
- );
58
- }
59
39
  }
60
40
 
61
41
  /**
@@ -65,9 +45,8 @@ export class WorkflowExecutionAlreadyStartedError extends TemporalFailure {
65
45
  * - Workflow is closed (for some calls, e.g. `terminate`)
66
46
  * - Workflow was deleted from the Server after reaching its retention limit
67
47
  */
48
+ @SymbolBasedInstanceOfError('WorkflowNotFoundError')
68
49
  export class WorkflowNotFoundError extends Error {
69
- public readonly name: string = 'WorkflowNotFoundError';
70
-
71
50
  constructor(message: string, public readonly workflowId: string, public readonly runId: string | undefined) {
72
51
  super(message);
73
52
  }
@@ -76,9 +55,8 @@ export class WorkflowNotFoundError extends Error {
76
55
  /**
77
56
  * Thrown when the specified namespace is not known to Temporal Server.
78
57
  */
58
+ @SymbolBasedInstanceOfError('NamespaceNotFoundError')
79
59
  export class NamespaceNotFoundError extends Error {
80
- public readonly name: string = 'NamespaceNotFoundError';
81
-
82
60
  constructor(public readonly namespace: string) {
83
61
  super(`Namespace not found: '${namespace}'`);
84
62
  }