@restatedev/restate-sdk-cloudflare-workers 1.17.1 → 1.17.3
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 +2 -2
- package/dist/common_api.d.cts.map +1 -1
- package/dist/common_api.d.ts +2 -2
- package/dist/common_api.d.ts.map +1 -1
- package/dist/common_api.js.map +1 -1
- package/dist/context_impl.cjs +74 -17
- package/dist/context_impl.js +74 -17
- package/dist/context_impl.js.map +1 -1
- package/dist/endpoint/endpoint.cjs +1 -1
- package/dist/endpoint/endpoint.js +1 -1
- package/dist/endpoint/endpoint.js.map +1 -1
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings.d.ts +3 -1
- package/dist/endpoint/handlers/vm/sdk_shared_core_wasm_bindings_bg.js +24 -0
- 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 +3 -1
- 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/internal.cjs +19 -1
- package/dist/internal.d.cts +67 -4
- package/dist/internal.d.cts.map +1 -1
- package/dist/internal.d.ts +67 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +19 -1
- package/dist/internal.js.map +1 -1
- 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/promises.cjs +5 -1
- package/dist/promises.d.cts.map +1 -1
- package/dist/promises.d.ts.map +1 -1
- package/dist/promises.js +5 -1
- package/dist/promises.js.map +1 -1
- package/dist/types/errors.cjs +2 -2
- package/dist/types/errors.d.cts +1 -1
- package/dist/types/errors.d.cts.map +1 -1
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +2 -2
- package/dist/types/errors.js.map +1 -1
- package/dist/types/interface.cjs +4 -2
- package/dist/types/interface.js +4 -2
- package/dist/types/interface.js.map +1 -1
- package/package.json +3 -3
package/dist/promises.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promises.js","names":["handle: number","completer: (\n value: AsyncResultValue,\n prom: PromiseWithResolvers<T>\n ) => Promise<void>","invocationIdPromise: Promise<InvocationId>","combinatorVariant: CombinatorVariant","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 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 unresolvedFuture(): vm.WasmUnresolvedFuture | null;\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: PromiseWithResolvers<any> = Promise.withResolvers();\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 \"Unknown\",\n ([thisPromise, sleepPromise]: Promise<any>[]) => {\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 unresolvedFuture(): vm.WasmUnresolvedFuture | null;\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: PromiseWithResolvers<T> = Promise.withResolvers();\n\n constructor(\n ctx: ContextImpl,\n readonly handle: number,\n private readonly completer: (\n value: AsyncResultValue,\n prom: PromiseWithResolvers<T>\n ) => Promise<void>\n ) {\n super(ctx);\n }\n\n unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n return this.state === PromiseState.COMPLETED\n ? null\n : { Single: 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: PromiseWithResolvers<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 type CombinatorVariant =\n | \"Unknown\"\n | \"FirstCompleted\" // race\n | \"AllCompleted\" // allSettled\n | \"FirstSucceededOrAllFailed\" // any\n | \"AllSucceededOrFirstFailed\"; // all\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 private readonly combinatorVariant: CombinatorVariant,\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 combinatorVariant: CombinatorVariant,\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 combinatorVariant,\n combinatorConstructor,\n castedPromises\n );\n }\n\n unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n if (this.state === PromiseState.COMPLETED) return null;\n const children = this.childs\n .map((p) => p.unresolvedFuture())\n .filter((f): f is vm.WasmUnresolvedFuture => f !== null);\n if (children.length === 0) return null;\n return { [this.combinatorVariant]: children } as vm.WasmUnresolvedFuture;\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 unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n const inner = this.inner.unresolvedFuture();\n return inner === null ? null : { Unknown: [inner] };\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 unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n return null;\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 unresolvedFuture = restatePromise.unresolvedFuture();\n if (unresolvedFuture === null) {\n // Completed, we're good!\n return;\n }\n const doProgressResult = this.coreVm.do_progress(unresolvedFuture);\n\n if (doProgressResult === \"AnyCompleted\") {\n // Next recursion will cause the promise to do some progress\n } else if (doProgressResult === \"WaitExternalProgress\") {\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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"}
|
|
1
|
+
{"version":3,"file":"promises.js","names":["handle: number","completer: (\n value: AsyncResultValue,\n prom: PromiseWithResolvers<T>\n ) => Promise<void>","invocationIdPromise: Promise<InvocationId>","combinatorVariant: CombinatorVariant","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","ephemeralRequestTracker: EphemeralRequestTracker","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 type {\n ContextImpl,\n RunClosuresTracker,\n EphemeralRequestTracker,\n} 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 unresolvedFuture(): vm.WasmUnresolvedFuture | null;\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: PromiseWithResolvers<any> = Promise.withResolvers();\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 \"Unknown\",\n ([thisPromise, sleepPromise]: Promise<any>[]) => {\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 unresolvedFuture(): vm.WasmUnresolvedFuture | null;\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: PromiseWithResolvers<T> = Promise.withResolvers();\n\n constructor(\n ctx: ContextImpl,\n readonly handle: number,\n private readonly completer: (\n value: AsyncResultValue,\n prom: PromiseWithResolvers<T>\n ) => Promise<void>\n ) {\n super(ctx);\n }\n\n unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n return this.state === PromiseState.COMPLETED\n ? null\n : { Single: 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: PromiseWithResolvers<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 type CombinatorVariant =\n | \"Unknown\"\n | \"FirstCompleted\" // race\n | \"AllCompleted\" // allSettled\n | \"FirstSucceededOrAllFailed\" // any\n | \"AllSucceededOrFirstFailed\"; // all\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 private readonly combinatorVariant: CombinatorVariant,\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 combinatorVariant: CombinatorVariant,\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 combinatorVariant,\n combinatorConstructor,\n castedPromises\n );\n }\n\n unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n if (this.state === PromiseState.COMPLETED) return null;\n const children = this.childs\n .map((p) => p.unresolvedFuture())\n .filter((f): f is vm.WasmUnresolvedFuture => f !== null);\n if (children.length === 0) return null;\n return { [this.combinatorVariant]: children } as vm.WasmUnresolvedFuture;\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 unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n const inner = this.inner.unresolvedFuture();\n return inner === null ? null : { Unknown: [inner] };\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 unresolvedFuture(): vm.WasmUnresolvedFuture | null {\n return null;\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 ephemeralRequestTracker: EphemeralRequestTracker,\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 unresolvedFuture = restatePromise.unresolvedFuture();\n if (unresolvedFuture === null) {\n // Completed, we're good!\n return;\n }\n const doProgressResult = this.coreVm.do_progress(unresolvedFuture);\n\n if (doProgressResult === \"AnyCompleted\") {\n // Next recursion will cause the promise to do some progress\n } else if (doProgressResult === \"WaitExternalProgress\") {\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 if (\"EphemeralNotificationReady\" in doProgressResult) {\n // The notification of an ephemeral command is ready, this takes precedence over everything else.\n // Complete the related promise, then the next recursion will continue making progress.\n const completionId = doProgressResult.EphemeralNotificationReady;\n await this.ephemeralRequestTracker.complete(\n completionId,\n this.coreVm.take_ephemeral_notification(completionId)\n );\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":";;;;AAoCA,SAAgB,iBAAgC;AAC9C,QAAO,IAAI,cAAiB,GAAG;;;;;;;;AAajC,SAAgB,iBAAoB,GAAuC;AACzE,QAAO,aAAa;;AAGtB,IAAK,wDAAL;AACE;AACA;;EAFG;AAKL,IAAsB,yBAAtB,MAA6E;AAuC7E,MAAM,qBAAqB,OAAO,iBAAiB;AAEnD,SAAS,eAAe,GAAiC;AAEvD,QAAO,EAAE;;AAGX,IAAe,qBAAf,cAA6C,uBAA0B;CACrE,CAAC;CACD,AAAQ;CACR,AAAQ,gBAA2C,QAAQ,eAAe;CAE1E,AAAU,YAAY,KAAkB;AACtC,SAAO;AACP,OAAK,sBAAsB;;CAK7B,KACE,aACA,YAC8B;AAC9B,OAAK,iBACH,KAAK,kBACL,KAAK,oBAAoB,iBACtB,WAAW,KAAK,CAChB,YAAY,GAAG;AACpB,SAAO,KAAK,8BAA8B,CAAC,KAAK,aAAa,WAAW;;CAG1E,MACE,YACsB;AACtB,OAAK,iBACH,KAAK,kBACL,KAAK,oBAAoB,iBACtB,WAAW,KAAK,CAChB,YAAY,GAAG;AACpB,SAAO,KAAK,8BAA8B,CAAC,MAAM,WAAW;;CAG9D,QAAQ,WAA6C;AACnD,OAAK,iBACH,KAAK,kBACL,KAAK,oBAAoB,iBACtB,WAAW,KAAK,CAChB,YAAY,GAAG;AACpB,SAAO,KAAK,8BAA8B,CAAC,QAAQ,UAAU;;CAG/D,AAAQ,+BAA2C;AACjD,SAAO,QAAQ,KAAK,CAClB,KAAK,cAAc,SACnB,KAAK,eAAe,CACrB,CAAC;;CAKJ,UAAU,UAAgD;AACxD,SAAO,IAAI,yBACT,KAAK,qBACL,YACC,CAAC,aAAa,kBAAkC;AAC/C,UAAO,IAAI,SAAS,SAAS,WAAW;AACtC,gBAAa,KAAK,SAAS,OAAO;AAClC,iBAAc,WAAW;AACvB,YAAO,IAAI,cAAc,CAAC;OACzB,OAAO;KACV;KAEJ,CACE,MACA,KAAK,oBAAoB,MAAM,SAAS,CACzC,CACF;;CAGH,IAAO,QAAsE;AAC3E,SAAO,IAAI,qBAAqB,KAAK,qBAAqB,MAAM,OAAO;;CAGzE,YAAY;AACV,OAAK,cAAc,OAAO,IAAI,gBAAgB,CAAC;;;AAYnD,IAAa,uBAAb,cAA6C,mBAAsB;CACjE,AAAQ,QAAsB,aAAa;CAC3C,AAAQ,qBAA8C,QAAQ,eAAe;CAE7E,YACE,KACA,AAASA,QACT,AAAiBC,WAIjB;AACA,QAAM,IAAI;EAND;EACQ;;CAQnB,mBAAmD;AACjD,SAAO,KAAK,UAAU,aAAa,YAC/B,OACA,EAAE,QAAQ,KAAK,QAAQ;;CAG7B,MAAM,cAA6B;AACjC,MAAI,KAAK,UAAU,aAAa,UAC9B;EAEF,MAAM,eAAe,KAAK,oBAAoB,OAAO,kBACnD,KAAK,OACN;AACD,MAAI,iBAAiB,WACnB;AAEF,OAAK,QAAQ,aAAa;AAC1B,QAAM,KAAK,UAAU,cAAc,KAAK,mBAAmB;;CAG7D,gBAA4B;AAC1B,SAAO,KAAK,mBAAmB;;CAGjC,cAAuB;AACrB,SAAO,KAAK,UAAU,aAAa;;CAGrC,CAAU,OAAO,eAAe;;AAGlC,IAAa,2BAAb,cACU,qBAEV;CACE,YACE,KACA,QACA,WAIA,AAAiBC,qBACjB;AACA,QAAM,KAAK,QAAQ,UAAU;EAFZ;;CAKnB,IAAI,eAAsC;AACxC,SAAO,KAAK;;;AAWhB,IAAa,2BAAb,MAAa,iCAAiC,mBAAwB;CACpE,AAAQ,QAAsB,aAAa;CAC3C,AAAiB;CAEjB,YACE,KACA,AAAiBC,mBACjB,uBACA,AAASC,QACT;AACA,QAAM,IAAI;EAJO;EAER;AAGT,OAAK,oBAAoB,sBACvB,OAAO,KAAK,MAAM,EAAE,eAAe,CAAC,CACrC,CAAC,cAAc;AACd,QAAK,QAAQ,aAAa;IAC1B;;CAIJ,OAAc,aACZ,mBACA,uBACA,UACyB;EACzB,MAAMC,iBAAgD,EAAE;EACxD,IAAIC,eAAwC;AAE5C,OAAK,MAAM,CAAC,KAAK,YAAY,SAAS,SAAS,EAAE;AAC/C,OAAI,CAAC,iBAAiB,QAAQ,CAC5B,OAAM,IAAI,MACR,iBAAiB,IAAI,0FACtB;YACQ,iBAAiB,OAC1B,gBAAe,eAAe,QAAQ;QACjC;IACL,MAAM,cAAc,eAAe,QAAQ;AAC3C,QAAI,gBAAgB,UAAa,gBAAgB,aAC/C,OAAM,IAAI,MACR,yFACD;;AAGL,kBAAe,KAAK,QAAuC;;AAG7D,MAAI,iBAAiB,OAInB,QAAO,oBAAoB,YACzB,sBAAsB,eAAe,EACrC,KACD;AAGH,SAAO,IAAI,yBACT,cACA,mBACA,uBACA,eACD;;CAGH,mBAAmD;AACjD,MAAI,KAAK,UAAU,aAAa,UAAW,QAAO;EAClD,MAAM,WAAW,KAAK,OACnB,KAAK,MAAM,EAAE,kBAAkB,CAAC,CAChC,QAAQ,MAAoC,MAAM,KAAK;AAC1D,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,SAAO,GAAG,KAAK,oBAAoB,UAAU;;CAG/C,MAAM,cAA6B;AACjC,QAAM,QAAQ,WAAW,KAAK,OAAO,KAAK,MAAM,EAAE,aAAa,CAAC,CAAC;;CAGnE,gBAAkC;AAChC,SAAO,KAAK;;CAGd,CAAU,OAAO,eAAe;;AAGlC,IAAa,uBAAb,cAAgD,mBAAsB;CACpE,AAAQ;CAMR,AAAQ;CAER,YACE,KACA,AAASC,OACT,QACA;AACA,QAAM,IAAI;EAHD;AAIT,OAAK,uBAAuB,OAAW,YAA4B;AACjE,OAAI;AACF,WAAO,QAAQ,QAAQ,OAAO,OAAO,QAAQ,CAAC;YACvC,GAAG;AACV,QAAI,aAAa,cACf,QAAO,QAAQ,OAAO,EAAE;SACnB;AACL,SAAI,aAAa,EAAE;AACnB,YAAO,gBAAgB;;;;;CAM/B,MAAM,cAA6B;AACjC,QAAM,KAAK,MAAM,aAAa;;CAGhC,mBAAmD;EACjD,MAAM,QAAQ,KAAK,MAAM,kBAAkB;AAC3C,SAAO,UAAU,OAAO,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE;;CAGrD,gBAA4B;AAC1B,SAAQ,KAAK,mBAAmB,KAAK,oBAAoB;;CAG3D,AAAQ,qBAAiC;EACvC,MAAM,gBAAgB,KAAK;AAC3B,SAAO,KAAK,MAAM,eAAe,CAAC,MAC/B,MAAM,cAAc,GAAG,OAAU,GACjC,UAAU;AACT,OAAI,iBAAiB,aACnB,QAAO,cAAc,QAAW,MAAM;OAGtC,OAAM;IAGX;;CAGH,CAAU,OAAO,eAAe;;AAGlC,IAAa,sBAAb,MAAa,4BAA+B,uBAA0B;CACpE,AAAQ;CAER,AAAQ,YAKN,AAAiBC,gBACjB,AAAiBC,SACjB;AACA,SAAO;EAHU;EACA;;CAKnB,IAAY,eAA2B;AACrC,SAAQ,KAAK,kBAAkB,KAAK,gBAAgB;;CAGtD,OAAO,QAAW,OAA2C;AAC3D,SAAO,IAAI,0BAA0B,QAAQ,QAAQ,MAAM,EAAE,KAAK;;CAGpE,OAAO,OAAkB,QAA+C;AACtE,SAAO,IAAI,0BAA6B,QAAQ,OAAO,OAAO,EAAE,KAAK;;CAGvE,OAAO,UAAqC;AAC1C,SAAO,IAAI,0BAA6B,gBAAmB,EAAE,MAAM;;CAGrE,OAAO,YACL,SACA,SACwB;AACxB,SAAO,IAAI,0BAA0B,SAAS,QAAQ;;CAKxD,KACE,aACA,YAC8B;AAC9B,SAAO,KAAK,aAAa,KAAK,aAAa,WAAW;;CAGxD,MACE,YACsB;AACtB,SAAO,KAAK,aAAa,MAAM,WAAW;;CAG5C,QAAQ,WAA6C;AACnD,SAAO,KAAK,aAAa,QAAQ,UAAU;;CAK7C,YAA+B;AAC7B,MAAI,KAAK,QAAS,QAAO;AACzB,SAAO,oBAAoB,OAAO,IAAI,cAAc,CAAC;;CAGvD,IAAO,QAAsE;AAC3E,MAAI,CAAC,KAAK,QAAS,QAAO;EAC1B,MAAM,mBAAmB,KAAK;AAC9B,SAAO,IAAI,0BAEP,iBAAiB,MACd,UAAU,OAAO,OAAO,OAAU,GAClC,WAAW,OAAO,QAAW,OAAwB,CACvD,EACH,KAAK,QACN;;CAGH,YAAY;CAEZ,gBAA4B;AAC1B,SAAO,KAAK;;CAGd,cAA6B;AAC3B,SAAO,QAAQ,SAAS;;CAG1B,mBAAmD;AACjD,SAAO;;CAGT,CAAU,OAAO,eAAe;;;;;AAMlC,IAAa,mBAAb,MAA8B;CAC5B,YACE,AAAiBC,QACjB,AAAiBC,YACjB,AAAiBC,oBACjB,AAAiBC,yBACjB,AAAiBC,yBACjB,AAAiBC,eACjB;EANiB;EACA;EACA;EACA;EACA;EACA;;CAGnB,MAAM,WAAW,gBAAiD;AAEhE,QAAM,KAAK,WAAW,mBAAmB;AACzC,QAAM,KAAK,gBAAgB,eAAe;;CAG5C,MAAc,gBACZ,gBACA;AAEA,MAAI;AACF,SAAM,eAAe,aAAa;WAC3B,GAAG;AAGV,QAAK,cAAc,EAAE;AACrB,UAAO,QAAQ,SAAS;;AAS1B,SAAO,cAAc,CAAC,KAAK,YAAY;AACrC,OAAI;IAEF,MAAM,mBAAmB,eAAe,kBAAkB;AAC1D,QAAI,qBAAqB,KAEvB;IAEF,MAAM,mBAAmB,KAAK,OAAO,YAAY,iBAAiB;AAElE,QAAI,qBAAqB,gBAAgB,YAE9B,qBAAqB,wBAAwB;AAYtD,WAAM,KAAK,WAAW,mBAAmB;AAGzC,WAAM,KAAK,wBAAwB,WAAW;eACrC,qBAAqB,wBAAwB;AACtD,oBAAe,WAAW;AAC1B;eACS,gCAAgC,kBAAkB;KAG3D,MAAM,eAAe,iBAAiB;AACtC,WAAM,KAAK,wBAAwB,SACjC,cACA,KAAK,OAAO,4BAA4B,aAAa,CACtD;WACI;AAEL,UAAK,mBAAmB,WAAW,iBAAiB,WAAW;AAE/D,WAAM,cAAc;;AAItB,UAAM,KAAK,gBAAgB,eAAe;YACnC,GAAG;AAEV,SAAK,cAAc,EAAE;;IAEvB"}
|
package/dist/types/errors.cjs
CHANGED
|
@@ -105,7 +105,7 @@ var RetryableError = class RetryableError extends RestateError {
|
|
|
105
105
|
*
|
|
106
106
|
* You can wrap another error using {@link from}.
|
|
107
107
|
*/
|
|
108
|
-
var PauseError = class extends RestateError {
|
|
108
|
+
var PauseError = class PauseError extends RestateError {
|
|
109
109
|
name = "PauseError";
|
|
110
110
|
constructor(message, options) {
|
|
111
111
|
super(message, {
|
|
@@ -118,7 +118,7 @@ var PauseError = class extends RestateError {
|
|
|
118
118
|
*/
|
|
119
119
|
static from(cause) {
|
|
120
120
|
const error = ensureError(cause);
|
|
121
|
-
return new
|
|
121
|
+
return new PauseError(error.message, {
|
|
122
122
|
errorCode: error["errorCode"],
|
|
123
123
|
cause
|
|
124
124
|
});
|
package/dist/types/errors.d.cts
CHANGED
|
@@ -85,7 +85,7 @@ declare class PauseError extends RestateError {
|
|
|
85
85
|
/**
|
|
86
86
|
* Create a `PauseError` from the given cause.
|
|
87
87
|
*/
|
|
88
|
-
static from(cause: any):
|
|
88
|
+
static from(cause: any): PauseError;
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* Returns true if the error indicates the current attempt is ending without
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.cts","names":[],"sources":["../../src/types/errors.ts"],"sourcesContent":[],"mappings":";;;;AAwHa,cA3CA,YAAA,SAAqB,KAAA,CA2Ca;EAWlC,SAAA,IAAA,EAAA,MAAe;EAQX,IAAA,EAAA,MAAA;EAaJ,WAAA,CAAA,OAAe,EAAA,MAAA,EAAA,OAuBQ,CAvBR,EAAA;IAGJ,SAAA,CAAA,EAAA,MAAA;IAIV,KAAA,CAAA,EAAA,GAAA;EAgBsB,CAAA;;;;AAgBpC;
|
|
1
|
+
{"version":3,"file":"errors.d.cts","names":[],"sources":["../../src/types/errors.ts"],"sourcesContent":[],"mappings":";;;;AAwHa,cA3CA,YAAA,SAAqB,KAAA,CA2Ca;EAWlC,SAAA,IAAA,EAAA,MAAe;EAQX,IAAA,EAAA,MAAA;EAaJ,WAAA,CAAA,OAAe,EAAA,MAAA,EAAA,OAuBQ,CAvBR,EAAA;IAGJ,SAAA,CAAA,EAAA,MAAA;IAIV,KAAA,CAAA,EAAA,GAAA;EAgBsB,CAAA;;;;AAgBpC;AAuCA;;cA1Ia,aAAA,SAAsB,YAAA;;sBAEN;;;;;;;;;;;;eAeZ;;;;;;cAWJ,YAAA,SAAqB,aAAA;;;;;;;cAWrB,cAAA,SAAuB,aAAA;;;;UAQnB,qBAAA;;;;eAIF;;;;;;;;cASF,cAAA,SAAuB,YAAA;;wBAGZ;yCAIV;;;;;;;oCAgBsB,wBAAwB;;;;;;;;cAgB/C,UAAA,SAAmB,YAAA;;;;;;;;;2BAoBL;;;;;;;;;;;iBAmBX,gBAAA"}
|
package/dist/types/errors.d.ts
CHANGED
|
@@ -85,7 +85,7 @@ declare class PauseError extends RestateError {
|
|
|
85
85
|
/**
|
|
86
86
|
* Create a `PauseError` from the given cause.
|
|
87
87
|
*/
|
|
88
|
-
static from(cause: any):
|
|
88
|
+
static from(cause: any): PauseError;
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* Returns true if the error indicates the current attempt is ending without
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/types/errors.ts"],"sourcesContent":[],"mappings":";;;;AAwHa,cA3CA,YAAA,SAAqB,KAAA,CA2Ca;EAWlC,SAAA,IAAA,EAAA,MAAe;EAQX,IAAA,EAAA,MAAA;EAaJ,WAAA,CAAA,OAAe,EAAA,MAAA,EAAA,OAuBQ,CAvBR,EAAA;IAGJ,SAAA,CAAA,EAAA,MAAA;IAIV,KAAA,CAAA,EAAA,GAAA;EAgBsB,CAAA;;;;AAgBpC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/types/errors.ts"],"sourcesContent":[],"mappings":";;;;AAwHa,cA3CA,YAAA,SAAqB,KAAA,CA2Ca;EAWlC,SAAA,IAAA,EAAA,MAAe;EAQX,IAAA,EAAA,MAAA;EAaJ,WAAA,CAAA,OAAe,EAAA,MAAA,EAAA,OAuBQ,CAvBR,EAAA;IAGJ,SAAA,CAAA,EAAA,MAAA;IAIV,KAAA,CAAA,EAAA,GAAA;EAgBsB,CAAA;;;;AAgBpC;AAuCA;;cA1Ia,aAAA,SAAsB,YAAA;;sBAEN;;;;;;;;;;;;eAeZ;;;;;;cAWJ,YAAA,SAAqB,aAAA;;;;;;;cAWrB,cAAA,SAAuB,aAAA;;;;UAQnB,qBAAA;;;;eAIF;;;;;;;;cASF,cAAA,SAAuB,YAAA;;wBAGZ;yCAIV;;;;;;;oCAgBsB,wBAAwB;;;;;;;;cAgB/C,UAAA,SAAmB,YAAA;;;;;;;;;2BAoBL;;;;;;;;;;;iBAmBX,gBAAA"}
|
package/dist/types/errors.js
CHANGED
|
@@ -104,7 +104,7 @@ var RetryableError = class RetryableError extends RestateError {
|
|
|
104
104
|
*
|
|
105
105
|
* You can wrap another error using {@link from}.
|
|
106
106
|
*/
|
|
107
|
-
var PauseError = class extends RestateError {
|
|
107
|
+
var PauseError = class PauseError extends RestateError {
|
|
108
108
|
name = "PauseError";
|
|
109
109
|
constructor(message, options) {
|
|
110
110
|
super(message, {
|
|
@@ -117,7 +117,7 @@ var PauseError = class extends RestateError {
|
|
|
117
117
|
*/
|
|
118
118
|
static from(cause) {
|
|
119
119
|
const error = ensureError(cause);
|
|
120
|
-
return new
|
|
120
|
+
return new PauseError(error.message, {
|
|
121
121
|
errorCode: error["errorCode"],
|
|
122
122
|
cause
|
|
123
123
|
});
|
package/dist/types/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../../src/types/errors.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 { Duration } from \"@restatedev/restate-sdk-core\";\n\nexport const INTERNAL_ERROR_CODE = 500;\nexport const TIMEOUT_ERROR_CODE = 408;\nexport const CANCEL_ERROR_CODE = 409;\nexport const UNKNOWN_ERROR_CODE = 500;\n\n// From shared core!\nexport const CLOSED_ERROR_CODE = 598;\nexport const SUSPENDED_ERROR_CODE = 599;\n\nexport function ensureError(\n e: unknown,\n asTerminalError?: (error: any) => TerminalError | undefined\n): Error {\n if (e instanceof TerminalError) {\n return e;\n }\n // Try convert to terminal error\n const maybeTerminalError = asTerminalError ? asTerminalError(e) : undefined;\n if (maybeTerminalError) {\n return maybeTerminalError;\n }\n\n if (e instanceof Error) {\n return e;\n }\n if (typeof e === \"object\" && e !== null && \"code\" in e && \"message\" in e) {\n // This is an error from the VM\n return new RestateError(e.message as string, {\n errorCode: e.code as number,\n });\n }\n\n // None of the types we know\n let msg;\n try {\n msg = JSON.stringify(e);\n } catch {\n msg = \"(no JSON representation)\";\n }\n\n return new Error(\"Non-Error value: \" + msg);\n}\n\nexport function logError(log: Console, e: unknown) {\n if (e instanceof RestateError) {\n if (e.code === SUSPENDED_ERROR_CODE) {\n log.info(\"Invocation suspended\");\n return;\n } else if (e.code === CLOSED_ERROR_CODE) {\n log.error(\n \"DANGER! The invocation is closed, but some related operation is still running. \\n\" +\n \"This might indicate that a RestatePromise is being awaited on an asynchronous task, outside the handler, or you're awaiting a RestatePromise inside a ctx.run.\\n\" +\n \"This is dangerous, and can lead the service to deadlock. Please fix the issue.\\n\" +\n \"Diagnostic: \",\n e\n );\n return;\n }\n }\n log.warn(\"Error when processing a Restate context operation.\\n\", e);\n}\n\nexport class RestateError extends Error {\n public readonly code: number;\n public override name = \"RestateError\";\n\n constructor(message: string, options?: { errorCode?: number; cause?: any }) {\n super(message, { cause: options?.cause });\n this.code = options?.errorCode ?? INTERNAL_ERROR_CODE;\n }\n}\n\n/**\n * Does not lead to Restate retries.\n *\n * Leads to an output message with a failure defined.\n */\nexport class TerminalError extends RestateError {\n public override name = \"TerminalError\";\n public readonly metadata?: Record<string, string>;\n\n constructor(\n message: string,\n options?: {\n /**\n * Error code. This should be an HTTP status code, and in case the service was invoked from the ingress, this will be propagated back to the caller.\n */\n errorCode?: number;\n /**\n * Metadata key-value pairs to attach to the terminal error.\n * These will be recorded together with error message and code.\n *\n * **Note **: requires Restate 1.6+.\n */\n metadata?: Record<string, string>;\n }\n ) {\n super(message, options);\n this.metadata = options?.metadata ?? {};\n }\n}\n\n/**\n * Returned by `RestatePromise.withTimeout` when the timeout is reached.\n */\nexport class TimeoutError extends TerminalError {\n public override name = \"TimeoutError\";\n\n constructor() {\n super(\"Timeout occurred\", { errorCode: TIMEOUT_ERROR_CODE });\n }\n}\n\n/**\n * Returned when the invocation was cancelled.\n */\nexport class CancelledError extends TerminalError {\n public override name = \"CancelledError\";\n\n constructor() {\n super(\"Cancelled\", { errorCode: CANCEL_ERROR_CODE });\n }\n}\n\nexport interface RetryableErrorOptions {\n /**\n * In how long it should retry.\n */\n retryAfter?: Duration | number;\n}\n\n/**\n * Error that Restate will retry. By using this error type within a `ctx.run` closure,\n * you can dynamically provide the retry delay specified in {@link RetryableErrorOptions}.\n *\n * You can wrap another error using {@link from}.\n */\nexport class RetryableError extends RestateError {\n public override name = \"RetryableError\";\n\n readonly retryAfter?: Duration | number;\n\n constructor(\n message: string,\n options?: RetryableErrorOptions & {\n errorCode?: number;\n cause?: any;\n }\n ) {\n super(message, {\n errorCode: options?.errorCode,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cause: options?.cause,\n });\n this.retryAfter = options?.retryAfter;\n }\n\n /**\n * Create a `RetryableError` from the given cause.\n */\n static from(cause: any, options?: RetryableErrorOptions): RetryableError {\n const error = ensureError(cause);\n return new RetryableError(error.message, {\n errorCode: error[\"errorCode\" as keyof typeof error] as number,\n cause: cause,\n ...options,\n });\n }\n}\n\n/**\n * When thrown, Restate will pause the execution of the current invocation.\n * This error type MUST be used only within a `ctx.run` closure. If thrown outside a `ctx.run` closure, pause will be ignored.\n *\n * You can wrap another error using {@link from}.\n */\nexport class PauseError extends RestateError {\n public override name = \"PauseError\";\n\n constructor(\n message: string,\n options?: {\n errorCode?: number;\n cause?: any;\n }\n ) {\n super(message, {\n errorCode: options?.errorCode,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cause: options?.cause,\n });\n }\n\n /**\n * Create a `PauseError` from the given cause.\n */\n static from(cause: any):
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../../src/types/errors.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 { Duration } from \"@restatedev/restate-sdk-core\";\n\nexport const INTERNAL_ERROR_CODE = 500;\nexport const TIMEOUT_ERROR_CODE = 408;\nexport const CANCEL_ERROR_CODE = 409;\nexport const UNKNOWN_ERROR_CODE = 500;\n\n// From shared core!\nexport const CLOSED_ERROR_CODE = 598;\nexport const SUSPENDED_ERROR_CODE = 599;\n\nexport function ensureError(\n e: unknown,\n asTerminalError?: (error: any) => TerminalError | undefined\n): Error {\n if (e instanceof TerminalError) {\n return e;\n }\n // Try convert to terminal error\n const maybeTerminalError = asTerminalError ? asTerminalError(e) : undefined;\n if (maybeTerminalError) {\n return maybeTerminalError;\n }\n\n if (e instanceof Error) {\n return e;\n }\n if (typeof e === \"object\" && e !== null && \"code\" in e && \"message\" in e) {\n // This is an error from the VM\n return new RestateError(e.message as string, {\n errorCode: e.code as number,\n });\n }\n\n // None of the types we know\n let msg;\n try {\n msg = JSON.stringify(e);\n } catch {\n msg = \"(no JSON representation)\";\n }\n\n return new Error(\"Non-Error value: \" + msg);\n}\n\nexport function logError(log: Console, e: unknown) {\n if (e instanceof RestateError) {\n if (e.code === SUSPENDED_ERROR_CODE) {\n log.info(\"Invocation suspended\");\n return;\n } else if (e.code === CLOSED_ERROR_CODE) {\n log.error(\n \"DANGER! The invocation is closed, but some related operation is still running. \\n\" +\n \"This might indicate that a RestatePromise is being awaited on an asynchronous task, outside the handler, or you're awaiting a RestatePromise inside a ctx.run.\\n\" +\n \"This is dangerous, and can lead the service to deadlock. Please fix the issue.\\n\" +\n \"Diagnostic: \",\n e\n );\n return;\n }\n }\n log.warn(\"Error when processing a Restate context operation.\\n\", e);\n}\n\nexport class RestateError extends Error {\n public readonly code: number;\n public override name = \"RestateError\";\n\n constructor(message: string, options?: { errorCode?: number; cause?: any }) {\n super(message, { cause: options?.cause });\n this.code = options?.errorCode ?? INTERNAL_ERROR_CODE;\n }\n}\n\n/**\n * Does not lead to Restate retries.\n *\n * Leads to an output message with a failure defined.\n */\nexport class TerminalError extends RestateError {\n public override name = \"TerminalError\";\n public readonly metadata?: Record<string, string>;\n\n constructor(\n message: string,\n options?: {\n /**\n * Error code. This should be an HTTP status code, and in case the service was invoked from the ingress, this will be propagated back to the caller.\n */\n errorCode?: number;\n /**\n * Metadata key-value pairs to attach to the terminal error.\n * These will be recorded together with error message and code.\n *\n * **Note **: requires Restate 1.6+.\n */\n metadata?: Record<string, string>;\n }\n ) {\n super(message, options);\n this.metadata = options?.metadata ?? {};\n }\n}\n\n/**\n * Returned by `RestatePromise.withTimeout` when the timeout is reached.\n */\nexport class TimeoutError extends TerminalError {\n public override name = \"TimeoutError\";\n\n constructor() {\n super(\"Timeout occurred\", { errorCode: TIMEOUT_ERROR_CODE });\n }\n}\n\n/**\n * Returned when the invocation was cancelled.\n */\nexport class CancelledError extends TerminalError {\n public override name = \"CancelledError\";\n\n constructor() {\n super(\"Cancelled\", { errorCode: CANCEL_ERROR_CODE });\n }\n}\n\nexport interface RetryableErrorOptions {\n /**\n * In how long it should retry.\n */\n retryAfter?: Duration | number;\n}\n\n/**\n * Error that Restate will retry. By using this error type within a `ctx.run` closure,\n * you can dynamically provide the retry delay specified in {@link RetryableErrorOptions}.\n *\n * You can wrap another error using {@link from}.\n */\nexport class RetryableError extends RestateError {\n public override name = \"RetryableError\";\n\n readonly retryAfter?: Duration | number;\n\n constructor(\n message: string,\n options?: RetryableErrorOptions & {\n errorCode?: number;\n cause?: any;\n }\n ) {\n super(message, {\n errorCode: options?.errorCode,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cause: options?.cause,\n });\n this.retryAfter = options?.retryAfter;\n }\n\n /**\n * Create a `RetryableError` from the given cause.\n */\n static from(cause: any, options?: RetryableErrorOptions): RetryableError {\n const error = ensureError(cause);\n return new RetryableError(error.message, {\n errorCode: error[\"errorCode\" as keyof typeof error] as number,\n cause: cause,\n ...options,\n });\n }\n}\n\n/**\n * When thrown, Restate will pause the execution of the current invocation.\n * This error type MUST be used only within a `ctx.run` closure. If thrown outside a `ctx.run` closure, pause will be ignored.\n *\n * You can wrap another error using {@link from}.\n */\nexport class PauseError extends RestateError {\n public override name = \"PauseError\";\n\n constructor(\n message: string,\n options?: {\n errorCode?: number;\n cause?: any;\n }\n ) {\n super(message, {\n errorCode: options?.errorCode,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cause: options?.cause,\n });\n }\n\n /**\n * Create a `PauseError` from the given cause.\n */\n static from(cause: any): PauseError {\n const error = ensureError(cause);\n return new PauseError(error.message, {\n errorCode: error[\"errorCode\" as keyof typeof error] as number,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n cause: cause,\n });\n }\n}\n\n/**\n * Returns true if the error indicates the current attempt is ending without\n * a failure — e.g. the runtime suspended the invocation (waiting for\n * `ctx.sleep()` or `ctx.call()`), or the connection was dropped (kill).\n *\n * Use this in handler interceptor catch blocks to distinguish attempt-ending\n * signals from real errors (e.g. to avoid logging it as a failure or to set\n * a neutral span status).\n */\nexport function isSuspendedError(e: unknown): boolean {\n return e instanceof RestateError && e.code === SUSPENDED_ERROR_CODE;\n}\n"],"mappings":";AAeA,MAAa,sBAAsB;AACnC,MAAa,qBAAqB;AAClC,MAAa,oBAAoB;AACjC,MAAa,qBAAqB;AAGlC,MAAa,oBAAoB;AACjC,MAAa,uBAAuB;AAEpC,SAAgB,YACd,GACA,iBACO;AACP,KAAI,aAAa,cACf,QAAO;CAGT,MAAM,qBAAqB,kBAAkB,gBAAgB,EAAE,GAAG;AAClE,KAAI,mBACF,QAAO;AAGT,KAAI,aAAa,MACf,QAAO;AAET,KAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,UAAU,KAAK,aAAa,EAErE,QAAO,IAAI,aAAa,EAAE,SAAmB,EAC3C,WAAW,EAAE,MACd,CAAC;CAIJ,IAAI;AACJ,KAAI;AACF,QAAM,KAAK,UAAU,EAAE;SACjB;AACN,QAAM;;AAGR,wBAAO,IAAI,MAAM,sBAAsB,IAAI;;AAG7C,SAAgB,SAAS,KAAc,GAAY;AACjD,KAAI,aAAa,cACf;MAAI,EAAE,SAAS,sBAAsB;AACnC,OAAI,KAAK,uBAAuB;AAChC;aACS,EAAE,SAAS,mBAAmB;AACvC,OAAI,MACF,iVAIA,EACD;AACD;;;AAGJ,KAAI,KAAK,wDAAwD,EAAE;;AAGrE,IAAa,eAAb,cAAkC,MAAM;CACtC,AAAgB;CAChB,AAAgB,OAAO;CAEvB,YAAY,SAAiB,SAA+C;AAC1E,QAAM,SAAS,EAAE,OAAO,SAAS,OAAO,CAAC;AACzC,OAAK,OAAO,SAAS,aAAa;;;;;;;;AAStC,IAAa,gBAAb,cAAmC,aAAa;CAC9C,AAAgB,OAAO;CACvB,AAAgB;CAEhB,YACE,SACA,SAaA;AACA,QAAM,SAAS,QAAQ;AACvB,OAAK,WAAW,SAAS,YAAY,EAAE;;;;;;AAO3C,IAAa,eAAb,cAAkC,cAAc;CAC9C,AAAgB,OAAO;CAEvB,cAAc;AACZ,QAAM,oBAAoB,EAAE,WAAW,oBAAoB,CAAC;;;;;;AAOhE,IAAa,iBAAb,cAAoC,cAAc;CAChD,AAAgB,OAAO;CAEvB,cAAc;AACZ,QAAM,aAAa,EAAE,WAAW,mBAAmB,CAAC;;;;;;;;;AAiBxD,IAAa,iBAAb,MAAa,uBAAuB,aAAa;CAC/C,AAAgB,OAAO;CAEvB,AAAS;CAET,YACE,SACA,SAIA;AACA,QAAM,SAAS;GACb,WAAW,SAAS;GAEpB,OAAO,SAAS;GACjB,CAAC;AACF,OAAK,aAAa,SAAS;;;;;CAM7B,OAAO,KAAK,OAAY,SAAiD;EACvE,MAAM,QAAQ,YAAY,MAAM;AAChC,SAAO,IAAI,eAAe,MAAM,SAAS;GACvC,WAAW,MAAM;GACV;GACP,GAAG;GACJ,CAAC;;;;;;;;;AAUN,IAAa,aAAb,MAAa,mBAAmB,aAAa;CAC3C,AAAgB,OAAO;CAEvB,YACE,SACA,SAIA;AACA,QAAM,SAAS;GACb,WAAW,SAAS;GAEpB,OAAO,SAAS;GACjB,CAAC;;;;;CAMJ,OAAO,KAAK,OAAwB;EAClC,MAAM,QAAQ,YAAY,MAAM;AAChC,SAAO,IAAI,WAAW,MAAM,SAAS;GACnC,WAAW,MAAM;GAEV;GACR,CAAC;;;;;;;;;;;;AAaN,SAAgB,iBAAiB,GAAqB;AACpD,QAAO,aAAa,gBAAgB,EAAE,SAAS"}
|
package/dist/types/interface.cjs
CHANGED
|
@@ -10,6 +10,8 @@ function implement(contract, config) {
|
|
|
10
10
|
const sdkOpts = {
|
|
11
11
|
input: desc._inputSerde,
|
|
12
12
|
output: desc._outputSerde,
|
|
13
|
+
description: desc._description,
|
|
14
|
+
metadata: desc._metadata,
|
|
13
15
|
...perHandlerOpts?.[name] ?? {}
|
|
14
16
|
};
|
|
15
17
|
if (contract._kind === "service") coreHandlers[name] = require_rpc.handlers.handler(sdkOpts, fn);
|
|
@@ -19,8 +21,8 @@ function implement(contract, config) {
|
|
|
19
21
|
const common = {
|
|
20
22
|
name: contract.name,
|
|
21
23
|
handlers: coreHandlers,
|
|
22
|
-
description: config.description,
|
|
23
|
-
metadata: config.metadata,
|
|
24
|
+
description: config.description ?? contract._description,
|
|
25
|
+
metadata: config.metadata ?? contract._metadata,
|
|
24
26
|
options: serviceOptions
|
|
25
27
|
};
|
|
26
28
|
const def = contract._kind === "service" ? require_rpc.service(common) : contract._kind === "object" ? require_rpc.object(common) : require_rpc.workflow(common);
|
package/dist/types/interface.js
CHANGED
|
@@ -10,6 +10,8 @@ function implement(contract, config) {
|
|
|
10
10
|
const sdkOpts = {
|
|
11
11
|
input: desc._inputSerde,
|
|
12
12
|
output: desc._outputSerde,
|
|
13
|
+
description: desc._description,
|
|
14
|
+
metadata: desc._metadata,
|
|
13
15
|
...perHandlerOpts?.[name] ?? {}
|
|
14
16
|
};
|
|
15
17
|
if (contract._kind === "service") coreHandlers[name] = handlers.handler(sdkOpts, fn);
|
|
@@ -19,8 +21,8 @@ function implement(contract, config) {
|
|
|
19
21
|
const common = {
|
|
20
22
|
name: contract.name,
|
|
21
23
|
handlers: coreHandlers,
|
|
22
|
-
description: config.description,
|
|
23
|
-
metadata: config.metadata,
|
|
24
|
+
description: config.description ?? contract._description,
|
|
25
|
+
metadata: config.metadata ?? contract._metadata,
|
|
24
26
|
options: serviceOptions
|
|
25
27
|
};
|
|
26
28
|
const def = contract._kind === "service" ? service(common) : contract._kind === "object" ? object(common) : workflow(common);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.js","names":["coreHandlers: Record<string, any>"],"sources":["../../src/types/interface.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2026 - 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/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument */\n\nimport type {\n Context,\n ObjectContext,\n ObjectSharedContext,\n WorkflowContext,\n WorkflowSharedContext,\n} from \"../context.js\";\nimport type {\n ServiceDefinition,\n VirtualObjectDefinition,\n WorkflowDefinition,\n Descriptor,\n HandlerDescriptor,\n ServiceDescriptor,\n ObjectDescriptor,\n WorkflowDescriptor,\n InferInput,\n InferOutput,\n} from \"@restatedev/restate-sdk-core\";\nimport {\n handlers,\n service,\n object,\n workflow,\n type ServiceHandlerOpts,\n type ObjectHandlerOpts,\n type WorkflowHandlerOpts,\n type ServiceOptions,\n type ObjectOptions,\n type WorkflowOptions,\n} from \"./rpc.js\";\n\n// =============================================================================\n// implement() — provide handler implementations for a service interface\n// (contract) declared with `iface` (see @restatedev/restate-sdk-core), and\n// obtain a normal, bindable service/object/workflow definition.\n// =============================================================================\n\n/** @internal A handler function whose input argument is dropped when `I` is `void`. */\nexport type FnOf<C, I, O> = [I] extends [void]\n ? (ctx: C) => Promise<O>\n : (ctx: C, input: I) => Promise<O>;\n\n/** @internal */\nexport type ServiceImplHandlers<H extends Record<string, HandlerDescriptor>> = {\n [K in keyof H]: FnOf<Context, InferInput<H[K]>, InferOutput<H[K]>>;\n};\n\n/** @internal Object handler contexts follow the descriptor's shared flag. */\nexport type ObjectImplHandlers<H extends Record<string, HandlerDescriptor>> = {\n [K in keyof H]: H[K] extends HandlerDescriptor<any, any, infer Shared>\n ? FnOf<\n Shared extends true ? ObjectSharedContext : ObjectContext,\n InferInput<H[K]>,\n InferOutput<H[K]>\n >\n : never;\n};\n\n/** @internal `run` gets a WorkflowContext; every other handler a shared one. */\nexport type WorkflowImplHandlers<H extends Record<string, HandlerDescriptor>> =\n {\n [K in keyof H]: K extends \"run\"\n ? FnOf<WorkflowContext, InferInput<H[K]>, InferOutput<H[K]>>\n : FnOf<WorkflowSharedContext, InferInput<H[K]>, InferOutput<H[K]>>;\n };\n\n/** @internal */\nexport type ServicePerHandlerOpts = Omit<\n ServiceHandlerOpts<unknown, unknown>,\n \"input\" | \"output\"\n>;\n/** @internal */\nexport type ObjectPerHandlerOpts = Omit<\n ObjectHandlerOpts<unknown, unknown>,\n \"input\" | \"output\"\n>;\n/** @internal */\nexport type WorkflowPerHandlerOpts = Omit<\n WorkflowHandlerOpts<unknown, unknown>,\n \"input\" | \"output\"\n>;\n\nexport function implement<\n P extends string,\n H extends Record<string, HandlerDescriptor>,\n>(\n serviceInterface: ServiceDescriptor<P, H>,\n config: {\n handlers: ServiceImplHandlers<H>;\n description?: string;\n metadata?: Record<string, string>;\n options?: ServiceOptions & {\n handlers?: Partial<Record<keyof H, ServicePerHandlerOpts>>;\n };\n }\n): ServiceDefinition<P, ServiceImplHandlers<H>> & ServiceDescriptor<P, H>;\n\nexport function implement<\n P extends string,\n H extends Record<string, HandlerDescriptor>,\n>(\n objectInterface: ObjectDescriptor<P, H>,\n config: {\n handlers: ObjectImplHandlers<H>;\n description?: string;\n metadata?: Record<string, string>;\n options?: ObjectOptions & {\n handlers?: Partial<Record<keyof H, ObjectPerHandlerOpts>>;\n };\n }\n): VirtualObjectDefinition<P, ObjectImplHandlers<H>> & ObjectDescriptor<P, H>;\n\nexport function implement<\n P extends string,\n H extends Record<string, HandlerDescriptor>,\n>(\n workflowInterface: WorkflowDescriptor<P, H>,\n config: {\n handlers: WorkflowImplHandlers<H>;\n description?: string;\n metadata?: Record<string, string>;\n options?: WorkflowOptions & {\n handlers?: Partial<Record<keyof H, WorkflowPerHandlerOpts>>;\n };\n }\n): WorkflowDefinition<P, WorkflowImplHandlers<H>> & WorkflowDescriptor<P, H>;\n\nexport function implement(\n contract: Descriptor<any, any, any>,\n config: {\n handlers: Record<string, any>;\n description?: string;\n metadata?: Record<string, string>;\n options?: any;\n }\n): any {\n const { handlers: perHandlerOpts, ...serviceOptions } = config.options ?? {};\n\n const coreHandlers: Record<string, any> = {};\n for (const [name, desc] of Object.entries(\n contract._handlers as Record<string, HandlerDescriptor>\n )) {\n const fn = config.handlers[name];\n if (typeof fn !== \"function\") {\n throw new Error(`implement(): missing handler \"${name}\"`);\n }\n const sdkOpts = {\n input: desc._inputSerde,\n output: desc._outputSerde,\n ...((perHandlerOpts?.[name] as object) ?? {}),\n };\n\n if (contract._kind === \"service\") {\n coreHandlers[name] = handlers.handler(sdkOpts as any, fn);\n } else if (contract._kind === \"object\") {\n coreHandlers[name] = desc._shared\n ? handlers.object.shared(sdkOpts as any, fn)\n : handlers.object.exclusive(sdkOpts as any, fn);\n } else {\n coreHandlers[name] =\n name === \"run\"\n ? handlers.workflow.workflow(sdkOpts as any, fn)\n : handlers.workflow.shared(sdkOpts as any, fn);\n }\n }\n\n const common = {\n name: contract.name,\n handlers: coreHandlers as any,\n description: config.description,\n metadata: config.metadata,\n options: serviceOptions,\n };\n\n const def =\n contract._kind === \"service\"\n ? service(common)\n : contract._kind === \"object\"\n ? object(common)\n : workflow(common);\n\n return Object.assign(def, {\n _kind: contract._kind,\n _handlers: contract._handlers,\n });\n}\n"],"mappings":";;;AA4IA,SAAgB,UACd,UACA,QAMK;CACL,MAAM,EAAE,UAAU,eAAgB,GAAG,mBAAmB,OAAO,WAAW,EAAE;CAE5E,MAAMA,eAAoC,EAAE;AAC5C,MAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAChC,SAAS,UACV,EAAE;EACD,MAAM,KAAK,OAAO,SAAS;AAC3B,MAAI,OAAO,OAAO,WAChB,OAAM,IAAI,MAAM,iCAAiC,KAAK,GAAG;EAE3D,MAAM,UAAU;GACd,OAAO,KAAK;GACZ,QAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"interface.js","names":["coreHandlers: Record<string, any>"],"sources":["../../src/types/interface.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2026 - 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/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument */\n\nimport type {\n Context,\n ObjectContext,\n ObjectSharedContext,\n WorkflowContext,\n WorkflowSharedContext,\n} from \"../context.js\";\nimport type {\n ServiceDefinition,\n VirtualObjectDefinition,\n WorkflowDefinition,\n Descriptor,\n HandlerDescriptor,\n ServiceDescriptor,\n ObjectDescriptor,\n WorkflowDescriptor,\n InferInput,\n InferOutput,\n} from \"@restatedev/restate-sdk-core\";\nimport {\n handlers,\n service,\n object,\n workflow,\n type ServiceHandlerOpts,\n type ObjectHandlerOpts,\n type WorkflowHandlerOpts,\n type ServiceOptions,\n type ObjectOptions,\n type WorkflowOptions,\n} from \"./rpc.js\";\n\n// =============================================================================\n// implement() — provide handler implementations for a service interface\n// (contract) declared with `iface` (see @restatedev/restate-sdk-core), and\n// obtain a normal, bindable service/object/workflow definition.\n// =============================================================================\n\n/** @internal A handler function whose input argument is dropped when `I` is `void`. */\nexport type FnOf<C, I, O> = [I] extends [void]\n ? (ctx: C) => Promise<O>\n : (ctx: C, input: I) => Promise<O>;\n\n/** @internal */\nexport type ServiceImplHandlers<H extends Record<string, HandlerDescriptor>> = {\n [K in keyof H]: FnOf<Context, InferInput<H[K]>, InferOutput<H[K]>>;\n};\n\n/** @internal Object handler contexts follow the descriptor's shared flag. */\nexport type ObjectImplHandlers<H extends Record<string, HandlerDescriptor>> = {\n [K in keyof H]: H[K] extends HandlerDescriptor<any, any, infer Shared>\n ? FnOf<\n Shared extends true ? ObjectSharedContext : ObjectContext,\n InferInput<H[K]>,\n InferOutput<H[K]>\n >\n : never;\n};\n\n/** @internal `run` gets a WorkflowContext; every other handler a shared one. */\nexport type WorkflowImplHandlers<H extends Record<string, HandlerDescriptor>> =\n {\n [K in keyof H]: K extends \"run\"\n ? FnOf<WorkflowContext, InferInput<H[K]>, InferOutput<H[K]>>\n : FnOf<WorkflowSharedContext, InferInput<H[K]>, InferOutput<H[K]>>;\n };\n\n/** @internal */\nexport type ServicePerHandlerOpts = Omit<\n ServiceHandlerOpts<unknown, unknown>,\n \"input\" | \"output\"\n>;\n/** @internal */\nexport type ObjectPerHandlerOpts = Omit<\n ObjectHandlerOpts<unknown, unknown>,\n \"input\" | \"output\"\n>;\n/** @internal */\nexport type WorkflowPerHandlerOpts = Omit<\n WorkflowHandlerOpts<unknown, unknown>,\n \"input\" | \"output\"\n>;\n\nexport function implement<\n P extends string,\n H extends Record<string, HandlerDescriptor>,\n>(\n serviceInterface: ServiceDescriptor<P, H>,\n config: {\n handlers: ServiceImplHandlers<H>;\n description?: string;\n metadata?: Record<string, string>;\n options?: ServiceOptions & {\n handlers?: Partial<Record<keyof H, ServicePerHandlerOpts>>;\n };\n }\n): ServiceDefinition<P, ServiceImplHandlers<H>> & ServiceDescriptor<P, H>;\n\nexport function implement<\n P extends string,\n H extends Record<string, HandlerDescriptor>,\n>(\n objectInterface: ObjectDescriptor<P, H>,\n config: {\n handlers: ObjectImplHandlers<H>;\n description?: string;\n metadata?: Record<string, string>;\n options?: ObjectOptions & {\n handlers?: Partial<Record<keyof H, ObjectPerHandlerOpts>>;\n };\n }\n): VirtualObjectDefinition<P, ObjectImplHandlers<H>> & ObjectDescriptor<P, H>;\n\nexport function implement<\n P extends string,\n H extends Record<string, HandlerDescriptor>,\n>(\n workflowInterface: WorkflowDescriptor<P, H>,\n config: {\n handlers: WorkflowImplHandlers<H>;\n description?: string;\n metadata?: Record<string, string>;\n options?: WorkflowOptions & {\n handlers?: Partial<Record<keyof H, WorkflowPerHandlerOpts>>;\n };\n }\n): WorkflowDefinition<P, WorkflowImplHandlers<H>> & WorkflowDescriptor<P, H>;\n\nexport function implement(\n contract: Descriptor<any, any, any>,\n config: {\n handlers: Record<string, any>;\n description?: string;\n metadata?: Record<string, string>;\n options?: any;\n }\n): any {\n const { handlers: perHandlerOpts, ...serviceOptions } = config.options ?? {};\n\n const coreHandlers: Record<string, any> = {};\n for (const [name, desc] of Object.entries(\n contract._handlers as Record<string, HandlerDescriptor>\n )) {\n const fn = config.handlers[name];\n if (typeof fn !== \"function\") {\n throw new Error(`implement(): missing handler \"${name}\"`);\n }\n const sdkOpts = {\n input: desc._inputSerde,\n output: desc._outputSerde,\n // Contract-declared docs/metadata are defaults; explicit per-handler opts\n // passed to implement() override them (they come after in the spread).\n description: desc._description,\n metadata: desc._metadata,\n ...((perHandlerOpts?.[name] as object) ?? {}),\n };\n\n if (contract._kind === \"service\") {\n coreHandlers[name] = handlers.handler(sdkOpts as any, fn);\n } else if (contract._kind === \"object\") {\n coreHandlers[name] = desc._shared\n ? handlers.object.shared(sdkOpts as any, fn)\n : handlers.object.exclusive(sdkOpts as any, fn);\n } else {\n coreHandlers[name] =\n name === \"run\"\n ? handlers.workflow.workflow(sdkOpts as any, fn)\n : handlers.workflow.shared(sdkOpts as any, fn);\n }\n }\n\n const common = {\n name: contract.name,\n handlers: coreHandlers as any,\n // Contract-declared docs/metadata are defaults; values passed to implement()\n // override them.\n description: config.description ?? contract._description,\n metadata: config.metadata ?? contract._metadata,\n options: serviceOptions,\n };\n\n const def =\n contract._kind === \"service\"\n ? service(common)\n : contract._kind === \"object\"\n ? object(common)\n : workflow(common);\n\n return Object.assign(def, {\n _kind: contract._kind,\n _handlers: contract._handlers,\n });\n}\n"],"mappings":";;;AA4IA,SAAgB,UACd,UACA,QAMK;CACL,MAAM,EAAE,UAAU,eAAgB,GAAG,mBAAmB,OAAO,WAAW,EAAE;CAE5E,MAAMA,eAAoC,EAAE;AAC5C,MAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAChC,SAAS,UACV,EAAE;EACD,MAAM,KAAK,OAAO,SAAS;AAC3B,MAAI,OAAO,OAAO,WAChB,OAAM,IAAI,MAAM,iCAAiC,KAAK,GAAG;EAE3D,MAAM,UAAU;GACd,OAAO,KAAK;GACZ,QAAQ,KAAK;GAGb,aAAa,KAAK;GAClB,UAAU,KAAK;GACf,GAAK,iBAAiB,SAAoB,EAAE;GAC7C;AAED,MAAI,SAAS,UAAU,UACrB,cAAa,QAAQ,SAAS,QAAQ,SAAgB,GAAG;WAChD,SAAS,UAAU,SAC5B,cAAa,QAAQ,KAAK,UACtB,SAAS,OAAO,OAAO,SAAgB,GAAG,GAC1C,SAAS,OAAO,UAAU,SAAgB,GAAG;MAEjD,cAAa,QACX,SAAS,QACL,SAAS,SAAS,SAAS,SAAgB,GAAG,GAC9C,SAAS,SAAS,OAAO,SAAgB,GAAG;;CAItD,MAAM,SAAS;EACb,MAAM,SAAS;EACf,UAAU;EAGV,aAAa,OAAO,eAAe,SAAS;EAC5C,UAAU,OAAO,YAAY,SAAS;EACtC,SAAS;EACV;CAED,MAAM,MACJ,SAAS,UAAU,YACf,QAAQ,OAAO,GACf,SAAS,UAAU,WACjB,OAAO,OAAO,GACd,SAAS,OAAO;AAExB,QAAO,OAAO,OAAO,KAAK;EACxB,OAAO,SAAS;EAChB,WAAW,SAAS;EACrB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@restatedev/restate-sdk-cloudflare-workers",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.3",
|
|
4
4
|
"description": "Typescript SDK for Restate",
|
|
5
5
|
"author": "Restate Developers",
|
|
6
6
|
"email": "code@restate.dev",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@restatedev/restate-sdk-core": "1.17.
|
|
38
|
+
"@restatedev/restate-sdk-core": "1.17.3"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/aws-lambda": "^8.10.115",
|
|
42
|
-
"@restatedev/restate-sdk": "1.17.
|
|
42
|
+
"@restatedev/restate-sdk": "1.17.3"
|
|
43
43
|
},
|
|
44
44
|
"typesVersions": {
|
|
45
45
|
"*": {
|