Socket
Socket
Sign inDemoInstall

@temporalio/client

Package Overview
Dependencies
Maintainers
4
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@temporalio/client - npm Package Compare versions

Comparing version 0.7.0 to 0.8.0

4

lib/errors.d.ts

@@ -36,3 +36,5 @@ import { temporal } from '@temporalio/proto';

/**
* Thrown by client when waiting on Workflow execution result if Workflow continues as new
* Thrown by client when waiting on Workflow execution result if Workflow continues as new.
*
* Only thrown if asked not to follow the chain of execution (see {@link WorkflowOptions.followRuns}).
*/

@@ -39,0 +41,0 @@ export declare class WorkflowExecutionContinuedAsNewError extends Error {

@@ -50,3 +50,5 @@ "use strict";

/**
* Thrown by client when waiting on Workflow execution result if Workflow continues as new
* Thrown by client when waiting on Workflow execution result if Workflow continues as new.
*
* Only thrown if asked not to follow the chain of execution (see {@link WorkflowOptions.followRuns}).
*/

@@ -53,0 +55,0 @@ class WorkflowExecutionContinuedAsNewError extends Error {

@@ -97,2 +97,9 @@ import { temporal } from '@temporalio/proto';

queryRejectCondition?: temporal.api.enums.v1.QueryRejectCondition;
/**
* Apply default options for starting new Workflows.
*
* These defaults are **shallowly** merged with options provided to methods that start Workflows
* e.g. {@link WorkflowHandle.start}.
*/
workflowDefaults?: Partial<WorkflowOptions>;
}

@@ -102,2 +109,25 @@ export declare type WorkflowClientOptionsWithDefaults = Required<WorkflowClientOptions>;

/**
* Same as the protocol's {@link WorkflowExecution} but `workflowId` is required.
*
* NOTE: Does not accept nulls.
*/
export interface ValidWorkflowExecution {
workflowId: string;
runId?: string;
}
/**
* Options for getting a result of a Workflow execution.
*/
export interface WorkflowResultOptions {
/**
* If set to true, instructs the client to follow the chain of execution before returning a Workflow's result.
*
* Workflow execution is chained if the Workflow has a cron schedule or continues-as-new or configured to retry
* after failure or timeout.
*
* @default true
*/
followRuns: boolean;
}
/**
* Client for starting Workflow executions and creating Workflow handles

@@ -112,11 +142,13 @@ */

*/
start<T extends Workflow>(opts: WorkflowOptions, name: string, ...args: Parameters<T>): Promise<string>;
start<T extends Workflow>(opts: Partial<WorkflowOptions>, name: string, ...args: Parameters<T>): Promise<string>;
/**
* Starts a new Workflow execution and awaits its completion
*/
execute<T extends Workflow>(opts: WorkflowOptions, name: string, ...args: Parameters<T>): WorkflowResultType<T>;
execute<T extends Workflow>(opts: Partial<WorkflowOptions>, name: string, ...args: Parameters<T>): Promise<WorkflowResultType<T>>;
/**
* Gets the result of a Workflow execution
* Gets the result of a Workflow execution.
*
* Follows the chain of execution in case Workflow continues as new, or has a cron schedule or retry policy.
*/
result<T extends Workflow>(workflowId: string, runId?: string): ReturnType<T['execute']>;
result<T extends Workflow>({ workflowId, runId }: ValidWorkflowExecution, opts?: WorkflowResultOptions): Promise<WorkflowResultType<T>>;
/**

@@ -164,3 +196,3 @@ * Uses given input to make a queryWorkflow call to the service

*/
createWorkflowHandle<T extends Workflow>(name: string, options: WorkflowOptions): WorkflowHandle<T>;
createWorkflowHandle<T extends Workflow>(name: string, options?: Partial<WorkflowOptions>): WorkflowHandle<T>;
/**

@@ -172,19 +204,19 @@ * Create a {@link WorkflowHandle} for starting a new Workflow execution

*/
createWorkflowHandle<T extends Workflow>(func: T, options: WorkflowOptions): WorkflowHandle<T>;
createWorkflowHandle<T extends Workflow>(func: T, options?: Partial<WorkflowOptions>): WorkflowHandle<T>;
/**
* Create a {@link WorkflowHandle} for an existing Workflow execution
*/
createWorkflowHandle<T extends Workflow>(workflowId: string, runId?: string): WorkflowHandle<T>;
createWorkflowHandle<T extends Workflow>(execution: ValidWorkflowExecution): WorkflowHandle<T>;
/**
* Create a new workflow handle for new or existing Workflow execution
*/
protected _createWorkflowHandle<T extends Workflow>(workflowId: string, runId: string | undefined, interceptors: WorkflowClientCallsInterceptor[], start: WorkflowHandle<T>['start'], signalWithStart: WorkflowHandle<T>['signalWithStart']): WorkflowHandle<T>;
protected _createWorkflowHandle<T extends Workflow>(workflowId: string, runId: string | undefined, interceptors: WorkflowClientCallsInterceptor[], start: WorkflowHandle<T>['start'], signalWithStart: WorkflowHandle<T>['signalWithStart'], resultOptions: WorkflowResultOptions): WorkflowHandle<T>;
/**
* Creates a Workflow handle for existing Workflow using `workflowId` and optional `runId`
*/
protected connectToExistingWorkflow<T extends Workflow>(workflowId: string, runId?: string): WorkflowHandle<T>;
protected connectToExistingWorkflow<T extends Workflow>({ workflowId, runId, }: ValidWorkflowExecution): WorkflowHandle<T>;
/**
* Creates a Workflow handle for new Workflow execution
*/
protected createNewWorkflow<T extends Workflow>(name: string, options: WorkflowOptions): WorkflowHandle<T>;
protected createNewWorkflow<T extends Workflow>(name: string, options?: Partial<WorkflowOptions>): WorkflowHandle<T>;
}

