@restatedev/restate-sdk-cloudflare-workers 1.15.0-rc.7 → 1.15.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/dist/common_api.d.cts +1 -1
- package/dist/common_api.d.cts.map +1 -1
- package/dist/common_api.d.ts +1 -1
- package/dist/common_api.d.ts.map +1 -1
- package/dist/common_api.js.map +1 -1
- package/dist/context.d.cts +95 -1
- package/dist/context.d.cts.map +1 -1
- package/dist/context.d.ts +95 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/context_impl.cjs +11 -2
- package/dist/context_impl.js +11 -2
- package/dist/context_impl.js.map +1 -1
- package/dist/endpoint/handlers/generic.cjs +3 -0
- package/dist/endpoint/handlers/generic.js +3 -0
- package/dist/endpoint/handlers/generic.js.map +1 -1
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts +5 -2
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.js +54 -6
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.wasm +0 -0
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.wasm.d.ts +5 -2
- package/dist/fetch.d.cts +2 -2
- package/dist/fetch.d.ts +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/lambda.d.cts +2 -2
- package/dist/lambda.d.ts +2 -2
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/types/rpc.cjs +7 -3
- package/dist/types/rpc.d.cts +68 -5
- package/dist/types/rpc.d.cts.map +1 -1
- package/dist/types/rpc.d.ts +68 -5
- package/dist/types/rpc.d.ts.map +1 -1
- package/dist/types/rpc.js +7 -3
- package/dist/types/rpc.js.map +1 -1
- package/package.json +3 -3
package/dist/context_impl.cjs
CHANGED
|
@@ -102,7 +102,7 @@ var ContextImpl = class {
|
|
|
102
102
|
return Object.assign(require_promises.ConstRestatePromise.pending(), { invocationId: require_promises.pendingPromise() });
|
|
103
103
|
}
|
|
104
104
|
try {
|
|
105
|
-
const call_handles = this.coreVm.sys_call(call.service, call.method, parameter, call.key, call.headers ? Object.entries(call.headers).map(([key, value]) => new require_sdk_shared_core_wasm_bindings.WasmHeader(key, value)) : [], call.idempotencyKey, call.name);
|
|
105
|
+
const call_handles = this.coreVm.sys_call(call.service, call.method, parameter, call.key, call.headers ? Object.entries(call.headers).map(([key, value]) => new require_sdk_shared_core_wasm_bindings.WasmHeader(key, value)) : [], call.idempotencyKey, call.scope, call.limitKey, call.name);
|
|
106
106
|
const commandIndex = this.coreVm.last_command_index();
|
|
107
107
|
const invocationIdPromise = new require_promises.SingleRestatePromise(this, call_handles.invocation_id_completion_id, completeCommandPromiseUsing(require_sdk_shared_core_wasm_bindings.WasmCommandType.Call, commandIndex, InvocationIdCompleter));
|
|
108
108
|
this.trackedInvocationIdPromises?.push(invocationIdPromise);
|
|
@@ -123,7 +123,7 @@ var ContextImpl = class {
|
|
|
123
123
|
}
|
|
124
124
|
try {
|
|
125
125
|
const delay = send.delay !== void 0 ? (0, __restatedev_restate_sdk_core.millisOrDurationToMillis)(send.delay) : void 0;
|
|
126
|
-
const handles = this.coreVm.sys_send(send.service, send.method, parameter, send.key, send.headers ? Object.entries(send.headers).map(([key, value]) => new require_sdk_shared_core_wasm_bindings.WasmHeader(key, value)) : [], delay !== void 0 && delay > 0 ? BigInt(delay) : void 0, send.idempotencyKey, send.name);
|
|
126
|
+
const handles = this.coreVm.sys_send(send.service, send.method, parameter, send.key, send.headers ? Object.entries(send.headers).map(([key, value]) => new require_sdk_shared_core_wasm_bindings.WasmHeader(key, value)) : [], delay !== void 0 && delay > 0 ? BigInt(delay) : void 0, send.idempotencyKey, send.scope, send.limitKey, send.name);
|
|
127
127
|
const commandIndex = this.coreVm.last_command_index();
|
|
128
128
|
return { invocationId: new require_promises.SingleRestatePromise(this, handles.invocation_id_completion_id, completeCommandPromiseUsing(require_sdk_shared_core_wasm_bindings.WasmCommandType.OneWayCall, commandIndex, InvocationIdCompleter)) };
|
|
129
129
|
} catch (e) {
|
|
@@ -149,6 +149,14 @@ var ContextImpl = class {
|
|
|
149
149
|
workflowSendClient({ name }, key) {
|
|
150
150
|
return require_rpc.makeRpcSendProxy((send) => this.genericSend(send), this.defaultSerde, name, key);
|
|
151
151
|
}
|
|
152
|
+
scope(scopeKey) {
|
|
153
|
+
return {
|
|
154
|
+
serviceClient: ({ name }) => require_rpc.makeRpcCallProxy((call) => this.genericCall(call), this.defaultSerde, name, void 0, scopeKey),
|
|
155
|
+
serviceSendClient: ({ name }) => require_rpc.makeRpcSendProxy((send) => this.genericSend(send), this.defaultSerde, name, void 0, scopeKey),
|
|
156
|
+
workflowClient: ({ name }, key) => require_rpc.makeRpcCallProxy((call) => this.genericCall(call), this.defaultSerde, name, key, scopeKey),
|
|
157
|
+
workflowSendClient: ({ name }, key) => require_rpc.makeRpcSendProxy((send) => this.genericSend(send), this.defaultSerde, name, key, scopeKey)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
152
160
|
run(nameOrAction, actionSecondParameter, options) {
|
|
153
161
|
const { name, action } = unpackRunParameters(nameOrAction, actionSecondParameter);
|
|
154
162
|
const serde$1 = options?.serde ?? this.defaultSerde;
|
|
@@ -418,6 +426,7 @@ var RunClosuresTracker = class {
|
|
|
418
426
|
executeRun(handle) {
|
|
419
427
|
const runClosure = this.runsToExecute.get(handle);
|
|
420
428
|
if (runClosure === void 0) throw new Error(`Handle ${handle} doesn't exist`);
|
|
429
|
+
this.runsToExecute.delete(handle);
|
|
421
430
|
runClosure().finally(() => this.channel.signal()).catch(() => {});
|
|
422
431
|
}
|
|
423
432
|
registerRunClosure(handle, runClosure) {
|
package/dist/context_impl.js
CHANGED
|
@@ -100,7 +100,7 @@ var ContextImpl = class {
|
|
|
100
100
|
return Object.assign(ConstRestatePromise.pending(), { invocationId: pendingPromise() });
|
|
101
101
|
}
|
|
102
102
|
try {
|
|
103
|
-
const call_handles = this.coreVm.sys_call(call.service, call.method, parameter, call.key, call.headers ? Object.entries(call.headers).map(([key, value]) => new WasmHeader(key, value)) : [], call.idempotencyKey, call.name);
|
|
103
|
+
const call_handles = this.coreVm.sys_call(call.service, call.method, parameter, call.key, call.headers ? Object.entries(call.headers).map(([key, value]) => new WasmHeader(key, value)) : [], call.idempotencyKey, call.scope, call.limitKey, call.name);
|
|
104
104
|
const commandIndex = this.coreVm.last_command_index();
|
|
105
105
|
const invocationIdPromise = new SingleRestatePromise(this, call_handles.invocation_id_completion_id, completeCommandPromiseUsing(WasmCommandType.Call, commandIndex, InvocationIdCompleter));
|
|
106
106
|
this.trackedInvocationIdPromises?.push(invocationIdPromise);
|
|
@@ -121,7 +121,7 @@ var ContextImpl = class {
|
|
|
121
121
|
}
|
|
122
122
|
try {
|
|
123
123
|
const delay = send.delay !== void 0 ? millisOrDurationToMillis(send.delay) : void 0;
|
|
124
|
-
const handles = this.coreVm.sys_send(send.service, send.method, parameter, send.key, send.headers ? Object.entries(send.headers).map(([key, value]) => new WasmHeader(key, value)) : [], delay !== void 0 && delay > 0 ? BigInt(delay) : void 0, send.idempotencyKey, send.name);
|
|
124
|
+
const handles = this.coreVm.sys_send(send.service, send.method, parameter, send.key, send.headers ? Object.entries(send.headers).map(([key, value]) => new WasmHeader(key, value)) : [], delay !== void 0 && delay > 0 ? BigInt(delay) : void 0, send.idempotencyKey, send.scope, send.limitKey, send.name);
|
|
125
125
|
const commandIndex = this.coreVm.last_command_index();
|
|
126
126
|
return { invocationId: new SingleRestatePromise(this, handles.invocation_id_completion_id, completeCommandPromiseUsing(WasmCommandType.OneWayCall, commandIndex, InvocationIdCompleter)) };
|
|
127
127
|
} catch (e) {
|
|
@@ -147,6 +147,14 @@ var ContextImpl = class {
|
|
|
147
147
|
workflowSendClient({ name }, key) {
|
|
148
148
|
return makeRpcSendProxy((send) => this.genericSend(send), this.defaultSerde, name, key);
|
|
149
149
|
}
|
|
150
|
+
scope(scopeKey) {
|
|
151
|
+
return {
|
|
152
|
+
serviceClient: ({ name }) => makeRpcCallProxy((call) => this.genericCall(call), this.defaultSerde, name, void 0, scopeKey),
|
|
153
|
+
serviceSendClient: ({ name }) => makeRpcSendProxy((send) => this.genericSend(send), this.defaultSerde, name, void 0, scopeKey),
|
|
154
|
+
workflowClient: ({ name }, key) => makeRpcCallProxy((call) => this.genericCall(call), this.defaultSerde, name, key, scopeKey),
|
|
155
|
+
workflowSendClient: ({ name }, key) => makeRpcSendProxy((send) => this.genericSend(send), this.defaultSerde, name, key, scopeKey)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
150
158
|
run(nameOrAction, actionSecondParameter, options) {
|
|
151
159
|
const { name, action } = unpackRunParameters(nameOrAction, actionSecondParameter);
|
|
152
160
|
const serde$1 = options?.serde ?? this.defaultSerde;
|
|
@@ -416,6 +424,7 @@ var RunClosuresTracker = class {
|
|
|
416
424
|
executeRun(handle) {
|
|
417
425
|
const runClosure = this.runsToExecute.get(handle);
|
|
418
426
|
if (runClosure === void 0) throw new Error(`Handle ${handle} doesn't exist`);
|
|
427
|
+
this.runsToExecute.delete(handle);
|
|
419
428
|
runClosure().finally(() => this.channel.signal()).catch(() => {});
|
|
420
429
|
}
|
|
421
430
|
registerRunClosure(handle, runClosure) {
|
package/dist/context_impl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context_impl.js","names":["coreVm: WasmVM","console: Console","handlerKind: HandlerKind","vmLogger: Console","invocationRequest: Request","invocationEndPromise: PromiseWithResolvers<void>","journalValueCodec: JournalValueCodec","serde","requestSerde: Serde<REQ>","responseSerde: Serde<RES>","parameter: Uint8Array","wasmRun: vm.WasmRun","doRun: () => Promise<any>","res: T","awakeable: vm.WasmAwakeable","value: Uint8Array","handle: number","cancelled: InvocationId[]","ctx: ContextImpl","invocationId: InvocationId","name: string","channel: ExternalProgressChannel","cause: unknown","commandType: WasmCommandType","commandIndex?: number","VoidAsNull: Completer","VoidAsUndefined: Completer","buffer: Uint8Array","Failure: Completer","StateKeys: Completer","InvocationIdCompleter: Completer"],"sources":["../src/context_impl.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type {\n ContextDate,\n DurablePromise,\n GenericCall,\n GenericSend,\n InvocationHandle,\n InvocationId,\n InvocationPromise,\n InvocationReference,\n ObjectContext,\n Rand,\n Request,\n RestatePromise,\n RunAction,\n RunOptions,\n SignalReference,\n WorkflowContext,\n} from \"./context.js\";\nimport type * as vm from \"./endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js\";\nimport {\n WasmCommandType,\n WasmHeader,\n WasmInput,\n WasmVM,\n} from \"./endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js\";\nimport {\n ensureError,\n INTERNAL_ERROR_CODE,\n PauseError,\n RetryableError,\n TerminalError,\n UNKNOWN_ERROR_CODE,\n} from \"./types/errors.js\";\nimport type { Client, SendClient } from \"./types/rpc.js\";\nimport {\n HandlerKind,\n makeRpcCallProxy,\n makeRpcSendProxy,\n} from \"./types/rpc.js\";\nimport type {\n Duration,\n JournalValueCodec,\n Serde,\n Service,\n ServiceDefinitionFrom,\n VirtualObject,\n VirtualObjectDefinitionFrom,\n Workflow,\n WorkflowDefinitionFrom,\n} from \"@restatedev/restate-sdk-core\";\nimport { millisOrDurationToMillis, serde } from \"@restatedev/restate-sdk-core\";\nimport { RandImpl } from \"./utils/rand.js\";\nimport { AsyncResultValue, CombinatorRestatePromise } from \"./promises.js\";\nimport {\n ConstRestatePromise,\n pendingPromise,\n PromisesExecutor,\n InvocationRestatePromise,\n SingleRestatePromise,\n} from \"./promises.js\";\nimport { InputPump, OutputPump } from \"./io.js\";\nimport { ExternalProgressChannel } from \"./utils/external_progress_channel.js\";\nimport type { ContextInternal } from \"./internal.js\";\nimport { InputReader, OutputWriter } from \"./endpoint/handlers/types.js\";\nimport { ExecutionOptions } from \"./endpoint/components.js\";\n\nexport class ContextImpl\n implements ObjectContext, WorkflowContext, ContextInternal\n{\n public readonly rand: Rand;\n\n public readonly date: ContextDate = {\n now: (): Promise<number> => {\n return this.run(() => Date.now());\n },\n\n toJSON: (): Promise<string> => {\n return this.run(() => new Date().toJSON());\n },\n };\n\n private readonly outputPump: OutputPump;\n readonly inputPump: InputPump;\n private readonly runClosuresTracker: RunClosuresTracker;\n readonly promisesExecutor: PromisesExecutor;\n private readonly serviceKey: string;\n private runInterceptor: (\n name: string,\n runner: () => Promise<void>\n ) => Promise<void>;\n private cancellationPromise?: SingleRestatePromise<void>;\n readonly defaultSerde: Serde<any>;\n private readonly asTerminalError?: (error: any) => TerminalError | undefined;\n\n // If undefined, we're not tracking invocation id promises\n private readonly trackedInvocationIdPromises?: SingleRestatePromise<string>[];\n\n constructor(\n readonly coreVm: WasmVM,\n input: WasmInput,\n public readonly console: Console,\n public readonly handlerKind: HandlerKind,\n readonly vmLogger: Console,\n private readonly invocationRequest: Request,\n readonly invocationEndPromise: PromiseWithResolvers<void>,\n inputReader: InputReader,\n outputWriter: OutputWriter,\n readonly journalValueCodec: JournalValueCodec,\n executionOptions?: ExecutionOptions\n ) {\n this.rand = new RandImpl(input.random_seed, () => {\n // TODO reimplement this check with async context\n // if (coreVm.is_inside_run()) {\n // throw new Error(\n // \"Cannot generate random numbers within a run closure. Use the random object outside the run closure.\"\n // );\n // }\n });\n this.outputPump = new OutputPump(coreVm, outputWriter);\n const externalProgressChannel = new ExternalProgressChannel();\n this.runClosuresTracker = new RunClosuresTracker(externalProgressChannel);\n this.inputPump = new InputPump(\n coreVm,\n inputReader,\n externalProgressChannel,\n this.abortAttempt.bind(this)\n );\n this.promisesExecutor = new PromisesExecutor(\n coreVm,\n this.outputPump,\n this.runClosuresTracker,\n externalProgressChannel,\n this.abortAttempt.bind(this)\n );\n this.serviceKey = input.key;\n // Identity interceptor by default; replaced by startUserHandler after hooks are instantiated\n this.runInterceptor = (_name, runner) => runner();\n this.defaultSerde = executionOptions?.defaultSerde ?? serde.json;\n this.asTerminalError = executionOptions?.asTerminalError;\n this.trackedInvocationIdPromises = executionOptions?.explicitCancellation\n ? []\n : undefined;\n }\n\n setRunInterceptor(\n interceptor: (name: string, runner: () => Promise<void>) => Promise<void>\n ) {\n this.runInterceptor = interceptor;\n }\n\n isProcessing(): boolean {\n return this.coreVm.is_processing();\n }\n\n cancel(invocationId: InvocationId): void {\n this._cancel(invocationId);\n }\n\n private _cancel(invocationId: string): void {\n this.processNonCompletableEntry(\n WasmCommandType.CancelInvocation,\n () => {},\n (vm) => vm.sys_cancel_invocation(invocationId)\n );\n }\n\n attach<T>(invocationId: InvocationId, serde?: Serde<T>): RestatePromise<T> {\n return this.processCompletableEntry(\n WasmCommandType.AttachInvocation,\n () => {},\n (vm) => vm.sys_attach_invocation(invocationId),\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec),\n Failure\n );\n }\n\n public get key(): string {\n switch (this.handlerKind) {\n case HandlerKind.EXCLUSIVE:\n case HandlerKind.SHARED:\n case HandlerKind.WORKFLOW: {\n return this.serviceKey;\n }\n default:\n throw new TerminalError(\"this handler type doesn't support key()\");\n }\n }\n\n public request(): Request {\n return this.invocationRequest;\n }\n\n public get<T>(name: string, serde?: Serde<T>): RestatePromise<T | null> {\n return this.processCompletableEntry(\n WasmCommandType.GetState,\n () => {},\n (vm) => vm.sys_get_state(name),\n VoidAsNull,\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec)\n );\n }\n\n public stateKeys(): RestatePromise<Array<string>> {\n return this.processCompletableEntry(\n WasmCommandType.GetStateKeys,\n () => {},\n (vm) => vm.sys_get_state_keys(),\n StateKeys\n );\n }\n\n public set<T>(name: string, value: T, serde?: Serde<T>): void {\n this.processNonCompletableEntry(\n WasmCommandType.SetState,\n () =>\n this.journalValueCodec.encode(\n (serde ?? this.defaultSerde).serialize(value)\n ),\n (vm, bytes) => vm.sys_set_state(name, bytes)\n );\n }\n\n public clear(name: string): void {\n this.processNonCompletableEntry(\n WasmCommandType.ClearState,\n () => {},\n (vm) => vm.sys_clear_state(name)\n );\n }\n\n public clearAll(): void {\n this.processNonCompletableEntry(\n WasmCommandType.ClearAllState,\n () => {},\n (vm) => vm.sys_clear_all_state()\n );\n }\n\n // --- Calls, background calls, etc\n //\n public genericCall<REQ = Uint8Array, RES = Uint8Array>(\n call: GenericCall<REQ, RES>\n ): InvocationPromise<RES> {\n const requestSerde: Serde<REQ> =\n call.inputSerde ?? (serde.binary as Serde<REQ>);\n const responseSerde: Serde<RES> =\n call.outputSerde ?? (serde.binary as Serde<RES>);\n\n let parameter: Uint8Array;\n try {\n parameter = this.journalValueCodec.encode(\n requestSerde.serialize(call.parameter)\n );\n } catch (e) {\n this.abortAttempt(e, WasmCommandType.Call);\n return Object.assign(ConstRestatePromise.pending<RES>(), {\n invocationId: pendingPromise<InvocationId>(),\n });\n }\n\n try {\n const call_handles = this.coreVm.sys_call(\n call.service,\n call.method,\n parameter,\n call.key,\n call.headers\n ? Object.entries(call.headers).map(\n ([key, value]) => new WasmHeader(key, value)\n )\n : [],\n call.idempotencyKey,\n call.name\n );\n const commandIndex = this.coreVm.last_command_index();\n\n const invocationIdPromise = new SingleRestatePromise(\n this,\n call_handles.invocation_id_completion_id,\n completeCommandPromiseUsing(\n WasmCommandType.Call,\n commandIndex,\n InvocationIdCompleter\n )\n );\n\n this.trackedInvocationIdPromises?.push(\n invocationIdPromise as SingleRestatePromise<string>\n );\n\n return new InvocationRestatePromise(\n this,\n call_handles.call_completion_id,\n completeCommandPromiseUsing(\n WasmCommandType.Call,\n commandIndex,\n SuccessWithSerde(responseSerde, this.journalValueCodec),\n Failure\n ),\n invocationIdPromise as RestatePromise<InvocationId>\n );\n } catch (e) {\n this.abortAttempt(e);\n // We return a pending promise to avoid the caller to see the error.\n return Object.assign(ConstRestatePromise.pending<RES>(), {\n invocationId: pendingPromise<InvocationId>(),\n });\n }\n }\n\n public genericSend<REQ = Uint8Array>(\n send: GenericSend<REQ>\n ): InvocationHandle {\n const requestSerde = send.inputSerde ?? (serde.binary as Serde<REQ>);\n\n let parameter: Uint8Array;\n try {\n parameter = this.journalValueCodec.encode(\n requestSerde.serialize(send.parameter)\n );\n } catch (e) {\n this.abortAttempt(e, WasmCommandType.OneWayCall);\n return Object.assign(ConstRestatePromise.pending<void>(), {\n invocationId: pendingPromise<InvocationId>(),\n });\n }\n\n try {\n const delay =\n send.delay !== undefined\n ? millisOrDurationToMillis(send.delay)\n : undefined;\n\n const handles = this.coreVm.sys_send(\n send.service,\n send.method,\n parameter,\n send.key,\n send.headers\n ? Object.entries(send.headers).map(\n ([key, value]) => new WasmHeader(key, value)\n )\n : [],\n delay !== undefined && delay > 0 ? BigInt(delay) : undefined,\n send.idempotencyKey,\n send.name\n );\n const commandIndex = this.coreVm.last_command_index();\n\n return {\n invocationId: new SingleRestatePromise(\n this,\n handles.invocation_id_completion_id,\n completeCommandPromiseUsing(\n WasmCommandType.OneWayCall,\n commandIndex,\n InvocationIdCompleter\n )\n ),\n };\n } catch (e) {\n this.abortAttempt(e);\n return {\n invocationId: pendingPromise(),\n };\n }\n }\n\n serviceClient<D>({ name }: ServiceDefinitionFrom<D>): Client<Service<D>> {\n return makeRpcCallProxy(\n (call) => this.genericCall(call),\n this.defaultSerde,\n\n name\n );\n }\n\n objectClient<D>(\n { name }: VirtualObjectDefinitionFrom<D>,\n key: string\n ): Client<VirtualObject<D>> {\n return makeRpcCallProxy(\n (call) => this.genericCall(call),\n this.defaultSerde,\n name,\n key\n );\n }\n\n workflowClient<D>(\n { name }: WorkflowDefinitionFrom<D>,\n key: string\n ): Client<Workflow<D>> {\n return makeRpcCallProxy(\n (call) => this.genericCall(call),\n this.defaultSerde,\n name,\n key\n );\n }\n\n public serviceSendClient<D>({\n name,\n }: ServiceDefinitionFrom<D>): SendClient<Service<D>> {\n return makeRpcSendProxy(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n undefined\n );\n }\n\n public objectSendClient<D>(\n { name }: VirtualObjectDefinitionFrom<D>,\n key: string\n ): SendClient<VirtualObject<D>> {\n return makeRpcSendProxy(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n key\n );\n }\n\n workflowSendClient<D>(\n { name }: WorkflowDefinitionFrom<D>,\n key: string\n ): SendClient<Workflow<D>> {\n return makeRpcSendProxy(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n key\n );\n }\n\n // DON'T make this function async!!!\n // The reason is that we want the errors thrown by the initial checks to be propagated in the caller context,\n // and not in the promise context. To understand the semantic difference, make this function async and run the\n // UnawaitedSideEffectShouldFailSubsequentContextCall test.\n public run<T>(\n nameOrAction: string | RunAction<T>,\n actionSecondParameter?: RunAction<T>,\n options?: RunOptions<T>\n ): RestatePromise<T> {\n const { name, action } = unpackRunParameters(\n nameOrAction,\n actionSecondParameter\n );\n const serde = options?.serde ?? this.defaultSerde;\n\n // Prepare the handle\n let wasmRun: vm.WasmRun;\n try {\n wasmRun = this.coreVm.sys_run(name ?? \"\");\n } catch (e) {\n this.abortAttempt(e);\n return ConstRestatePromise.pending();\n }\n const handle = wasmRun.handle;\n const commandIndex = this.coreVm.last_command_index();\n\n if (!wasmRun.replayed) {\n // Let's prepare the run task only if the run wasnt replayed.\n const doRun: () => Promise<any> = async () => {\n // Execute the user code, wrapping with run interceptor hooks\n const startTime = Date.now();\n let res: T;\n let err;\n try {\n await this.runInterceptor(name ?? \"\", async () => {\n res = await action();\n });\n } catch (e) {\n err = ensureError(e, this.asTerminalError);\n }\n const attemptDuration = Date.now() - startTime;\n\n // Propose the completion to the VM\n try {\n if (err !== undefined) {\n if (err instanceof TerminalError) {\n // Record failure, go ahead\n this.coreVm.propose_run_completion_failure(handle, {\n code: err.code,\n message: err.message,\n metadata: Object.entries(err.metadata ?? {}).map(\n ([key, value]) => ({ key, value })\n ),\n });\n } else if (err instanceof RetryableError) {\n this.coreVm.propose_run_completion_failure_transient_with_delay_override(\n handle,\n err.message,\n err.stack,\n BigInt(attemptDuration),\n err.retryAfter !== undefined\n ? BigInt(millisOrDurationToMillis(err.retryAfter))\n : undefined,\n options?.maxRetryAttempts,\n options?.maxRetryDuration !== undefined\n ? BigInt(millisOrDurationToMillis(options?.maxRetryDuration))\n : undefined\n );\n } else if (err instanceof PauseError) {\n this.coreVm.propose_run_completion_failure_transient_with_pause(\n handle,\n err.message,\n err.stack,\n BigInt(attemptDuration)\n );\n } else {\n this.vmLogger.warn(\n `Error when processing ctx.run '${name}'.\\n`,\n err\n );\n\n // Configure the retry policy if any of the parameters are set.\n let retryPolicy;\n if (\n options?.retryIntervalFactor !== undefined ||\n options?.maxRetryAttempts !== undefined ||\n options?.initialRetryInterval !== undefined ||\n options?.maxRetryDuration !== undefined ||\n options?.maxRetryInterval !== undefined\n ) {\n retryPolicy = {\n factor: options?.retryIntervalFactor ?? 2.0,\n initial_interval: millisOrDurationToMillis(\n options?.initialRetryInterval ?? 50\n ),\n max_attempts: options?.maxRetryAttempts,\n max_duration:\n options?.maxRetryDuration === undefined\n ? undefined\n : millisOrDurationToMillis(options?.maxRetryDuration),\n max_interval: millisOrDurationToMillis(\n options?.maxRetryInterval ?? { seconds: 10 }\n ),\n };\n }\n this.coreVm.propose_run_completion_failure_transient(\n handle,\n err.message,\n err.stack,\n BigInt(attemptDuration),\n retryPolicy\n );\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n const serializedRes = serde.serialize(res);\n const encodedRes = this.journalValueCodec.encode(serializedRes);\n this.coreVm.propose_run_completion_success(handle, encodedRes);\n }\n } catch (e) {\n this.abortAttempt(e);\n return pendingPromise<T>();\n }\n await this.outputPump.awaitNextProgress();\n };\n\n // Register the run to execute\n this.runClosuresTracker.registerRunClosure(handle, doRun);\n }\n\n // TODO: here as well\n // Return the promise\n return new SingleRestatePromise(\n this,\n handle,\n completeCommandPromiseUsing(\n WasmCommandType.Run,\n commandIndex,\n SuccessWithSerde(serde, this.journalValueCodec),\n Failure\n )\n );\n }\n\n public sleep(\n duration: number | Duration,\n name?: string\n ): RestatePromise<void> {\n return this.processCompletableEntry(\n WasmCommandType.Sleep,\n () => {\n if (duration === undefined) {\n throw new Error(`Duration is undefined.`);\n }\n const millis = millisOrDurationToMillis(duration);\n if (millis < 0) {\n throw new Error(\n `Invalid negative sleep duration: ${millis}ms.\\nIf this duration is computed from a desired wake up time, make sure to record 'now' using 'wakeUpTime - ctx.date.now()'.`\n );\n }\n return BigInt(millis);\n },\n (vm, millis) => vm.sys_sleep(millis, name),\n VoidAsUndefined\n );\n }\n\n // -- Awakeables\n\n public awakeable<T>(serde?: Serde<T>): {\n id: string;\n promise: RestatePromise<T>;\n } {\n let awakeable: vm.WasmAwakeable;\n try {\n awakeable = this.coreVm.sys_awakeable();\n } catch (e) {\n this.abortAttempt(e);\n return {\n id: \"invalid\",\n promise: ConstRestatePromise.pending(),\n };\n }\n\n return {\n id: awakeable.id,\n promise: new SingleRestatePromise(\n this,\n awakeable.handle,\n completeSignalPromiseUsing(\n VoidAsUndefined,\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec),\n Failure\n )\n ),\n };\n }\n\n public resolveAwakeable<T>(id: string, payload?: T, serde?: Serde<T>): void {\n this.processNonCompletableEntry(\n WasmCommandType.CompleteAwakeable,\n () => {\n // We coerce undefined to null as null can be stringified by JSON.stringify\n let value: Uint8Array;\n\n if (serde) {\n value =\n payload === undefined ? new Uint8Array() : serde.serialize(payload);\n } else {\n value =\n payload !== undefined\n ? this.defaultSerde.serialize(payload)\n : this.defaultSerde.serialize(null);\n }\n return this.journalValueCodec.encode(value);\n },\n (vm, bytes) => vm.sys_complete_awakeable_success(id, bytes)\n );\n }\n\n public rejectAwakeable(id: string, reason: string | TerminalError): void {\n this.processNonCompletableEntry(\n WasmCommandType.CompleteAwakeable,\n () => {},\n (vm) => {\n vm.sys_complete_awakeable_failure(id, toWasmFailure(reason));\n }\n );\n }\n\n // -- Signals\n\n public signal<T>(name: string, serde?: Serde<T>): RestatePromise<T> {\n let handle: number;\n try {\n handle = this.coreVm.sys_signal(name);\n } catch (e) {\n this.abortAttempt(e);\n return ConstRestatePromise.pending();\n }\n\n return new SingleRestatePromise(\n this,\n handle,\n completeSignalPromiseUsing(\n VoidAsUndefined,\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec),\n Failure\n )\n );\n }\n\n public invocation(invocationId: InvocationId): InvocationReference {\n return new InvocationReferenceImpl(this, invocationId);\n }\n\n public promise<T>(name: string, serde?: Serde<T>): DurablePromise<T> {\n return new DurablePromiseImpl(this, name, serde);\n }\n\n cancellation(): RestatePromise<void> {\n if (!this.cancellationPromise || this.cancellationPromise.isCompleted()) {\n this.cancellationPromise = new SingleRestatePromise(\n this,\n 1 /* HANDLE 1 is a hardcoded cancellation signal! */,\n completeSignalPromiseUsing(VoidAsUndefined)\n );\n }\n\n return this.cancellationPromise;\n }\n\n cancelPreviousCalls(): RestatePromise<InvocationId[]> {\n if (!this.trackedInvocationIdPromises) {\n return ConstRestatePromise.resolve([]);\n }\n\n return CombinatorRestatePromise.fromPromises(\n \"AllCompleted\",\n (p: Promise<any>[]) => Promise.allSettled(p),\n this.trackedInvocationIdPromises.splice(0)\n ).map((results, failure) => {\n if (failure) {\n throw failure;\n }\n const cancelled: InvocationId[] = [];\n for (const result of results as PromiseSettledResult<string>[]) {\n if (result.status === \"fulfilled\") {\n this._cancel(result.value);\n cancelled.push(result.value as InvocationId);\n } else {\n this.console.warn(\n `Error when trying to get invocation id: ${result.reason}`\n );\n }\n }\n return cancelled;\n });\n }\n\n // -- Various private methods\n\n processNonCompletableEntry<T>(\n commandType: vm.WasmCommandType,\n prepare: () => T,\n vmCall: (vm: vm.WasmVM, input: T) => void\n ) {\n let input;\n try {\n input = prepare();\n } catch (e) {\n this.abortAttempt(e, commandType);\n return;\n }\n\n try {\n vmCall(this.coreVm, input);\n } catch (e) {\n this.abortAttempt(e);\n }\n }\n\n processCompletableEntry<T, U>(\n commandType: vm.WasmCommandType,\n prepare: () => T,\n vmCall: (vm: vm.WasmVM, t: T) => number,\n ...completers: Array<Completer>\n ): RestatePromise<U> {\n let input;\n try {\n input = prepare();\n } catch (e) {\n this.abortAttempt(e, commandType);\n return ConstRestatePromise.pending();\n }\n\n let handle: number;\n try {\n handle = vmCall(this.coreVm, input);\n } catch (e) {\n this.abortAttempt(e);\n return ConstRestatePromise.pending();\n }\n const commandIndex = this.coreVm.last_command_index();\n return new SingleRestatePromise(\n this,\n handle,\n completeCommandPromiseUsing(commandType, commandIndex, ...completers)\n );\n }\n\n abortAttempt(e: unknown, commandType?: WasmCommandType) {\n // ensureError so interceptors always receive a proper Error,\n // not a raw VM object like { code, message }.\n this.invocationEndPromise.reject(\n commandType !== undefined\n ? new CommandError(e, commandType)\n : ensureError(e)\n );\n }\n}\n\nfunction toWasmFailure(reason: string | TerminalError): vm.WasmFailure {\n if (typeof reason === \"string\") {\n return {\n code: UNKNOWN_ERROR_CODE,\n message: reason,\n metadata: [],\n };\n }\n return {\n code: reason.code,\n message: reason.message,\n metadata: Object.entries(reason.metadata ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n };\n}\n\nfunction unpackRunParameters<T>(\n a: string | RunAction<T>,\n b?: RunAction<T>\n): { name?: string; action: RunAction<T> } {\n if (typeof a === \"string\") {\n if (typeof b !== \"function\") {\n throw new TypeError(\"\");\n }\n return { name: a, action: b };\n }\n if (typeof a !== \"function\") {\n throw new TypeError(\"unexpected type at the first parameter\");\n }\n if (b) {\n throw new TypeError(\"unexpected a function as a second parameter.\");\n }\n return { action: a };\n}\n\nclass InvocationReferenceImpl implements InvocationReference {\n constructor(\n private readonly ctx: ContextImpl,\n private readonly invocationId: InvocationId\n ) {}\n\n signal<T>(name: string, serde?: Serde<T>): SignalReference<T> {\n return new SignalReferenceImpl(this.ctx, this.invocationId, name, serde);\n }\n\n cancel(): void {\n this.ctx.cancel(this.invocationId);\n }\n\n attach<T>(serde?: Serde<T>): RestatePromise<T> {\n return this.ctx.attach(this.invocationId, serde);\n }\n}\n\nclass SignalReferenceImpl<T> implements SignalReference<T> {\n private readonly serde: Serde<T>;\n\n constructor(\n private readonly ctx: ContextImpl,\n private readonly invocationId: InvocationId,\n private readonly name: string,\n serde?: Serde<T>\n ) {\n this.serde = serde ?? (this.ctx.defaultSerde as unknown as Serde<T>);\n }\n\n resolve(payload?: T): void {\n this.ctx.processNonCompletableEntry(\n WasmCommandType.SendSignal,\n () =>\n this.ctx.journalValueCodec.encode(this.serde.serialize(payload as T)),\n (vm, bytes) =>\n vm.sys_complete_signal_success(this.invocationId, this.name, bytes)\n );\n }\n\n reject(reason: string | TerminalError): void {\n this.ctx.processNonCompletableEntry(\n WasmCommandType.SendSignal,\n () => {},\n (vm) => {\n vm.sys_complete_signal_failure(\n this.invocationId,\n this.name,\n toWasmFailure(reason)\n );\n }\n );\n }\n}\n\nclass DurablePromiseImpl<T> implements DurablePromise<T> {\n private readonly serde: Serde<T>;\n\n constructor(\n private readonly ctx: ContextImpl,\n private readonly name: string,\n serde?: Serde<T>\n ) {\n this.serde = serde ?? (this.ctx.defaultSerde as unknown as Serde<T>);\n }\n\n then<TResult1 = T, TResult2 = never>(\n onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<T | TResult> {\n return this.get().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.get().finally(onfinally);\n }\n\n [Symbol.toStringTag] = \"DurablePromise\";\n\n get(): RestatePromise<T> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.GetPromise,\n () => {},\n (vm) => vm.sys_get_promise(this.name),\n SuccessWithSerde(this.serde, this.ctx.journalValueCodec),\n Failure\n );\n }\n\n peek(): Promise<T | undefined> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.PeekPromise,\n () => {},\n (vm) => vm.sys_peek_promise(this.name),\n VoidAsUndefined,\n SuccessWithSerde(this.serde, this.ctx.journalValueCodec),\n Failure\n );\n }\n\n resolve(value?: T): Promise<void> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.CompletePromise,\n () => this.ctx.journalValueCodec.encode(this.serde.serialize(value as T)),\n (vm, bytes) => vm.sys_complete_promise_success(this.name, bytes),\n VoidAsUndefined,\n Failure\n );\n }\n\n reject(errorMsg: string): Promise<void> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.CompletePromise,\n () => {},\n (vm) =>\n vm.sys_complete_promise_failure(this.name, {\n code: INTERNAL_ERROR_CODE,\n message: errorMsg,\n metadata: [],\n }),\n VoidAsUndefined,\n Failure\n );\n }\n}\n\n/// Tracker of run closures to run\nexport class RunClosuresTracker {\n private runsToExecute: Map<number, () => Promise<any>> = new Map<\n number,\n () => Promise<any>\n >();\n\n constructor(private readonly channel: ExternalProgressChannel) {}\n\n executeRun(handle: number) {\n const runClosure = this.runsToExecute.get(handle);\n if (runClosure === undefined) {\n throw new Error(`Handle ${handle} doesn't exist`);\n }\n runClosure()\n .finally(() => this.channel.signal())\n .catch(() => {});\n }\n\n registerRunClosure(handle: number, runClosure: () => Promise<any>) {\n this.runsToExecute.set(handle, runClosure);\n }\n}\n\n// ---- Functions used to parse async results\n\ntype Completer = (\n value: AsyncResultValue,\n prom: PromiseWithResolvers<any>\n) => Promise<boolean>;\n\n// Wraps an error with command metadata so the centralized catch in\n// process() can call the right VM notification method.\n//\n// - Preparation failure (command not yet in journal): new CommandError(e, type)\n// → notify_error_for_next_command\n// - Completion failure (command exists): new CommandError(e, type, index)\n// → notify_error_for_specific_command\nexport class CommandError extends Error {\n constructor(cause: unknown, commandType: WasmCommandType);\n constructor(\n cause: unknown,\n commandType: WasmCommandType,\n commandIndex: number\n );\n constructor(\n override readonly cause: unknown,\n readonly commandType: WasmCommandType,\n readonly commandIndex?: number\n ) {\n const msg = cause instanceof Error ? cause.message : String(cause);\n super(msg, { cause });\n }\n\n /** True when the error is for a specific command that exists in the journal. */\n get hasCommandIndex(): boolean {\n return this.commandIndex !== undefined;\n }\n}\n\nfunction completeCommandPromiseUsing<T>(\n commandType: WasmCommandType,\n commandIndex: number,\n ...completers: Array<Completer>\n): (value: AsyncResultValue, prom: PromiseWithResolvers<T>) => Promise<void> {\n return async (value: AsyncResultValue, prom: PromiseWithResolvers<any>) => {\n try {\n for (const completer of completers) {\n if (await completer(value, prom)) {\n return;\n }\n }\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n throw new CommandError(e, commandType, commandIndex);\n }\n\n throw new Error(\n `Unexpected variant in async result: ${JSON.stringify(value)}`\n );\n };\n}\n\n// This is like the function above, but won't decorate the error with the command metadata\nfunction completeSignalPromiseUsing<T>(\n ...completers: Array<Completer>\n): (value: AsyncResultValue, prom: PromiseWithResolvers<T>) => Promise<void> {\n return async (value: AsyncResultValue, prom: PromiseWithResolvers<any>) => {\n for (const completer of completers) {\n if (await completer(value, prom)) {\n return;\n }\n }\n\n throw new Error(\n `Unexpected variant in async result: ${JSON.stringify(value)}`\n );\n };\n}\n\nconst VoidAsNull: Completer = (value, prom) => {\n if (value === \"Empty\") {\n prom.resolve(null);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\nconst VoidAsUndefined: Completer = (value, prom) => {\n if (value === \"Empty\") {\n prom.resolve(undefined);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n\nfunction SuccessWithSerde<T>(\n serde: Serde<T>,\n journalCodec?: JournalValueCodec,\n transform?: <U>(success: T) => U\n): Completer {\n return async (value, prom) => {\n if (typeof value !== \"object\" || !(\"Success\" in value)) {\n return false;\n }\n let buffer: Uint8Array;\n if (journalCodec !== undefined) {\n buffer = await journalCodec.decode(value.Success);\n } else {\n buffer = value.Success;\n }\n let val = serde.deserialize(buffer);\n if (transform) {\n val = transform(val);\n }\n prom.resolve(val);\n return true;\n };\n}\n\nconst Failure: Completer = (value, prom) => {\n if (typeof value === \"object\" && \"Failure\" in value) {\n const metadata = (value.Failure.metadata ?? []).reduce(\n (\n acc: Record<string, string>,\n { key, value: v }: { key: string; value: string }\n ) => {\n acc[key] = v;\n return acc;\n },\n {} as Record<string, string>\n );\n prom.reject(\n new TerminalError(value.Failure.message, {\n errorCode: value.Failure.code,\n metadata,\n })\n );\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n\nconst StateKeys: Completer = (value, prom) => {\n if (typeof value === \"object\" && \"StateKeys\" in value) {\n prom.resolve(value.StateKeys);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n\nconst InvocationIdCompleter: Completer = (value, prom) => {\n if (typeof value === \"object\" && \"InvocationId\" in value) {\n prom.resolve(value.InvocationId);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"context_impl.js","names":["coreVm: WasmVM","console: Console","handlerKind: HandlerKind","vmLogger: Console","invocationRequest: Request","invocationEndPromise: PromiseWithResolvers<void>","journalValueCodec: JournalValueCodec","serde","requestSerde: Serde<REQ>","responseSerde: Serde<RES>","parameter: Uint8Array","wasmRun: vm.WasmRun","doRun: () => Promise<any>","res: T","awakeable: vm.WasmAwakeable","value: Uint8Array","handle: number","cancelled: InvocationId[]","ctx: ContextImpl","invocationId: InvocationId","name: string","channel: ExternalProgressChannel","cause: unknown","commandType: WasmCommandType","commandIndex?: number","VoidAsNull: Completer","VoidAsUndefined: Completer","buffer: Uint8Array","Failure: Completer","StateKeys: Completer","InvocationIdCompleter: Completer"],"sources":["../src/context_impl.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type {\n ContextDate,\n DurablePromise,\n GenericCall,\n GenericSend,\n InvocationHandle,\n InvocationId,\n InvocationPromise,\n InvocationReference,\n ObjectContext,\n Rand,\n Request,\n RestatePromise,\n RunAction,\n RunOptions,\n SignalReference,\n ScopedContext,\n WorkflowContext,\n} from \"./context.js\";\nimport type * as vm from \"./endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js\";\nimport {\n WasmCommandType,\n WasmHeader,\n WasmInput,\n WasmVM,\n} from \"./endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js\";\nimport {\n ensureError,\n INTERNAL_ERROR_CODE,\n PauseError,\n RetryableError,\n TerminalError,\n UNKNOWN_ERROR_CODE,\n} from \"./types/errors.js\";\nimport type { Client, SendClient } from \"./types/rpc.js\";\nimport {\n HandlerKind,\n makeRpcCallProxy,\n makeRpcSendProxy,\n} from \"./types/rpc.js\";\nimport type {\n Duration,\n JournalValueCodec,\n Serde,\n Service,\n ServiceDefinitionFrom,\n VirtualObject,\n VirtualObjectDefinitionFrom,\n Workflow,\n WorkflowDefinitionFrom,\n} from \"@restatedev/restate-sdk-core\";\nimport { millisOrDurationToMillis, serde } from \"@restatedev/restate-sdk-core\";\nimport { RandImpl } from \"./utils/rand.js\";\nimport { AsyncResultValue, CombinatorRestatePromise } from \"./promises.js\";\nimport {\n ConstRestatePromise,\n pendingPromise,\n PromisesExecutor,\n InvocationRestatePromise,\n SingleRestatePromise,\n} from \"./promises.js\";\nimport { InputPump, OutputPump } from \"./io.js\";\nimport { ExternalProgressChannel } from \"./utils/external_progress_channel.js\";\nimport type { ContextInternal } from \"./internal.js\";\nimport { InputReader, OutputWriter } from \"./endpoint/handlers/types.js\";\nimport { ExecutionOptions } from \"./endpoint/components.js\";\n\nexport class ContextImpl\n implements ObjectContext, WorkflowContext, ContextInternal\n{\n public readonly rand: Rand;\n\n public readonly date: ContextDate = {\n now: (): Promise<number> => {\n return this.run(() => Date.now());\n },\n\n toJSON: (): Promise<string> => {\n return this.run(() => new Date().toJSON());\n },\n };\n\n private readonly outputPump: OutputPump;\n readonly inputPump: InputPump;\n private readonly runClosuresTracker: RunClosuresTracker;\n readonly promisesExecutor: PromisesExecutor;\n private readonly serviceKey: string;\n private runInterceptor: (\n name: string,\n runner: () => Promise<void>\n ) => Promise<void>;\n private cancellationPromise?: SingleRestatePromise<void>;\n readonly defaultSerde: Serde<any>;\n private readonly asTerminalError?: (error: any) => TerminalError | undefined;\n\n // If undefined, we're not tracking invocation id promises\n private readonly trackedInvocationIdPromises?: SingleRestatePromise<string>[];\n\n constructor(\n readonly coreVm: WasmVM,\n input: WasmInput,\n public readonly console: Console,\n public readonly handlerKind: HandlerKind,\n readonly vmLogger: Console,\n private readonly invocationRequest: Request,\n readonly invocationEndPromise: PromiseWithResolvers<void>,\n inputReader: InputReader,\n outputWriter: OutputWriter,\n readonly journalValueCodec: JournalValueCodec,\n executionOptions?: ExecutionOptions\n ) {\n this.rand = new RandImpl(input.random_seed, () => {\n // TODO reimplement this check with async context\n // if (coreVm.is_inside_run()) {\n // throw new Error(\n // \"Cannot generate random numbers within a run closure. Use the random object outside the run closure.\"\n // );\n // }\n });\n this.outputPump = new OutputPump(coreVm, outputWriter);\n const externalProgressChannel = new ExternalProgressChannel();\n this.runClosuresTracker = new RunClosuresTracker(externalProgressChannel);\n this.inputPump = new InputPump(\n coreVm,\n inputReader,\n externalProgressChannel,\n this.abortAttempt.bind(this)\n );\n this.promisesExecutor = new PromisesExecutor(\n coreVm,\n this.outputPump,\n this.runClosuresTracker,\n externalProgressChannel,\n this.abortAttempt.bind(this)\n );\n this.serviceKey = input.key;\n // Identity interceptor by default; replaced by startUserHandler after hooks are instantiated\n this.runInterceptor = (_name, runner) => runner();\n this.defaultSerde = executionOptions?.defaultSerde ?? serde.json;\n this.asTerminalError = executionOptions?.asTerminalError;\n this.trackedInvocationIdPromises = executionOptions?.explicitCancellation\n ? []\n : undefined;\n }\n\n setRunInterceptor(\n interceptor: (name: string, runner: () => Promise<void>) => Promise<void>\n ) {\n this.runInterceptor = interceptor;\n }\n\n isProcessing(): boolean {\n return this.coreVm.is_processing();\n }\n\n cancel(invocationId: InvocationId): void {\n this._cancel(invocationId);\n }\n\n private _cancel(invocationId: string): void {\n this.processNonCompletableEntry(\n WasmCommandType.CancelInvocation,\n () => {},\n (vm) => vm.sys_cancel_invocation(invocationId)\n );\n }\n\n attach<T>(invocationId: InvocationId, serde?: Serde<T>): RestatePromise<T> {\n return this.processCompletableEntry(\n WasmCommandType.AttachInvocation,\n () => {},\n (vm) => vm.sys_attach_invocation(invocationId),\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec),\n Failure\n );\n }\n\n public get key(): string {\n switch (this.handlerKind) {\n case HandlerKind.EXCLUSIVE:\n case HandlerKind.SHARED:\n case HandlerKind.WORKFLOW: {\n return this.serviceKey;\n }\n default:\n throw new TerminalError(\"this handler type doesn't support key()\");\n }\n }\n\n public request(): Request {\n return this.invocationRequest;\n }\n\n public get<T>(name: string, serde?: Serde<T>): RestatePromise<T | null> {\n return this.processCompletableEntry(\n WasmCommandType.GetState,\n () => {},\n (vm) => vm.sys_get_state(name),\n VoidAsNull,\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec)\n );\n }\n\n public stateKeys(): RestatePromise<Array<string>> {\n return this.processCompletableEntry(\n WasmCommandType.GetStateKeys,\n () => {},\n (vm) => vm.sys_get_state_keys(),\n StateKeys\n );\n }\n\n public set<T>(name: string, value: T, serde?: Serde<T>): void {\n this.processNonCompletableEntry(\n WasmCommandType.SetState,\n () =>\n this.journalValueCodec.encode(\n (serde ?? this.defaultSerde).serialize(value)\n ),\n (vm, bytes) => vm.sys_set_state(name, bytes)\n );\n }\n\n public clear(name: string): void {\n this.processNonCompletableEntry(\n WasmCommandType.ClearState,\n () => {},\n (vm) => vm.sys_clear_state(name)\n );\n }\n\n public clearAll(): void {\n this.processNonCompletableEntry(\n WasmCommandType.ClearAllState,\n () => {},\n (vm) => vm.sys_clear_all_state()\n );\n }\n\n // --- Calls, background calls, etc\n //\n public genericCall<REQ = Uint8Array, RES = Uint8Array>(\n call: GenericCall<REQ, RES>\n ): InvocationPromise<RES> {\n const requestSerde: Serde<REQ> =\n call.inputSerde ?? (serde.binary as Serde<REQ>);\n const responseSerde: Serde<RES> =\n call.outputSerde ?? (serde.binary as Serde<RES>);\n\n let parameter: Uint8Array;\n try {\n parameter = this.journalValueCodec.encode(\n requestSerde.serialize(call.parameter)\n );\n } catch (e) {\n this.abortAttempt(e, WasmCommandType.Call);\n return Object.assign(ConstRestatePromise.pending<RES>(), {\n invocationId: pendingPromise<InvocationId>(),\n });\n }\n\n try {\n const call_handles = this.coreVm.sys_call(\n call.service,\n call.method,\n parameter,\n call.key,\n call.headers\n ? Object.entries(call.headers).map(\n ([key, value]) => new WasmHeader(key, value)\n )\n : [],\n call.idempotencyKey,\n call.scope,\n call.limitKey,\n call.name\n );\n const commandIndex = this.coreVm.last_command_index();\n\n const invocationIdPromise = new SingleRestatePromise(\n this,\n call_handles.invocation_id_completion_id,\n completeCommandPromiseUsing(\n WasmCommandType.Call,\n commandIndex,\n InvocationIdCompleter\n )\n );\n\n this.trackedInvocationIdPromises?.push(\n invocationIdPromise as SingleRestatePromise<string>\n );\n\n return new InvocationRestatePromise(\n this,\n call_handles.call_completion_id,\n completeCommandPromiseUsing(\n WasmCommandType.Call,\n commandIndex,\n SuccessWithSerde(responseSerde, this.journalValueCodec),\n Failure\n ),\n invocationIdPromise as RestatePromise<InvocationId>\n );\n } catch (e) {\n this.abortAttempt(e);\n // We return a pending promise to avoid the caller to see the error.\n return Object.assign(ConstRestatePromise.pending<RES>(), {\n invocationId: pendingPromise<InvocationId>(),\n });\n }\n }\n\n public genericSend<REQ = Uint8Array>(\n send: GenericSend<REQ>\n ): InvocationHandle {\n const requestSerde = send.inputSerde ?? (serde.binary as Serde<REQ>);\n\n let parameter: Uint8Array;\n try {\n parameter = this.journalValueCodec.encode(\n requestSerde.serialize(send.parameter)\n );\n } catch (e) {\n this.abortAttempt(e, WasmCommandType.OneWayCall);\n return Object.assign(ConstRestatePromise.pending<void>(), {\n invocationId: pendingPromise<InvocationId>(),\n });\n }\n\n try {\n const delay =\n send.delay !== undefined\n ? millisOrDurationToMillis(send.delay)\n : undefined;\n\n const handles = this.coreVm.sys_send(\n send.service,\n send.method,\n parameter,\n send.key,\n send.headers\n ? Object.entries(send.headers).map(\n ([key, value]) => new WasmHeader(key, value)\n )\n : [],\n delay !== undefined && delay > 0 ? BigInt(delay) : undefined,\n send.idempotencyKey,\n send.scope,\n send.limitKey,\n send.name\n );\n const commandIndex = this.coreVm.last_command_index();\n\n return {\n invocationId: new SingleRestatePromise(\n this,\n handles.invocation_id_completion_id,\n completeCommandPromiseUsing(\n WasmCommandType.OneWayCall,\n commandIndex,\n InvocationIdCompleter\n )\n ),\n };\n } catch (e) {\n this.abortAttempt(e);\n return {\n invocationId: pendingPromise(),\n };\n }\n }\n\n serviceClient<D>({ name }: ServiceDefinitionFrom<D>): Client<Service<D>> {\n return makeRpcCallProxy(\n (call) => this.genericCall(call),\n this.defaultSerde,\n\n name\n );\n }\n\n objectClient<D>(\n { name }: VirtualObjectDefinitionFrom<D>,\n key: string\n ): Client<VirtualObject<D>> {\n return makeRpcCallProxy(\n (call) => this.genericCall(call),\n this.defaultSerde,\n name,\n key\n );\n }\n\n workflowClient<D>(\n { name }: WorkflowDefinitionFrom<D>,\n key: string\n ): Client<Workflow<D>> {\n return makeRpcCallProxy(\n (call) => this.genericCall(call),\n this.defaultSerde,\n name,\n key\n );\n }\n\n public serviceSendClient<D>({\n name,\n }: ServiceDefinitionFrom<D>): SendClient<Service<D>> {\n return makeRpcSendProxy(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n undefined\n );\n }\n\n public objectSendClient<D>(\n { name }: VirtualObjectDefinitionFrom<D>,\n key: string\n ): SendClient<VirtualObject<D>> {\n return makeRpcSendProxy(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n key\n );\n }\n\n workflowSendClient<D>(\n { name }: WorkflowDefinitionFrom<D>,\n key: string\n ): SendClient<Workflow<D>> {\n return makeRpcSendProxy(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n key\n );\n }\n\n scope(scopeKey: string): ScopedContext {\n return {\n serviceClient: <D>({ name }: ServiceDefinitionFrom<D>) =>\n makeRpcCallProxy<Client<Service<D>>>(\n (call) => this.genericCall(call),\n this.defaultSerde,\n name,\n undefined,\n scopeKey\n ),\n serviceSendClient: <D>({ name }: ServiceDefinitionFrom<D>) =>\n makeRpcSendProxy<SendClient<Service<D>>>(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n undefined,\n scopeKey\n ),\n workflowClient: <D>({ name }: WorkflowDefinitionFrom<D>, key: string) =>\n makeRpcCallProxy<Client<Workflow<D>>>(\n (call) => this.genericCall(call),\n this.defaultSerde,\n name,\n key,\n scopeKey\n ),\n workflowSendClient: <D>(\n { name }: WorkflowDefinitionFrom<D>,\n key: string\n ) =>\n makeRpcSendProxy<SendClient<Workflow<D>>>(\n (send) => this.genericSend(send),\n this.defaultSerde,\n name,\n key,\n scopeKey\n ),\n };\n }\n\n // DON'T make this function async!!!\n // The reason is that we want the errors thrown by the initial checks to be propagated in the caller context,\n // and not in the promise context. To understand the semantic difference, make this function async and run the\n // UnawaitedSideEffectShouldFailSubsequentContextCall test.\n public run<T>(\n nameOrAction: string | RunAction<T>,\n actionSecondParameter?: RunAction<T>,\n options?: RunOptions<T>\n ): RestatePromise<T> {\n const { name, action } = unpackRunParameters(\n nameOrAction,\n actionSecondParameter\n );\n const serde = options?.serde ?? this.defaultSerde;\n\n // Prepare the handle\n let wasmRun: vm.WasmRun;\n try {\n wasmRun = this.coreVm.sys_run(name ?? \"\");\n } catch (e) {\n this.abortAttempt(e);\n return ConstRestatePromise.pending();\n }\n const handle = wasmRun.handle;\n const commandIndex = this.coreVm.last_command_index();\n\n if (!wasmRun.replayed) {\n // Let's prepare the run task only if the run wasnt replayed.\n const doRun: () => Promise<any> = async () => {\n // Execute the user code, wrapping with run interceptor hooks\n const startTime = Date.now();\n let res: T;\n let err;\n try {\n await this.runInterceptor(name ?? \"\", async () => {\n res = await action();\n });\n } catch (e) {\n err = ensureError(e, this.asTerminalError);\n }\n const attemptDuration = Date.now() - startTime;\n\n // Propose the completion to the VM\n try {\n if (err !== undefined) {\n if (err instanceof TerminalError) {\n // Record failure, go ahead\n this.coreVm.propose_run_completion_failure(handle, {\n code: err.code,\n message: err.message,\n metadata: Object.entries(err.metadata ?? {}).map(\n ([key, value]) => ({ key, value })\n ),\n });\n } else if (err instanceof RetryableError) {\n this.coreVm.propose_run_completion_failure_transient_with_delay_override(\n handle,\n err.message,\n err.stack,\n BigInt(attemptDuration),\n err.retryAfter !== undefined\n ? BigInt(millisOrDurationToMillis(err.retryAfter))\n : undefined,\n options?.maxRetryAttempts,\n options?.maxRetryDuration !== undefined\n ? BigInt(millisOrDurationToMillis(options?.maxRetryDuration))\n : undefined\n );\n } else if (err instanceof PauseError) {\n this.coreVm.propose_run_completion_failure_transient_with_pause(\n handle,\n err.message,\n err.stack,\n BigInt(attemptDuration)\n );\n } else {\n this.vmLogger.warn(\n `Error when processing ctx.run '${name}'.\\n`,\n err\n );\n\n // Configure the retry policy if any of the parameters are set.\n let retryPolicy;\n if (\n options?.retryIntervalFactor !== undefined ||\n options?.maxRetryAttempts !== undefined ||\n options?.initialRetryInterval !== undefined ||\n options?.maxRetryDuration !== undefined ||\n options?.maxRetryInterval !== undefined\n ) {\n retryPolicy = {\n factor: options?.retryIntervalFactor ?? 2.0,\n initial_interval: millisOrDurationToMillis(\n options?.initialRetryInterval ?? 50\n ),\n max_attempts: options?.maxRetryAttempts,\n max_duration:\n options?.maxRetryDuration === undefined\n ? undefined\n : millisOrDurationToMillis(options?.maxRetryDuration),\n max_interval: millisOrDurationToMillis(\n options?.maxRetryInterval ?? { seconds: 10 }\n ),\n };\n }\n this.coreVm.propose_run_completion_failure_transient(\n handle,\n err.message,\n err.stack,\n BigInt(attemptDuration),\n retryPolicy\n );\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n const serializedRes = serde.serialize(res);\n const encodedRes = this.journalValueCodec.encode(serializedRes);\n this.coreVm.propose_run_completion_success(handle, encodedRes);\n }\n } catch (e) {\n this.abortAttempt(e);\n return pendingPromise<T>();\n }\n await this.outputPump.awaitNextProgress();\n };\n\n // Register the run to execute\n this.runClosuresTracker.registerRunClosure(handle, doRun);\n }\n\n // TODO: here as well\n // Return the promise\n return new SingleRestatePromise(\n this,\n handle,\n completeCommandPromiseUsing(\n WasmCommandType.Run,\n commandIndex,\n SuccessWithSerde(serde, this.journalValueCodec),\n Failure\n )\n );\n }\n\n public sleep(\n duration: number | Duration,\n name?: string\n ): RestatePromise<void> {\n return this.processCompletableEntry(\n WasmCommandType.Sleep,\n () => {\n if (duration === undefined) {\n throw new Error(`Duration is undefined.`);\n }\n const millis = millisOrDurationToMillis(duration);\n if (millis < 0) {\n throw new Error(\n `Invalid negative sleep duration: ${millis}ms.\\nIf this duration is computed from a desired wake up time, make sure to record 'now' using 'wakeUpTime - ctx.date.now()'.`\n );\n }\n return BigInt(millis);\n },\n (vm, millis) => vm.sys_sleep(millis, name),\n VoidAsUndefined\n );\n }\n\n // -- Awakeables\n\n public awakeable<T>(serde?: Serde<T>): {\n id: string;\n promise: RestatePromise<T>;\n } {\n let awakeable: vm.WasmAwakeable;\n try {\n awakeable = this.coreVm.sys_awakeable();\n } catch (e) {\n this.abortAttempt(e);\n return {\n id: \"invalid\",\n promise: ConstRestatePromise.pending(),\n };\n }\n\n return {\n id: awakeable.id,\n promise: new SingleRestatePromise(\n this,\n awakeable.handle,\n completeSignalPromiseUsing(\n VoidAsUndefined,\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec),\n Failure\n )\n ),\n };\n }\n\n public resolveAwakeable<T>(id: string, payload?: T, serde?: Serde<T>): void {\n this.processNonCompletableEntry(\n WasmCommandType.CompleteAwakeable,\n () => {\n // We coerce undefined to null as null can be stringified by JSON.stringify\n let value: Uint8Array;\n\n if (serde) {\n value =\n payload === undefined ? new Uint8Array() : serde.serialize(payload);\n } else {\n value =\n payload !== undefined\n ? this.defaultSerde.serialize(payload)\n : this.defaultSerde.serialize(null);\n }\n return this.journalValueCodec.encode(value);\n },\n (vm, bytes) => vm.sys_complete_awakeable_success(id, bytes)\n );\n }\n\n public rejectAwakeable(id: string, reason: string | TerminalError): void {\n this.processNonCompletableEntry(\n WasmCommandType.CompleteAwakeable,\n () => {},\n (vm) => {\n vm.sys_complete_awakeable_failure(id, toWasmFailure(reason));\n }\n );\n }\n\n // -- Signals\n\n public signal<T>(name: string, serde?: Serde<T>): RestatePromise<T> {\n let handle: number;\n try {\n handle = this.coreVm.sys_signal(name);\n } catch (e) {\n this.abortAttempt(e);\n return ConstRestatePromise.pending();\n }\n\n return new SingleRestatePromise(\n this,\n handle,\n completeSignalPromiseUsing(\n VoidAsUndefined,\n SuccessWithSerde(serde ?? this.defaultSerde, this.journalValueCodec),\n Failure\n )\n );\n }\n\n public invocation(invocationId: InvocationId): InvocationReference {\n return new InvocationReferenceImpl(this, invocationId);\n }\n\n public promise<T>(name: string, serde?: Serde<T>): DurablePromise<T> {\n return new DurablePromiseImpl(this, name, serde);\n }\n\n cancellation(): RestatePromise<void> {\n if (!this.cancellationPromise || this.cancellationPromise.isCompleted()) {\n this.cancellationPromise = new SingleRestatePromise(\n this,\n 1 /* HANDLE 1 is a hardcoded cancellation signal! */,\n completeSignalPromiseUsing(VoidAsUndefined)\n );\n }\n\n return this.cancellationPromise;\n }\n\n cancelPreviousCalls(): RestatePromise<InvocationId[]> {\n if (!this.trackedInvocationIdPromises) {\n return ConstRestatePromise.resolve([]);\n }\n\n return CombinatorRestatePromise.fromPromises(\n \"AllCompleted\",\n (p: Promise<any>[]) => Promise.allSettled(p),\n this.trackedInvocationIdPromises.splice(0)\n ).map((results, failure) => {\n if (failure) {\n throw failure;\n }\n const cancelled: InvocationId[] = [];\n for (const result of results as PromiseSettledResult<string>[]) {\n if (result.status === \"fulfilled\") {\n this._cancel(result.value);\n cancelled.push(result.value as InvocationId);\n } else {\n this.console.warn(\n `Error when trying to get invocation id: ${result.reason}`\n );\n }\n }\n return cancelled;\n });\n }\n\n // -- Various private methods\n\n processNonCompletableEntry<T>(\n commandType: vm.WasmCommandType,\n prepare: () => T,\n vmCall: (vm: vm.WasmVM, input: T) => void\n ) {\n let input;\n try {\n input = prepare();\n } catch (e) {\n this.abortAttempt(e, commandType);\n return;\n }\n\n try {\n vmCall(this.coreVm, input);\n } catch (e) {\n this.abortAttempt(e);\n }\n }\n\n processCompletableEntry<T, U>(\n commandType: vm.WasmCommandType,\n prepare: () => T,\n vmCall: (vm: vm.WasmVM, t: T) => number,\n ...completers: Array<Completer>\n ): RestatePromise<U> {\n let input;\n try {\n input = prepare();\n } catch (e) {\n this.abortAttempt(e, commandType);\n return ConstRestatePromise.pending();\n }\n\n let handle: number;\n try {\n handle = vmCall(this.coreVm, input);\n } catch (e) {\n this.abortAttempt(e);\n return ConstRestatePromise.pending();\n }\n const commandIndex = this.coreVm.last_command_index();\n return new SingleRestatePromise(\n this,\n handle,\n completeCommandPromiseUsing(commandType, commandIndex, ...completers)\n );\n }\n\n abortAttempt(e: unknown, commandType?: WasmCommandType) {\n // ensureError so interceptors always receive a proper Error,\n // not a raw VM object like { code, message }.\n this.invocationEndPromise.reject(\n commandType !== undefined\n ? new CommandError(e, commandType)\n : ensureError(e)\n );\n }\n}\n\nfunction toWasmFailure(reason: string | TerminalError): vm.WasmFailure {\n if (typeof reason === \"string\") {\n return {\n code: UNKNOWN_ERROR_CODE,\n message: reason,\n metadata: [],\n };\n }\n return {\n code: reason.code,\n message: reason.message,\n metadata: Object.entries(reason.metadata ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n };\n}\n\nfunction unpackRunParameters<T>(\n a: string | RunAction<T>,\n b?: RunAction<T>\n): { name?: string; action: RunAction<T> } {\n if (typeof a === \"string\") {\n if (typeof b !== \"function\") {\n throw new TypeError(\"\");\n }\n return { name: a, action: b };\n }\n if (typeof a !== \"function\") {\n throw new TypeError(\"unexpected type at the first parameter\");\n }\n if (b) {\n throw new TypeError(\"unexpected a function as a second parameter.\");\n }\n return { action: a };\n}\n\nclass InvocationReferenceImpl implements InvocationReference {\n constructor(\n private readonly ctx: ContextImpl,\n private readonly invocationId: InvocationId\n ) {}\n\n signal<T>(name: string, serde?: Serde<T>): SignalReference<T> {\n return new SignalReferenceImpl(this.ctx, this.invocationId, name, serde);\n }\n\n cancel(): void {\n this.ctx.cancel(this.invocationId);\n }\n\n attach<T>(serde?: Serde<T>): RestatePromise<T> {\n return this.ctx.attach(this.invocationId, serde);\n }\n}\n\nclass SignalReferenceImpl<T> implements SignalReference<T> {\n private readonly serde: Serde<T>;\n\n constructor(\n private readonly ctx: ContextImpl,\n private readonly invocationId: InvocationId,\n private readonly name: string,\n serde?: Serde<T>\n ) {\n this.serde = serde ?? (this.ctx.defaultSerde as unknown as Serde<T>);\n }\n\n resolve(payload?: T): void {\n this.ctx.processNonCompletableEntry(\n WasmCommandType.SendSignal,\n () =>\n this.ctx.journalValueCodec.encode(this.serde.serialize(payload as T)),\n (vm, bytes) =>\n vm.sys_complete_signal_success(this.invocationId, this.name, bytes)\n );\n }\n\n reject(reason: string | TerminalError): void {\n this.ctx.processNonCompletableEntry(\n WasmCommandType.SendSignal,\n () => {},\n (vm) => {\n vm.sys_complete_signal_failure(\n this.invocationId,\n this.name,\n toWasmFailure(reason)\n );\n }\n );\n }\n}\n\nclass DurablePromiseImpl<T> implements DurablePromise<T> {\n private readonly serde: Serde<T>;\n\n constructor(\n private readonly ctx: ContextImpl,\n private readonly name: string,\n serde?: Serde<T>\n ) {\n this.serde = serde ?? (this.ctx.defaultSerde as unknown as Serde<T>);\n }\n\n then<TResult1 = T, TResult2 = never>(\n onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null\n ): Promise<TResult1 | TResult2> {\n return this.get().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<T | TResult> {\n return this.get().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.get().finally(onfinally);\n }\n\n [Symbol.toStringTag] = \"DurablePromise\";\n\n get(): RestatePromise<T> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.GetPromise,\n () => {},\n (vm) => vm.sys_get_promise(this.name),\n SuccessWithSerde(this.serde, this.ctx.journalValueCodec),\n Failure\n );\n }\n\n peek(): Promise<T | undefined> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.PeekPromise,\n () => {},\n (vm) => vm.sys_peek_promise(this.name),\n VoidAsUndefined,\n SuccessWithSerde(this.serde, this.ctx.journalValueCodec),\n Failure\n );\n }\n\n resolve(value?: T): Promise<void> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.CompletePromise,\n () => this.ctx.journalValueCodec.encode(this.serde.serialize(value as T)),\n (vm, bytes) => vm.sys_complete_promise_success(this.name, bytes),\n VoidAsUndefined,\n Failure\n );\n }\n\n reject(errorMsg: string): Promise<void> {\n return this.ctx.processCompletableEntry(\n WasmCommandType.CompletePromise,\n () => {},\n (vm) =>\n vm.sys_complete_promise_failure(this.name, {\n code: INTERNAL_ERROR_CODE,\n message: errorMsg,\n metadata: [],\n }),\n VoidAsUndefined,\n Failure\n );\n }\n}\n\n/// Tracker of run closures to run\nexport class RunClosuresTracker {\n private runsToExecute: Map<number, () => Promise<any>> = new Map<\n number,\n () => Promise<any>\n >();\n\n constructor(private readonly channel: ExternalProgressChannel) {}\n\n executeRun(handle: number) {\n const runClosure = this.runsToExecute.get(handle);\n if (runClosure === undefined) {\n throw new Error(`Handle ${handle} doesn't exist`);\n }\n this.runsToExecute.delete(handle);\n runClosure()\n .finally(() => this.channel.signal())\n .catch(() => {});\n }\n\n registerRunClosure(handle: number, runClosure: () => Promise<any>) {\n this.runsToExecute.set(handle, runClosure);\n }\n}\n\n// ---- Functions used to parse async results\n\ntype Completer = (\n value: AsyncResultValue,\n prom: PromiseWithResolvers<any>\n) => Promise<boolean>;\n\n// Wraps an error with command metadata so the centralized catch in\n// process() can call the right VM notification method.\n//\n// - Preparation failure (command not yet in journal): new CommandError(e, type)\n// → notify_error_for_next_command\n// - Completion failure (command exists): new CommandError(e, type, index)\n// → notify_error_for_specific_command\nexport class CommandError extends Error {\n constructor(cause: unknown, commandType: WasmCommandType);\n constructor(\n cause: unknown,\n commandType: WasmCommandType,\n commandIndex: number\n );\n constructor(\n override readonly cause: unknown,\n readonly commandType: WasmCommandType,\n readonly commandIndex?: number\n ) {\n const msg = cause instanceof Error ? cause.message : String(cause);\n super(msg, { cause });\n }\n\n /** True when the error is for a specific command that exists in the journal. */\n get hasCommandIndex(): boolean {\n return this.commandIndex !== undefined;\n }\n}\n\nfunction completeCommandPromiseUsing<T>(\n commandType: WasmCommandType,\n commandIndex: number,\n ...completers: Array<Completer>\n): (value: AsyncResultValue, prom: PromiseWithResolvers<T>) => Promise<void> {\n return async (value: AsyncResultValue, prom: PromiseWithResolvers<any>) => {\n try {\n for (const completer of completers) {\n if (await completer(value, prom)) {\n return;\n }\n }\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n throw new CommandError(e, commandType, commandIndex);\n }\n\n throw new Error(\n `Unexpected variant in async result: ${JSON.stringify(value)}`\n );\n };\n}\n\n// This is like the function above, but won't decorate the error with the command metadata\nfunction completeSignalPromiseUsing<T>(\n ...completers: Array<Completer>\n): (value: AsyncResultValue, prom: PromiseWithResolvers<T>) => Promise<void> {\n return async (value: AsyncResultValue, prom: PromiseWithResolvers<any>) => {\n for (const completer of completers) {\n if (await completer(value, prom)) {\n return;\n }\n }\n\n throw new Error(\n `Unexpected variant in async result: ${JSON.stringify(value)}`\n );\n };\n}\n\nconst VoidAsNull: Completer = (value, prom) => {\n if (value === \"Empty\") {\n prom.resolve(null);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\nconst VoidAsUndefined: Completer = (value, prom) => {\n if (value === \"Empty\") {\n prom.resolve(undefined);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n\nfunction SuccessWithSerde<T>(\n serde: Serde<T>,\n journalCodec?: JournalValueCodec,\n transform?: <U>(success: T) => U\n): Completer {\n return async (value, prom) => {\n if (typeof value !== \"object\" || !(\"Success\" in value)) {\n return false;\n }\n let buffer: Uint8Array;\n if (journalCodec !== undefined) {\n buffer = await journalCodec.decode(value.Success);\n } else {\n buffer = value.Success;\n }\n let val = serde.deserialize(buffer);\n if (transform) {\n val = transform(val);\n }\n prom.resolve(val);\n return true;\n };\n}\n\nconst Failure: Completer = (value, prom) => {\n if (typeof value === \"object\" && \"Failure\" in value) {\n const metadata = (value.Failure.metadata ?? []).reduce(\n (\n acc: Record<string, string>,\n { key, value: v }: { key: string; value: string }\n ) => {\n acc[key] = v;\n return acc;\n },\n {} as Record<string, string>\n );\n prom.reject(\n new TerminalError(value.Failure.message, {\n errorCode: value.Failure.code,\n metadata,\n })\n );\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n\nconst StateKeys: Completer = (value, prom) => {\n if (typeof value === \"object\" && \"StateKeys\" in value) {\n prom.resolve(value.StateKeys);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n\nconst InvocationIdCompleter: Completer = (value, prom) => {\n if (typeof value === \"object\" && \"InvocationId\" in value) {\n prom.resolve(value.InvocationId);\n return Promise.resolve(true);\n }\n return Promise.resolve(false);\n};\n"],"mappings":"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"}
|
|
@@ -161,6 +161,9 @@ var RestateInvokeResponse = class {
|
|
|
161
161
|
}, /* @__PURE__ */ new Map()),
|
|
162
162
|
body: input.input,
|
|
163
163
|
extraArgs: this.extraArgs,
|
|
164
|
+
idempotencyKey: input.idempotency_key || void 0,
|
|
165
|
+
scope: input.scope || void 0,
|
|
166
|
+
limitKey: input.limit_key || void 0,
|
|
164
167
|
attemptCompletedSignal: abortSignal
|
|
165
168
|
};
|
|
166
169
|
const loggerContext = new require_logger_transport.LoggerContext(input.invocation_id, this.handler.component().name(), this.handler.name(), this.handler.kind() === require_rpc.HandlerKind.SERVICE ? void 0 : input.key, invocationRequest, this.additionalContext);
|
|
@@ -159,6 +159,9 @@ var RestateInvokeResponse = class {
|
|
|
159
159
|
}, /* @__PURE__ */ new Map()),
|
|
160
160
|
body: input.input,
|
|
161
161
|
extraArgs: this.extraArgs,
|
|
162
|
+
idempotencyKey: input.idempotency_key || void 0,
|
|
163
|
+
scope: input.scope || void 0,
|
|
164
|
+
limitKey: input.limit_key || void 0,
|
|
162
165
|
attemptCompletedSignal: abortSignal
|
|
163
166
|
};
|
|
164
167
|
const loggerContext = new LoggerContext(input.invocation_id, this.handler.component().name(), this.handler.name(), this.handler.kind() === HandlerKind.SERVICE ? void 0 : input.key, invocationRequest, this.additionalContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic.js","names":["endpoint: Endpoint","protocolMode: ProtocolMode","additionalDiscoveryFields: Partial<EndpointManifest>","vm.WasmIdentityVerifier","vm.WasmHeader","service: Component","handler: ComponentHandler","attemptHeaders: Headers","extraArgs: unknown[]","additionalContext: AdditionalContext","journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined","loggerTransport: LoggerTransport","vm.WasmVM","journalValueCodec: JournalValueCodec","ctx: ContextImpl","invocationRequest: Request","hooks: Hooks[]","hookContext: { request: Request }","encodedOutput: Uint8Array | undefined","originalError: unknown"],"sources":["../../../src/endpoint/handlers/generic.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport {\n ensureError,\n logError,\n PauseError,\n RestateError,\n RetryableError,\n TerminalError,\n} from \"../../types/errors.js\";\nimport type {\n Endpoint as EndpointManifest,\n ProtocolMode,\n} from \"../discovery.js\";\nimport {\n Component,\n ComponentHandler,\n InvokePathComponents,\n} from \"../components.js\";\nimport { parseUrlComponents } from \"../components.js\";\nimport { X_RESTATE_SERVER } from \"../../user_agent.js\";\nimport { CommandError, ContextImpl } from \"../../context_impl.js\";\nimport { restoreError, sanitizeError } from \"../../error_sanitization.js\";\nimport type { InvocationId, Request } from \"../../context.js\";\nimport * as vm from \"./vm/sdk_shared_core_wasm_bindings.js\";\nimport { HandlerKind } from \"../../types/rpc.js\";\nimport { createLogger, type Logger } from \"../../logging/logger.js\";\nimport { DEFAULT_CONSOLE_LOGGER_LOG_LEVEL } from \"../../logging/console_logger_transport.js\";\nimport {\n LoggerContext,\n LoggerTransport,\n LogSource,\n RestateLogLevel,\n} from \"../../logging/logger_transport.js\";\nimport {\n type JournalValueCodec,\n millisOrDurationToMillis,\n} from \"@restatedev/restate-sdk-core\";\nimport type { Endpoint } from \"../endpoint.js\";\nimport {\n type RestateHandler,\n type Headers,\n type RestateRequest,\n type AdditionalContext,\n type RestateResponse,\n ResponseHeaders,\n InputReader,\n OutputWriter,\n} from \"./types.js\";\nimport { handleDiscovery } from \"./discovery.js\";\nimport { handlePreview } from \"./preview.js\";\nimport {\n errorResponse,\n invocationIdFromHeaders,\n simpleResponse,\n tryCreateContextualLogger,\n} from \"./utils.js\";\nimport { destroyLogger, registerLogger } from \"./core_logging.js\";\nimport type { Hooks } from \"../../hooks.js\";\n\n// Hidden symbol key used by first-party hooks to read the live\n// replay/processing phase without widening the public HooksProvider API.\nconst HOOK_CONTEXT_IS_PROCESSING_SYMBOL = Symbol.for(\n \"@restatedev/restate-sdk/hooks.isProcessing\"\n);\n\nexport function createRestateHandler(\n endpoint: Endpoint,\n protocolMode: ProtocolMode,\n additionalDiscoveryFields: Partial<EndpointManifest>\n): RestateHandler {\n return new RestateHandlerImpl(\n endpoint,\n protocolMode,\n additionalDiscoveryFields\n );\n}\n\n/**\n * This is the RestateHandler implementation\n */\nclass RestateHandlerImpl implements RestateHandler {\n private readonly identityVerifier?: vm.WasmIdentityVerifier;\n\n constructor(\n readonly endpoint: Endpoint,\n private readonly protocolMode: ProtocolMode,\n private readonly additionalDiscoveryFields: Partial<EndpointManifest>\n ) {\n // Setup identity verifier\n if (\n this.endpoint.keySet === undefined ||\n this.endpoint.keySet.length === 0\n ) {\n this.endpoint.rlog.warn(\n `Accepting requests without validating request signatures; handler access must be restricted`\n );\n } else {\n this.endpoint.rlog.info(\n `Validating requests using signing keys [${this.endpoint.keySet}]`\n );\n this.identityVerifier = new vm.WasmIdentityVerifier(this.endpoint.keySet);\n }\n\n // Set the logging level in the shared core too!\n vm.set_log_level(\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL)\n );\n }\n\n // handle does not throw.\n public handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n try {\n return this._handle(request, context);\n } catch (e) {\n const error = ensureError(e);\n (\n tryCreateContextualLogger(\n this.endpoint.loggerTransport,\n request.url,\n request.headers\n ) ?? this.endpoint.rlog\n ).error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n return errorResponse(\n error instanceof RestateError ? error.code : 500,\n error.message\n );\n }\n }\n\n private _handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n // this is the recommended way to get the relative path from a url that may be relative or absolute\n const path = new URL(request.url, \"https://example.com\").pathname;\n const parsed = parseUrlComponents(path);\n\n if (parsed.type === \"unknown\") {\n const msg =\n \"Invalid path. Allowed are /health, /discover, /invoke/SvcName/handlerName, \" +\n \"/serdes/SvcName/decode/<serdeName>, or \" +\n \"/serdes/SvcName/encode/<serdeName>, but was: \" +\n path;\n this.endpoint.rlog.trace(msg);\n return errorResponse(404, msg);\n }\n if (parsed.type === \"health\") {\n return simpleResponse(\n 200,\n {\n \"content-type\": \"application/text\",\n \"x-restate-server\": X_RESTATE_SERVER,\n },\n new TextEncoder().encode(\"OK\")\n );\n }\n\n // Discovery, preview, and handling invocations require identity verification\n const error = this.validateConnectionSignature(path, request.headers);\n if (error !== null) {\n return error;\n }\n if (parsed.type === \"discover\") {\n return handleDiscovery(\n this.endpoint,\n this.protocolMode,\n this.additionalDiscoveryFields,\n request.headers[\"accept\"]\n );\n }\n if (parsed.type === \"preview\") {\n return handlePreview(this.endpoint, parsed);\n }\n\n return this.handleInvoke(\n parsed,\n request.headers,\n request.extraArgs,\n context ?? {}\n );\n }\n\n private validateConnectionSignature(\n path: string,\n headers: Headers\n ): RestateResponse | null {\n if (!this.identityVerifier) {\n // not validating\n return null;\n }\n\n const vmHeaders = Object.entries(headers)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n\n try {\n this.identityVerifier.verify_identity(path, vmHeaders);\n return null;\n } catch (e) {\n this.endpoint.rlog.error(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Rejecting request as its JWT did not validate: ${e}`\n );\n return errorResponse(401, \"Unauthorized\");\n }\n }\n\n private handleInvoke(\n invokePathComponent: InvokePathComponents,\n headers: Headers,\n extraArgs: unknown[],\n additionalContext: AdditionalContext\n ): RestateResponse {\n // Check if we support this protocol version\n const serviceProtocolVersionString = headers[\"content-type\"];\n if (typeof serviceProtocolVersionString !== \"string\") {\n const errorMessage = \"Missing content-type header\";\n this.endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n const service = this.endpoint.components.get(\n invokePathComponent.componentName\n );\n if (!service) {\n const msg = `No service found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n const handler = service.handlerMatching(invokePathComponent);\n if (!handler) {\n const msg = `No handler found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n return new RestateInvokeResponse(\n service,\n handler,\n headers,\n extraArgs,\n additionalContext,\n this.endpoint.journalValueCodec,\n this.endpoint.loggerTransport\n );\n }\n}\n\nclass RestateInvokeResponse implements RestateResponse {\n private readonly headers: ResponseHeaders;\n private readonly statusCode: number;\n\n private readonly loggerId: number;\n private vmLogger: Logger;\n private readonly coreVm: vm.WasmVM;\n\n constructor(\n private readonly service: Component,\n private readonly handler: ComponentHandler,\n private readonly attemptHeaders: Headers,\n private readonly extraArgs: unknown[],\n private readonly additionalContext: AdditionalContext,\n private readonly journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined,\n private readonly loggerTransport: LoggerTransport\n ) {\n this.loggerId = Math.floor(Math.random() * 4_294_967_295 /* u32::MAX */);\n const isJournalCodecDefined = this.journalValueCodecInit !== undefined;\n\n // Instantiate core vm and prepare response headers\n const vmHeaders = Object.entries(this.attemptHeaders)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n this.coreVm = new vm.WasmVM(\n vmHeaders,\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL),\n this.loggerId,\n isJournalCodecDefined,\n handler.executionOptions.explicitCancellation ?? false,\n onJournalMismatchErrorsToWasm(\n handler.executionOptions.onJournalMismatchErrors\n )\n );\n const responseHead = this.coreVm.get_response_head();\n this.statusCode = responseHead.status_code;\n this.headers = responseHead.headers.reduce(\n (headers, { key, value }) => ({\n [key]: value,\n ...headers,\n }),\n {\n \"x-restate-server\": X_RESTATE_SERVER,\n }\n );\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n new LoggerContext(\n invocationIdFromHeaders(this.attemptHeaders),\n this.service.name(),\n this.handler.name(),\n undefined,\n undefined,\n this.additionalContext\n )\n );\n }\n\n async process({\n inputReader,\n outputWriter,\n writeHead,\n abortSignal,\n }: {\n inputReader: InputReader;\n outputWriter: OutputWriter;\n writeHead: (statusCode: number, headers: ResponseHeaders) => void;\n abortSignal: AbortSignal;\n }): Promise<void> {\n // Commit the response head immediately — the VM-determined head is known\n // at construction time and never changes during processing.\n writeHead(this.statusCode, this.headers);\n\n abortSignal.addEventListener(\n \"abort\",\n () => {\n // In any case, on abort remove the invocation logger to avoid memory leaks\n destroyLogger(this.loggerId);\n\n // When the HTTP connection closes (e.g. abort timeout), poison the VM.\n // We only read new input from the server when a Restate command is\n // waiting for a response. If no command has been issued, the server's\n // abort signal is never read. Poisoning the VM ensures the handler\n // fails on the next VM call (e.g. ctx.run, ctx.sleep).\n setImmediate(() => {\n const msg = \"Connection closed\";\n this.coreVm.notify_error(msg, msg);\n });\n },\n { once: true }\n );\n // Use a default logger that still respects the endpoint custom logger\n // We will override this later with a logger that has a LoggerContext\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n\n const journalValueCodec: JournalValueCodec = this.journalValueCodecInit\n ? await this.journalValueCodecInit\n : {\n encode: (entry) => entry,\n decode: (entry) => Promise.resolve(entry),\n };\n\n // This promise is used to signal the end of the computation,\n // which can be either the user returns a value,\n // or an exception gets caught, or the state machine fails/suspends.\n //\n // The last case is handled internally within the ContextImpl.\n const invocationEndPromise = Promise.withResolvers<void>();\n let ctx: ContextImpl;\n\n // Initial phase before running user code\n // -> Buffer in shared core the journal entries\n // -> Initiate loggers\n // -> Initialize the ContextImpl\n try {\n // Buffer journal inside shared core\n await bufferJournalReplayInCoreVm(this.coreVm, inputReader);\n\n // Get input from coreVm to build the request object\n const input = this.coreVm.sys_input();\n const invocationRequest: Request = {\n target: {\n service: this.service.name(),\n handler: this.handler.name(),\n key: input.key || undefined,\n toString() {\n return this.key !== undefined\n ? `${this.service}/${this.key}/${this.handler}`\n : `${this.service}/${this.handler}`;\n },\n },\n id: input.invocation_id as InvocationId,\n headers: input.headers.reduce((headers, { key, value }) => {\n headers.set(key, value);\n return headers;\n }, new Map()),\n attemptHeaders: Object.entries(this.attemptHeaders).reduce(\n (headers, [key, value]) => {\n if (value !== undefined) {\n headers.set(key, value instanceof Array ? value[0] : value);\n }\n return headers;\n },\n new Map()\n ),\n body: input.input,\n extraArgs: this.extraArgs,\n attemptCompletedSignal: abortSignal,\n };\n\n // Prepare logger\n const loggerContext = new LoggerContext(\n input.invocation_id,\n this.handler.component().name(),\n this.handler.name(),\n this.handler.kind() === HandlerKind.SERVICE ? undefined : input.key,\n invocationRequest,\n this.additionalContext\n );\n const ctxLogger = createLogger(\n this.loggerTransport,\n LogSource.USER,\n loggerContext,\n () => !this.coreVm.is_processing()\n );\n // Override the vmLogger created before with more info!\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n loggerContext\n // Filtering is done within the shared core\n );\n\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n if (!this.coreVm.is_processing()) {\n this.vmLogger.info(\"Replaying invocation.\");\n } else {\n this.vmLogger.info(\"Starting invocation.\");\n }\n\n // Prepare context\n ctx = new ContextImpl(\n this.coreVm,\n input,\n ctxLogger,\n this.handler.kind(),\n this.vmLogger,\n invocationRequest,\n invocationEndPromise,\n inputReader,\n outputWriter,\n journalValueCodec,\n this.handler.executionOptions\n );\n } catch (e) {\n // That's \"preflight\" failure cases, where stuff fails before running user code\n // In this scenario, we close the coreVm, then flush and close\n const error = ensureError(e);\n this.coreVm.notify_error(error.message, error.message);\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n Promise.resolve(inputReader),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n return;\n }\n\n // Run user code. Errors that reach the handler or interceptor code\n // (handler throws, interceptor throws, entry completes with terminal\n // failure) propagate naturally. Errors where the handler is stuck on\n // an await that will never settle (e.g. suspension, retryable run\n // error) are broken out by raceWithAttemptEnd, which races against\n // invocationEndPromise — rejected by ContextImpl when the attempt ends.\n try {\n await startUserHandler(\n ctx,\n this.service,\n this.handler,\n journalValueCodec\n );\n } catch (e) {\n notifyError(e, ctx, this.handler.executionOptions.asTerminalError);\n } finally {\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n ctx.inputPump.stop(),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n }\n }\n}\n\nasync function bufferJournalReplayInCoreVm(\n coreVm: vm.WasmVM,\n inputReader: InputReader\n) {\n while (!coreVm.is_ready_to_execute()) {\n const nextValue = await inputReader.next();\n if (nextValue.done) {\n coreVm.notify_input_closed();\n break;\n }\n if (nextValue.value !== undefined) {\n coreVm.notify_input(nextValue.value);\n }\n }\n}\n\nasync function startUserHandler(\n ctx: ContextImpl,\n service: Component,\n handler: ComponentHandler,\n journalValueCodec: JournalValueCodec\n) {\n // Instantiate hooks from providers.\n // If a provider throws, the same rules as handler failures apply:\n // TerminalError → terminate invocation, other errors → retry.\n const hooks: Hooks[] = [];\n for (const provider of handler.executionOptions.hooks ?? []) {\n const hookContext: { request: Request } = {\n request: ctx.request(),\n };\n Object.defineProperty(hookContext, HOOK_CONTEXT_IS_PROCESSING_SYMBOL, {\n value: () => ctx.isProcessing(),\n enumerable: false,\n });\n hooks.push(provider(hookContext));\n }\n\n // Compose interceptor.handler into a single interceptor (first = outermost)\n const handlerInterceptor = composeInterceptors(\n hooks.map((h) => h.interceptor?.handler).filter(isDefined)\n );\n\n ctx.setRunInterceptor(\n composeInterceptors(hooks.map((h) => h.interceptor?.run).filter(isDefined))\n );\n\n let encodedOutput: Uint8Array | undefined;\n await raceWithAttemptEnd(\n ctx,\n handlerInterceptor\n )(async () => {\n const decodedInput = await journalValueCodec\n .decode(ctx.request().body)\n .catch((e) =>\n // Re-throw as terminal error, to fail on input errors\n Promise.reject(\n new TerminalError(\n `Failed to decode input using journal value codec: ${\n ensureError(e).message\n }`,\n {\n errorCode: 400,\n }\n )\n )\n );\n\n // Then run user code\n const output = await handler.invoke(ctx, decodedInput);\n\n // Encode user code output\n encodedOutput = journalValueCodec.encode(output);\n });\n\n // Interceptor chain completed without error — commit the result.\n // sys_end() is called here (after interceptors) so that interceptor\n // errors after next() correctly prevent the invocation from succeeding.\n ctx.coreVm.sys_write_output_success(encodedOutput!);\n ctx.coreVm.sys_end();\n ctx.vmLogger.info(\"Invocation completed successfully.\");\n}\n\n/**\n * Classifies the error and notifies the VM. Called from the process() catch\n * block — the single place that decides how to report errors to the VM.\n */\nfunction notifyError(\n e: unknown,\n ctx: ContextImpl,\n asTerminalError?: (error: unknown) => TerminalError | undefined\n) {\n // Command-specific errors from ContextImpl carry metadata the VM needs\n // for command correlation. Check before ensureError to preserve the type.\n if (e instanceof CommandError) {\n const cause = ensureError(e.cause);\n logError(ctx.vmLogger, cause);\n if (e.hasCommandIndex) {\n // Completion failure — command exists in the journal\n ctx.coreVm.notify_error_for_specific_command(\n cause.message,\n cause.stack,\n e.commandType,\n e.commandIndex!,\n null\n );\n } else {\n // Preparation failure — command not yet issued\n ctx.coreVm.notify_error_for_next_command(\n cause.message,\n cause.stack,\n e.commandType\n );\n }\n return;\n }\n\n // Handler/interceptor errors\n const error = ensureError(e, asTerminalError);\n logError(ctx.vmLogger, error);\n\n try {\n if (error instanceof TerminalError) {\n // Terminal: write the failure as the invocation output\n ctx.coreVm.sys_write_output_failure({\n code: error.code,\n message: error.message,\n metadata: Object.entries(error.metadata ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n });\n ctx.coreVm.sys_end();\n } else if (error instanceof RetryableError) {\n // Retryable with explicit delay\n ctx.coreVm.notify_error_with_delay_override(\n error.message,\n error.stack,\n error.retryAfter !== undefined\n ? BigInt(millisOrDurationToMillis(error.retryAfter))\n : undefined\n );\n } else {\n if (error instanceof PauseError) {\n ctx.vmLogger.warn(\n \"Throwing PauseError from the handler context will be ignored, \" +\n \"as it leads to pause loops. You should use PauseError only inside `ctx.run`\"\n );\n }\n\n // Transient error — VM decides retry policy\n ctx.coreVm.notify_error(error.message, error.stack);\n }\n } catch (vmError) {\n // Safety net: if sys_write_output_failure or other VM calls fail,\n // fall back to notify_error.\n const inner = ensureError(vmError);\n ctx.coreVm.notify_error(inner.message, inner.stack);\n }\n}\n\nasync function flushAndClose(\n coreVm: vm.WasmVM,\n vmLogger: Logger,\n inputReaderGetter: Promise<InputReader>,\n outputWriter: OutputWriter\n): Promise<void> {\n let inputClosed = false;\n try {\n // Consume vm output buffer, write it out, then close the stream\n const nextOutput = coreVm.take_output();\n if (nextOutput?.length > 0) {\n await outputWriter.write(nextOutput);\n }\n\n // --- After this point, we should have flushed the shared core internal buffer\n\n // Wait for the input reader.\n // In case we executed the user code, this is wired up to the InputPump.stop()\n // to make sure there is only one reader for inputReader.\n const inputReader = await inputReaderGetter;\n\n // Let's make sure we properly close the request stream before closing the response stream\n while (!inputClosed) {\n try {\n const res = await inputReader.next();\n inputClosed = res.done ?? false;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n inputClosed = true;\n }\n }\n\n // Close the response stream\n await outputWriter.close();\n } catch (e) {\n // In case of failure, we can do little here except just logging stuff out,\n // because outputWriter is not usable here.\n const error = ensureError(e);\n const abortErrorOnWrite = isAbortErrorOnWrite(error);\n\n if (inputClosed && abortErrorOnWrite) {\n // Because we closed the input already,\n // these errors are benign and are caused by\n // synchronization issues wrt closing the response stream in the runtime\n // This will be fixed in the runtime with https://github.com/restatedev/restate/issues/4456\n return;\n }\n\n if (abortErrorOnWrite) {\n vmLogger.error(\n \"Got abort error from connection: \" +\n error.message +\n \"\\n\" +\n \"This might indicate that:\\n\" +\n \"* The restate-server aborted the connection after hitting the 'abort-timeout'\\n\" +\n \"* The connection with the restate-server was lost\\n\" +\n \"\\n\" +\n \"Please check the invocation in the Restate UI for more details.\"\n );\n } else {\n vmLogger.error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n }\n }\n}\n\nfunction isAbortErrorOnWrite(error: Error) {\n return (\n error.name === \"AbortError\" ||\n error.message === \"Invalid state: WritableStream is closed\" ||\n /**\n * Node stream closed error thrown on writes\n */\n (error as { code?: string }).code === \"ERR_HTTP2_INVALID_STREAM\"\n );\n}\n\n// -- Hook composition utils --------------------------------------------------\n\ntype InterceptorFn<Args extends unknown[]> = (\n ...args: [...Args, () => Promise<void>]\n) => Promise<void>;\n\nfunction composeInterceptors<Args extends unknown[]>(\n interceptors: InterceptorFn<Args>[]\n): InterceptorFn<Args> {\n return interceptors.reduceRight<InterceptorFn<Args>>(\n (innerInterceptor, interceptor) =>\n (...args) => {\n const context = args.slice(0, -1) as unknown as Args;\n const callback = args.at(-1) as () => Promise<void>;\n return interceptor(...context, () =>\n innerInterceptor(...context, callback)\n );\n },\n (...args) => (args.at(-1) as () => Promise<void>)()\n );\n}\n\n/**\n * Wraps an interceptor so that both `next()` and the interceptor body race\n * against `invocationEndPromise`. When the attempt ends (suspension, retryable\n * error, etc.), the promise rejects and the interceptor chain unwinds through\n * catch/finally blocks — preventing interceptors from hanging on a `next()`\n * that will never settle.\n *\n * SDK-internal metadata (CommandError, retryAfter) is stripped before the\n * interceptor sees the error and restored after the chain exits.\n */\nfunction raceWithAttemptEnd<Args extends unknown[]>(\n ctx: ContextImpl,\n interceptor: InterceptorFn<Args>\n): InterceptorFn<Args> {\n return (...args) => {\n let originalError: unknown;\n\n // Strip SDK metadata before interceptors see the error.\n // Store the original in the closure for restoration after the chain.\n const signal = ctx.invocationEndPromise.promise.catch((e) => {\n originalError = e;\n throw sanitizeError(e);\n }) as Promise<never>;\n\n const originalNext = args.at(-1) as () => Promise<void>;\n const racingNext = () => Promise.race([originalNext(), signal]);\n const newArgs = [...args.slice(0, -1), racingNext] as unknown as [\n ...Args,\n () => Promise<void>,\n ];\n\n return Promise.race([interceptor(...newArgs), signal]).catch((e) => {\n // Restore SDK metadata after the interceptor chain exits.\n if (originalError !== undefined) {\n throw restoreError(e, originalError);\n }\n throw e;\n });\n };\n}\n\nfunction isDefined<T>(value: T | undefined | null): value is T {\n return value != null;\n}\n\n// -- Logging utils -----------------------------------------------------------\n\nfunction restateLogLevelToWasmLogLevel(level: RestateLogLevel): vm.LogLevel {\n switch (level) {\n case RestateLogLevel.TRACE:\n return vm.LogLevel.TRACE;\n case RestateLogLevel.DEBUG:\n return vm.LogLevel.DEBUG;\n case RestateLogLevel.INFO:\n return vm.LogLevel.INFO;\n case RestateLogLevel.WARN:\n return vm.LogLevel.WARN;\n case RestateLogLevel.ERROR:\n return vm.LogLevel.ERROR;\n }\n}\n\nfunction onJournalMismatchErrorsToWasm(\n behavior: \"retry\" | \"pause\" | \"fail\" | undefined\n): vm.WasmJournalMismatchBehavior {\n switch (behavior) {\n case \"pause\":\n return vm.WasmJournalMismatchBehavior.Pause;\n case \"fail\":\n return vm.WasmJournalMismatchBehavior.Fail;\n case \"retry\":\n case undefined:\n return vm.WasmJournalMismatchBehavior.Retry;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generic.js","names":["endpoint: Endpoint","protocolMode: ProtocolMode","additionalDiscoveryFields: Partial<EndpointManifest>","vm.WasmIdentityVerifier","vm.WasmHeader","service: Component","handler: ComponentHandler","attemptHeaders: Headers","extraArgs: unknown[]","additionalContext: AdditionalContext","journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined","loggerTransport: LoggerTransport","vm.WasmVM","journalValueCodec: JournalValueCodec","ctx: ContextImpl","invocationRequest: Request","hooks: Hooks[]","hookContext: { request: Request }","encodedOutput: Uint8Array | undefined","originalError: unknown"],"sources":["../../../src/endpoint/handlers/generic.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport {\n ensureError,\n logError,\n PauseError,\n RestateError,\n RetryableError,\n TerminalError,\n} from \"../../types/errors.js\";\nimport type {\n Endpoint as EndpointManifest,\n ProtocolMode,\n} from \"../discovery.js\";\nimport {\n Component,\n ComponentHandler,\n InvokePathComponents,\n} from \"../components.js\";\nimport { parseUrlComponents } from \"../components.js\";\nimport { X_RESTATE_SERVER } from \"../../user_agent.js\";\nimport { CommandError, ContextImpl } from \"../../context_impl.js\";\nimport { restoreError, sanitizeError } from \"../../error_sanitization.js\";\nimport type { InvocationId, Request } from \"../../context.js\";\nimport * as vm from \"./vm/sdk_shared_core_wasm_bindings.js\";\nimport { HandlerKind } from \"../../types/rpc.js\";\nimport { createLogger, type Logger } from \"../../logging/logger.js\";\nimport { DEFAULT_CONSOLE_LOGGER_LOG_LEVEL } from \"../../logging/console_logger_transport.js\";\nimport {\n LoggerContext,\n LoggerTransport,\n LogSource,\n RestateLogLevel,\n} from \"../../logging/logger_transport.js\";\nimport {\n type JournalValueCodec,\n millisOrDurationToMillis,\n} from \"@restatedev/restate-sdk-core\";\nimport type { Endpoint } from \"../endpoint.js\";\nimport {\n type RestateHandler,\n type Headers,\n type RestateRequest,\n type AdditionalContext,\n type RestateResponse,\n ResponseHeaders,\n InputReader,\n OutputWriter,\n} from \"./types.js\";\nimport { handleDiscovery } from \"./discovery.js\";\nimport { handlePreview } from \"./preview.js\";\nimport {\n errorResponse,\n invocationIdFromHeaders,\n simpleResponse,\n tryCreateContextualLogger,\n} from \"./utils.js\";\nimport { destroyLogger, registerLogger } from \"./core_logging.js\";\nimport type { Hooks } from \"../../hooks.js\";\n\n// Hidden symbol key used by first-party hooks to read the live\n// replay/processing phase without widening the public HooksProvider API.\nconst HOOK_CONTEXT_IS_PROCESSING_SYMBOL = Symbol.for(\n \"@restatedev/restate-sdk/hooks.isProcessing\"\n);\n\nexport function createRestateHandler(\n endpoint: Endpoint,\n protocolMode: ProtocolMode,\n additionalDiscoveryFields: Partial<EndpointManifest>\n): RestateHandler {\n return new RestateHandlerImpl(\n endpoint,\n protocolMode,\n additionalDiscoveryFields\n );\n}\n\n/**\n * This is the RestateHandler implementation\n */\nclass RestateHandlerImpl implements RestateHandler {\n private readonly identityVerifier?: vm.WasmIdentityVerifier;\n\n constructor(\n readonly endpoint: Endpoint,\n private readonly protocolMode: ProtocolMode,\n private readonly additionalDiscoveryFields: Partial<EndpointManifest>\n ) {\n // Setup identity verifier\n if (\n this.endpoint.keySet === undefined ||\n this.endpoint.keySet.length === 0\n ) {\n this.endpoint.rlog.warn(\n `Accepting requests without validating request signatures; handler access must be restricted`\n );\n } else {\n this.endpoint.rlog.info(\n `Validating requests using signing keys [${this.endpoint.keySet}]`\n );\n this.identityVerifier = new vm.WasmIdentityVerifier(this.endpoint.keySet);\n }\n\n // Set the logging level in the shared core too!\n vm.set_log_level(\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL)\n );\n }\n\n // handle does not throw.\n public handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n try {\n return this._handle(request, context);\n } catch (e) {\n const error = ensureError(e);\n (\n tryCreateContextualLogger(\n this.endpoint.loggerTransport,\n request.url,\n request.headers\n ) ?? this.endpoint.rlog\n ).error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n return errorResponse(\n error instanceof RestateError ? error.code : 500,\n error.message\n );\n }\n }\n\n private _handle(\n request: RestateRequest,\n context?: AdditionalContext\n ): RestateResponse {\n // this is the recommended way to get the relative path from a url that may be relative or absolute\n const path = new URL(request.url, \"https://example.com\").pathname;\n const parsed = parseUrlComponents(path);\n\n if (parsed.type === \"unknown\") {\n const msg =\n \"Invalid path. Allowed are /health, /discover, /invoke/SvcName/handlerName, \" +\n \"/serdes/SvcName/decode/<serdeName>, or \" +\n \"/serdes/SvcName/encode/<serdeName>, but was: \" +\n path;\n this.endpoint.rlog.trace(msg);\n return errorResponse(404, msg);\n }\n if (parsed.type === \"health\") {\n return simpleResponse(\n 200,\n {\n \"content-type\": \"application/text\",\n \"x-restate-server\": X_RESTATE_SERVER,\n },\n new TextEncoder().encode(\"OK\")\n );\n }\n\n // Discovery, preview, and handling invocations require identity verification\n const error = this.validateConnectionSignature(path, request.headers);\n if (error !== null) {\n return error;\n }\n if (parsed.type === \"discover\") {\n return handleDiscovery(\n this.endpoint,\n this.protocolMode,\n this.additionalDiscoveryFields,\n request.headers[\"accept\"]\n );\n }\n if (parsed.type === \"preview\") {\n return handlePreview(this.endpoint, parsed);\n }\n\n return this.handleInvoke(\n parsed,\n request.headers,\n request.extraArgs,\n context ?? {}\n );\n }\n\n private validateConnectionSignature(\n path: string,\n headers: Headers\n ): RestateResponse | null {\n if (!this.identityVerifier) {\n // not validating\n return null;\n }\n\n const vmHeaders = Object.entries(headers)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n\n try {\n this.identityVerifier.verify_identity(path, vmHeaders);\n return null;\n } catch (e) {\n this.endpoint.rlog.error(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Rejecting request as its JWT did not validate: ${e}`\n );\n return errorResponse(401, \"Unauthorized\");\n }\n }\n\n private handleInvoke(\n invokePathComponent: InvokePathComponents,\n headers: Headers,\n extraArgs: unknown[],\n additionalContext: AdditionalContext\n ): RestateResponse {\n // Check if we support this protocol version\n const serviceProtocolVersionString = headers[\"content-type\"];\n if (typeof serviceProtocolVersionString !== \"string\") {\n const errorMessage = \"Missing content-type header\";\n this.endpoint.rlog.warn(errorMessage);\n return errorResponse(415, errorMessage);\n }\n\n const service = this.endpoint.components.get(\n invokePathComponent.componentName\n );\n if (!service) {\n const msg = `No service found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n const handler = service.handlerMatching(invokePathComponent);\n if (!handler) {\n const msg = `No handler found for URL: ${JSON.stringify(invokePathComponent)}`;\n this.endpoint.rlog.error(msg);\n return errorResponse(404, msg);\n }\n\n return new RestateInvokeResponse(\n service,\n handler,\n headers,\n extraArgs,\n additionalContext,\n this.endpoint.journalValueCodec,\n this.endpoint.loggerTransport\n );\n }\n}\n\nclass RestateInvokeResponse implements RestateResponse {\n private readonly headers: ResponseHeaders;\n private readonly statusCode: number;\n\n private readonly loggerId: number;\n private vmLogger: Logger;\n private readonly coreVm: vm.WasmVM;\n\n constructor(\n private readonly service: Component,\n private readonly handler: ComponentHandler,\n private readonly attemptHeaders: Headers,\n private readonly extraArgs: unknown[],\n private readonly additionalContext: AdditionalContext,\n private readonly journalValueCodecInit:\n | Promise<JournalValueCodec>\n | undefined,\n private readonly loggerTransport: LoggerTransport\n ) {\n this.loggerId = Math.floor(Math.random() * 4_294_967_295 /* u32::MAX */);\n const isJournalCodecDefined = this.journalValueCodecInit !== undefined;\n\n // Instantiate core vm and prepare response headers\n const vmHeaders = Object.entries(this.attemptHeaders)\n .filter(([, v]) => v !== undefined)\n .map(\n ([k, v]) =>\n new vm.WasmHeader(k, v instanceof Array ? v[0]! : (v as string))\n );\n this.coreVm = new vm.WasmVM(\n vmHeaders,\n restateLogLevelToWasmLogLevel(DEFAULT_CONSOLE_LOGGER_LOG_LEVEL),\n this.loggerId,\n isJournalCodecDefined,\n handler.executionOptions.explicitCancellation ?? false,\n onJournalMismatchErrorsToWasm(\n handler.executionOptions.onJournalMismatchErrors\n )\n );\n const responseHead = this.coreVm.get_response_head();\n this.statusCode = responseHead.status_code;\n this.headers = responseHead.headers.reduce(\n (headers, { key, value }) => ({\n [key]: value,\n ...headers,\n }),\n {\n \"x-restate-server\": X_RESTATE_SERVER,\n }\n );\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n new LoggerContext(\n invocationIdFromHeaders(this.attemptHeaders),\n this.service.name(),\n this.handler.name(),\n undefined,\n undefined,\n this.additionalContext\n )\n );\n }\n\n async process({\n inputReader,\n outputWriter,\n writeHead,\n abortSignal,\n }: {\n inputReader: InputReader;\n outputWriter: OutputWriter;\n writeHead: (statusCode: number, headers: ResponseHeaders) => void;\n abortSignal: AbortSignal;\n }): Promise<void> {\n // Commit the response head immediately — the VM-determined head is known\n // at construction time and never changes during processing.\n writeHead(this.statusCode, this.headers);\n\n abortSignal.addEventListener(\n \"abort\",\n () => {\n // In any case, on abort remove the invocation logger to avoid memory leaks\n destroyLogger(this.loggerId);\n\n // When the HTTP connection closes (e.g. abort timeout), poison the VM.\n // We only read new input from the server when a Restate command is\n // waiting for a response. If no command has been issued, the server's\n // abort signal is never read. Poisoning the VM ensures the handler\n // fails on the next VM call (e.g. ctx.run, ctx.sleep).\n setImmediate(() => {\n const msg = \"Connection closed\";\n this.coreVm.notify_error(msg, msg);\n });\n },\n { once: true }\n );\n // Use a default logger that still respects the endpoint custom logger\n // We will override this later with a logger that has a LoggerContext\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n\n const journalValueCodec: JournalValueCodec = this.journalValueCodecInit\n ? await this.journalValueCodecInit\n : {\n encode: (entry) => entry,\n decode: (entry) => Promise.resolve(entry),\n };\n\n // This promise is used to signal the end of the computation,\n // which can be either the user returns a value,\n // or an exception gets caught, or the state machine fails/suspends.\n //\n // The last case is handled internally within the ContextImpl.\n const invocationEndPromise = Promise.withResolvers<void>();\n let ctx: ContextImpl;\n\n // Initial phase before running user code\n // -> Buffer in shared core the journal entries\n // -> Initiate loggers\n // -> Initialize the ContextImpl\n try {\n // Buffer journal inside shared core\n await bufferJournalReplayInCoreVm(this.coreVm, inputReader);\n\n // Get input from coreVm to build the request object\n const input = this.coreVm.sys_input();\n const invocationRequest: Request = {\n target: {\n service: this.service.name(),\n handler: this.handler.name(),\n key: input.key || undefined,\n toString() {\n return this.key !== undefined\n ? `${this.service}/${this.key}/${this.handler}`\n : `${this.service}/${this.handler}`;\n },\n },\n id: input.invocation_id as InvocationId,\n headers: input.headers.reduce((headers, { key, value }) => {\n headers.set(key, value);\n return headers;\n }, new Map()),\n attemptHeaders: Object.entries(this.attemptHeaders).reduce(\n (headers, [key, value]) => {\n if (value !== undefined) {\n headers.set(key, value instanceof Array ? value[0] : value);\n }\n return headers;\n },\n new Map()\n ),\n body: input.input,\n extraArgs: this.extraArgs,\n idempotencyKey: input.idempotency_key || undefined,\n scope: input.scope || undefined,\n limitKey: input.limit_key || undefined,\n attemptCompletedSignal: abortSignal,\n };\n\n // Prepare logger\n const loggerContext = new LoggerContext(\n input.invocation_id,\n this.handler.component().name(),\n this.handler.name(),\n this.handler.kind() === HandlerKind.SERVICE ? undefined : input.key,\n invocationRequest,\n this.additionalContext\n );\n const ctxLogger = createLogger(\n this.loggerTransport,\n LogSource.USER,\n loggerContext,\n () => !this.coreVm.is_processing()\n );\n // Override the vmLogger created before with more info!\n this.vmLogger = createLogger(\n this.loggerTransport,\n LogSource.JOURNAL,\n loggerContext\n // Filtering is done within the shared core\n );\n\n // See vm_log below for more details\n registerLogger(this.loggerId, this.vmLogger);\n if (!this.coreVm.is_processing()) {\n this.vmLogger.info(\"Replaying invocation.\");\n } else {\n this.vmLogger.info(\"Starting invocation.\");\n }\n\n // Prepare context\n ctx = new ContextImpl(\n this.coreVm,\n input,\n ctxLogger,\n this.handler.kind(),\n this.vmLogger,\n invocationRequest,\n invocationEndPromise,\n inputReader,\n outputWriter,\n journalValueCodec,\n this.handler.executionOptions\n );\n } catch (e) {\n // That's \"preflight\" failure cases, where stuff fails before running user code\n // In this scenario, we close the coreVm, then flush and close\n const error = ensureError(e);\n this.coreVm.notify_error(error.message, error.message);\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n Promise.resolve(inputReader),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n return;\n }\n\n // Run user code. Errors that reach the handler or interceptor code\n // (handler throws, interceptor throws, entry completes with terminal\n // failure) propagate naturally. Errors where the handler is stuck on\n // an await that will never settle (e.g. suspension, retryable run\n // error) are broken out by raceWithAttemptEnd, which races against\n // invocationEndPromise — rejected by ContextImpl when the attempt ends.\n try {\n await startUserHandler(\n ctx,\n this.service,\n this.handler,\n journalValueCodec\n );\n } catch (e) {\n notifyError(e, ctx, this.handler.executionOptions.asTerminalError);\n } finally {\n try {\n await flushAndClose(\n this.coreVm,\n this.vmLogger,\n ctx.inputPump.stop(),\n outputWriter\n );\n } finally {\n // Safety net: the abort listener should clean this up when the attempt\n // ends, but process() owns the logger registration, so avoid leaking if\n // an adapter ever fails to abort the attempt-completed signal.\n destroyLogger(this.loggerId);\n }\n }\n }\n}\n\nasync function bufferJournalReplayInCoreVm(\n coreVm: vm.WasmVM,\n inputReader: InputReader\n) {\n while (!coreVm.is_ready_to_execute()) {\n const nextValue = await inputReader.next();\n if (nextValue.done) {\n coreVm.notify_input_closed();\n break;\n }\n if (nextValue.value !== undefined) {\n coreVm.notify_input(nextValue.value);\n }\n }\n}\n\nasync function startUserHandler(\n ctx: ContextImpl,\n service: Component,\n handler: ComponentHandler,\n journalValueCodec: JournalValueCodec\n) {\n // Instantiate hooks from providers.\n // If a provider throws, the same rules as handler failures apply:\n // TerminalError → terminate invocation, other errors → retry.\n const hooks: Hooks[] = [];\n for (const provider of handler.executionOptions.hooks ?? []) {\n const hookContext: { request: Request } = {\n request: ctx.request(),\n };\n Object.defineProperty(hookContext, HOOK_CONTEXT_IS_PROCESSING_SYMBOL, {\n value: () => ctx.isProcessing(),\n enumerable: false,\n });\n hooks.push(provider(hookContext));\n }\n\n // Compose interceptor.handler into a single interceptor (first = outermost)\n const handlerInterceptor = composeInterceptors(\n hooks.map((h) => h.interceptor?.handler).filter(isDefined)\n );\n\n ctx.setRunInterceptor(\n composeInterceptors(hooks.map((h) => h.interceptor?.run).filter(isDefined))\n );\n\n let encodedOutput: Uint8Array | undefined;\n await raceWithAttemptEnd(\n ctx,\n handlerInterceptor\n )(async () => {\n const decodedInput = await journalValueCodec\n .decode(ctx.request().body)\n .catch((e) =>\n // Re-throw as terminal error, to fail on input errors\n Promise.reject(\n new TerminalError(\n `Failed to decode input using journal value codec: ${\n ensureError(e).message\n }`,\n {\n errorCode: 400,\n }\n )\n )\n );\n\n // Then run user code\n const output = await handler.invoke(ctx, decodedInput);\n\n // Encode user code output\n encodedOutput = journalValueCodec.encode(output);\n });\n\n // Interceptor chain completed without error — commit the result.\n // sys_end() is called here (after interceptors) so that interceptor\n // errors after next() correctly prevent the invocation from succeeding.\n ctx.coreVm.sys_write_output_success(encodedOutput!);\n ctx.coreVm.sys_end();\n ctx.vmLogger.info(\"Invocation completed successfully.\");\n}\n\n/**\n * Classifies the error and notifies the VM. Called from the process() catch\n * block — the single place that decides how to report errors to the VM.\n */\nfunction notifyError(\n e: unknown,\n ctx: ContextImpl,\n asTerminalError?: (error: unknown) => TerminalError | undefined\n) {\n // Command-specific errors from ContextImpl carry metadata the VM needs\n // for command correlation. Check before ensureError to preserve the type.\n if (e instanceof CommandError) {\n const cause = ensureError(e.cause);\n logError(ctx.vmLogger, cause);\n if (e.hasCommandIndex) {\n // Completion failure — command exists in the journal\n ctx.coreVm.notify_error_for_specific_command(\n cause.message,\n cause.stack,\n e.commandType,\n e.commandIndex!,\n null\n );\n } else {\n // Preparation failure — command not yet issued\n ctx.coreVm.notify_error_for_next_command(\n cause.message,\n cause.stack,\n e.commandType\n );\n }\n return;\n }\n\n // Handler/interceptor errors\n const error = ensureError(e, asTerminalError);\n logError(ctx.vmLogger, error);\n\n try {\n if (error instanceof TerminalError) {\n // Terminal: write the failure as the invocation output\n ctx.coreVm.sys_write_output_failure({\n code: error.code,\n message: error.message,\n metadata: Object.entries(error.metadata ?? {}).map(([key, value]) => ({\n key,\n value,\n })),\n });\n ctx.coreVm.sys_end();\n } else if (error instanceof RetryableError) {\n // Retryable with explicit delay\n ctx.coreVm.notify_error_with_delay_override(\n error.message,\n error.stack,\n error.retryAfter !== undefined\n ? BigInt(millisOrDurationToMillis(error.retryAfter))\n : undefined\n );\n } else {\n if (error instanceof PauseError) {\n ctx.vmLogger.warn(\n \"Throwing PauseError from the handler context will be ignored, \" +\n \"as it leads to pause loops. You should use PauseError only inside `ctx.run`\"\n );\n }\n\n // Transient error — VM decides retry policy\n ctx.coreVm.notify_error(error.message, error.stack);\n }\n } catch (vmError) {\n // Safety net: if sys_write_output_failure or other VM calls fail,\n // fall back to notify_error.\n const inner = ensureError(vmError);\n ctx.coreVm.notify_error(inner.message, inner.stack);\n }\n}\n\nasync function flushAndClose(\n coreVm: vm.WasmVM,\n vmLogger: Logger,\n inputReaderGetter: Promise<InputReader>,\n outputWriter: OutputWriter\n): Promise<void> {\n let inputClosed = false;\n try {\n // Consume vm output buffer, write it out, then close the stream\n const nextOutput = coreVm.take_output();\n if (nextOutput?.length > 0) {\n await outputWriter.write(nextOutput);\n }\n\n // --- After this point, we should have flushed the shared core internal buffer\n\n // Wait for the input reader.\n // In case we executed the user code, this is wired up to the InputPump.stop()\n // to make sure there is only one reader for inputReader.\n const inputReader = await inputReaderGetter;\n\n // Let's make sure we properly close the request stream before closing the response stream\n while (!inputClosed) {\n try {\n const res = await inputReader.next();\n inputClosed = res.done ?? false;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n inputClosed = true;\n }\n }\n\n // Close the response stream\n await outputWriter.close();\n } catch (e) {\n // In case of failure, we can do little here except just logging stuff out,\n // because outputWriter is not usable here.\n const error = ensureError(e);\n const abortErrorOnWrite = isAbortErrorOnWrite(error);\n\n if (inputClosed && abortErrorOnWrite) {\n // Because we closed the input already,\n // these errors are benign and are caused by\n // synchronization issues wrt closing the response stream in the runtime\n // This will be fixed in the runtime with https://github.com/restatedev/restate/issues/4456\n return;\n }\n\n if (abortErrorOnWrite) {\n vmLogger.error(\n \"Got abort error from connection: \" +\n error.message +\n \"\\n\" +\n \"This might indicate that:\\n\" +\n \"* The restate-server aborted the connection after hitting the 'abort-timeout'\\n\" +\n \"* The connection with the restate-server was lost\\n\" +\n \"\\n\" +\n \"Please check the invocation in the Restate UI for more details.\"\n );\n } else {\n vmLogger.error(\n \"Error while handling request: \" + (error.stack ?? error.message)\n );\n }\n }\n}\n\nfunction isAbortErrorOnWrite(error: Error) {\n return (\n error.name === \"AbortError\" ||\n error.message === \"Invalid state: WritableStream is closed\" ||\n /**\n * Node stream closed error thrown on writes\n */\n (error as { code?: string }).code === \"ERR_HTTP2_INVALID_STREAM\"\n );\n}\n\n// -- Hook composition utils --------------------------------------------------\n\ntype InterceptorFn<Args extends unknown[]> = (\n ...args: [...Args, () => Promise<void>]\n) => Promise<void>;\n\nfunction composeInterceptors<Args extends unknown[]>(\n interceptors: InterceptorFn<Args>[]\n): InterceptorFn<Args> {\n return interceptors.reduceRight<InterceptorFn<Args>>(\n (innerInterceptor, interceptor) =>\n (...args) => {\n const context = args.slice(0, -1) as unknown as Args;\n const callback = args.at(-1) as () => Promise<void>;\n return interceptor(...context, () =>\n innerInterceptor(...context, callback)\n );\n },\n (...args) => (args.at(-1) as () => Promise<void>)()\n );\n}\n\n/**\n * Wraps an interceptor so that both `next()` and the interceptor body race\n * against `invocationEndPromise`. When the attempt ends (suspension, retryable\n * error, etc.), the promise rejects and the interceptor chain unwinds through\n * catch/finally blocks — preventing interceptors from hanging on a `next()`\n * that will never settle.\n *\n * SDK-internal metadata (CommandError, retryAfter) is stripped before the\n * interceptor sees the error and restored after the chain exits.\n */\nfunction raceWithAttemptEnd<Args extends unknown[]>(\n ctx: ContextImpl,\n interceptor: InterceptorFn<Args>\n): InterceptorFn<Args> {\n return (...args) => {\n let originalError: unknown;\n\n // Strip SDK metadata before interceptors see the error.\n // Store the original in the closure for restoration after the chain.\n const signal = ctx.invocationEndPromise.promise.catch((e) => {\n originalError = e;\n throw sanitizeError(e);\n }) as Promise<never>;\n\n const originalNext = args.at(-1) as () => Promise<void>;\n const racingNext = () => Promise.race([originalNext(), signal]);\n const newArgs = [...args.slice(0, -1), racingNext] as unknown as [\n ...Args,\n () => Promise<void>,\n ];\n\n return Promise.race([interceptor(...newArgs), signal]).catch((e) => {\n // Restore SDK metadata after the interceptor chain exits.\n if (originalError !== undefined) {\n throw restoreError(e, originalError);\n }\n throw e;\n });\n };\n}\n\nfunction isDefined<T>(value: T | undefined | null): value is T {\n return value != null;\n}\n\n// -- Logging utils -----------------------------------------------------------\n\nfunction restateLogLevelToWasmLogLevel(level: RestateLogLevel): vm.LogLevel {\n switch (level) {\n case RestateLogLevel.TRACE:\n return vm.LogLevel.TRACE;\n case RestateLogLevel.DEBUG:\n return vm.LogLevel.DEBUG;\n case RestateLogLevel.INFO:\n return vm.LogLevel.INFO;\n case RestateLogLevel.WARN:\n return vm.LogLevel.WARN;\n case RestateLogLevel.ERROR:\n return vm.LogLevel.ERROR;\n }\n}\n\nfunction onJournalMismatchErrorsToWasm(\n behavior: \"retry\" | \"pause\" | \"fail\" | undefined\n): vm.WasmJournalMismatchBehavior {\n switch (behavior) {\n case \"pause\":\n return vm.WasmJournalMismatchBehavior.Pause;\n case \"fail\":\n return vm.WasmJournalMismatchBehavior.Fail;\n case \"retry\":\n case undefined:\n return vm.WasmJournalMismatchBehavior.Retry;\n }\n}\n"],"mappings":"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"}
|
|
@@ -95,10 +95,13 @@ export class WasmInput {
|
|
|
95
95
|
free(): void;
|
|
96
96
|
[Symbol.dispose](): void;
|
|
97
97
|
readonly headers: WasmHeader[];
|
|
98
|
+
readonly idempotency_key: string | undefined;
|
|
98
99
|
readonly input: Uint8Array;
|
|
99
100
|
readonly invocation_id: string;
|
|
100
101
|
readonly key: string;
|
|
102
|
+
readonly limit_key: string | undefined;
|
|
101
103
|
readonly random_seed: bigint;
|
|
104
|
+
readonly scope: string | undefined;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
/**
|
|
@@ -150,7 +153,7 @@ export class WasmVM {
|
|
|
150
153
|
propose_run_completion_success(handle: number, buffer: Uint8Array): void;
|
|
151
154
|
sys_attach_invocation(invocation_id: string): number;
|
|
152
155
|
sys_awakeable(): WasmAwakeable;
|
|
153
|
-
sys_call(service: string, handler: string, buffer: Uint8Array, key: string | null | undefined, headers: WasmHeader[], idempotency_key?: string | null, name?: string | null): WasmCallHandle;
|
|
156
|
+
sys_call(service: string, handler: string, buffer: Uint8Array, key: string | null | undefined, headers: WasmHeader[], idempotency_key?: string | null, scope?: string | null, limit_key?: string | null, name?: string | null): WasmCallHandle;
|
|
154
157
|
sys_cancel_invocation(target_invocation_id: string): void;
|
|
155
158
|
sys_clear_all_state(): void;
|
|
156
159
|
sys_clear_state(key: string): void;
|
|
@@ -168,7 +171,7 @@ export class WasmVM {
|
|
|
168
171
|
sys_input(): WasmInput;
|
|
169
172
|
sys_peek_promise(key: string): number;
|
|
170
173
|
sys_run(name: string): WasmRun;
|
|
171
|
-
sys_send(service: string, handler: string, buffer: Uint8Array, key: string | null | undefined, headers: WasmHeader[], delay?: bigint | null, idempotency_key?: string | null, name?: string | null): WasmSendHandle;
|
|
174
|
+
sys_send(service: string, handler: string, buffer: Uint8Array, key: string | null | undefined, headers: WasmHeader[], delay?: bigint | null, idempotency_key?: string | null, scope?: string | null, limit_key?: string | null, name?: string | null): WasmSendHandle;
|
|
172
175
|
sys_set_state(key: string, buffer: Uint8Array): void;
|
|
173
176
|
sys_signal(signal_name: string): number;
|
|
174
177
|
sys_sleep(millis: bigint, name?: string | null): number;
|