import { JetroutineFunction, JetroutineFunctionReturnTypes, SupportedTypes, SymbolTable, } from '../config/_symbols'; import { remote } from '../proto/runtime/v1alpha1/remote'; import { RuntimeClient } from '../runtime/_client'; import { SystemError } from '../runtime/_errors'; type JetroutineConstructor = { runtimeClient: RuntimeClient; uniqueName: string; func: JetroutineFunction; external?: boolean; }; export class Jetroutine extends Function { func: JetroutineFunction; uniqueName: string; runtimeClient: RuntimeClient; // set to true when the jetroutine is pointing to an external runtime. external: boolean; constructor({ runtimeClient, uniqueName, func, external = false, }: JetroutineConstructor) { super(); this.uniqueName = uniqueName; this.runtimeClient = runtimeClient; this.func = func; this.external = external; if (!external) { SymbolTable.register(uniqueName, func); } /* eslint no-constructor-return: "off" */ return new Proxy(this, { apply: (target, _thisArg, args: SupportedTypes[]) => target.call(args), }); } call(args: SupportedTypes[]) { return this.createTask(args) .then((ctResp: remote.CreateTaskResponse) => this.runtimeClient.waitForResult(ctResp.task_id)) .then((wfResp: remote.WaitForResultResponse) => { const { value, error } = wfResp.result; if (error && error.encoded_error) { const err = JSON.parse(String.fromCharCode(...error.encoded_error)) as Error; // TODO: Parse error and label it as ApplicationError or SystemError. return Promise.reject(err); } const encodedValue = value?.encoded_value; if (encodedValue) { const jsonValue = JSON.parse( String.fromCharCode(...encodedValue), ) as JetroutineFunctionReturnTypes; return Promise.resolve(jsonValue); } return Promise.resolve(); }); } createTask(args: any[]) { const targetTime = new Date(); return this.runtimeClient.createTask(this.uniqueName, args, targetTime, this.external); } } export const loadEncodedArgs = async (runtimeClient: RuntimeClient, taskId: string) => { if (!taskId) { throw new SystemError('cannot load encoded args: taskId is missing.'); } const task = await runtimeClient.getTask(taskId); return JSON.parse(String.fromCharCode(...task.encoded_args)) as SupportedTypes[]; };