@@ -191,0 +223,0 @@ export declare class QueryRejectedError extends Error {

@@ -41,5 +41,11 @@ "use strict";

queryRejectCondition: proto_1.temporal.api.enums.v1.QueryRejectCondition.QUERY_REJECT_CONDITION_UNSPECIFIED,
workflowDefaults: {},
};
}
exports.defaultWorkflowClientOptions = defaultWorkflowClientOptions;
function assertRequiredWorkflowOptions(opts) {
if (!opts.taskQueue) {
throw new TypeError('Missing WorkflowOptions.taskQueue');
}
}
/**

@@ -57,3 +63,5 @@ * Client for starting Workflow executions and creating Workflow handles

async start(opts, name, ...args) {
const compiledOptions = (0, workflow_options_1.compileWorkflowOptions)((0, workflow_options_1.addDefaults)(opts));
const mergedOptions = { ...this.options.workflowDefaults, ...opts };
assertRequiredWorkflowOptions(mergedOptions);
const compiledOptions = (0, workflow_options_1.compileWorkflowOptions)((0, workflow_options_1.addDefaults)(mergedOptions));
const interceptors = (this.options.interceptors.calls ?? []).map((ctor) => ctor({ workflowId: compiledOptions.workflowId }));

@@ -75,13 +83,15 @@ const next = (0, common_1.composeInterceptors)(interceptors, 'start', this._startWorkflowHandler.bind(this));

const runId = await this.start({ ...opts, workflowId }, name, ...args);
return this.result(workflowId, runId);
return this.result({ workflowId, runId });
}
/**
* Gets the result of a Workflow execution
* Gets the result of a Workflow execution.
*
* Follows the chain of execution in case Workflow continues as new, or has a cron schedule or retry policy.
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
async result(workflowId, runId) {
async result({ workflowId, runId }, opts) {
const followRuns = opts?.followRuns ?? true;
const execution = { workflowId, runId };
const req = {
namespace: this.options.namespace,
execution: { workflowId, runId },
execution,
skipArchival: true,

@@ -109,29 +119,48 @@ waitNewEvent: true,

ev = events[0];
break;
}
if (ev.workflowExecutionCompletedEventAttributes) {
// Note that we can only return one value from our workflow function in JS.
// Ignore any other payloads in result
const [result] = await (0, common_1.arrayFromPayloads)(this.options.dataConverter, ev.workflowExecutionCompletedEventAttributes.result?.payloads);
return result;
}
else if (ev.workflowExecutionFailedEventAttributes) {
const { failure } = ev.workflowExecutionFailedEventAttributes;
throw new errors.WorkflowExecutionFailedError('Workflow execution failed', await (0, common_1.optionalFailureToOptionalError)(failure, this.options.dataConverter));
}
else if (ev.workflowExecutionCanceledEventAttributes) {
throw new errors.WorkflowExecutionCancelledError('Workflow execution cancelled', await (0, common_1.arrayFromPayloads)(this.options.dataConverter, ev.workflowExecutionCanceledEventAttributes.details?.payloads));
}
else if (ev.workflowExecutionTerminatedEventAttributes) {
throw new errors.WorkflowExecutionTerminatedError(ev.workflowExecutionTerminatedEventAttributes.reason || 'Workflow execution terminated', await (0, common_1.arrayFromPayloads)(this.options.dataConverter, ev.workflowExecutionTerminatedEventAttributes.details?.payloads), ev.workflowExecutionTerminatedEventAttributes.identity ?? undefined);
}
else if (ev.workflowExecutionTimedOutEventAttributes) {
throw new errors.WorkflowExecutionTimedOutError('Workflow execution timed out', ev.workflowExecutionTimedOutEventAttributes.retryState || 0);
}
else if (ev.workflowExecutionContinuedAsNewEventAttributes) {
const { newExecutionRunId } = ev.workflowExecutionContinuedAsNewEventAttributes;
if (!newExecutionRunId) {
throw new Error('Expected service to return newExecutionRunId for WorkflowExecutionContinuedAsNewEvent');
if (ev.workflowExecutionCompletedEventAttributes) {
if (followRuns && ev.workflowExecutionCompletedEventAttributes.newExecutionRunId) {
execution.runId = ev.workflowExecutionCompletedEventAttributes.newExecutionRunId;
req.nextPageToken = undefined;
continue;
}
// Note that we can only return one value from our workflow function in JS.
// Ignore any other payloads in result
const [result] = await (0, common_1.arrayFromPayloads)(this.options.dataConverter, ev.workflowExecutionCompletedEventAttributes.result?.payloads);
return result;
}
throw new errors.WorkflowExecutionContinuedAsNewError('Workflow execution continued as new', newExecutionRunId);
else if (ev.workflowExecutionFailedEventAttributes) {
if (followRuns && ev.workflowExecutionFailedEventAttributes.newExecutionRunId) {
execution.runId = ev.workflowExecutionFailedEventAttributes.newExecutionRunId;
req.nextPageToken = undefined;
continue;
}
const { failure } = ev.workflowExecutionFailedEventAttributes;
throw new errors.WorkflowExecutionFailedError('Workflow execution failed', await (0, common_1.optionalFailureToOptionalError)(failure, this.options.dataConverter));
}
else if (ev.workflowExecutionCanceledEventAttributes) {
throw new errors.WorkflowExecutionCancelledError('Workflow execution cancelled', await (0, common_1.arrayFromPayloads)(this.options.dataConverter, ev.workflowExecutionCanceledEventAttributes.details?.payloads));
}
else if (ev.workflowExecutionTerminatedEventAttributes) {
throw new errors.WorkflowExecutionTerminatedError(ev.workflowExecutionTerminatedEventAttributes.reason || 'Workflow execution terminated', await (0, common_1.arrayFromPayloads)(this.options.dataConverter, ev.workflowExecutionTerminatedEventAttributes.details?.payloads), ev.workflowExecutionTerminatedEventAttributes.identity ?? undefined);
}
else if (ev.workflowExecutionTimedOutEventAttributes) {
if (ev.workflowExecutionTimedOutEventAttributes.newExecutionRunId) {
execution.runId = ev.workflowExecutionTimedOutEventAttributes.newExecutionRunId;
req.nextPageToken = undefined;
continue;
}
throw new errors.WorkflowExecutionTimedOutError('Workflow execution timed out', ev.workflowExecutionTimedOutEventAttributes.retryState || 0);
}
else if (ev.workflowExecutionContinuedAsNewEventAttributes) {
const { newExecutionRunId } = ev.workflowExecutionContinuedAsNewEventAttributes;
if (!newExecutionRunId) {
throw new TypeError('Expected service to return newExecutionRunId for WorkflowExecutionContinuedAsNewEvent');
}
if (!followRuns) {
throw new errors.WorkflowExecutionContinuedAsNewError('Workflow execution continued as new', newExecutionRunId);
}
execution.runId = newExecutionRunId;
req.nextPageToken = undefined;
continue;
}
}

@@ -281,28 +310,16 @@ }

}
createWorkflowHandle(nameOrWorkflowIdOrFunc, optionsOrRunId) {
const nameOrWorkflowId = typeof nameOrWorkflowIdOrFunc === 'string'
? nameOrWorkflowIdOrFunc
: typeof nameOrWorkflowIdOrFunc === 'function'
? nameOrWorkflowIdOrFunc.name
createWorkflowHandle(executionOrNameOrFunc, options) {
const workflowExecution = typeof executionOrNameOrFunc === 'object' && executionOrNameOrFunc.workflowId ? executionOrNameOrFunc : undefined;
if (workflowExecution !== undefined) {
return this.connectToExistingWorkflow(workflowExecution);
}
const workflowType = typeof executionOrNameOrFunc === 'string'
? executionOrNameOrFunc
: typeof executionOrNameOrFunc === 'function'
? executionOrNameOrFunc.name
: undefined;
if (typeof nameOrWorkflowId !== 'string') {
throw new TypeError(`Invalid argument: ${nameOrWorkflowIdOrFunc}, expected a Workflow function or a string with the Workflow name or Workflow ID`);
if (typeof workflowType !== 'string') {
throw new TypeError(`Invalid argument: ${executionOrNameOrFunc}, expected one of: Workflow function, a string with the Workflow type name, or WorkflowExecution`);
}
if (optionsOrRunId === undefined) {
const workflowId = nameOrWorkflowId;
return this.connectToExistingWorkflow(workflowId);
}
else if (typeof optionsOrRunId === 'string') {
const workflowId = nameOrWorkflowId;
const runId = optionsOrRunId;
return this.connectToExistingWorkflow(workflowId, runId);
}
else if (typeof optionsOrRunId === 'object') {
const name = nameOrWorkflowId;
const options = optionsOrRunId;
return this.createNewWorkflow(name, options);
}
else {
throw new TypeError(`Invalid argument: ${optionsOrRunId}, expected either runId (string) or options (WorkflowOptions)`);
}
return this.createNewWorkflow(workflowType, options);
}

@@ -312,18 +329,23 @@ /**

*/
_createWorkflowHandle(workflowId, runId, interceptors, start, signalWithStart) {
_createWorkflowHandle(workflowId, runId, interceptors, start, signalWithStart, resultOptions) {
const namespace = this.options.namespace;
let startPromise = undefined;
const workflow = {
client: this,
workflowId,
execute(...args) {
// TODO: fix the type here
return this.start(...args).then(() => this.result());
async execute(...args) {
await this.start(...args);
return await this.result();
},
async start(...args) {
if (startPromise !== undefined) {
throw new common_1.IllegalStateError('Workflow execution already started');
}
startPromise = start(...args);
// Override runId in outer scope
runId = await start(...args);
runId = await startPromise;
return runId;
},
result() {
return this.client.result(workflowId, runId);
async result() {
return this.client.result({ workflowId, runId }, resultOptions);
},

@@ -394,10 +416,10 @@ async terminate(reason) {

*/
connectToExistingWorkflow(workflowId, runId) {
connectToExistingWorkflow({ workflowId, runId, }) {
const interceptors = (this.options.interceptors.calls ?? []).map((ctor) => ctor({ workflowId, runId }));
const startCallback = () => {
throw new common_1.IllegalStateError('Workflow created with no WorkflowOptions cannot be started');
throw new common_1.IllegalStateError('WorkflowHandle created with no WorkflowOptions cannot be started');
};
return this._createWorkflowHandle(workflowId, runId, interceptors, startCallback,
// Requires cast because workflow signals are optional which complicate the type
startCallback);
startCallback, { followRuns: this.options.workflowDefaults.followRuns ?? true });
}

@@ -408,3 +430,5 @@ /**

createNewWorkflow(name, options) {
const compiledOptions = (0, workflow_options_1.compileWorkflowOptions)((0, workflow_options_1.addDefaults)(options));
const mergedOptions = { ...this.options.workflowDefaults, ...options };
assertRequiredWorkflowOptions(mergedOptions);
const compiledOptions = (0, workflow_options_1.compileWorkflowOptions)((0, workflow_options_1.addDefaults)(mergedOptions));
const interceptors = (this.options.interceptors.calls ?? []).map((ctor) => ctor({ workflowId: compiledOptions.workflowId }));

@@ -433,3 +457,3 @@ const start = (...args) => {

// Requires cast because workflow signals are optional which complicate the type
signalWithStart);
signalWithStart, { followRuns: mergedOptions.followRuns ?? true });
}

@@ -436,0 +460,0 @@ }

@@ -1,6 +0,22 @@

import { WorkflowOptions as BaseWorkflowOptions, WorkflowOptionsWithDefaults } from '@temporalio/common/lib/workflow-options';
export { WorkflowOptionsWithDefaults, CompiledWorkflowOptions, compileWorkflowOptions, } from '@temporalio/common/lib/workflow-options';
import { WorkflowOptions as BaseWorkflowOptions, WorkflowOptionsWithDefaults as BaseWorkflowOptionsWithDefaults } from '@temporalio/common/lib/workflow-options';
export { CompiledWorkflowOptions, compileWorkflowOptions } from '@temporalio/common/lib/workflow-options';
export interface WorkflowOptions extends BaseWorkflowOptions {
/**
* Task queue to use for Workflow tasks. It should match a task queue specified when creating a
* `Worker` that hosts the Workflow code.
*/
taskQueue: string;
followRuns?: boolean;
}
export interface WorkflowOptionsWithDefaults extends BaseWorkflowOptionsWithDefaults {
/**
* If set to true, instructs the client to follow the chain of execution before returning a Workflow's result.
*
* Workflow execution is chained if the Workflow has a cron schedule or continues-as-new or configured to retry
* after failure or timeout.
*
* @default true
*/
followRuns: boolean;
}
/**

@@ -7,0 +23,0 @@ * Adds default values to `workflowId` and `workflowIdReusePolicy` to given workflow options.

@@ -32,3 +32,4 @@ "use strict";

return {
workflowId: (0, uuid_1.v4)(),
followRuns: true,
workflowId: opts.workflowId ?? (0, uuid_1.v4)(),
workflowIdReusePolicy: iface.temporal.api.enums.v1.WorkflowIdReusePolicy.WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY,

@@ -35,0 +36,0 @@ ...opts,

{
"name": "@temporalio/client",
"version": "0.7.0",
"version": "0.8.0",
"description": "Temporal.io SDK Client sub-package",

@@ -17,4 +17,4 @@ "main": "lib/index.js",

"@grpc/grpc-js": "^1.3.7",
"@temporalio/common": "^0.3.0",
"@temporalio/proto": "^0.3.2",
"@temporalio/common": "^0.4.0",
"@temporalio/proto": "^0.3.3",
"ms": "^2.1.3",

@@ -34,3 +34,3 @@ "protobufjs": "^6.11.2",

},
"gitHead": "23da8507a90049774cc6ddd28a8ec3dfc37d345f"
"gitHead": "a46c7b9ce2e78d9f615bfdb1730af0956a25eb61"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc