@restatedev/restate-sdk 1.14.2 → 1.14.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"promises.js","names":["handle: number","completer: (\n value: AsyncResultValue,\n prom: CompletablePromise<T>\n ) => Promise<void>","invocationIdPromise: Promise<InvocationId>","childs: Array<InternalRestatePromise<any>>","castedPromises: InternalRestatePromise<any>[]","foundContext: ContextImpl | undefined","inner: InternalRestatePromise<T>","promiseFactory: () => Promise<T>","settled: boolean","coreVm: vm.WasmVM","inputPump: InputPump","outputPump: OutputPump","runClosuresTracker: RunClosuresTracker","errorCallback: (e: any) => void"],"sources":["../src/promises.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2025 - 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 RestatePromise,\n InvocationId,\n InvocationPromise,\n} from \"./context.js\";\nimport type * as vm from \"./endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js\";\nimport {\n CancelledError,\n RestateError,\n TerminalError,\n TimeoutError,\n} from \"./types/errors.js\";\nimport { CompletablePromise } from \"./utils/completable_promise.js\";\nimport type { ContextImpl, RunClosuresTracker } from \"./context_impl.js\";\nimport { setImmediate } from \"node:timers/promises\";\nimport type { InputPump, OutputPump } from \"./io.js\";\nimport type { Duration } from \"@restatedev/restate-sdk-core\";\n\n// A promise that is never completed\nexport function pendingPromise<T>(): Promise<T> {\n return new Promise<T>(() => {});\n}\n\n// ------ Restate promises ------\n// These promises are \"proxy promises\" that will be handed over to the user,\n// and moved forward by the PromiseExecutor below when the user awaits on them.\n\n/**\n * Returns `true` if the given value is a {@link RestatePromise}.\n *\n * Use this for runtime type detection when you need to distinguish Restate promises\n * from regular promises, e.g. for overload resolution.\n */\nexport function isRestatePromise<T>(p: Promise<T>): p is RestatePromise<T> {\n return p instanceof InternalRestatePromise;\n}\n\nenum PromiseState {\n COMPLETED,\n NOT_COMPLETED,\n}\n\nexport abstract class InternalRestatePromise<T> implements RestatePromise<T> {\n abstract then<TResult1, TResult2>(\n onfulfilled:\n | ((value: T) => PromiseLike<TResult1> | TResult1)\n | undefined\n | null,\n onrejected:\n | ((reason: any) => PromiseLike<TResult2> | TResult2)\n | undefined\n | null\n ): Promise<TResult1 | TResult2>;\n abstract catch<TResult>(\n onrejected:\n | ((reason: any) => PromiseLike<TResult> | TResult)\n | undefined\n | null\n ): Promise<T | TResult>;\n abstract finally(onfinally: (() => void) | undefined | null): Promise<T>;\n\n abstract map<U>(\n mapper: (value?: T, failure?: TerminalError) => U\n ): RestatePromise<U>;\n abstract orTimeout(millis: Duration | number): RestatePromise<T>;\n\n abstract tryCancel(): void;\n abstract tryComplete(): Promise<void>;\n abstract uncompletedLeaves(): Array<number>;\n abstract publicPromise(): Promise<T>;\n\n abstract readonly [Symbol.toStringTag]: string;\n}\n\nexport type AsyncResultValue =\n | \"Empty\"\n | { Success: Uint8Array }\n | { Failure: vm.WasmFailure }\n | { StateKeys: string[] }\n | { InvocationId: string };\n\nconst RESTATE_CTX_SYMBOL = Symbol(\"restateContext\");\n\nfunction extractContext(n: any): ContextImpl | undefined {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return n[RESTATE_CTX_SYMBOL] as ContextImpl | undefined;\n}\n\nabstract class BaseRestatePromise<T> extends InternalRestatePromise<T> {\n [RESTATE_CTX_SYMBOL]: ContextImpl;\n private pollingPromise?: Promise<any>;\n private cancelPromise: CompletablePromise<any> = new CompletablePromise();\n\n protected constructor(ctx: ContextImpl) {\n super();\n this[RESTATE_CTX_SYMBOL] = ctx;\n }\n\n // --- Promise methods\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 this.pollingPromise =\n this.pollingPromise ||\n this[RESTATE_CTX_SYMBOL].promisesExecutor\n .doProgress(this)\n .catch(() => {});\n return this.publicPromiseOrCancelPromise().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<T | TResult> {\n this.pollingPromise =\n this.pollingPromise ||\n this[RESTATE_CTX_SYMBOL].promisesExecutor\n .doProgress(this)\n .catch(() => {});\n return this.publicPromiseOrCancelPromise().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n this.pollingPromise =\n this.pollingPromise ||\n this[RESTATE_CTX_SYMBOL].promisesExecutor\n .doProgress(this)\n .catch(() => {});\n return this.publicPromiseOrCancelPromise().finally(onfinally);\n }\n\n private publicPromiseOrCancelPromise(): Promise<T> {\n return Promise.race([\n this.cancelPromise.promise as Promise<T>,\n this.publicPromise(),\n ]);\n }\n\n // --- RestatePromise methods\n\n orTimeout(duration: number | Duration): RestatePromise<T> {\n return new CombinatorRestatePromise(\n this[RESTATE_CTX_SYMBOL],\n ([thisPromise, sleepPromise]) => {\n return new Promise((resolve, reject) => {\n thisPromise!.then(resolve, reject);\n sleepPromise!.then(() => {\n reject(new TimeoutError());\n }, reject);\n });\n },\n [\n this,\n this[RESTATE_CTX_SYMBOL].sleep(duration) as InternalRestatePromise<any>,\n ]\n ) as RestatePromise<T>;\n }\n\n map<U>(mapper: (value?: T, failure?: TerminalError) => U): RestatePromise<U> {\n return new MappedRestatePromise(this[RESTATE_CTX_SYMBOL], this, mapper);\n }\n\n tryCancel() {\n this.cancelPromise.reject(new CancelledError());\n }\n\n abstract override tryComplete(): Promise<void>;\n\n abstract override uncompletedLeaves(): Array<number>;\n\n abstract override publicPromise(): Promise<T>;\n\n abstract override [Symbol.toStringTag]: string;\n}\n\nexport class SingleRestatePromise<T> extends BaseRestatePromise<T> {\n private state: PromiseState = PromiseState.NOT_COMPLETED;\n private completablePromise: CompletablePromise<T> = new CompletablePromise();\n\n constructor(\n ctx: ContextImpl,\n readonly handle: number,\n private readonly completer: (\n value: AsyncResultValue,\n prom: CompletablePromise<T>\n ) => Promise<void>\n ) {\n super(ctx);\n }\n\n uncompletedLeaves(): number[] {\n return this.state === PromiseState.COMPLETED ? [] : [this.handle];\n }\n\n async tryComplete(): Promise<void> {\n if (this.state === PromiseState.COMPLETED) {\n return;\n }\n const notification = this[RESTATE_CTX_SYMBOL].coreVm.take_notification(\n this.handle\n );\n if (notification === \"NotReady\") {\n return;\n }\n this.state = PromiseState.COMPLETED;\n await this.completer(notification, this.completablePromise);\n }\n\n publicPromise(): Promise<T> {\n return this.completablePromise.promise;\n }\n\n isCompleted(): boolean {\n return this.state === PromiseState.COMPLETED;\n }\n\n readonly [Symbol.toStringTag] = \"RestateSinglePromise\";\n}\n\nexport class InvocationRestatePromise<T>\n extends SingleRestatePromise<T>\n implements InvocationPromise<T>\n{\n constructor(\n ctx: ContextImpl,\n handle: number,\n completer: (\n value: AsyncResultValue,\n prom: CompletablePromise<T>\n ) => Promise<void>,\n private readonly invocationIdPromise: Promise<InvocationId>\n ) {\n super(ctx, handle, completer);\n }\n\n get invocationId(): Promise<InvocationId> {\n return this.invocationIdPromise;\n }\n}\n\nexport class CombinatorRestatePromise extends BaseRestatePromise<any> {\n private state: PromiseState = PromiseState.NOT_COMPLETED;\n private readonly combinatorPromise: Promise<any>;\n\n constructor(\n ctx: ContextImpl,\n combinatorConstructor: (promises: Promise<any>[]) => Promise<any>,\n readonly childs: Array<InternalRestatePromise<any>>\n ) {\n super(ctx);\n this.combinatorPromise = combinatorConstructor(\n childs.map((p) => p.publicPromise())\n ).finally(() => {\n this.state = PromiseState.COMPLETED;\n });\n }\n\n // Used by static methods of RestatePromise\n public static fromPromises<T extends readonly RestatePromise<unknown>[]>(\n combinatorConstructor: (promises: Promise<any>[]) => Promise<any>,\n promises: T\n ): RestatePromise<unknown> {\n const castedPromises: InternalRestatePromise<any>[] = [];\n let foundContext: ContextImpl | undefined = undefined;\n\n for (const [idx, promise] of promises.entries()) {\n if (!isRestatePromise(promise)) {\n throw new Error(\n `Promise index ${idx} used inside the combinator is not an instance of RestatePromise. This is not supported.`\n );\n } else if (foundContext === undefined) {\n foundContext = extractContext(promise);\n } else {\n const thisContext = extractContext(promise);\n if (thisContext !== undefined && thisContext !== foundContext) {\n throw new Error(\n \"You're mixing up RestatePromises from different RestateContext. This is not supported.\"\n );\n }\n }\n castedPromises.push(promise as InternalRestatePromise<any>);\n }\n\n if (foundContext === undefined) {\n // The only situation where this can happen is when the combined promise contains only ConstRestatePromise as children.\n // In this case, just return back a nice and clean ConstRestatePromise.\n // There is a specific workaround for the funky interface of Promise.race, inside the RestatePromise.race factory method.\n return ConstRestatePromise.fromPromise(\n combinatorConstructor(castedPromises),\n true\n );\n }\n\n return new CombinatorRestatePromise(\n foundContext,\n combinatorConstructor,\n castedPromises\n );\n }\n\n uncompletedLeaves(): number[] {\n return this.state === PromiseState.COMPLETED\n ? []\n : this.childs.flatMap((p) => p.uncompletedLeaves());\n }\n\n async tryComplete(): Promise<void> {\n await Promise.allSettled(this.childs.map((c) => c.tryComplete()));\n }\n\n publicPromise(): Promise<unknown> {\n return this.combinatorPromise;\n }\n\n readonly [Symbol.toStringTag] = \"RestateCombinatorPromise\";\n}\n\nexport class MappedRestatePromise<T, U> extends BaseRestatePromise<U> {\n private publicPromiseMapper: (\n value?: T,\n failure?: TerminalError\n ) => Promise<U>;\n // Memoized so the mapper fires at most once regardless of how many times\n // the promise is awaited / consumed via then/catch/finally/publicPromise.\n private _mappedPromise?: Promise<U>;\n\n constructor(\n ctx: ContextImpl,\n readonly inner: InternalRestatePromise<T>,\n mapper: (value?: T, failure?: TerminalError) => U\n ) {\n super(ctx);\n this.publicPromiseMapper = (value?: T, failure?: TerminalError) => {\n try {\n return Promise.resolve(mapper(value, failure));\n } catch (e) {\n if (e instanceof TerminalError) {\n return Promise.reject(e);\n } else {\n ctx.abortAttempt(e);\n return pendingPromise();\n }\n }\n };\n }\n\n async tryComplete(): Promise<void> {\n await this.inner.tryComplete();\n }\n\n uncompletedLeaves(): number[] {\n return this.inner.uncompletedLeaves();\n }\n\n publicPromise(): Promise<U> {\n return (this._mappedPromise ??= this.buildMappedPromise());\n }\n\n private buildMappedPromise(): Promise<U> {\n const promiseMapper = this.publicPromiseMapper;\n return this.inner.publicPromise().then(\n (t) => promiseMapper(t, undefined),\n (error) => {\n if (error instanceof RestateError) {\n return promiseMapper(undefined, error);\n } else {\n // Something else, just re-throw it\n throw error;\n }\n }\n );\n }\n\n readonly [Symbol.toStringTag] = \"RestateMappedPromise\";\n}\n\nexport class ConstRestatePromise<T> extends InternalRestatePromise<T> {\n private _constPromise?: Promise<T>;\n\n private constructor(\n // Factory for the underlying promise. Called at most once, memoized in\n // `_constPromise`.\n //\n // This way `map` is lazy, making it deterministically invoked on await points.\n private readonly promiseFactory: () => Promise<T>,\n private readonly settled: boolean\n ) {\n super();\n }\n\n private get constPromise(): Promise<T> {\n return (this._constPromise ??= this.promiseFactory());\n }\n\n static resolve<T>(value: T): ConstRestatePromise<Awaited<T>> {\n return new ConstRestatePromise(() => Promise.resolve(value), true);\n }\n\n static reject<T = never>(reason: TerminalError): ConstRestatePromise<T> {\n return new ConstRestatePromise<T>(() => Promise.reject(reason), true);\n }\n\n static pending<T>(): ConstRestatePromise<T> {\n return new ConstRestatePromise<T>(() => pendingPromise<T>(), false);\n }\n\n static fromPromise<T>(\n promise: Promise<T>,\n settled: boolean\n ): ConstRestatePromise<T> {\n return new ConstRestatePromise(() => promise, settled);\n }\n\n // --- Promise methods\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.constPromise.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<T | TResult> {\n return this.constPromise.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.constPromise.finally(onfinally);\n }\n\n // --- RestatePromise methods\n\n orTimeout(): RestatePromise<T> {\n if (this.settled) return this;\n return ConstRestatePromise.reject(new TimeoutError());\n }\n\n map<U>(mapper: (value?: T, failure?: TerminalError) => U): RestatePromise<U> {\n if (!this.settled) return this as unknown as RestatePromise<U>;\n const selfConstPromise = this.constPromise;\n return new ConstRestatePromise<U>(\n () =>\n selfConstPromise.then(\n (value) => mapper(value, undefined),\n (reason) => mapper(undefined, reason as TerminalError)\n ),\n this.settled\n );\n }\n\n tryCancel() {}\n\n publicPromise(): Promise<T> {\n return this.constPromise;\n }\n\n tryComplete(): Promise<void> {\n return Promise.resolve();\n }\n\n uncompletedLeaves(): Array<number> {\n return [];\n }\n\n readonly [Symbol.toStringTag] = \"ConstRestatePromise\";\n}\n\n/**\n * Promises executor, gluing VM with I/O and Promises given to user space.\n */\nexport class PromisesExecutor {\n constructor(\n private readonly coreVm: vm.WasmVM,\n private readonly inputPump: InputPump,\n private readonly outputPump: OutputPump,\n private readonly runClosuresTracker: RunClosuresTracker,\n private readonly errorCallback: (e: any) => void\n ) {}\n\n async doProgress(restatePromise: InternalRestatePromise<unknown>) {\n // Only the first time try process output\n await this.outputPump.awaitNextProgress();\n await this.doProgressInner(restatePromise);\n }\n\n private async doProgressInner(\n restatePromise: InternalRestatePromise<unknown>\n ) {\n // Try complete the promise\n try {\n await restatePromise.tryComplete();\n } catch (e) {\n // This can happen if either take_notification throws an exception or completer throws an exception.\n // This could either happen for a deserialization issue, or for an SDK bug, but we cover them here.\n this.errorCallback(e);\n return Promise.resolve();\n }\n\n // tl;dr don't touch this, or you can break combineable promises,\n // slinkydeveloper won't be happy about it\n //\n // The reason for this setTimeout is that we need to enqueue the polling after\n // we eventually resolve some promises. This is especially crucial for RestateCombinatorPromise\n // as it flips the completed state using .finally() on the combinator.\n return setImmediate().then(async () => {\n try {\n // Invoke do progress on the vm\n const handles = restatePromise.uncompletedLeaves();\n if (handles.length === 0) {\n // Completed, we're good!\n return;\n }\n const doProgressResult = this.coreVm.do_progress(\n new Uint32Array(handles)\n );\n\n if (doProgressResult === \"AnyCompleted\") {\n // Next recursion will cause the promise to do some progress\n } else if (\n doProgressResult === \"ReadFromInput\" ||\n doProgressResult === \"WaitingPendingRun\"\n ) {\n // The shared-core now can't make progress without \"external progress\".\n //\n // There are really 3 situations here:\n // * Input is still open, and a run is being executed.\n // Both reading from input or proposing a run completion causes the invocation to make progress.\n // * Input is still open, there is no run being executed.\n // Only reading from input causes the invocation to make progress.\n // * Input is closed, a run is being executed.\n // Only proposing a run completion causes the invocation to make progress.\n\n // In this scenario, we might need to write some stuff out which might be in the shared-core buffer.\n await this.outputPump.awaitNextProgress();\n\n await Promise.race([\n this.inputPump.awaitNextProgress(),\n this.runClosuresTracker.awaitNextCompletedRun(),\n ]);\n } else if (doProgressResult === \"CancelSignalReceived\") {\n restatePromise.tryCancel();\n return;\n } else {\n // We need to execute a run closure\n this.runClosuresTracker.executeRun(doProgressResult.ExecuteRun);\n // Let the run context switch, then come back to this flow.\n await setImmediate();\n }\n\n // Recursion\n await this.doProgressInner(restatePromise);\n } catch (e) {\n // Not good, this is a retryable error.\n this.errorCallback(e);\n }\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"promises.js","names":["handle: number","completer: (\n value: AsyncResultValue,\n prom: CompletablePromise<T>\n ) => Promise<void>","invocationIdPromise: Promise<InvocationId>","childs: Array<InternalRestatePromise<any>>","castedPromises: InternalRestatePromise<any>[]","foundContext: ContextImpl | undefined","inner: InternalRestatePromise<T>","promiseFactory: () => Promise<T>","settled: boolean","coreVm: vm.WasmVM","outputPump: OutputPump","runClosuresTracker: RunClosuresTracker","externalProgressChannel: ExternalProgressChannel","errorCallback: (e: any) => void"],"sources":["../src/promises.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2025 - 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 RestatePromise,\n InvocationId,\n InvocationPromise,\n} from \"./context.js\";\nimport type * as vm from \"./endpoint/handlers/vm/sdk_shared_core_wasm_bindings.js\";\nimport {\n CancelledError,\n RestateError,\n TerminalError,\n TimeoutError,\n} from \"./types/errors.js\";\nimport { CompletablePromise } from \"./utils/completable_promise.js\";\nimport type { ContextImpl, RunClosuresTracker } from \"./context_impl.js\";\nimport { setImmediate } from \"node:timers/promises\";\nimport type { OutputPump } from \"./io.js\";\nimport type { ExternalProgressChannel } from \"./utils/external_progress_channel.js\";\nimport type { Duration } from \"@restatedev/restate-sdk-core\";\n\n// A promise that is never completed\nexport function pendingPromise<T>(): Promise<T> {\n return new Promise<T>(() => {});\n}\n\n// ------ Restate promises ------\n// These promises are \"proxy promises\" that will be handed over to the user,\n// and moved forward by the PromiseExecutor below when the user awaits on them.\n\n/**\n * Returns `true` if the given value is a {@link RestatePromise}.\n *\n * Use this for runtime type detection when you need to distinguish Restate promises\n * from regular promises, e.g. for overload resolution.\n */\nexport function isRestatePromise<T>(p: Promise<T>): p is RestatePromise<T> {\n return p instanceof InternalRestatePromise;\n}\n\nenum PromiseState {\n COMPLETED,\n NOT_COMPLETED,\n}\n\nexport abstract class InternalRestatePromise<T> implements RestatePromise<T> {\n abstract then<TResult1, TResult2>(\n onfulfilled:\n | ((value: T) => PromiseLike<TResult1> | TResult1)\n | undefined\n | null,\n onrejected:\n | ((reason: any) => PromiseLike<TResult2> | TResult2)\n | undefined\n | null\n ): Promise<TResult1 | TResult2>;\n abstract catch<TResult>(\n onrejected:\n | ((reason: any) => PromiseLike<TResult> | TResult)\n | undefined\n | null\n ): Promise<T | TResult>;\n abstract finally(onfinally: (() => void) | undefined | null): Promise<T>;\n\n abstract map<U>(\n mapper: (value?: T, failure?: TerminalError) => U\n ): RestatePromise<U>;\n abstract orTimeout(millis: Duration | number): RestatePromise<T>;\n\n abstract tryCancel(): void;\n abstract tryComplete(): Promise<void>;\n abstract uncompletedLeaves(): Array<number>;\n abstract publicPromise(): Promise<T>;\n\n abstract readonly [Symbol.toStringTag]: string;\n}\n\nexport type AsyncResultValue =\n | \"Empty\"\n | { Success: Uint8Array }\n | { Failure: vm.WasmFailure }\n | { StateKeys: string[] }\n | { InvocationId: string };\n\nconst RESTATE_CTX_SYMBOL = Symbol(\"restateContext\");\n\nfunction extractContext(n: any): ContextImpl | undefined {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return n[RESTATE_CTX_SYMBOL] as ContextImpl | undefined;\n}\n\nabstract class BaseRestatePromise<T> extends InternalRestatePromise<T> {\n [RESTATE_CTX_SYMBOL]: ContextImpl;\n private pollingPromise?: Promise<any>;\n private cancelPromise: CompletablePromise<any> = new CompletablePromise();\n\n protected constructor(ctx: ContextImpl) {\n super();\n this[RESTATE_CTX_SYMBOL] = ctx;\n }\n\n // --- Promise methods\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 this.pollingPromise =\n this.pollingPromise ||\n this[RESTATE_CTX_SYMBOL].promisesExecutor\n .doProgress(this)\n .catch(() => {});\n return this.publicPromiseOrCancelPromise().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<T | TResult> {\n this.pollingPromise =\n this.pollingPromise ||\n this[RESTATE_CTX_SYMBOL].promisesExecutor\n .doProgress(this)\n .catch(() => {});\n return this.publicPromiseOrCancelPromise().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n this.pollingPromise =\n this.pollingPromise ||\n this[RESTATE_CTX_SYMBOL].promisesExecutor\n .doProgress(this)\n .catch(() => {});\n return this.publicPromiseOrCancelPromise().finally(onfinally);\n }\n\n private publicPromiseOrCancelPromise(): Promise<T> {\n return Promise.race([\n this.cancelPromise.promise as Promise<T>,\n this.publicPromise(),\n ]);\n }\n\n // --- RestatePromise methods\n\n orTimeout(duration: number | Duration): RestatePromise<T> {\n return new CombinatorRestatePromise(\n this[RESTATE_CTX_SYMBOL],\n ([thisPromise, sleepPromise]) => {\n return new Promise((resolve, reject) => {\n thisPromise!.then(resolve, reject);\n sleepPromise!.then(() => {\n reject(new TimeoutError());\n }, reject);\n });\n },\n [\n this,\n this[RESTATE_CTX_SYMBOL].sleep(duration) as InternalRestatePromise<any>,\n ]\n ) as RestatePromise<T>;\n }\n\n map<U>(mapper: (value?: T, failure?: TerminalError) => U): RestatePromise<U> {\n return new MappedRestatePromise(this[RESTATE_CTX_SYMBOL], this, mapper);\n }\n\n tryCancel() {\n this.cancelPromise.reject(new CancelledError());\n }\n\n abstract override tryComplete(): Promise<void>;\n\n abstract override uncompletedLeaves(): Array<number>;\n\n abstract override publicPromise(): Promise<T>;\n\n abstract override [Symbol.toStringTag]: string;\n}\n\nexport class SingleRestatePromise<T> extends BaseRestatePromise<T> {\n private state: PromiseState = PromiseState.NOT_COMPLETED;\n private completablePromise: CompletablePromise<T> = new CompletablePromise();\n\n constructor(\n ctx: ContextImpl,\n readonly handle: number,\n private readonly completer: (\n value: AsyncResultValue,\n prom: CompletablePromise<T>\n ) => Promise<void>\n ) {\n super(ctx);\n }\n\n uncompletedLeaves(): number[] {\n return this.state === PromiseState.COMPLETED ? [] : [this.handle];\n }\n\n async tryComplete(): Promise<void> {\n if (this.state === PromiseState.COMPLETED) {\n return;\n }\n const notification = this[RESTATE_CTX_SYMBOL].coreVm.take_notification(\n this.handle\n );\n if (notification === \"NotReady\") {\n return;\n }\n this.state = PromiseState.COMPLETED;\n await this.completer(notification, this.completablePromise);\n }\n\n publicPromise(): Promise<T> {\n return this.completablePromise.promise;\n }\n\n isCompleted(): boolean {\n return this.state === PromiseState.COMPLETED;\n }\n\n readonly [Symbol.toStringTag] = \"RestateSinglePromise\";\n}\n\nexport class InvocationRestatePromise<T>\n extends SingleRestatePromise<T>\n implements InvocationPromise<T>\n{\n constructor(\n ctx: ContextImpl,\n handle: number,\n completer: (\n value: AsyncResultValue,\n prom: CompletablePromise<T>\n ) => Promise<void>,\n private readonly invocationIdPromise: Promise<InvocationId>\n ) {\n super(ctx, handle, completer);\n }\n\n get invocationId(): Promise<InvocationId> {\n return this.invocationIdPromise;\n }\n}\n\nexport class CombinatorRestatePromise extends BaseRestatePromise<any> {\n private state: PromiseState = PromiseState.NOT_COMPLETED;\n private readonly combinatorPromise: Promise<any>;\n\n constructor(\n ctx: ContextImpl,\n combinatorConstructor: (promises: Promise<any>[]) => Promise<any>,\n readonly childs: Array<InternalRestatePromise<any>>\n ) {\n super(ctx);\n this.combinatorPromise = combinatorConstructor(\n childs.map((p) => p.publicPromise())\n ).finally(() => {\n this.state = PromiseState.COMPLETED;\n });\n }\n\n // Used by static methods of RestatePromise\n public static fromPromises<T extends readonly RestatePromise<unknown>[]>(\n combinatorConstructor: (promises: Promise<any>[]) => Promise<any>,\n promises: T\n ): RestatePromise<unknown> {\n const castedPromises: InternalRestatePromise<any>[] = [];\n let foundContext: ContextImpl | undefined = undefined;\n\n for (const [idx, promise] of promises.entries()) {\n if (!isRestatePromise(promise)) {\n throw new Error(\n `Promise index ${idx} used inside the combinator is not an instance of RestatePromise. This is not supported.`\n );\n } else if (foundContext === undefined) {\n foundContext = extractContext(promise);\n } else {\n const thisContext = extractContext(promise);\n if (thisContext !== undefined && thisContext !== foundContext) {\n throw new Error(\n \"You're mixing up RestatePromises from different RestateContext. This is not supported.\"\n );\n }\n }\n castedPromises.push(promise as InternalRestatePromise<any>);\n }\n\n if (foundContext === undefined) {\n // The only situation where this can happen is when the combined promise contains only ConstRestatePromise as children.\n // In this case, just return back a nice and clean ConstRestatePromise.\n // There is a specific workaround for the funky interface of Promise.race, inside the RestatePromise.race factory method.\n return ConstRestatePromise.fromPromise(\n combinatorConstructor(castedPromises),\n true\n );\n }\n\n return new CombinatorRestatePromise(\n foundContext,\n combinatorConstructor,\n castedPromises\n );\n }\n\n uncompletedLeaves(): number[] {\n return this.state === PromiseState.COMPLETED\n ? []\n : this.childs.flatMap((p) => p.uncompletedLeaves());\n }\n\n async tryComplete(): Promise<void> {\n await Promise.allSettled(this.childs.map((c) => c.tryComplete()));\n }\n\n publicPromise(): Promise<unknown> {\n return this.combinatorPromise;\n }\n\n readonly [Symbol.toStringTag] = \"RestateCombinatorPromise\";\n}\n\nexport class MappedRestatePromise<T, U> extends BaseRestatePromise<U> {\n private publicPromiseMapper: (\n value?: T,\n failure?: TerminalError\n ) => Promise<U>;\n // Memoized so the mapper fires at most once regardless of how many times\n // the promise is awaited / consumed via then/catch/finally/publicPromise.\n private _mappedPromise?: Promise<U>;\n\n constructor(\n ctx: ContextImpl,\n readonly inner: InternalRestatePromise<T>,\n mapper: (value?: T, failure?: TerminalError) => U\n ) {\n super(ctx);\n this.publicPromiseMapper = (value?: T, failure?: TerminalError) => {\n try {\n return Promise.resolve(mapper(value, failure));\n } catch (e) {\n if (e instanceof TerminalError) {\n return Promise.reject(e);\n } else {\n ctx.abortAttempt(e);\n return pendingPromise();\n }\n }\n };\n }\n\n async tryComplete(): Promise<void> {\n await this.inner.tryComplete();\n }\n\n uncompletedLeaves(): number[] {\n return this.inner.uncompletedLeaves();\n }\n\n publicPromise(): Promise<U> {\n return (this._mappedPromise ??= this.buildMappedPromise());\n }\n\n private buildMappedPromise(): Promise<U> {\n const promiseMapper = this.publicPromiseMapper;\n return this.inner.publicPromise().then(\n (t) => promiseMapper(t, undefined),\n (error) => {\n if (error instanceof RestateError) {\n return promiseMapper(undefined, error);\n } else {\n // Something else, just re-throw it\n throw error;\n }\n }\n );\n }\n\n readonly [Symbol.toStringTag] = \"RestateMappedPromise\";\n}\n\nexport class ConstRestatePromise<T> extends InternalRestatePromise<T> {\n private _constPromise?: Promise<T>;\n\n private constructor(\n // Factory for the underlying promise. Called at most once, memoized in\n // `_constPromise`.\n //\n // This way `map` is lazy, making it deterministically invoked on await points.\n private readonly promiseFactory: () => Promise<T>,\n private readonly settled: boolean\n ) {\n super();\n }\n\n private get constPromise(): Promise<T> {\n return (this._constPromise ??= this.promiseFactory());\n }\n\n static resolve<T>(value: T): ConstRestatePromise<Awaited<T>> {\n return new ConstRestatePromise(() => Promise.resolve(value), true);\n }\n\n static reject<T = never>(reason: TerminalError): ConstRestatePromise<T> {\n return new ConstRestatePromise<T>(() => Promise.reject(reason), true);\n }\n\n static pending<T>(): ConstRestatePromise<T> {\n return new ConstRestatePromise<T>(() => pendingPromise<T>(), false);\n }\n\n static fromPromise<T>(\n promise: Promise<T>,\n settled: boolean\n ): ConstRestatePromise<T> {\n return new ConstRestatePromise(() => promise, settled);\n }\n\n // --- Promise methods\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.constPromise.then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null\n ): Promise<T | TResult> {\n return this.constPromise.catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.constPromise.finally(onfinally);\n }\n\n // --- RestatePromise methods\n\n orTimeout(): RestatePromise<T> {\n if (this.settled) return this;\n return ConstRestatePromise.reject(new TimeoutError());\n }\n\n map<U>(mapper: (value?: T, failure?: TerminalError) => U): RestatePromise<U> {\n if (!this.settled) return this as unknown as RestatePromise<U>;\n const selfConstPromise = this.constPromise;\n return new ConstRestatePromise<U>(\n () =>\n selfConstPromise.then(\n (value) => mapper(value, undefined),\n (reason) => mapper(undefined, reason as TerminalError)\n ),\n this.settled\n );\n }\n\n tryCancel() {}\n\n publicPromise(): Promise<T> {\n return this.constPromise;\n }\n\n tryComplete(): Promise<void> {\n return Promise.resolve();\n }\n\n uncompletedLeaves(): Array<number> {\n return [];\n }\n\n readonly [Symbol.toStringTag] = \"ConstRestatePromise\";\n}\n\n/**\n * Promises executor, gluing VM with I/O and Promises given to user space.\n */\nexport class PromisesExecutor {\n constructor(\n private readonly coreVm: vm.WasmVM,\n private readonly outputPump: OutputPump,\n private readonly runClosuresTracker: RunClosuresTracker,\n private readonly externalProgressChannel: ExternalProgressChannel,\n private readonly errorCallback: (e: any) => void\n ) {}\n\n async doProgress(restatePromise: InternalRestatePromise<unknown>) {\n // Only the first time try process output\n await this.outputPump.awaitNextProgress();\n await this.doProgressInner(restatePromise);\n }\n\n private async doProgressInner(\n restatePromise: InternalRestatePromise<unknown>\n ) {\n // Try complete the promise\n try {\n await restatePromise.tryComplete();\n } catch (e) {\n // This can happen if either take_notification throws an exception or completer throws an exception.\n // This could either happen for a deserialization issue, or for an SDK bug, but we cover them here.\n this.errorCallback(e);\n return Promise.resolve();\n }\n\n // tl;dr don't touch this, or you can break combineable promises,\n // slinkydeveloper won't be happy about it\n //\n // The reason for this setTimeout is that we need to enqueue the polling after\n // we eventually resolve some promises. This is especially crucial for RestateCombinatorPromise\n // as it flips the completed state using .finally() on the combinator.\n return setImmediate().then(async () => {\n try {\n // Invoke do progress on the vm\n const handles = restatePromise.uncompletedLeaves();\n if (handles.length === 0) {\n // Completed, we're good!\n return;\n }\n const doProgressResult = this.coreVm.do_progress(\n new Uint32Array(handles)\n );\n\n if (doProgressResult === \"AnyCompleted\") {\n // Next recursion will cause the promise to do some progress\n } else if (\n doProgressResult === \"ReadFromInput\" ||\n doProgressResult === \"WaitingPendingRun\"\n ) {\n // The shared-core now can't make progress without \"external progress\".\n //\n // There are really 3 situations here:\n // * Input is still open, and a run is being executed.\n // Both reading from input or proposing a run completion causes the invocation to make progress.\n // * Input is still open, there is no run being executed.\n // Only reading from input causes the invocation to make progress.\n // * Input is closed, a run is being executed.\n // Only proposing a run completion causes the invocation to make progress.\n\n // In this scenario, we might need to write some stuff out which might be in the shared-core buffer.\n await this.outputPump.awaitNextProgress();\n\n // Await next external progress\n await this.externalProgressChannel.awaitNext();\n } else if (doProgressResult === \"CancelSignalReceived\") {\n restatePromise.tryCancel();\n return;\n } else {\n // We need to execute a run closure\n this.runClosuresTracker.executeRun(doProgressResult.ExecuteRun);\n // Let the run context switch, then come back to this flow.\n await setImmediate();\n }\n\n // Recursion\n await this.doProgressInner(restatePromise);\n } catch (e) {\n // Not good, this is a retryable error.\n this.errorCallback(e);\n }\n });\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+
2
+ //#region src/utils/external_progress_channel.ts
3
+ /**
4
+ * Multi-producer single-consumer unit-signal channel used to wake the
5
+ * {@link PromisesExecutor} when any external progress source (input read or
6
+ * run-closure completion) has made progress.
7
+ *
8
+ * Producers call {@link signal} to emit a progress event.
9
+ * The single consumer calls {@link awaitNext} to await the next signal.
10
+ *
11
+ * Signals emitted with no consumer waiting are buffered, so no progress signal
12
+ * is ever lost. At most one {@link awaitNext} may be pending at a time; a
13
+ * concurrent second call rejects.
14
+ */
15
+ var ExternalProgressChannel = class {
16
+ pending = 0;
17
+ waiter;
18
+ signal() {
19
+ if (this.waiter !== void 0) {
20
+ const w = this.waiter;
21
+ this.waiter = void 0;
22
+ w();
23
+ } else this.pending++;
24
+ }
25
+ awaitNext() {
26
+ if (this.waiter !== void 0) return Promise.reject(/* @__PURE__ */ new Error("awaitNext already pending"));
27
+ if (this.pending > 0) {
28
+ this.pending--;
29
+ return Promise.resolve();
30
+ }
31
+ return new Promise((resolve) => {
32
+ this.waiter = resolve;
33
+ });
34
+ }
35
+ };
36
+
37
+ //#endregion
38
+ exports.ExternalProgressChannel = ExternalProgressChannel;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Multi-producer single-consumer unit-signal channel used to wake the
3
+ * {@link PromisesExecutor} when any external progress source (input read or
4
+ * run-closure completion) has made progress.
5
+ *
6
+ * Producers call {@link signal} to emit a progress event.
7
+ * The single consumer calls {@link awaitNext} to await the next signal.
8
+ *
9
+ * Signals emitted with no consumer waiting are buffered, so no progress signal
10
+ * is ever lost. At most one {@link awaitNext} may be pending at a time; a
11
+ * concurrent second call rejects.
12
+ */
13
+ export declare class ExternalProgressChannel {
14
+ private pending;
15
+ private waiter;
16
+ signal(): void;
17
+ awaitNext(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=external_progress_channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external_progress_channel.d.ts","sourceRoot":"","sources":["../../src/utils/external_progress_channel.ts"],"names":[],"mappings":"AAWA;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,MAAM,CAA2B;IAEzC,MAAM,IAAI,IAAI;IAUd,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAY3B"}
@@ -0,0 +1,38 @@
1
+ //#region src/utils/external_progress_channel.ts
2
+ /**
3
+ * Multi-producer single-consumer unit-signal channel used to wake the
4
+ * {@link PromisesExecutor} when any external progress source (input read or
5
+ * run-closure completion) has made progress.
6
+ *
7
+ * Producers call {@link signal} to emit a progress event.
8
+ * The single consumer calls {@link awaitNext} to await the next signal.
9
+ *
10
+ * Signals emitted with no consumer waiting are buffered, so no progress signal
11
+ * is ever lost. At most one {@link awaitNext} may be pending at a time; a
12
+ * concurrent second call rejects.
13
+ */
14
+ var ExternalProgressChannel = class {
15
+ pending = 0;
16
+ waiter;
17
+ signal() {
18
+ if (this.waiter !== void 0) {
19
+ const w = this.waiter;
20
+ this.waiter = void 0;
21
+ w();
22
+ } else this.pending++;
23
+ }
24
+ awaitNext() {
25
+ if (this.waiter !== void 0) return Promise.reject(/* @__PURE__ */ new Error("awaitNext already pending"));
26
+ if (this.pending > 0) {
27
+ this.pending--;
28
+ return Promise.resolve();
29
+ }
30
+ return new Promise((resolve) => {
31
+ this.waiter = resolve;
32
+ });
33
+ }
34
+ };
35
+
36
+ //#endregion
37
+ export { ExternalProgressChannel };
38
+ //# sourceMappingURL=external_progress_channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external_progress_channel.js","names":[],"sources":["../../src/utils/external_progress_channel.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2025 - 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/**\n * Multi-producer single-consumer unit-signal channel used to wake the\n * {@link PromisesExecutor} when any external progress source (input read or\n * run-closure completion) has made progress.\n *\n * Producers call {@link signal} to emit a progress event.\n * The single consumer calls {@link awaitNext} to await the next signal.\n *\n * Signals emitted with no consumer waiting are buffered, so no progress signal\n * is ever lost. At most one {@link awaitNext} may be pending at a time; a\n * concurrent second call rejects.\n */\nexport class ExternalProgressChannel {\n private pending = 0;\n private waiter: (() => void) | undefined;\n\n signal(): void {\n if (this.waiter !== undefined) {\n const w = this.waiter;\n this.waiter = undefined;\n w();\n } else {\n this.pending++;\n }\n }\n\n awaitNext(): Promise<void> {\n if (this.waiter !== undefined) {\n return Promise.reject(new Error(\"awaitNext already pending\"));\n }\n if (this.pending > 0) {\n this.pending--;\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n this.waiter = resolve;\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,IAAa,0BAAb,MAAqC;CACnC,AAAQ,UAAU;CAClB,AAAQ;CAER,SAAe;AACb,MAAI,KAAK,WAAW,QAAW;GAC7B,MAAM,IAAI,KAAK;AACf,QAAK,SAAS;AACd,MAAG;QAEH,MAAK;;CAIT,YAA2B;AACzB,MAAI,KAAK,WAAW,OAClB,QAAO,QAAQ,uBAAO,IAAI,MAAM,4BAA4B,CAAC;AAE/D,MAAI,KAAK,UAAU,GAAG;AACpB,QAAK;AACL,UAAO,QAAQ,SAAS;;AAE1B,SAAO,IAAI,SAAS,YAAY;AAC9B,QAAK,SAAS;IACd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@restatedev/restate-sdk",
3
- "version": "1.14.2",
3
+ "version": "1.14.4",
4
4
  "description": "Typescript SDK for Restate",
5
5
  "author": "Restate Developers",
6
6
  "email": "code@restate.dev",
@@ -44,7 +44,7 @@
44
44
  "access": "public"
45
45
  },
46
46
  "dependencies": {
47
- "@restatedev/restate-sdk-core": "1.14.2"
47
+ "@restatedev/restate-sdk-core": "1.14.4"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/aws-lambda": "^8.10.115"