Skip to content

Commit 73ebc35

Browse files
authored
fix: Revert all breaking changes since 1.0.1, deprecate sourceMap (#827)
1 parent 92ba36c commit 73ebc35

File tree

13 files changed

+1669
-1612
lines changed

13 files changed

+1669
-1612
lines changed

package-lock.json

Lines changed: 1589 additions & 1566 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/client/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"@temporalio/internal-non-workflow-common": "file:../internal-non-workflow-common",
1919
"@temporalio/internal-workflow-common": "file:../internal-workflow-common",
2020
"@temporalio/proto": "file:../proto",
21+
"@types/long": "^5.0.0",
22+
"long": "^5.2.0",
2123
"ms": "^2.1.3",
2224
"protobufjs": "^7.0.0",
2325
"uuid": "^8.3.2"

packages/client/src/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { SearchAttributes } from '@temporalio/internal-workflow-common';
22
import { temporal } from '@temporalio/proto';
33
import type * as grpc from '@grpc/grpc-js';
4+
import Long from 'long';
45

56
export interface WorkflowExecution {
67
workflowId: string;
@@ -30,7 +31,7 @@ export interface WorkflowExecutionDescription {
3031
runId: string;
3132
taskQueue: string;
3233
status: { code: temporal.api.enums.v1.WorkflowExecutionStatus; name: WorkflowExecutionStatusName };
33-
historyLength: number;
34+
historyLength: Long;
3435
startTime: Date;
3536
executionTime?: Date;
3637
closeTime?: Date;

packages/client/src/workflow-client.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -853,9 +853,10 @@ export class WorkflowClient {
853853
code: raw.workflowExecutionInfo!.status!,
854854
name: workflowStatusCodeToName(raw.workflowExecutionInfo!.status!),
855855
},
856-
// Safe to convert to number
856+
// Technically safe to convert to number, unfortunately this was overlooked when this was originally
857+
// implemented.
857858
// Max history length is 50k, which is much less than Number.MAX_SAFE_INTEGER
858-
historyLength: raw.workflowExecutionInfo!.historyLength!.toNumber(),
859+
historyLength: raw.workflowExecutionInfo!.historyLength!,
859860
startTime: tsToDate(raw.workflowExecutionInfo!.startTime!),
860861
executionTime: optionalTsToDate(raw.workflowExecutionInfo!.executionTime),
861862
closeTime: optionalTsToDate(raw.workflowExecutionInfo!.closeTime),

packages/test/src/integration-tests.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,15 +665,23 @@ export function runIntegrationTests(codec?: PayloadCodec): void {
665665
CustomDoubleField: [3.14],
666666
});
667667
const { searchAttributes } = await workflow.describe();
668-
t.deepEqual(searchAttributes, {
669-
BinaryChecksums: [`@temporalio/worker@${pkg.version}`],
668+
const { BinaryChecksums, ...rest } = searchAttributes;
669+
t.deepEqual(rest, {
670670
CustomBoolField: [true],
671671
CustomIntField: [], // clear
672672
CustomKeywordField: ['durable code'],
673673
CustomTextField: ['is useful'],
674674
CustomDatetimeField: [date],
675675
CustomDoubleField: [3.14],
676676
});
677+
t.true(BinaryChecksums?.length === 1);
678+
const [checksum] = BinaryChecksums ?? ['invalid'];
679+
console.log(checksum);
680+
t.true(
681+
typeof checksum === 'string' &&
682+
checksum.startsWith(`@temporalio/worker@${pkg.version}+`) &&
683+
/\+[a-f0-9]{64}$/.test(checksum) // bundle checksum
684+
);
677685
});
678686

679687
test('Workflow can read WorkflowInfo', async (t) => {

packages/test/src/test-local-activities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ApplicationFailure, defaultPayloadConverter, WorkflowClient, WorkflowFailedError } from '@temporalio/client';
22
import { temporal } from '@temporalio/proto';
3-
import { bundleWorkflowCode, Worker, WorkflowBundle } from '@temporalio/worker';
3+
import { bundleWorkflowCode, Worker, WorkflowBundleWithSourceMap as WorkflowBundle } from '@temporalio/worker';
44
import { isCancellation } from '@temporalio/workflow';
55
import anyTest, { TestInterface } from 'ava';
66
import { firstValueFrom, Subject } from 'rxjs';

packages/worker/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ export {
3434
ReplayWorkerOptions,
3535
WorkerOptions,
3636
WorkflowBundleOption,
37+
WorkflowBundle,
3738
WorkflowBundlePath,
39+
WorkflowBundlePathWithSourceMap, // eslint-disable-line deprecation/deprecation
3840
} from './worker-options';
3941
export { WorkflowInboundLogInterceptor, workflowLogAttributes } from './workflow-log-interceptor';
40-
export { BundleOptions, bundleWorkflowCode, WorkflowBundle } from './workflow/bundler';
42+
export { BundleOptions, bundleWorkflowCode, WorkflowBundleWithSourceMap } from './workflow/bundler';

packages/worker/src/worker-options.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Runtime } from './runtime';
99
import { InjectedSinks } from './sinks';
1010
import { GiB } from './utils';
1111
import { LoggerSinks } from './workflow-log-interceptor';
12-
import { WorkflowBundle } from './workflow/bundler';
12+
import { WorkflowBundleWithSourceMap } from './workflow/bundler';
1313
import * as v8 from 'v8';
1414
import * as os from 'os';
1515

@@ -18,7 +18,27 @@ export type { WebpackConfiguration };
1818
export interface WorkflowBundlePath {
1919
codePath: string;
2020
}
21-
export type WorkflowBundleOption = WorkflowBundle | WorkflowBundlePath;
21+
22+
/**
23+
* Note this no longer contains a source map.
24+
* The name was preserved to avoid breaking backwards compatibility.
25+
*
26+
* @deprecated
27+
*/
28+
export interface WorkflowBundlePathWithSourceMap {
29+
codePath: string;
30+
sourceMapPath: string;
31+
}
32+
33+
export interface WorkflowBundle {
34+
code: string;
35+
}
36+
37+
export type WorkflowBundleOption =
38+
| WorkflowBundle
39+
| WorkflowBundleWithSourceMap
40+
| WorkflowBundlePath
41+
| WorkflowBundlePathWithSourceMap; // eslint-disable-line deprecation/deprecation
2242

2343
export function isCodeBundleOption(bundleOpt: WorkflowBundleOption): bundleOpt is WorkflowBundle {
2444
const opt = bundleOpt as any; // Cast to access properties without TS complaining

packages/worker/src/worker.ts

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ import {
7272
isCodeBundleOption,
7373
isPathBundleOption,
7474
ReplayWorkerOptions,
75+
WorkflowBundle,
7576
WorkerOptions,
7677
} from './worker-options';
7778
import { WorkflowCodecRunner } from './workflow-codec-runner';
78-
import { WorkflowBundle, WorkflowCodeBundler } from './workflow/bundler';
79+
import { WorkflowCodeBundler } from './workflow/bundler';
7980
import { Workflow, WorkflowCreator } from './workflow/interface';
8081
import { ThreadedVMWorkflowCreator } from './workflow/threaded-vm';
8182
import { VMWorkflowCreator } from './workflow/vm';
@@ -132,6 +133,8 @@ export type ActivityTaskWithContext = ContextAware<{
132133
base64TaskToken: string;
133134
}>;
134135

136+
type CompiledWorkerOptionsWithBuildId = CompiledWorkerOptions & { buildId: string };
137+
135138
export interface NativeWorkerLike {
136139
initiateShutdown: Promisify<OmitFirstParam<typeof native.workerInitiateShutdown>>;
137140
finalizeShutdown(): Promise<void>;
@@ -145,22 +148,15 @@ export interface NativeWorkerLike {
145148
}
146149

147150
export interface WorkerConstructor {
148-
create(
149-
connection: NativeConnection,
150-
options: CompiledWorkerOptions,
151-
bundle?: WorkflowBundle
152-
): Promise<NativeWorkerLike>;
153-
createReplay(options: CompiledWorkerOptions, history: History, bundle: WorkflowBundle): Promise<NativeWorkerLike>;
151+
create(connection: NativeConnection, options: CompiledWorkerOptionsWithBuildId): Promise<NativeWorkerLike>;
152+
createReplay(options: CompiledWorkerOptionsWithBuildId, history: History): Promise<NativeWorkerLike>;
154153
}
155154

156155
function isOptionsWithBuildId<T extends CompiledWorkerOptions>(options: T): options is T & { buildId: string } {
157156
return options.buildId != null;
158157
}
159158

160-
function addBuildIdIfMissing<T extends CompiledWorkerOptions>(
161-
options: T,
162-
bundleCode?: string
163-
): T & { buildId: string } {
159+
function addBuildIdIfMissing(options: CompiledWorkerOptions, bundleCode?: string): CompiledWorkerOptionsWithBuildId {
164160
if (isOptionsWithBuildId(options)) {
165161
return options;
166162
}
@@ -178,24 +174,19 @@ export class NativeWorker implements NativeWorkerLike {
178174

179175
public static async create(
180176
connection: NativeConnection,
181-
options: CompiledWorkerOptions,
182-
bundle?: WorkflowBundle
177+
options: CompiledWorkerOptionsWithBuildId
183178
): Promise<NativeWorkerLike> {
184179
const runtime = Runtime.instance();
185-
const nativeWorker = await runtime.registerWorker(
186-
extractNativeClient(connection),
187-
addBuildIdIfMissing(options, bundle?.code)
188-
);
180+
const nativeWorker = await runtime.registerWorker(extractNativeClient(connection), options);
189181
return new NativeWorker(runtime, nativeWorker);
190182
}
191183

192184
public static async createReplay(
193-
options: CompiledWorkerOptions,
194-
history: History,
195-
bundle: WorkflowBundle
185+
options: CompiledWorkerOptionsWithBuildId,
186+
history: History
196187
): Promise<NativeWorkerLike> {
197188
const runtime = Runtime.instance();
198-
const nativeWorker = await runtime.createReplayWorker(addBuildIdIfMissing(options, bundle.code), history);
189+
const nativeWorker = await runtime.createReplayWorker(options, history);
199190
return new NativeWorker(runtime, nativeWorker);
200191
}
201192

@@ -426,7 +417,7 @@ export class Worker {
426417
const connection = options.connection ?? (await InternalNativeConnection.connect());
427418
let nativeWorker: NativeWorkerLike;
428419
try {
429-
nativeWorker = await nativeWorkerCtor.create(connection, compiledOptions);
420+
nativeWorker = await nativeWorkerCtor.create(connection, addBuildIdIfMissing(compiledOptions, bundle?.code));
430421
} catch (err) {
431422
// We just created this connection, close it
432423
if (!options.connection) {
@@ -439,7 +430,7 @@ export class Worker {
439430
}
440431

441432
protected static async createWorkflowCreator(
442-
workflowBundle: WorkflowBundleWithSourceMap,
433+
workflowBundle: WorkflowBundleWithSourceMapAndFilename,
443434
compiledOptions: CompiledWorkerOptions
444435
): Promise<WorkflowCreator> {
445436
if (compiledOptions.debugMode) {
@@ -499,7 +490,10 @@ export class Worker {
499490
throw new TypeError('ReplayWorkerOptions must contain workflowsPath or workflowBundle');
500491
}
501492
const workflowCreator = await this.createWorkflowCreator(bundle, compiledOptions);
502-
const replayWorker = await nativeWorkerCtor.createReplay(compiledOptions, history, bundle);
493+
const replayWorker = await nativeWorkerCtor.createReplay(
494+
addBuildIdIfMissing(compiledOptions, bundle.code),
495+
history
496+
);
503497
const constructedWorker = new this(replayWorker, workflowCreator, compiledOptions);
504498

505499
const runPromise = constructedWorker.run();
@@ -540,7 +534,7 @@ export class Worker {
540534
protected static async getOrCreateBundle(
541535
compiledOptions: CompiledWorkerOptions,
542536
logger: Logger
543-
): Promise<WorkflowBundleWithSourceMap | undefined> {
537+
): Promise<WorkflowBundleWithSourceMapAndFilename | undefined> {
544538
if (compiledOptions.workflowsPath) {
545539
if (compiledOptions.workflowBundle) {
546540
throw new ValueError(
@@ -561,7 +555,7 @@ export class Worker {
561555
return parseWorkflowCode(bundle.code);
562556
} else if (compiledOptions.workflowBundle) {
563557
if (compiledOptions.bundlerOptions) {
564-
throw new ValueError(`You cannot set both WorkerOptions.workflowBundle and .bundlerOptions`);
558+
throw new ValueError('You cannot set both WorkerOptions.workflowBundle and .bundlerOptions');
565559
}
566560

567561
if (isCodeBundleOption(compiledOptions.workflowBundle)) {
@@ -1652,13 +1646,13 @@ export class Worker {
16521646
}
16531647
}
16541648

1655-
export interface WorkflowBundleWithSourceMap {
1649+
export interface WorkflowBundleWithSourceMapAndFilename {
16561650
code: string;
16571651
sourceMap: RawSourceMap;
16581652
filename: string;
16591653
}
16601654

1661-
export function parseWorkflowCode(code: string, codePath?: string): WorkflowBundleWithSourceMap {
1655+
export function parseWorkflowCode(code: string, codePath?: string): WorkflowBundleWithSourceMapAndFilename {
16621656
const sourceMappingUrlDataRegex = /\s*\n[/][/][#]\s+sourceMappingURL=data:(?:[^,]*;)base64,([0-9A-Za-z+/=]+)\s*$/;
16631657
const sourceMapMatcher = code.match(sourceMappingUrlDataRegex);
16641658
if (!sourceMapMatcher) throw new Error("Can't extract inlined source map from the provided Workflow Bundle");

packages/worker/src/workflow/bundler.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ export function moduleMatches(userModule: string, modules: string[]): boolean {
2626
return modules.some((module) => userModule === module || userModule.startsWith(`${module}/`));
2727
}
2828

29-
export interface WorkflowBundle {
29+
export interface WorkflowBundleWithSourceMap {
30+
/**
31+
* Source maps are generated inline - this is no longer used
32+
* @deprecated
33+
*/
34+
sourceMap: string;
3035
code: string;
3136
}
3237

@@ -65,7 +70,7 @@ export class WorkflowCodeBundler {
6570
/**
6671
* @return a {@link WorkflowBundle} containing bundled code, including inlined source map
6772
*/
68-
public async createBundle(): Promise<WorkflowBundle> {
73+
public async createBundle(): Promise<WorkflowBundleWithSourceMap> {
6974
const vol = new memfs.Volume();
7075
const ufs = new unionfs.Union();
7176

@@ -102,6 +107,7 @@ export class WorkflowCodeBundler {
102107

103108
// Cast because the type definitions are inaccurate
104109
return {
110+
sourceMap: 'deprecated: this is no longer in use',
105111
code: memoryFs.readFileSync(bundleFilePath, 'utf8') as string,
106112
};
107113
}
@@ -333,7 +339,7 @@ export interface BundleOptions {
333339
* When using with {@link Worker.runReplayHistory}, make sure to pass the same interceptors and payload converter used
334340
* when the history was generated.
335341
*/
336-
export async function bundleWorkflowCode(options: BundleOptions): Promise<WorkflowBundle> {
342+
export async function bundleWorkflowCode(options: BundleOptions): Promise<WorkflowBundleWithSourceMap> {
337343
const bundler = new WorkflowCodeBundler(options);
338344
return await bundler.createBundle();
339345
}

packages/worker/src/workflow/threaded-vm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { coresdk } from '@temporalio/proto';
1313
import { IllegalStateError, SinkCall } from '@temporalio/workflow';
1414
import { Worker as NodeWorker } from 'worker_threads';
1515
import { UnexpectedError } from '../errors';
16-
import { WorkflowBundleWithSourceMap } from '../worker';
16+
import { WorkflowBundleWithSourceMapAndFilename } from '../worker';
1717
import { Workflow, WorkflowCreateOptions, WorkflowCreator } from './interface';
1818
import { WorkerThreadInput, WorkerThreadRequest } from './workflow-worker-thread/input';
1919
import { WorkerThreadOutput, WorkerThreadResponse } from './workflow-worker-thread/output';
@@ -119,7 +119,7 @@ export class WorkerThreadClient {
119119
}
120120

121121
export interface ThreadedVMWorkflowCreatorOptions {
122-
workflowBundle: WorkflowBundleWithSourceMap;
122+
workflowBundle: WorkflowBundleWithSourceMapAndFilename;
123123
threadPoolSize: number;
124124
isolateExecutionTimeoutMs: number;
125125
}

packages/worker/src/workflow/vm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import vm from 'vm';
1111
import v8 from 'v8';
1212
import { partition } from '../utils';
1313
import { Workflow, WorkflowCreateOptions, WorkflowCreator } from './interface';
14-
import { WorkflowBundleWithSourceMap } from '../worker';
14+
import { WorkflowBundleWithSourceMapAndFilename } from '../worker';
1515

1616
interface ActivationContext {
1717
isReplaying: boolean;
@@ -213,7 +213,7 @@ export class VMWorkflowCreator implements WorkflowCreator {
213213
*/
214214
public static async create<T extends typeof VMWorkflowCreator>(
215215
this: T,
216-
workflowBundle: WorkflowBundleWithSourceMap,
216+
workflowBundle: WorkflowBundleWithSourceMapAndFilename,
217217
isolateExecutionTimeoutMs: number
218218
): Promise<InstanceType<T>> {
219219
const script = new vm.Script(workflowBundle.code, { filename: workflowBundle.filename });

packages/worker/src/workflow/workflow-worker-thread/input.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { WorkflowBundleWithSourceMap } from '../../worker';
1+
import { WorkflowBundleWithSourceMapAndFilename } from '../../worker';
22
import { WorkflowCreateOptions } from '../interface';
33

44
/**
@@ -7,7 +7,7 @@ import { WorkflowCreateOptions } from '../interface';
77
export interface Init {
88
type: 'init';
99
isolateExecutionTimeoutMs: number;
10-
workflowBundle: WorkflowBundleWithSourceMap;
10+
workflowBundle: WorkflowBundleWithSourceMapAndFilename;
1111
}
1212

1313
/**

0 commit comments

Comments
 (0)