@restatedev/restate-sdk-gen 0.0.0 → 1.14.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["CURRENT: unknown","adapt","defaultLib: AwaitableLib","future: FutureWithBacking<T>","leafOp: PrimitiveOp<T>","resume: Settled | null","next: IteratorResult<unknown, unknown>","outcome: Settled | null","backing: Backing<unknown>","promises: PromiseSource[]","settled: Settled","out: unknown[]","errors: unknown[]","items: PromiseSource[]","raceWinner: { i: number } & Settled","errSettled: Settled","settled: Settled","signal","out: restate.RunOptions<T>","spawnOp","selectOp","SchedulerClass"],"sources":["../src/current.ts","../src/free.ts","../src/operation.ts","../src/state.ts","../src/clients.ts","../src/default-lib.ts","../src/future.ts","../src/fiber.ts","../src/channel.ts","../src/scheduler.ts","../src/restate-operations.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\n// Synchronous current-fiber slot.\n// =============================================================================\n//\n// A module-level pointer to the active `RestateOperations`, set on\n// entry to `Fiber.advance()` and cleared in its `finally`. Free-standing\n// API functions (`sleep`, `run`, `all`, …) read it to reach the\n// scheduler/context without an explicit `ops` parameter.\n//\n// Why this is safe without AsyncLocalStorage: user generators yield —\n// they do not `await`. `iterator.next()` returns control synchronously\n// to `Fiber.advance`, so the slot is \"owned\" only during the synchronous\n// span between `setCurrent` and `clearCurrent`. Concurrent `execute()`\n// calls in the same Node process interleave only at scheduler-level\n// `await` boundaries (the main-loop race), never in the middle of a\n// fiber's sync body — Node never preempts sync JS.\n//\n// Failure mode: a free function called while no fiber is advancing\n// (module init, an `ops.run` async closure that resolves later, a\n// timer firing) reads `null` and throws. Loud and immediate; never\n// silent corruption.\n//\n// The slot value is typed `unknown` here to avoid a circular import on\n// `RestateOperations` (which itself imports the scheduler graph). Free\n// functions cast back via the typed `currentOps()` helper that lives\n// next to `RestateOperations`.\n\nlet CURRENT: unknown = null;\n\n/**\n * Save the previous slot, install `value` as the current. Returns the\n * previous value so `clearCurrent` can restore it (supports nested\n * scheduler invocations on the same thread, even though we don't expect\n * any in production).\n */\nexport function setCurrent(value: unknown): unknown {\n const prev = CURRENT;\n CURRENT = value;\n return prev;\n}\n\n/** Restore a slot previously captured by `setCurrent`. */\nexport function clearCurrent(prev: unknown): void {\n CURRENT = prev;\n}\n\n/**\n * Read the slot, throwing if no fiber is currently advancing. Callers\n * cast the return type — the slot is intentionally `unknown` here so\n * this module stays free of cycles.\n */\nexport function getCurrent(): unknown {\n if (CURRENT === null) {\n throw new Error(\n \"@restatedev/restate-sdk-gen: free-standing API called outside an active fiber. \" +\n \"Call from inside `execute(ctx, gen(function*() { ... }))`.\"\n );\n }\n return CURRENT;\n}\n","/*\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\n// Free-standing API\n// =============================================================================\n//\n// Module-level functions that mirror `RestateOperations` methods but\n// read the active operations from the synchronous current-fiber slot\n// (`current.ts`). User code inside a `gen(function*() { ... })` body\n// can call these directly — no `ops` parameter needed.\n//\n// Each function is a one-liner that resolves the slot via `currentOps()`\n// and delegates to the underlying `RestateOperations` method, so this\n// file stays in lockstep with the class without duplicating logic.\n//\n// Usage:\n//\n// import { gen, execute, sleep, run, all } from \"@restatedev/restate-sdk-gen\";\n//\n// const myWorkflow = gen(function*() {\n// const a = run(() => fetchA(), { name: \"a\" });\n// const b = run(() => fetchB(), { name: \"b\" });\n// const [av, bv] = yield* all([a, b]);\n// yield* sleep(100);\n// return av + bv;\n// });\n//\n// // Handler:\n// execute(ctx, myWorkflow);\n//\n// `select` and `spawn` are already free functions in `operation.ts`\n// and require no slot — they yield markers the scheduler dispatches.\n// They are re-exported from `index.ts`.\n\nimport type * as restate from \"@restatedev/restate-sdk\";\nimport type { Future, FutureValues, FutureSettledResult } from \"./future.js\";\nimport type { Channel } from \"./channel.js\";\nimport type { State, SharedState, TypedState, UntypedState } from \"./state.js\";\nimport type { FluentClient, FluentDurablePromise } from \"./clients.js\";\nimport type {\n RestateOperations,\n RunAction,\n RunOpts,\n} from \"./restate-operations.js\";\nimport { getCurrent } from \"./current.js\";\n\n/**\n * Read the active `RestateOperations` from the current-fiber slot.\n * Throws if called outside a fiber's synchronous advance span (e.g.,\n * at module init or inside an `ops.run` async closure that resolved\n * after the fiber returned).\n */\nexport function currentOps(): RestateOperations {\n return getCurrent() as RestateOperations;\n}\n\n// ---- journal-backed Futures ----\n\n/**\n * Run a side-effecting closure as a journal entry. See\n * `RestateOperations.run` for full semantics.\n *\n * `name` is derived from `action.name` (works for named functions and\n * arrow functions assigned to a `const`) or specified explicitly via\n * `opts.name`. If neither resolves, throws.\n */\nexport const run = <T>(action: RunAction<T>, opts?: RunOpts<T>): Future<T> =>\n currentOps().run(action, opts);\n\nexport const sleep = (\n duration: restate.Duration | number,\n name?: string\n): Future<void> => currentOps().sleep(duration, name);\n\nexport const awakeable = <T>(\n serde?: restate.Serde<T>\n): { id: string; promise: Future<T> } => currentOps().awakeable(serde);\n\nexport const resolveAwakeable = <T>(\n id: string,\n payload?: T,\n serde?: restate.Serde<T>\n): void => currentOps().resolveAwakeable(id, payload, serde);\n\nexport const rejectAwakeable = (\n id: string,\n reason: string | restate.TerminalError\n): void => currentOps().rejectAwakeable(id, reason);\n\nexport const signal = <T>(name: string, serde?: restate.Serde<T>): Future<T> =>\n currentOps().signal(name, serde);\n\nexport const attach = <T>(\n invocationId: restate.InvocationId,\n serde?: restate.Serde<T>\n): Future<T> => currentOps().attach(invocationId, serde);\n\n// ---- typed clients ----\n\nexport const serviceClient = <D>(\n api: restate.ServiceDefinitionFrom<D>\n): FluentClient<restate.Client<restate.Service<D>>> =>\n currentOps().serviceClient<D>(api);\n\nexport const objectClient = <D>(\n api: restate.VirtualObjectDefinitionFrom<D>,\n key: string\n): FluentClient<restate.Client<restate.VirtualObject<D>>> =>\n currentOps().objectClient<D>(api, key);\n\nexport const workflowClient = <D>(\n api: restate.WorkflowDefinitionFrom<D>,\n key: string\n): FluentClient<restate.Client<restate.Workflow<D>>> =>\n currentOps().workflowClient<D>(api, key);\n\nexport const serviceSendClient = <D>(\n api: restate.ServiceDefinitionFrom<D>\n): restate.SendClient<restate.Service<D>> =>\n currentOps().serviceSendClient<D>(api);\n\nexport const objectSendClient = <D>(\n api: restate.VirtualObjectDefinitionFrom<D>,\n key: string\n): restate.SendClient<restate.VirtualObject<D>> =>\n currentOps().objectSendClient<D>(api, key);\n\nexport const workflowSendClient = <D>(\n api: restate.WorkflowDefinitionFrom<D>,\n key: string\n): restate.SendClient<restate.Workflow<D>> =>\n currentOps().workflowSendClient<D>(api, key);\n\n// ---- generic call/send ----\n\nexport const genericCall = <REQ = Uint8Array, RES = Uint8Array>(\n call: restate.GenericCall<REQ, RES>\n): Future<RES> => currentOps().genericCall<REQ, RES>(call);\n\nexport const genericSend = <REQ = Uint8Array>(\n call: restate.GenericSend<REQ>\n): restate.InvocationHandle => currentOps().genericSend<REQ>(call);\n\n// ---- cancel another invocation ----\n\nexport const cancel = (invocationId: restate.InvocationId): void =>\n currentOps().cancel(invocationId);\n\n// ---- channels & state ----\n\nexport const channel = <T>(): Channel<T> => currentOps().channel<T>();\n\nexport const state = <\n TState extends TypedState = UntypedState,\n>(): State<TState> => currentOps().state<TState>();\n\nexport const sharedState = <\n TState extends TypedState = UntypedState,\n>(): SharedState<TState> => currentOps().sharedState<TState>();\n\n// ---- workflow durable promise ----\n\nexport const workflowPromise = <T>(\n name: string,\n serde?: restate.Serde<T>\n): FluentDurablePromise<T> => currentOps().workflowPromise<T>(name, serde);\n\n// ---- combinators ----\n\n/**\n * Wait for every future to settle; return their values in input order.\n * Heterogeneous-tuple typing — `all([fA, fB])` where `fA: Future<A>`\n * and `fB: Future<B>` yields `Future<[A, B]>`. Mirrors `Promise.all`.\n */\nexport const all = <const T extends readonly Future<unknown>[] | []>(\n futures: T\n): Future<FutureValues<T>> => currentOps().all(futures);\n\n/**\n * Return the first future to settle; losers continue running but their\n * results are discarded. Heterogeneous-tuple typing — `race([fA, fB])`\n * yields `Future<A | B>`. Mirrors `Promise.race`.\n */\nexport const race = <const T extends readonly Future<unknown>[] | []>(\n futures: T\n): Future<FutureValues<T>[number]> => currentOps().race(futures);\n\n/**\n * First-to-succeed wins (non-rejected). Rejects with `AggregateError(errors)`\n * when every input rejects (including the empty input case). Tuple-aware —\n * `any([fA, fB])` yields `Future<A | B>`. Mirrors `Promise.any`.\n */\nexport const any = <const T extends readonly Future<unknown>[] | []>(\n futures: T\n): Future<FutureValues<T>[number]> => currentOps().any(futures);\n\n/**\n * Wait for every future to settle; never rejects. Tuple-aware —\n * `allSettled([fA, fB])` yields\n * `Future<[FutureSettledResult<A>, FutureSettledResult<B>]>`.\n * Mirrors `Promise.allSettled`.\n */\nexport const allSettled = <const T extends readonly Future<unknown>[] | []>(\n futures: T\n): Future<{\n -readonly [P in keyof T]: FutureSettledResult<\n T[P] extends Future<infer U> ? U : never\n >;\n}> => currentOps().allSettled(futures);\n\n// `select` and `spawn` are already free functions in `operation.ts`\n// (they yield markers the scheduler dispatches). They are re-exported\n// from `index.ts` directly.\n","/*\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\n// Operation<T>\n// =============================================================================\n//\n// Operation<T> is a lazy, one-shot description of work that produces a T.\n// Constructed via gen() for user-authored bodies, or by primitives that\n// yield a marker the scheduler dispatches on (Leaf, Spawn, AwaitAny).\n//\n// The reuse trap from naked-generator designs is closed at the type level:\n// gen() takes a factory `() => Generator<...>`, not a generator object, so\n// `gen(bare())` doesn't typecheck — you have to write `gen(() => bare())`,\n// which produces a fresh body per `[Symbol.iterator]()` call.\n\nimport type { Future } from \"./future.js\";\nimport type { Settled } from \"./scheduler-types.js\";\n\nexport const opTag = Symbol(\"restateOperation\");\n\nexport interface Operation<T> {\n [Symbol.iterator](): Iterator<unknown, T, unknown>;\n}\n\n// =============================================================================\n// Primitive nodes — only the scheduler interprets these.\n// =============================================================================\n\nexport type LeafNode<T> = {\n readonly _tag: \"Leaf\";\n readonly future: Future<T>;\n};\n\nexport type SpawnNode<T> = {\n readonly _tag: \"Spawn\";\n readonly child: Operation<T>;\n};\n\nexport type AwaitRaceResult = { index: number; settled: Settled };\n\nexport type AwaitRace = {\n readonly _tag: \"AwaitRace\";\n readonly futures: ReadonlyArray<Future<unknown>>;\n};\n\nexport type Node<T> = LeafNode<T> | SpawnNode<T>;\n\nexport interface PrimitiveOp<T> extends Operation<T> {\n readonly [opTag]: Node<T> | AwaitRace;\n}\n\nexport function makePrimitive<T>(node: Node<T>): PrimitiveOp<T> {\n const op = {\n [opTag]: node,\n *[Symbol.iterator]() {\n return (yield op) as T;\n },\n };\n return op;\n}\n\n// AwaitAny is module-internal — used by combinator implementations inside\n// this package (race, select). It never appears in the user API.\nexport function awaitRace<T>(\n futures: ReadonlyArray<Future<T>>\n): Operation<AwaitRaceResult> {\n const op = {\n [opTag]: { _tag: \"AwaitRace\", futures } as AwaitRace,\n *[Symbol.iterator]() {\n return (yield op) as AwaitRaceResult;\n },\n };\n return op as unknown as Operation<AwaitRaceResult>;\n}\n\n// =============================================================================\n// gen — the only way to lift a generator function into an Operation.\n// =============================================================================\n\nexport function gen<T>(\n body: () => Generator<unknown, T, unknown>\n): Operation<T> {\n return { [Symbol.iterator]: body };\n}\n\n// =============================================================================\n// spawn — register a child operation as a new routine, get back a Future<T>.\n// =============================================================================\n//\n// `yield* spawn(op)` registers op as a fresh routine and resolves with a\n// Future<T> the caller can park on, hand around, or pass to combinators.\n\nexport function spawn<T>(op: Operation<T>): Operation<Future<T>> {\n // makePrimitive's generic parameter is the *yield resume type* — for\n // Spawn, that's Future<T>, since the scheduler resumes the yielder\n // with a Future.\n const node: SpawnNode<T> = { _tag: \"Spawn\", child: op };\n return makePrimitive<Future<T>>(node as unknown as Node<Future<T>>);\n}\n\n// =============================================================================\n// select — wait for one branch to settle, return its tag and the future.\n// =============================================================================\n//\n// The user unwraps the future after switching on the tag — `yield* r.future`\n// is effectively sync at that point since it's already settled. select\n// doesn't propagate the value or the error: telling you which branch is\n// ready is its only job.\n\nexport type SelectResult<B extends Record<string, Future<unknown>>> = {\n [K in keyof B]: { tag: K; future: B[K] };\n}[keyof B];\n\nexport function* select<B extends Record<string, Future<unknown>>>(\n branches: B\n): Generator<unknown, SelectResult<B>, unknown> {\n const tags = Object.keys(branches) as Array<keyof B & string>;\n const futures = tags.map((t) => branches[t]) as Future<unknown>[];\n const result = yield* awaitRace(futures);\n const tag = tags[result.index]!;\n return { tag, future: branches[tag] } as SelectResult<B>;\n}\n","/*\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\n// State<TState>\n// =============================================================================\n//\n// Wrapper around Restate's KeyValueStore — the per-key state attached\n// to a virtual object or workflow invocation. Available via\n// `ops.state()` (read-write) or `ops.sharedState()` (read-only) from\n// within `execute()`.\n//\n// Read-only vs read-write is a real distinction:\n// - ObjectContext / WorkflowContext expose the full KeyValueStore\n// (get + keys + set + clear + clearAll).\n// - ObjectSharedContext / WorkflowSharedContext expose only the\n// reads. Calling `set` etc. on the underlying context throws at\n// runtime; we surface that at the type level by giving shared\n// handlers a narrower interface.\n//\n// Both interfaces are generic over `TState extends TypedState`:\n// - Default `UntypedState` keeps the loose `(name: string)` shape\n// and a per-call value type — same as the SDK's untyped mode.\n// - Pass an explicit shape to get keyof-checked names and per-key\n// value types: `ops.state<{count: number; user: User}>()` then\n// `state.get(\"count\")` infers `Future<number | null>`.\n\nimport type * as restate from \"@restatedev/restate-sdk\";\nimport type { Awaitable } from \"./awaitable.js\";\nimport type { Future } from \"./future.js\";\nimport type { Scheduler } from \"./scheduler.js\";\n\n/**\n * Marker types matching the SDK's typed-state convention. Pass a\n * concrete shape (e.g. `{count: number; name: string}`) to enable\n * keyof-checked names; leave the default to keep names as `string`\n * with a per-call value generic.\n */\nexport type TypedState = Record<string, unknown>;\nexport type UntypedState = { _: never };\n\n/**\n * Read-only state, for handlers running under an\n * ObjectSharedContext or WorkflowSharedContext.\n */\nexport interface SharedState<TState extends TypedState = UntypedState> {\n /** Read a state value. Returns null if the key isn't set. */\n get<TValue, TKey extends keyof TState = string>(\n name: TState extends UntypedState ? string : TKey,\n serde?: restate.Serde<TState extends UntypedState ? TValue : TState[TKey]>\n ): Future<(TState extends UntypedState ? TValue : TState[TKey]) | null>;\n\n /** List all currently-known state keys. */\n keys(): Future<string[]>;\n}\n\n/**\n * Read-write state, for handlers running under an ObjectContext or\n * WorkflowContext. Extends SharedState with mutation methods.\n *\n * Writes are synchronous in the SDK — the journal entry is recorded\n * immediately, no yield required — so `set` / `clear` / `clearAll`\n * return `void` rather than `Operation<void>`.\n */\nexport interface State<\n TState extends TypedState = UntypedState,\n> extends SharedState<TState> {\n /** Write a state value. Sync; journal entry recorded immediately. */\n set<TValue, TKey extends keyof TState = string>(\n name: TState extends UntypedState ? string : TKey,\n value: TState extends UntypedState ? TValue : TState[TKey],\n serde?: restate.Serde<TState extends UntypedState ? TValue : TState[TKey]>\n ): void;\n\n /** Clear a single key. */\n clear<TKey extends keyof TState>(\n name: TState extends UntypedState ? string : TKey\n ): void;\n\n /** Clear all state for this invocation. */\n clearAll(): void;\n}\n\n// Loose type covering every Restate context flavor that exposes any\n// state methods. We only call KeyValueStore methods on this; the rest\n// of Context is unused here.\ntype StateContext =\n | restate.ObjectContext\n | restate.ObjectSharedContext\n | restate.WorkflowContext\n | restate.WorkflowSharedContext;\n\n/**\n * Build a `State<TState>` over the given context. The runtime delegates\n * straight to `ctx.get` / `ctx.set` / etc.; the TState generic is purely\n * a TS-level convenience and gets erased at runtime.\n *\n * For shared (read-only) contexts, the returned State has the same\n * runtime shape but the caller should use the `SharedState<TState>`\n * type to drop the write methods. The convenience method\n * `RestateOperations.sharedState()` does this cast.\n */\nexport function makeState<TState extends TypedState = UntypedState>(\n ctx: StateContext,\n sched: Scheduler,\n adapt: <T>(p: restate.RestatePromise<T>) => Awaitable<T>\n): State<TState> {\n // Cast for write methods: the typed shared variants don't have them\n // on the type, but the runtime object does carry them in writable\n // contexts. Calling write() from a shared handler throws naturally.\n const writeCtx = ctx as restate.ObjectContext;\n\n // Internally we use the loose UntypedState signatures and cast the\n // resulting object to the narrower State<TState>. Runtime is identical;\n // the conditional types only matter at the call site.\n const impl: State<UntypedState> = {\n get<T>(name: string, serde?: restate.Serde<T>): Future<T | null> {\n return sched.makeJournalFuture(\n adapt(\n ctx.get<T>(name, serde) as unknown as restate.RestatePromise<T | null>\n )\n );\n },\n keys(): Future<string[]> {\n return sched.makeJournalFuture(\n adapt(ctx.stateKeys() as unknown as restate.RestatePromise<string[]>)\n );\n },\n set<T>(name: string, value: T, serde?: restate.Serde<T>): void {\n writeCtx.set(name, value, serde);\n },\n clear(name: string): void {\n writeCtx.clear(name);\n },\n clearAll(): void {\n writeCtx.clearAll();\n },\n };\n return impl as unknown as State<TState>;\n}\n","/*\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\n// Client wrappers\n// =============================================================================\n//\n// Thin Proxy wrappers around the SDK's typed Clients (`Client<M>`,\n// `SendClient<M>`, `DurablePromise<T>`). The SDK returns RestatePromise\n// from each handler-invocation method; this module wraps those into\n// Future<T> so users can `yield* client.foo(arg)` from a fluent generator\n// instead of `await`ing.\n//\n// Send clients aren't transformed — their methods are synchronous,\n// returning `InvocationHandle` immediately, so the SDK shape passes\n// through unchanged.\n\nimport type * as restate from \"@restatedev/restate-sdk\";\nimport type { Future } from \"./future.js\";\n\n/**\n * Same shape as the SDK's `Client<M>` but each handler returns\n * `Future<O>` instead of `InvocationPromise<O>`. The mapped type\n * preserves the original argument list (including the trailing\n * `opts?: Opts<...>` parameter from the SDK).\n */\nexport type FluentClient<C> = {\n [K in keyof C]: C[K] extends (\n ...args: infer A\n ) => restate.InvocationPromise<infer R>\n ? (...args: A) => Future<R>\n : C[K];\n};\n\n/**\n * Same shape as the SDK's `DurablePromise<T>` but each method returns\n * `Future<...>` instead of `Promise<...>`/`RestatePromise<...>`.\n *\n * Workflow promises are durable; reads are journaled (so `peek`/`get`\n * are journal-backed Futures), and writes (`resolve`/`reject`) record\n * a journal entry that the user yields on.\n */\nexport type FluentDurablePromise<T> = {\n peek(): Future<T | undefined>;\n resolve(value?: T): Future<void>;\n reject(errorMsg: string): Future<void>;\n get(): Future<T>;\n};\n\n/**\n * Wrap an SDK `Client<M>` so each handler-invocation returns\n * `Future<T>` (via the supplied `toFuture` adapter) instead of\n * `InvocationPromise<T>`.\n */\nexport function wrapClient<C extends object>(\n client: C,\n toFuture: <T>(p: restate.RestatePromise<T>) => Future<T>\n): FluentClient<C> {\n return new Proxy(client, {\n get(target, prop, receiver) {\n const orig = Reflect.get(target, prop, receiver) as unknown;\n if (typeof orig !== \"function\") return orig;\n return (...args: unknown[]) => {\n const rp = (\n orig as (...a: unknown[]) => restate.RestatePromise<unknown>\n ).apply(target, args);\n return toFuture(rp);\n };\n },\n }) as FluentClient<C>;\n}\n\n/**\n * Wrap an SDK `DurablePromise<T>` so each method returns `Future<...>`\n * instead of `Promise<...>`/`RestatePromise<...>`.\n */\nexport function wrapDurablePromise<T>(\n dp: restate.DurablePromise<T>,\n toFuture: <U>(p: restate.RestatePromise<U> | Promise<U>) => Future<U>\n): FluentDurablePromise<T> {\n return {\n peek: () =>\n toFuture(dp.peek() as unknown as restate.RestatePromise<T | undefined>),\n resolve: (value?: T) =>\n toFuture(dp.resolve(value) as unknown as restate.RestatePromise<void>),\n reject: (errorMsg: string) =>\n // dp.reject takes a string per Restate's DurablePromise API.\n // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n toFuture(dp.reject(errorMsg) as unknown as restate.RestatePromise<void>),\n get: () => toFuture(dp.get()),\n };\n}\n","/*\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\n// Production wiring: an AwaitableLib backed by restate.RestatePromise.\n//\n// RestatePromise is structurally compatible with Awaitable<T> already — it\n// has `.map((v, e) => U)` and is thenable. The adapter is a simple cast\n// at the boundary; the four combinators forward to RestatePromise's\n// static methods, preserving the tuple-aware result types declared on\n// AwaitableLib.\n\nimport * as restate from \"@restatedev/restate-sdk\";\nimport type { Awaitable, AwaitableLib } from \"./awaitable.js\";\nimport type { FutureSettledResult } from \"./future.js\";\n\nexport const defaultLib: AwaitableLib = {\n all<const T extends readonly Awaitable<unknown>[]>(\n items: T\n ): Awaitable<{ -readonly [P in keyof T]: Awaited<T[P]> }> {\n return restate.RestatePromise.all(\n items as unknown as readonly restate.RestatePromise<unknown>[]\n ) as unknown as Awaitable<{ -readonly [P in keyof T]: Awaited<T[P]> }>;\n },\n race<const T extends readonly Awaitable<unknown>[]>(\n items: T\n ): Awaitable<Awaited<T[number]>> {\n return restate.RestatePromise.race(\n items as unknown as readonly restate.RestatePromise<unknown>[]\n ) as unknown as Awaitable<Awaited<T[number]>>;\n },\n any<const T extends readonly Awaitable<unknown>[]>(\n items: T\n ): Awaitable<Awaited<T[number]>> {\n return restate.RestatePromise.any(\n items as unknown as readonly restate.RestatePromise<unknown>[]\n ) as unknown as Awaitable<Awaited<T[number]>>;\n },\n allSettled<const T extends readonly Awaitable<unknown>[]>(\n items: T\n ): Awaitable<{\n -readonly [P in keyof T]: FutureSettledResult<Awaited<T[P]>>;\n }> {\n return restate.RestatePromise.allSettled(\n items as unknown as readonly restate.RestatePromise<unknown>[]\n ) as unknown as Awaitable<{\n -readonly [P in keyof T]: FutureSettledResult<Awaited<T[P]>>;\n }>;\n },\n // Invocation cancellation arrives at the aggregate race promise as a\n // CancelledError (the SDK's terminal-error subclass with code 409).\n isCancellation(e: unknown): boolean {\n return e instanceof restate.CancelledError;\n },\n};\n","/*\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\n// Future<T>\n// =============================================================================\n//\n// One user-visible type. Two internal backings, distinguished only inside\n// combinator implementations and the scheduler. The user sees uniform\n// behavior — all Futures yield and compose the same way regardless of\n// backing.\n//\n// Two kinds of backing:\n//\n// - \"journal\" — wraps a remote promise (RestatePromise in production,\n// TestPromise in tests). Resolution is observed by Restate's runtime\n// and journaled. Goes through the scheduler's main-loop `lib.race`.\n//\n// - \"local\" — wraps an in-memory `WaitTarget`. Resolution lives only\n// in the JS heap; never touches the journal, never goes through\n// `lib.race`. Fibers (settled by their iterator finishing) and\n// Channels (settled by `send()`) both implement `WaitTarget`.\n// Future in-memory primitives — semaphores, latches — slot in here\n// too without further changes to the scheduler/fiber.\n\nimport type { Awaitable } from \"./awaitable.js\";\nimport {\n type Operation,\n type PrimitiveOp,\n type LeafNode,\n makePrimitive,\n} from \"./operation.js\";\nimport type { Settled, Waiter } from \"./scheduler-types.js\";\n\n// `futureBacking` is the symbol slot where each Future stashes its backing\n// (journal-backed promise or local WaitTarget). NOT exported from index.ts:\n// the symbol-keyed property is an implementation detail, accessed only by\n// the scheduler/fiber via the internal `getBacking` helper below.\nexport const futureBacking = Symbol(\"restateFutureBacking\");\n\nexport type JournalBacking<T> = {\n readonly kind: \"journal\";\n readonly promise: Awaitable<T>;\n};\n\n/**\n * In-memory completion source. Anything that gets settled exactly once\n * and notifies waiters can be a `WaitTarget` — fibers, channels, and\n * any future in-memory primitive we add (latch, semaphore, …).\n *\n * Contract mirrors `Fiber`'s lifecycle methods:\n * - `isDone()` and `settledValue()` for a synchronous short-circuit\n * when the target is already settled at park time.\n * - `awaitCompletion(waiter)` registers a one-shot callback;\n * returns the settled value if already done so the caller can\n * short-circuit without queuing.\n */\nexport interface WaitTarget<T> {\n isDone(): boolean;\n settledValue(): Settled;\n awaitCompletion(waiter: Waiter): Settled | null;\n // The generic parameter T is documentation; the concrete settle path\n // already carries the value via `Settled`. Kept on the interface so\n // call-site types match `Fiber<T>` / `ChannelImpl<T>` cleanly.\n readonly _phantom?: T;\n}\n\nexport type LocalBacking<T> = {\n readonly kind: \"local\";\n readonly target: WaitTarget<T>;\n};\n\nexport type Backing<T> = JournalBacking<T> | LocalBacking<T>;\n\n// Public Future is opaque — only the iterable shape is visible. The\n// `[futureBacking]: Backing<T>` storage lives on the internal type, kept\n// off the published API so we don't drag JournalBacking/LocalBacking/\n// WaitTarget/Awaitable/Settled/Waiter into the public surface.\nexport interface Future<T> extends Operation<T> {}\n\n/**\n * Internal shape — Future plus its symbol-keyed backing slot. Kept off\n * the public `Future<T>` interface so `Backing`/`JournalBacking`/\n * `LocalBacking`/`WaitTarget` (and their transitive deps) don't leak\n * into the published `.d.ts`.\n */\nexport interface FutureWithBacking<T> extends Future<T> {\n readonly [futureBacking]: Backing<T>;\n}\n\n/** Like `FutureWithBacking<T>` but narrowed to a journal backing. */\nexport interface JournalBackedFuture<T> extends Future<T> {\n readonly [futureBacking]: JournalBacking<T>;\n}\n\n/**\n * Internal accessor — read the backing off a Future. Only the scheduler\n * and fiber call this; user code never sees Backing.\n */\nexport function getBacking<T>(f: Future<T>): Backing<T> {\n return (f as FutureWithBacking<T>)[futureBacking];\n}\n\nexport function makeFuture<T>(backing: Backing<T>): Future<T> {\n // Each Future carries a single Leaf op that the scheduler dispatches on.\n // Reused across [Symbol.iterator]() calls since it's stateless — just a\n // back-reference to this future for the scheduler to inspect.\n //\n // The forward-reference inside the iterator closure is safe: the\n // generator body only runs when [Symbol.iterator]() is iterated, which\n // can only happen after this function returns and `leafOp` is bound.\n const future: FutureWithBacking<T> = {\n [futureBacking]: backing,\n *[Symbol.iterator]() {\n return (yield leafOp) as T;\n },\n };\n const leafOp: PrimitiveOp<T> = makePrimitive<T>({\n _tag: \"Leaf\",\n future,\n } as LeafNode<T>);\n return future;\n}\n\nexport function isJournalBacked<T>(f: Future<T>): f is JournalBackedFuture<T> {\n return getBacking(f).kind === \"journal\";\n}\n\n// =============================================================================\n// Helper types for heterogeneous combinator inputs.\n// =============================================================================\n//\n// `all([fA, fB, fC])` where each Future has a different value type\n// should yield `[A, B, C]`, not `(A | B | C)[]`. Mirrors the standard\n// lib's `Promise.all` pattern (see `lib.es2015.iterable.d.ts`):\n//\n// all<T extends readonly unknown[] | []>(values: T):\n// Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>\n//\n// Same idea here, but unwrapping `Future<U>` to `U` instead of\n// awaiting a Promise.\n\n/** Extract the value type from a `Future<U>`; `never` for non-Futures. */\nexport type FutureValue<F> = F extends Future<infer U> ? U : never;\n\n/**\n * Map a tuple of Futures to the tuple of their value types.\n * For `[Future<A>, Future<B>]` produces `[A, B]`.\n * For an unbounded `Future<X>[]` produces `X[]`.\n */\nexport type FutureValues<T extends readonly Future<unknown>[] | []> = {\n -readonly [P in keyof T]: T[P] extends Future<infer U> ? U : never;\n};\n\n// =============================================================================\n// FutureSettledResult variants — re-declared here with `reason: unknown`\n// instead of the std-lib's `reason: any`, which leaks `any` into allSettled's\n// return type and every caller that pattern-matches on the result.\n// =============================================================================\n\nexport interface FutureFulfilledResult<T> {\n readonly status: \"fulfilled\";\n readonly value: T;\n}\n\nexport interface FutureRejectedResult {\n readonly status: \"rejected\";\n readonly reason: unknown;\n}\n\nexport type FutureSettledResult<T> =\n | FutureFulfilledResult<T>\n | FutureRejectedResult;\n","/*\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\n// Fiber<T>\n// =============================================================================\n//\n// A single strand of cooperative execution. Owns its iterator, its\n// lifecycle state (ready / parked / done), and its waiter list. The\n// scheduler orchestrates many fibers: keeping a ready queue, polling\n// parked fibers' sources, telling fibers to advance.\n//\n// Design boundary:\n//\n// Fiber owns: iterator, state transitions, dispatch of yielded\n// Leaf/Spawn/AwaitAny ops, waiter notification.\n// Scheduler owns: the set of live fibers, the ready queue, the\n// Awaitable lib (race/all primitives), the main loop,\n// and cancellation broadcast.\n//\n// Communication is narrow:\n//\n// Scheduler → Fiber: new Fiber(op, sched), fiber.advance(),\n// fiber.wake(resume), fiber.parkedSources(),\n// fiber.awaitCompletion(waiter), fiber.isDone(),\n// fiber.settledValue().\n// Fiber → Scheduler: sched.markReady(this), sched.markDone(this),\n// sched.spawn(childOp).\n\nimport type { Operation, PrimitiveOp, LeafNode } from \"./operation.js\";\nimport { opTag } from \"./operation.js\";\nimport type { Future, Backing, WaitTarget } from \"./future.js\";\nimport { getBacking } from \"./future.js\";\nimport type { Settled, PromiseSource, Waiter } from \"./scheduler-types.js\";\nimport { setCurrent, clearCurrent } from \"./current.js\";\n\n/**\n * Narrow interface a Fiber needs from its scheduler. Avoids a wide\n * coupling to Scheduler's full API; Fiber only ever calls these three.\n */\nexport interface SchedulerOps {\n markReady(f: Fiber<unknown>): void;\n markDone(f: Fiber<unknown>): void;\n /**\n * Spawn an operation as a fresh fiber and return a Future that\n * resolves with the fiber's eventual outcome. The fiber is added to\n * the scheduler's live set; the Future is what user code yields on.\n */\n spawnFuture<U>(op: Operation<U>): Future<U>;\n /**\n * The \"current fiber\" slot — the value installed by `execute()` as\n * the active `RestateOperations`. `Fiber.advance` publishes this to\n * the module-level slot so free-standing API functions can read it.\n * Typed `unknown` to avoid cycles with `restate-operations.ts`.\n */\n readonly contextSlot: unknown;\n}\n\ntype FiberState =\n | { kind: \"ready\"; resume: Settled | null }\n | { kind: \"parked\"; promises: PromiseSource[] }\n | { kind: \"done\"; settled: Settled };\n\nexport class Fiber<T = unknown> implements WaitTarget<T> {\n private readonly it: Iterator<unknown, unknown, unknown>;\n private readonly sched: SchedulerOps;\n private state: FiberState = { kind: \"ready\", resume: null };\n private waiters: Waiter[] = [];\n\n constructor(op: Operation<T>, sched: SchedulerOps) {\n this.it = op[Symbol.iterator]() as Iterator<unknown, unknown, unknown>;\n this.sched = sched;\n }\n\n // ---- lifecycle queries ----\n\n isDone(): boolean {\n return this.state.kind === \"done\";\n }\n\n /**\n * For a fiber known to be done, return its settled outcome. Throws\n * if called on a non-done fiber — callers must check `isDone()` first\n * (or use `awaitCompletion` for the polymorphic version).\n */\n settledValue(): Settled {\n if (this.state.kind !== \"done\") {\n throw new Error(\"Fiber.settledValue called on non-done fiber\");\n }\n return this.state.settled;\n }\n\n /**\n * Returns the parked sources this fiber is currently racing against.\n * Empty if the fiber is parked only on routine waiters (e.g.,\n * waiting on a sibling fiber to finish), or in any non-parked state.\n * The scheduler reads these to assemble its main-loop race.\n */\n parkedSources(): readonly PromiseSource[] {\n return this.state.kind === \"parked\" ? this.state.promises : [];\n }\n\n /**\n * \"I want to be notified when this fiber is done.\" If the fiber is\n * already done, returns its settled outcome immediately (caller\n * should NOT also expect the waiter to be invoked). Otherwise\n * returns null and queues the waiter for invocation when the fiber\n * eventually finishes.\n */\n awaitCompletion(waiter: Waiter): Settled | null {\n if (this.state.kind === \"done\") return this.state.settled;\n this.waiters.push(waiter);\n return null;\n }\n\n // ---- driving ----\n\n /**\n * Wake this fiber with a resume value. Transitions to ready and\n * notifies the scheduler. May be called from any state except done\n * (waking a done fiber is a programming error and is ignored\n * defensively).\n */\n wake(resume: Settled | null): void {\n if (this.state.kind === \"done\") return;\n this.state = { kind: \"ready\", resume };\n this.sched.markReady(this);\n }\n\n /**\n * Drive the fiber's iterator until it parks (yields a primitive\n * whose dispatch ends with the fiber waiting on a source) or\n * finishes (returns or throws).\n *\n * No-op if the fiber is not in the ready state — protects against\n * stale entries in the scheduler's ready queue.\n */\n advance(): void {\n if (this.state.kind !== \"ready\") return;\n // Publish the scheduler's RestateOperations slot to the module-level\n // pointer that free-standing API functions (sleep, run, all, …)\n // read. The slot lifetime is exactly the synchronous span of this\n // method; restored in `finally` so concurrent schedulers (different\n // execute() calls) don't clobber each other.\n const prevSlot = setCurrent(this.sched.contextSlot);\n try {\n let resume: Settled | null = this.state.resume;\n while (true) {\n let next: IteratorResult<unknown, unknown>;\n try {\n next = stepIterator(this.it, resume);\n } catch (e) {\n this.finish({ ok: false, e });\n return;\n }\n if (next.done) {\n this.finish({ ok: true, v: next.value });\n return;\n }\n\n const op = next.value as PrimitiveOp<unknown>;\n const node = op[opTag];\n // Each branch returns null to mean \"I parked, the fiber is\n // suspended\" or a Settled to mean \"resume the iterator with\n // this value.\" The Spawn case never parks; Leaf and AwaitAny\n // may or may not depending on whether their target is already\n // settled.\n let outcome: Settled | null;\n switch (node._tag) {\n case \"Leaf\":\n outcome = this.parkOnLeaf(node);\n break;\n case \"Spawn\":\n outcome = {\n ok: true,\n v: this.sched.spawnFuture(node.child),\n };\n break;\n case \"AwaitRace\":\n outcome = this.parkOnAwaitRace(node.futures);\n break;\n }\n\n if (outcome === null) return;\n resume = outcome;\n }\n } finally {\n clearCurrent(prevSlot);\n }\n }\n\n // ---- yield dispatch ----\n\n /**\n * Park on a single Future, or short-circuit if the Future is already\n * settled. Returns the Settled value to feed back into the iterator\n * if a short-circuit is possible (routine-backed future whose target\n * already finished); returns null if the fiber is parked and the\n * caller should suspend.\n */\n private parkOnLeaf(leaf: LeafNode<unknown>): Settled | null {\n const backing: Backing<unknown> = getBacking(leaf.future);\n if (backing.kind === \"journal\") {\n this.state = {\n kind: \"parked\",\n promises: [{ promise: backing.promise, fire: (s) => this.wake(s) }],\n };\n return null;\n }\n // Local-backed: ask the target (fiber, channel, etc.) to either\n // give us its settled outcome (sync short-circuit) or register us\n // as a waiter.\n const settled = backing.target.awaitCompletion((s) => this.wake(s));\n if (settled !== null) return settled;\n this.state = { kind: \"parked\", promises: [] };\n return null;\n }\n\n /**\n * Park on the first-to-settle of a list of Futures, or short-circuit\n * if any source is already settled. Returns `{index, settled}`\n * (wrapped as Settled) on short-circuit, or null if parked.\n *\n * On the parked path, every source registers a one-shot fire\n * callback that wakes the fiber with `{index, settled}`. The `won`\n * flag guards against duplicate wakes when multiple sources settle\n * in the same tick. Local sources (fibers, channels) park on the\n * target's waiter list; journal sources race in the main loop's\n * race promise.\n */\n private parkOnAwaitRace(\n futures: ReadonlyArray<Future<unknown>>\n ): Settled | null {\n // Sync-check first: a local source whose target is already done\n // wins immediately. Journal sources can't be sync-checked — they\n // always defer to the race.\n for (let i = 0; i < futures.length; i++) {\n const b = getBacking(futures[i]!);\n if (b.kind === \"local\" && b.target.isDone()) {\n return { ok: true, v: { index: i, settled: b.target.settledValue() } };\n }\n }\n\n let won = false;\n const promises: PromiseSource[] = [];\n for (let i = 0; i < futures.length; i++) {\n const idx = i;\n const b = getBacking(futures[i]!);\n const fireOnce = (settled: Settled) => {\n if (won) return;\n won = true;\n this.wake({ ok: true, v: { index: idx, settled } });\n };\n if (b.kind === \"local\") {\n // The target may already be done — but we sync-checked above\n // and short-circuited if so. So awaitCompletion here will queue\n // the waiter (returning null). We ignore its return.\n b.target.awaitCompletion(fireOnce);\n } else {\n promises.push({ promise: b.promise, fire: fireOnce });\n }\n }\n this.state = { kind: \"parked\", promises };\n return null;\n }\n\n // ---- termination ----\n\n /**\n * Iterator finished or threw. Transition to done, fire all waiters\n * with the settled outcome, notify scheduler.\n */\n private finish(settled: Settled): void {\n this.state = { kind: \"done\", settled };\n const waiters = this.waiters;\n this.waiters = [];\n for (const w of waiters) w(settled);\n this.sched.markDone(this);\n }\n}\n\n/**\n * Drive a generator iterator one step, feeding it whatever value or\n * exception the caller is resuming with. `resume === null` is the\n * very first step; `{ok: true, v}` resumes with a value; `{ok: false,\n * e}` throws into the iterator (or, if the iterator has no `throw`\n * method, rethrows so the fiber fails).\n */\nfunction stepIterator(\n it: Iterator<unknown, unknown, unknown>,\n resume: Settled | null\n): IteratorResult<unknown, unknown> {\n if (resume === null) return it.next(undefined);\n if (resume.ok) return it.next(resume.v);\n if (it.throw) return it.throw(resume.e);\n throw resume.e;\n}\n","/*\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\n// Channel<T>\n// =============================================================================\n//\n// A single-shot in-memory communication primitive. Cooperative — the\n// receiver chooses when to read, by yielding the channel's `receive`\n// Future. Composes with select, race, and any other Future-shaped\n// primitive.\n//\n// Semantics:\n//\n// send(v) — yieldable. `yield* ch.send(v)` settles the channel\n// with v. The first send wins; subsequent sends are\n// silently dropped (idempotent).\n// receive — a Future<T> that resolves with the sent value once\n// send fires. Always the same Future on every access;\n// settles once, stays settled forever, safe to share\n// across multiple selects/races.\n//\n// `send` returns `Operation<void>` so the only way to fire it is via\n// `yield*` from inside a generator body. This keeps channels\n// intra-workflow by construction — external code (setTimeout,\n// webhooks, cross-handler signals) doesn't have a generator to\n// `yield*` from, and should use `ops.awakeable()` instead, which is\n// durably journaled.\n//\n// Implementation: ChannelImpl is a `WaitTarget` (see future.ts). The\n// receive Future has `LocalBacking` pointing at this impl. When a\n// fiber yields receive, parkOnAwaitAny / parkOnLeaf treats it the\n// same as a routine-backed target — register a waiter, fire on\n// settle. `lib.race` never sees the channel; production's\n// RestatePromise.race is not involved.\n\nimport type { Settled, Waiter } from \"./scheduler-types.js\";\nimport { type Future, makeFuture, type WaitTarget } from \"./future.js\";\nimport { type Operation, gen } from \"./operation.js\";\n\nclass ChannelImpl<T> implements WaitTarget<T> {\n private state: { kind: \"pending\" } | { kind: \"settled\"; value: T } = {\n kind: \"pending\",\n };\n private waiters: Waiter[] = [];\n\n // Synchronous side-effect; only invoked from inside the gen body\n // returned by Channel.send (which itself is only iterable via\n // yield* inside a fiber).\n fire(value: T): void {\n if (this.state.kind === \"settled\") return;\n this.state = { kind: \"settled\", value };\n const ws = this.waiters;\n this.waiters = [];\n const settled: Settled = { ok: true, v: value };\n for (const w of ws) w(settled);\n }\n\n isDone(): boolean {\n return this.state.kind === \"settled\";\n }\n\n settledValue(): Settled {\n if (this.state.kind !== \"settled\") {\n throw new Error(\"ChannelImpl.settledValue called on a pending channel\");\n }\n return { ok: true, v: this.state.value };\n }\n\n awaitCompletion(waiter: Waiter): Settled | null {\n if (this.state.kind === \"settled\") {\n return { ok: true, v: this.state.value };\n }\n this.waiters.push(waiter);\n return null;\n }\n}\n\nexport interface Channel<T> {\n /**\n * Yieldable. Use as `yield* ch.send(value)` from within a gen body.\n * The first call settles the channel; subsequent calls are silently\n * dropped (idempotent).\n *\n * Return value is `Operation<void>` rather than `void` so the only\n * way to fire send is via `yield*` inside a fiber — which enforces\n * the channel-is-intra-workflow contract at the type level.\n */\n send(value: T): Operation<void>;\n readonly receive: Future<T>;\n}\n\nexport function makeChannel<T>(): Channel<T> {\n const impl = new ChannelImpl<T>();\n return {\n send: (v: T): Operation<void> =>\n // The generator body is intentionally yield-less: send's purpose\n // is a synchronous side effect that runs only when iterated via\n // `yield*`. The Operation wrapper exists for the type-level\n // enforcement, not because there's anything to suspend on.\n gen<void>(function* () {\n impl.fire(v);\n }),\n receive: makeFuture<T>({ kind: \"local\", target: impl }),\n };\n}\n","/*\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\n// Scheduler\n// =============================================================================\n//\n// The runtime that drives Operations. Decoupled from Restate via the\n// Awaitable abstraction — production wires it to RestatePromise, tests\n// wire it to a hand-controlled promise type.\n//\n// The scheduler's job is orchestration:\n//\n// - Maintain the set of live fibers.\n// - Maintain the ready queue (which fibers want to run next).\n// - Run the main loop: assemble the parked sources from every live\n// fiber, race them via the lib, dispatch the winner.\n// - Broadcast invocation cancellation when the race rejects.\n// - Construct journal-backed and routine-backed Futures for users.\n//\n// The fiber's job is execution. The boundary between Scheduler and\n// Fiber is narrow (see `fiber.ts` and `SchedulerOps` interface).\n\nimport type { Awaitable, AwaitableLib } from \"./awaitable.js\";\nimport {\n type Future,\n type FutureValue,\n type FutureValues,\n type FutureSettledResult,\n futureBacking,\n makeFuture,\n isJournalBacked,\n} from \"./future.js\";\nimport { type Operation, awaitRace, gen } from \"./operation.js\";\nimport type { Settled, PromiseSource } from \"./scheduler-types.js\";\nimport { Fiber, type SchedulerOps } from \"./fiber.js\";\nimport { type Channel, makeChannel } from \"./channel.js\";\n\nexport class Scheduler implements SchedulerOps {\n private readonly fibers: Set<Fiber<unknown>> = new Set();\n private readonly ready: Fiber<unknown>[] = [];\n private readonly lib: AwaitableLib;\n // Replaced (not just re-aborted) each time the scheduler observes\n // invocation cancellation. AbortControllers are one-way — once\n // aborted, signal.aborted stays true forever — so the scheduler-\n // level signal must be a fresh controller per cancel event to\n // preserve recoverability. Closures that captured the old signal\n // still see it as aborted (correctly, since their work was caught\n // by the cancellation); closures created after recovery see the new,\n // unaborted signal.\n private abortController: AbortController = new AbortController();\n /**\n * Slot for the RestateOperations bound to this scheduler. Set by\n * `execute()` after construction (we can't pass it into the ctor\n * because RestateOperations needs the scheduler to construct itself).\n * `Fiber.advance` publishes this to the module-level current-fiber\n * slot read by free-standing API functions. Typed `unknown` here to\n * keep this module independent of `restate-operations.ts`.\n */\n contextSlot: unknown = null;\n\n constructor(lib: AwaitableLib) {\n this.lib = lib;\n }\n\n /**\n * The scheduler's current AbortSignal. Aborts when invocation\n * cancellation is observed (the SDK rejects the main race promise\n * with TerminalError). After cancellation has been delivered to\n * fibers and the scheduler has resumed, this getter returns a\n * *fresh* signal — one that is not aborted, even though the previous\n * cancel was just delivered.\n *\n * Pass `signal` to AbortSignal-aware APIs in `ops.run` closures\n * (e.g. `fetch(url, {signal})`) so they cancel promptly when the\n * surrounding work is cancelled. Cleanup closures yielded after a\n * caught CancelledError get a fresh, unaborted signal — so they can\n * do real work and only abort if a *new* cancellation arrives.\n */\n get abortSignal(): AbortSignal {\n return this.abortController.signal;\n }\n\n // ---- SchedulerOps: narrow interface for Fiber ----\n\n markReady(f: Fiber<unknown>): void {\n this.ready.push(f);\n }\n\n markDone(f: Fiber<unknown>): void {\n // Remove from the live set so long-running loops that spawn (e.g.,\n // race in a while-true) don't accumulate dead-fiber objects. Safe\n // here because markDone is called from Fiber.advance, which only\n // runs between main-loop awaits — no other code is iterating\n // `fibers` now.\n this.fibers.delete(f);\n }\n\n spawnFuture<U>(op: Operation<U>): Future<U> {\n const f = this.createFiber(op);\n return makeFuture<U>({ kind: \"local\", target: f });\n }\n\n private createFiber<U>(op: Operation<U>): Fiber<U> {\n const f = new Fiber<U>(op, this);\n this.fibers.add(f as Fiber<unknown>);\n this.ready.push(f as Fiber<unknown>);\n return f;\n }\n\n // ---- public construction helpers ----\n\n makeJournalFuture<U>(promise: Awaitable<U>): Future<U> {\n return makeFuture<U>({ kind: \"journal\", promise });\n }\n\n /**\n * Spawn an operation as a fresh fiber and return a Future that\n * resolves with its eventual value. Same as the SchedulerOps method;\n * exposed publicly for external callers (combinator helpers, the\n * main run() entry point).\n */\n spawnDetached<U>(op: Operation<U>): Future<U> {\n return this.spawnFuture(op);\n }\n\n /**\n * Construct a single-shot in-memory channel. Send must be called from\n * a fiber currently advancing under this scheduler. See `channel.ts`\n * for full semantics.\n */\n makeChannel<U>(): Channel<U> {\n return makeChannel<U>();\n }\n\n // ---- combinator helpers (used by RestateOperations) ----\n\n /**\n * Combinator over Futures. Fast path when every input is journal-\n * backed: use the lib's all/race for a single combinator entry.\n * Otherwise, fall back to a synthesized fiber that yields each in\n * turn.\n *\n * Tuple-aware typing (mirrors `Promise.all` in the standard lib):\n * `all([fA, fB])` where `fA: Future<A>` and `fB: Future<B>`\n * yields `Future<[A, B]>`, not `Future<(A | B)[]>`. The `const T`\n * lets TS infer a tuple from a literal array.\n */\n all<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<FutureValues<T>> {\n // Cast to a uniform shape so `every(isJournalBacked)`'s type\n // predicate narrows elements correctly; the input tuple's\n // heterogeneous element types are recovered via the return cast.\n const fs = futures as ReadonlyArray<Future<unknown>>;\n if (fs.every(isJournalBacked)) {\n const promises = fs.map((f) => f[futureBacking].promise);\n return this.makeJournalFuture(this.lib.all(promises)) as Future<\n FutureValues<T>\n >;\n }\n return this.spawnDetached(\n gen<FutureValues<T>>(function* () {\n const out: unknown[] = new Array(fs.length);\n for (let i = 0; i < fs.length; i++) {\n // In case of failure, this throws, respecting the contract that all shortcircuits on failure\n out[i] = yield* fs[i]!;\n }\n return out as FutureValues<T>;\n })\n );\n }\n\n race<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<FutureValues<T>[number]> {\n type R = FutureValues<T>[number];\n const fs = futures as ReadonlyArray<Future<unknown>>;\n // No need here to try downcasting to RestateFuture's, awaitRace will anyway produce the same UnresolvedFuture tree!\n return this.spawnDetached(\n gen<R>(function* () {\n const result = yield* awaitRace(fs);\n if (result.settled.ok) return result.settled.v as R;\n throw result.settled.e;\n })\n );\n }\n\n /**\n * First-success combinator. Mirrors `Promise.any` /\n * `RestatePromise.any`: settles with the first input that succeeds\n * (non-rejected); rejects with `AggregateError(errors)` when every\n * input rejects (including the empty-array case).\n *\n * Fast path collapses to a single `lib.any` over journal awaitables.\n * Fallback synthesizes a fiber that loops `awaitAnyOf` over the\n * still-pending subset, accumulating rejections in input order until\n * one input fulfills or all have rejected.\n *\n * Tuple-aware: `any([fA, fB])` where `fA: Future<A>` and `fB:\n * Future<B>` yields `Future<A | B>` (the union of slot types), same\n * shape as `Promise.any`.\n */\n any<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<FutureValues<T>[number]> {\n type R = FutureValues<T>[number];\n const fs = futures as ReadonlyArray<Future<unknown>>;\n if (fs.every(isJournalBacked)) {\n const promises = fs.map((f) => f[futureBacking].promise);\n return this.makeJournalFuture(this.lib.any(promises)) as Future<R>;\n }\n return this.spawnDetached(\n gen<R>(function* () {\n const errors: unknown[] = new Array(fs.length);\n const remaining = new Set<number>();\n for (let i = 0; i < fs.length; i++) remaining.add(i);\n while (remaining.size > 0) {\n const liveIdx = Array.from(remaining);\n const live = liveIdx.map((i) => fs[i]!);\n const result = yield* awaitRace(live);\n const original = liveIdx[result.index]!;\n if (result.settled.ok) return result.settled.v as R;\n errors[original] = result.settled.e;\n remaining.delete(original);\n }\n throw new AggregateError(errors, \"All promises were rejected\");\n })\n );\n }\n\n /**\n * Settle-all combinator. Mirrors `Promise.allSettled` /\n * `RestatePromise.allSettled`: resolves with an array of\n * `FutureSettledResult` in input order, never rejects.\n *\n * Fast path collapses to a single `lib.allSettled`. Fallback yields\n * each Future in turn — safe because Futures are eager (already in\n * flight); sequential harvesting just reads them as they complete\n * without blocking concurrency.\n *\n * Tuple-aware: `allSettled([fA, fB])` yields\n * `Future<[FutureSettledResult<A>, FutureSettledResult<B>]>`.\n */\n allSettled<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<{\n -readonly [P in keyof T]: FutureSettledResult<FutureValue<T[P]>>;\n }> {\n type R = {\n -readonly [P in keyof T]: FutureSettledResult<FutureValue<T[P]>>;\n };\n const fs = futures as ReadonlyArray<Future<unknown>>;\n if (fs.every(isJournalBacked)) {\n const promises = fs.map((f) => f[futureBacking].promise);\n return this.makeJournalFuture(this.lib.allSettled(promises)) as Future<R>;\n }\n return this.spawnDetached(\n gen<R>(function* () {\n const out = new Array<FutureSettledResult<unknown>>(fs.length);\n for (let i = 0; i < fs.length; i++) {\n try {\n const value = yield* fs[i]!;\n out[i] = { status: \"fulfilled\", value };\n } catch (reason) {\n out[i] = { status: \"rejected\", reason };\n }\n }\n return out as R;\n })\n );\n }\n\n // ---- driving ----\n\n private drainReady(): void {\n while (this.ready.length > 0) this.ready.shift()!.advance();\n }\n\n /**\n * Run an operation to completion. Drain the ready queue, then loop:\n * collect every PromiseSource from every parked fiber, race them,\n * dispatch the winner via its fire callback, drain. Stop when no\n * fiber is alive.\n */\n async run<T>(op: Operation<T>): Promise<T> {\n const main = this.createFiber(op);\n this.drainReady();\n\n while (this.fibers.size > 0) {\n const items: PromiseSource[] = [];\n for (const f of this.fibers) {\n for (const src of f.parkedSources()) items.push(src);\n }\n if (items.length === 0) {\n // Live fibers exist but no journal promises are pending — a\n // wait-cycle deadlock, or fibers parked only on routine waiters\n // whose targets can't progress.\n throw new Error(\n \"scheduler stuck: live fibers but nothing pending on a journal promise\"\n );\n }\n\n const tagged = items.map(({ promise }, i) =>\n promise.map((v, e): { i: number } & Settled =>\n e !== undefined ? { i, ok: false, e } : { i, ok: true, v }\n )\n );\n\n // The race promise itself can be settled with a rejection by\n // the SDK when invocation cancellation arrives. Per-source\n // promises are unaffected — the rejection lives on this\n // aggregate race promise. We fan the rejection out to every\n // parked fiber: each was, in effect, contributing a source to\n // this race, so each gets the TerminalError delivered at its\n // current yield point. Fibers may catch and continue normally;\n // subsequent iterations build fresh race promises that are not\n // infected by this rejection.\n //\n // Before fanning out, abort the current AbortController so\n // in-flight syscalls inside ops.run closures (those listening\n // on the captured signal) start cancelling immediately. Then\n // replace the controller with a fresh one so that closures\n // created during recovery (cleanup yields, etc.) see an\n // unaborted signal — cancellation is not a sticky state.\n let raceWinner: { i: number } & Settled;\n try {\n raceWinner = (await this.lib.race(tagged)) as { i: number } & Settled;\n } catch (e) {\n if (this.lib.isCancellation(e)) {\n this.abortController.abort(e);\n this.abortController = new AbortController();\n }\n const errSettled: Settled = { ok: false, e };\n for (const it of items) it.fire(errSettled);\n this.drainReady();\n continue;\n }\n\n const { i, ...settledFields } = raceWinner;\n const settled: Settled = settledFields.ok\n ? { ok: true, v: settledFields.v }\n : { ok: false, e: settledFields.e };\n items[i]!.fire(settled);\n this.drainReady();\n }\n\n if (!main.isDone()) {\n throw new Error(\"scheduler exited but main fiber never completed\");\n }\n const final = main.settledValue();\n if (final.ok) return final.v as T;\n throw final.e;\n }\n}\n","/*\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\n// RestateOperations\n// =============================================================================\n//\n// Production-side wrapper around restate.Context. Produces journal-backed\n// Futures by delegating to the Restate SDK; defers to the scheduler for\n// spawn/all/race/select.\n//\n// Tests don't need this class — they construct Futures via\n// `Scheduler.makeJournalFuture(testPromise)` directly, build operations via\n// `gen()`, and run them via `Scheduler.run()`. This module's only job is\n// gluing the Restate SDK to the scheduler for production use.\n\nimport * as restate from \"@restatedev/restate-sdk\";\nimport type { Awaitable } from \"./awaitable.js\";\nimport type { Future, FutureValues, FutureSettledResult } from \"./future.js\";\nimport type { Channel } from \"./channel.js\";\nimport {\n type Operation,\n type SelectResult,\n spawn as spawnOp,\n select as selectOp,\n} from \"./operation.js\";\nimport type { Scheduler } from \"./scheduler.js\";\nimport {\n type State,\n type SharedState,\n type TypedState,\n type UntypedState,\n makeState,\n} from \"./state.js\";\nimport {\n type FluentClient,\n type FluentDurablePromise,\n wrapClient,\n wrapDurablePromise,\n} from \"./clients.js\";\n\n// Adapt a real RestatePromise to our Awaitable interface. RestatePromise\n// already has `.map((v, e) => U)` and is thenable, so the adapter is a\n// structural pass-through.\nfunction adapt<T>(p: restate.RestatePromise<T>): Awaitable<T> {\n return p as unknown as Awaitable<T>;\n}\n\n/**\n * Retry policy for `run`. Mirrors the SDK's `RunOptions` retry knobs\n * but namespaced (no `Retry` prefix on each field) and grouped under\n * `RunOpts.retry` for readability.\n */\nexport type RetryOptions = {\n /**\n * Max attempts (including the initial). When reached, `run` throws\n * a `TerminalError` wrapping the original error message.\n */\n maxAttempts?: number;\n /**\n * Max total duration of retries before giving up. Number is ms.\n */\n maxDuration?: restate.Duration | number;\n /**\n * First retry delay. Subsequent delays grow by `intervalFactor`.\n * Number is ms. Defaults to 50 ms.\n */\n initialInterval?: restate.Duration | number;\n /**\n * Cap on retry delay. Number is ms. Defaults to 10 s.\n */\n maxInterval?: restate.Duration | number;\n /**\n * Multiplier applied to the previous delay. Defaults to 2.\n */\n intervalFactor?: number;\n};\n\n/**\n * Options for `run`. Both fields are optional; if `name` is omitted,\n * the action's `Function.name` is used (works for named functions and\n * for arrow functions assigned to a `const` since JS infers names from\n * the binding site). If neither resolves, `run` throws.\n */\nexport type RunOpts<T> = {\n /** Journal entry name. Falls back to `action.name` if absent. */\n name?: string;\n /** Retry policy. Defaults to the SDK's defaults if absent. */\n retry?: RetryOptions;\n /** Custom serde for the journaled value. */\n serde?: restate.Serde<T>;\n};\n\n/**\n * Options object passed to the closure of `run(...)`. Carries an\n * AbortSignal that fires when invocation cancellation arrives.\n *\n * Using an object (rather than positional args) leaves room to extend\n * the closure's API surface — additional fields may be added later\n * without breaking existing closures.\n */\nexport type RunActionOpts = {\n readonly signal: AbortSignal;\n};\n\n/**\n * The closure that `run` invokes. Receives `{ signal }` — pass the\n * signal into AbortSignal-aware APIs (e.g. `fetch(url, { signal })`)\n * to cancel in-flight syscalls promptly.\n */\nexport type RunAction<T> = (opts: RunActionOpts) => Promise<T>;\n\n/**\n * Wrap a user-supplied `run` closure to surface the abort reason\n * (typically a TerminalError(CANCELLED)) on throw paths if the signal\n * aborted during execution. This converts AbortError (and any other\n * abort-caused failure) into the canonical cancellation TerminalError\n * for journal recording.\n *\n * Defensive coercion: if `signal.reason` is itself not a TerminalError\n * (which shouldn't happen in production but might during testing or\n * with non-cancellation race rejections), we wrap it in one. The\n * journal must record a *terminal* outcome to avoid retries against\n * a cancelled invocation.\n *\n * Exposed for testing — the wrapper's behavior is the part that has\n * semantic bite, separate from the ctx.run plumbing.\n */\nexport function wrapActionForCancellation<T>(\n signal: AbortSignal,\n action: RunAction<T>\n): () => Promise<T> {\n return async () => {\n try {\n return await action({ signal });\n } catch (e) {\n if (signal.aborted) {\n throw asTerminalError(signal.reason);\n }\n throw e;\n }\n };\n}\n\n/**\n * Resolve the journal-entry name; throw `TerminalError` if neither\n * source provides one.\n *\n * `TerminalError` (not a plain `Error`) because a missing name is a\n * programming bug — retrying the invocation will hit the same code\n * path and fail the same way. The SDK treats terminal errors as\n * non-retryable; the invocation fails fast instead of looping.\n */\nfunction resolveRunName<T>(action: RunAction<T>, opts?: RunOpts<T>): string {\n const fromOpts = opts?.name?.trim();\n if (fromOpts) return fromOpts;\n const fromFn = action.name;\n if (fromFn) return fromFn;\n throw new restate.TerminalError(\n \"@restatedev/restate-sdk-gen: run() requires a journal-entry name. \" +\n \"Either pass a named function (`run(myFn)`) or supply \" +\n \"`{ name: '...' }` in the second argument.\"\n );\n}\n\n/** Translate our `RetryOptions` into the SDK's flat `RunOptions` shape. */\nfunction toSdkRunOptions<T>(opts?: RunOpts<T>): restate.RunOptions<T> {\n const out: restate.RunOptions<T> = {};\n if (opts?.serde !== undefined) out.serde = opts.serde;\n const r = opts?.retry;\n if (r) {\n if (r.maxAttempts !== undefined) out.maxRetryAttempts = r.maxAttempts;\n if (r.maxDuration !== undefined) out.maxRetryDuration = r.maxDuration;\n if (r.initialInterval !== undefined)\n out.initialRetryInterval = r.initialInterval;\n if (r.maxInterval !== undefined) out.maxRetryInterval = r.maxInterval;\n if (r.intervalFactor !== undefined)\n out.retryIntervalFactor = r.intervalFactor;\n }\n return out;\n}\n\nfunction asTerminalError(reason: unknown): restate.TerminalError {\n if (reason instanceof restate.TerminalError) return reason;\n // Non-Terminal reason: wrap as CancelledError. The SDK's CancelledError\n // is the canonical type for \"invocation was cancelled\" — TerminalError\n // subclass with the proper error code (409). The original reason is\n // discarded; defensible since this branch should never fire in\n // production (cancellation rejections from the SDK are always Terminal).\n return new restate.CancelledError();\n}\n\nexport class RestateOperations {\n private readonly ctx: restate.internal.ContextInternal;\n private readonly sched: Scheduler;\n\n constructor(context: restate.Context, sched: Scheduler) {\n this.ctx = context as restate.internal.ContextInternal;\n this.sched = sched;\n }\n\n // Internal: wrap an SDK RestatePromise as a journal-backed Future.\n // Not part of the public surface — every primitive that needs it\n // (run/sleep/awakeable/typed clients/genericCall/workflowPromise)\n // funnels through here so the adapt + makeJournalFuture wiring\n // stays in one place.\n private toFuture<T>(p: restate.RestatePromise<T>): Future<T> {\n return this.sched.makeJournalFuture(adapt(p));\n }\n\n // ---- journal-backed Futures ----\n\n /**\n * Run a side-effecting closure as a journal entry.\n *\n * The closure receives `{ signal }` — an AbortSignal that fires when\n * invocation cancellation arrives. Pass it into AbortSignal-aware\n * APIs (e.g. `fetch(url, { signal })`) to abort in-flight syscalls.\n *\n * `name` is the journal entry's stable identifier (must be\n * deterministic across replay). It can come from either:\n *\n * - `opts.name` — explicit override\n * - `action.name` — the function's own name (works for `function`\n * declarations and arrow functions assigned to a `const`,\n * since JS infers names from the binding site)\n *\n * If neither resolves, `run` throws.\n *\n * @example Named function — name derived\n * async function fetchUser({ signal }: RunActionOpts): Promise<User> {\n * const r = await fetch(`/users/${id}`, { signal });\n * return r.json();\n * }\n * yield* run(fetchUser);\n *\n * @example Named arrow — name derived from binding\n * const fetchUser = async ({ signal }: RunActionOpts) => { ... };\n * yield* run(fetchUser);\n *\n * @example Inline arrow — name explicit\n * yield* run(async ({ signal }) => fetch(url, { signal }), { name: \"fetch\" });\n *\n * @example With retry policy\n * yield* run(fetchUser, { retry: { maxAttempts: 3 } });\n *\n * Cancellation hygiene: if the closure throws while the signal is\n * aborted, we rethrow `signal.reason` (the original TerminalError)\n * instead of whatever the closure threw. This ensures the journal\n * entry records `TerminalError(CANCELLED)` rather than `AbortError`.\n */\n run<T>(action: RunAction<T>, opts?: RunOpts<T>): Future<T> {\n const name = resolveRunName(action, opts);\n const wrapped = wrapActionForCancellation(this.sched.abortSignal, action);\n return this.sched.makeJournalFuture(\n adapt(this.ctx.run(name, wrapped, toSdkRunOptions(opts)))\n );\n }\n\n sleep(duration: restate.Duration | number, name?: string): Future<void> {\n return this.sched.makeJournalFuture(adapt(this.ctx.sleep(duration, name)));\n }\n\n awakeable<T>(serde?: restate.Serde<T>): { id: string; promise: Future<T> } {\n const { id, promise } = this.ctx.awakeable(serde);\n return { id, promise: this.sched.makeJournalFuture(adapt(promise)) };\n }\n\n resolveAwakeable<T>(id: string, payload?: T, serde?: restate.Serde<T>) {\n this.ctx.resolveAwakeable(id, payload, serde);\n }\n\n rejectAwakeable(id: string, reason: string | restate.TerminalError) {\n this.ctx.rejectAwakeable(id, reason);\n }\n\n signal<T>(name: string, serde?: restate.Serde<T>): Future<T> {\n return this.sched.makeJournalFuture(adapt(this.ctx.signal(name, serde)));\n }\n\n attach<T>(\n invocationId: restate.InvocationId,\n serde?: restate.Serde<T>\n ): Future<T> {\n return this.sched.makeJournalFuture(\n adapt(this.ctx.attach(invocationId, serde))\n );\n }\n\n // ---- typed clients (call) ----\n\n /**\n * Typed RPC client for a service: `ops.serviceClient(api).foo(arg)`\n * yields a `Future<T>` whose value is the handler's return value.\n *\n * Same shape as `ctx.serviceClient(api)` from the SDK, but each\n * handler-method returns `Future<T>` rather than `InvocationPromise<T>`.\n */\n serviceClient<D>(\n api: restate.ServiceDefinitionFrom<D>\n ): FluentClient<restate.Client<restate.Service<D>>> {\n return wrapClient(this.ctx.serviceClient<D>(api), (p) => this.toFuture(p));\n }\n\n /** Typed RPC client for a virtual object. See {@link serviceClient}. */\n objectClient<D>(\n api: restate.VirtualObjectDefinitionFrom<D>,\n key: string\n ): FluentClient<restate.Client<restate.VirtualObject<D>>> {\n return wrapClient(this.ctx.objectClient<D>(api, key), (p) =>\n this.toFuture(p)\n );\n }\n\n /** Typed RPC client for a workflow. See {@link serviceClient}. */\n workflowClient<D>(\n api: restate.WorkflowDefinitionFrom<D>,\n key: string\n ): FluentClient<restate.Client<restate.Workflow<D>>> {\n return wrapClient(this.ctx.workflowClient<D>(api, key), (p) =>\n this.toFuture(p)\n );\n }\n\n // ---- typed clients (send) ----\n //\n // Send clients fire-and-forget; their methods return `InvocationHandle`\n // synchronously, so we pass the SDK client through unchanged.\n\n serviceSendClient<D>(\n api: restate.ServiceDefinitionFrom<D>\n ): restate.SendClient<restate.Service<D>> {\n return this.ctx.serviceSendClient<D>(api);\n }\n\n objectSendClient<D>(\n api: restate.VirtualObjectDefinitionFrom<D>,\n key: string\n ): restate.SendClient<restate.VirtualObject<D>> {\n return this.ctx.objectSendClient<D>(api, key);\n }\n\n workflowSendClient<D>(\n api: restate.WorkflowDefinitionFrom<D>,\n key: string\n ): restate.SendClient<restate.Workflow<D>> {\n return this.ctx.workflowSendClient<D>(api, key);\n }\n\n // ---- generic call/send ----\n //\n // Untyped calls: caller supplies `service`/`method`/`parameter` and the\n // raw bytes get serialized/deserialized via the supplied serdes. Mostly\n // useful for proxies and dispatchers that don't statically know the\n // target's typed definition.\n\n genericCall<REQ = Uint8Array, RES = Uint8Array>(\n call: restate.GenericCall<REQ, RES>\n ): Future<RES> {\n return this.toFuture(this.ctx.genericCall<REQ, RES>(call));\n }\n\n genericSend<REQ = Uint8Array>(\n call: restate.GenericSend<REQ>\n ): restate.InvocationHandle {\n return this.ctx.genericSend<REQ>(call);\n }\n\n // ---- cancel another invocation ----\n\n /**\n * Cancel another invocation by its id. To observe cancellation\n * arriving at *this* invocation, catch the `TerminalError` thrown by\n * the next `yield*` boundary or use the `signal` exposed inside\n * `ops.run` closures.\n */\n cancel(invocationId: restate.InvocationId): void {\n this.ctx.cancel(invocationId);\n }\n\n // ---- workflow durable promise ----\n\n /**\n * Workflow-bound durable promise. Use only inside a workflow handler\n * (the underlying context must be `WorkflowContext` or\n * `WorkflowSharedContext`). Returns a wrapper whose `peek`/`get`/\n * `resolve`/`reject` methods return Futures.\n */\n workflowPromise<T>(\n name: string,\n serde?: restate.Serde<T>\n ): FluentDurablePromise<T> {\n const wfCtx = this.ctx as unknown as restate.WorkflowSharedContext;\n return wrapDurablePromise(wfCtx.promise<T>(name, serde), <U>(p: unknown) =>\n this.toFuture(p as restate.RestatePromise<U>)\n );\n }\n\n // ---- spawn ----\n\n spawn<T>(op: Operation<T>): Operation<Future<T>> {\n return spawnOp(op);\n }\n\n // ---- channels ----\n\n /**\n * Create a single-shot in-memory channel. Returns a Channel<T> with\n * `send(v)` (fire-and-forget, idempotent — first call settles, rest\n * are dropped) and `receive: Future<T>` (a stable settle-once Future,\n * the same handle on every access).\n *\n * Canonical use: cooperative cancellation. Spawn a routine that\n * selects over its work and `stop.receive`; the canceller calls\n * `stop.send()` to request termination. The receiver decides what\n * to do — return a partial result, do cleanup yields, ignore.\n *\n * Because `receive` is a stable, settle-once Future, multiple readers\n * all observe the same value (one-time broadcast) and the worker can\n * use it in every iteration of a select-loop without leaking orphan\n * receivers.\n *\n * Multi-event streams (producer-consumer, progress events) are NOT\n * supported — Channel is intentionally single-shot. A separate\n * primitive for that use case is yet to be designed.\n */\n channel<T>(): Channel<T> {\n return this.sched.makeChannel<T>();\n }\n\n // ---- state ----\n\n /**\n * Per-invocation read-write key-value store. Use from a handler whose\n * underlying context is ObjectContext or WorkflowContext.\n *\n * The optional `TState` generic gives keyof-checked names and per-key\n * value types:\n *\n * ops.state<{count: number; user: User}>()\n * // state.get(\"count\") → Future<number | null>\n *\n * Without it, names are `string` and values are inferred per call:\n *\n * ops.state()\n * // state.get<number>(\"count\") → Future<number | null>\n *\n * Calling write methods from a shared (read-only) context throws at\n * runtime — for shared handlers, use `sharedState()` below to get a\n * narrower type that drops the write methods.\n */\n state<TState extends TypedState = UntypedState>(): State<TState> {\n return makeState<TState>(\n this.ctx as unknown as restate.ObjectContext,\n this.sched,\n adapt\n );\n }\n\n /**\n * Per-invocation read-only key-value store. Use from a handler whose\n * underlying context is ObjectSharedContext or WorkflowSharedContext.\n *\n * Same `TState` generic as `state()`. Returns the read-only subset\n * (`get`, `keys`); attempting to call writes is a type error.\n */\n sharedState<TState extends TypedState = UntypedState>(): SharedState<TState> {\n return makeState<TState>(\n this.ctx as unknown as restate.ObjectSharedContext,\n this.sched,\n adapt\n );\n }\n\n // ---- combinators ----\n\n /**\n * Wait for every future to settle; return their values in input\n * order. Heterogeneous-tuple typing — `all([fA, fB])` where\n * `fA: Future<A>` and `fB: Future<B>` yields `Future<[A, B]>`.\n * Mirrors `Promise.all` from the standard lib.\n */\n all<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<FutureValues<T>> {\n return this.sched.all(futures);\n }\n\n /**\n * Return the first future to settle; losers continue running but\n * their results are discarded. Heterogeneous-tuple typing —\n * `race([fA, fB])` yields `Future<A | B>`. Mirrors `Promise.race`.\n */\n race<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<FutureValues<T>[number]> {\n return this.sched.race(futures);\n }\n\n /**\n * First-success combinator. Resolves with the first input that\n * succeeds (non-rejected); rejects with `AggregateError(errors)` when\n * every input rejects (including an empty input array). See `Promise.any`.\n *\n * Tuple-aware typing — `any([fA, fB])` where `fA: Future<A>` and\n * `fB: Future<B>` yields `Future<A | B>`.\n */\n any<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<FutureValues<T>[number]> {\n return this.sched.any(futures);\n }\n\n /**\n * Settle-all combinator. Resolves with an array of\n * `FutureSettledResult` in input order; never rejects. See\n * `Promise.allSettled`.\n *\n * Tuple-aware typing — `allSettled([fA, fB])` yields\n * `Future<[FutureSettledResult<A>, FutureSettledResult<B>]>`.\n */\n allSettled<const T extends readonly Future<unknown>[] | []>(\n futures: T\n ): Future<{\n -readonly [P in keyof T]: FutureSettledResult<\n T[P] extends Future<infer U> ? U : never\n >;\n }> {\n return this.sched.allSettled(futures);\n }\n\n // Wait for one branch to settle, return its tag and the future itself.\n // The user unwraps the future after switching on the tag — `yield* r.future`\n // is effectively sync at that point since it's already settled.\n *select<B extends Record<string, Future<unknown>>>(\n branches: B\n ): Generator<unknown, SelectResult<B>, unknown> {\n return yield* selectOp(branches);\n }\n}\n\n// =============================================================================\n// Production execute() entry point.\n// =============================================================================\n\nimport { defaultLib } from \"./default-lib.js\";\nimport { Scheduler as SchedulerClass } from \"./scheduler.js\";\n\n/**\n * Run a generator-based workflow against a Restate context.\n *\n * `op` is an `Operation<T>` — typically the result of\n * `gen(function*() { ... })`. Inside the generator body, reach for the\n * free-standing API (`run`, `sleep`, `all`, `state`, …) imported\n * from `@restatedev/restate-sdk-gen`. They read the active scheduler from a\n * synchronous current-fiber slot installed by `Fiber.advance`.\n *\n * `gen()` already takes a factory, so the same `Operation` is re-\n * iterable across multiple `execute()` calls — no need for a builder\n * lambda at this boundary.\n *\n * @example\n * execute(ctx, gen(function* () {\n * const greeting = yield* run(async () => \"hi\", { name: \"compose\" });\n * return greeting;\n * }));\n */\nexport async function execute<T>(\n context: restate.Context,\n op: Operation<T>\n): Promise<T> {\n const sched = new SchedulerClass(defaultLib);\n // Publish a private `RestateOperations` on the scheduler so\n // `Fiber.advance` can install it on the module-level current-fiber\n // slot read by the free-standing API.\n sched.contextSlot = new RestateOperations(context, sched);\n return sched.run(op);\n}\n"],"mappings":";;;AAqCA,IAAIA,UAAmB;;;;;;;AAQvB,SAAgB,WAAW,OAAyB;CAClD,MAAM,OAAO;AACb,WAAU;AACV,QAAO;;;AAIT,SAAgB,aAAa,MAAqB;AAChD,WAAU;;;;;;;AAQZ,SAAgB,aAAsB;AACpC,KAAI,YAAY,KACd,OAAM,IAAI,MACR,4IAED;AAEH,QAAO;;;;;;;;;;;ACRT,SAAgB,aAAgC;AAC9C,QAAO,YAAY;;;;;;;;;;AAarB,MAAa,OAAU,QAAsB,SAC3C,YAAY,CAAC,IAAI,QAAQ,KAAK;AAEhC,MAAa,SACX,UACA,SACiB,YAAY,CAAC,MAAM,UAAU,KAAK;AAErD,MAAa,aACX,UACuC,YAAY,CAAC,UAAU,MAAM;AAEtE,MAAa,oBACX,IACA,SACA,UACS,YAAY,CAAC,iBAAiB,IAAI,SAAS,MAAM;AAE5D,MAAa,mBACX,IACA,WACS,YAAY,CAAC,gBAAgB,IAAI,OAAO;AAEnD,MAAa,UAAa,MAAc,UACtC,YAAY,CAAC,OAAO,MAAM,MAAM;AAElC,MAAa,UACX,cACA,UACc,YAAY,CAAC,OAAO,cAAc,MAAM;AAIxD,MAAa,iBACX,QAEA,YAAY,CAAC,cAAiB,IAAI;AAEpC,MAAa,gBACX,KACA,QAEA,YAAY,CAAC,aAAgB,KAAK,IAAI;AAExC,MAAa,kBACX,KACA,QAEA,YAAY,CAAC,eAAkB,KAAK,IAAI;AAE1C,MAAa,qBACX,QAEA,YAAY,CAAC,kBAAqB,IAAI;AAExC,MAAa,oBACX,KACA,QAEA,YAAY,CAAC,iBAAoB,KAAK,IAAI;AAE5C,MAAa,sBACX,KACA,QAEA,YAAY,CAAC,mBAAsB,KAAK,IAAI;AAI9C,MAAa,eACX,SACgB,YAAY,CAAC,YAAsB,KAAK;AAE1D,MAAa,eACX,SAC6B,YAAY,CAAC,YAAiB,KAAK;AAIlE,MAAa,UAAU,iBACrB,YAAY,CAAC,OAAO,aAAa;AAInC,MAAa,gBAA+B,YAAY,CAAC,SAAY;AAErE,MAAa,cAES,YAAY,CAAC,OAAe;AAElD,MAAa,oBAEe,YAAY,CAAC,aAAqB;AAI9D,MAAa,mBACX,MACA,UAC4B,YAAY,CAAC,gBAAmB,MAAM,MAAM;;;;;;AAS1E,MAAa,OACX,YAC4B,YAAY,CAAC,IAAI,QAAQ;;;;;;AAOvD,MAAa,QACX,YACoC,YAAY,CAAC,KAAK,QAAQ;;;;;;AAOhE,MAAa,OACX,YACoC,YAAY,CAAC,IAAI,QAAQ;;;;;;;AAQ/D,MAAa,cACX,YAKI,YAAY,CAAC,WAAW,QAAQ;;;;AC9LtC,MAAa,QAAQ,OAAO,mBAAmB;AAiC/C,SAAgB,cAAiB,MAA+B;CAC9D,MAAM,KAAK;GACR,QAAQ;EACT,EAAE,OAAO,YAAY;AACnB,UAAQ,MAAM;;EAEjB;AACD,QAAO;;AAKT,SAAgB,UACd,SAC4B;CAC5B,MAAM,KAAK;GACR,QAAQ;GAAE,MAAM;GAAa;GAAS;EACvC,EAAE,OAAO,YAAY;AACnB,UAAQ,MAAM;;EAEjB;AACD,QAAO;;AAOT,SAAgB,IACd,MACc;AACd,QAAO,GAAG,OAAO,WAAW,MAAM;;AAUpC,SAAgB,MAAS,IAAwC;AAK/D,QAAO,cADoB;EAAE,MAAM;EAAS,OAAO;EAAI,CACY;;AAgBrE,UAAiB,OACf,UAC8C;CAC9C,MAAM,OAAO,OAAO,KAAK,SAAS;CAGlC,MAAM,MAAM,MADG,OAAO,UADN,KAAK,KAAK,MAAM,SAAS,GAAG,CACJ,EAChB;AACxB,QAAO;EAAE;EAAK,QAAQ,SAAS;EAAM;;;;;;;;;;;;;;;ACnBvC,SAAgB,UACd,KACA,OACA,SACe;CAIf,MAAM,WAAW;AA4BjB,QAvBkC;EAChC,IAAO,MAAc,OAA4C;AAC/D,UAAO,MAAM,kBACXC,QACE,IAAI,IAAO,MAAM,MAAM,CACxB,CACF;;EAEH,OAAyB;AACvB,UAAO,MAAM,kBACXA,QAAM,IAAI,WAAW,CAAgD,CACtE;;EAEH,IAAO,MAAc,OAAU,OAAgC;AAC7D,YAAS,IAAI,MAAM,OAAO,MAAM;;EAElC,MAAM,MAAoB;AACxB,YAAS,MAAM,KAAK;;EAEtB,WAAiB;AACf,YAAS,UAAU;;EAEtB;;;;;;;;;;ACnFH,SAAgB,WACd,QACA,UACiB;AACjB,QAAO,IAAI,MAAM,QAAQ,EACvB,IAAI,QAAQ,MAAM,UAAU;EAC1B,MAAM,OAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;AAChD,MAAI,OAAO,SAAS,WAAY,QAAO;AACvC,UAAQ,GAAG,SAAoB;AAI7B,UAAO,SAFL,KACA,MAAM,QAAQ,KAAK,CACF;;IAGxB,CAAC;;;;;;AAOJ,SAAgB,mBACd,IACA,UACyB;AACzB,QAAO;EACL,YACE,SAAS,GAAG,MAAM,CAAqD;EACzE,UAAU,UACR,SAAS,GAAG,QAAQ,MAAM,CAA4C;EACxE,SAAS,aAGP,SAAS,GAAG,OAAO,SAAS,CAA4C;EAC1E,WAAW,SAAS,GAAG,KAAK,CAAC;EAC9B;;;;;AC1EH,MAAaC,aAA2B;CACtC,IACE,OACwD;AACxD,SAAO,QAAQ,eAAe,IAC5B,MACD;;CAEH,KACE,OAC+B;AAC/B,SAAO,QAAQ,eAAe,KAC5B,MACD;;CAEH,IACE,OAC+B;AAC/B,SAAO,QAAQ,eAAe,IAC5B,MACD;;CAEH,WACE,OAGC;AACD,SAAO,QAAQ,eAAe,WAC5B,MACD;;CAMH,eAAe,GAAqB;AAClC,SAAO,aAAa,QAAQ;;CAE/B;;;;AChBD,MAAa,gBAAgB,OAAO,uBAAuB;;;;;AA6D3D,SAAgB,WAAc,GAA0B;AACtD,QAAQ,EAA2B;;AAGrC,SAAgB,WAAc,SAAgC;CAQ5D,MAAMC,SAA+B;GAClC,gBAAgB;EACjB,EAAE,OAAO,YAAY;AACnB,UAAQ,MAAM;;EAEjB;CACD,MAAMC,SAAyB,cAAiB;EAC9C,MAAM;EACN;EACD,CAAgB;AACjB,QAAO;;AAGT,SAAgB,gBAAmB,GAA2C;AAC5E,QAAO,WAAW,EAAE,CAAC,SAAS;;;;;AC9DhC,IAAa,QAAb,MAAyD;CACvD,AAAiB;CACjB,AAAiB;CACjB,AAAQ,QAAoB;EAAE,MAAM;EAAS,QAAQ;EAAM;CAC3D,AAAQ,UAAoB,EAAE;CAE9B,YAAY,IAAkB,OAAqB;AACjD,OAAK,KAAK,GAAG,OAAO,WAAW;AAC/B,OAAK,QAAQ;;CAKf,SAAkB;AAChB,SAAO,KAAK,MAAM,SAAS;;;;;;;CAQ7B,eAAwB;AACtB,MAAI,KAAK,MAAM,SAAS,OACtB,OAAM,IAAI,MAAM,8CAA8C;AAEhE,SAAO,KAAK,MAAM;;;;;;;;CASpB,gBAA0C;AACxC,SAAO,KAAK,MAAM,SAAS,WAAW,KAAK,MAAM,WAAW,EAAE;;;;;;;;;CAUhE,gBAAgB,QAAgC;AAC9C,MAAI,KAAK,MAAM,SAAS,OAAQ,QAAO,KAAK,MAAM;AAClD,OAAK,QAAQ,KAAK,OAAO;AACzB,SAAO;;;;;;;;CAWT,KAAK,QAA8B;AACjC,MAAI,KAAK,MAAM,SAAS,OAAQ;AAChC,OAAK,QAAQ;GAAE,MAAM;GAAS;GAAQ;AACtC,OAAK,MAAM,UAAU,KAAK;;;;;;;;;;CAW5B,UAAgB;AACd,MAAI,KAAK,MAAM,SAAS,QAAS;EAMjC,MAAM,WAAW,WAAW,KAAK,MAAM,YAAY;AACnD,MAAI;GACF,IAAIC,SAAyB,KAAK,MAAM;AACxC,UAAO,MAAM;IACX,IAAIC;AACJ,QAAI;AACF,YAAO,aAAa,KAAK,IAAI,OAAO;aAC7B,GAAG;AACV,UAAK,OAAO;MAAE,IAAI;MAAO;MAAG,CAAC;AAC7B;;AAEF,QAAI,KAAK,MAAM;AACb,UAAK,OAAO;MAAE,IAAI;MAAM,GAAG,KAAK;MAAO,CAAC;AACxC;;IAIF,MAAM,OADK,KAAK,MACA;IAMhB,IAAIC;AACJ,YAAQ,KAAK,MAAb;KACE,KAAK;AACH,gBAAU,KAAK,WAAW,KAAK;AAC/B;KACF,KAAK;AACH,gBAAU;OACR,IAAI;OACJ,GAAG,KAAK,MAAM,YAAY,KAAK,MAAM;OACtC;AACD;KACF,KAAK;AACH,gBAAU,KAAK,gBAAgB,KAAK,QAAQ;AAC5C;;AAGJ,QAAI,YAAY,KAAM;AACtB,aAAS;;YAEH;AACR,gBAAa,SAAS;;;;;;;;;;CAa1B,AAAQ,WAAW,MAAyC;EAC1D,MAAMC,UAA4B,WAAW,KAAK,OAAO;AACzD,MAAI,QAAQ,SAAS,WAAW;AAC9B,QAAK,QAAQ;IACX,MAAM;IACN,UAAU,CAAC;KAAE,SAAS,QAAQ;KAAS,OAAO,MAAM,KAAK,KAAK,EAAE;KAAE,CAAC;IACpE;AACD,UAAO;;EAKT,MAAM,UAAU,QAAQ,OAAO,iBAAiB,MAAM,KAAK,KAAK,EAAE,CAAC;AACnE,MAAI,YAAY,KAAM,QAAO;AAC7B,OAAK,QAAQ;GAAE,MAAM;GAAU,UAAU,EAAE;GAAE;AAC7C,SAAO;;;;;;;;;;;;;;CAeT,AAAQ,gBACN,SACgB;AAIhB,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,IAAI,WAAW,QAAQ,GAAI;AACjC,OAAI,EAAE,SAAS,WAAW,EAAE,OAAO,QAAQ,CACzC,QAAO;IAAE,IAAI;IAAM,GAAG;KAAE,OAAO;KAAG,SAAS,EAAE,OAAO,cAAc;KAAE;IAAE;;EAI1E,IAAI,MAAM;EACV,MAAMC,WAA4B,EAAE;AACpC,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,MAAM;GACZ,MAAM,IAAI,WAAW,QAAQ,GAAI;GACjC,MAAM,YAAY,YAAqB;AACrC,QAAI,IAAK;AACT,UAAM;AACN,SAAK,KAAK;KAAE,IAAI;KAAM,GAAG;MAAE,OAAO;MAAK;MAAS;KAAE,CAAC;;AAErD,OAAI,EAAE,SAAS,QAIb,GAAE,OAAO,gBAAgB,SAAS;OAElC,UAAS,KAAK;IAAE,SAAS,EAAE;IAAS,MAAM;IAAU,CAAC;;AAGzD,OAAK,QAAQ;GAAE,MAAM;GAAU;GAAU;AACzC,SAAO;;;;;;CAST,AAAQ,OAAO,SAAwB;AACrC,OAAK,QAAQ;GAAE,MAAM;GAAQ;GAAS;EACtC,MAAM,UAAU,KAAK;AACrB,OAAK,UAAU,EAAE;AACjB,OAAK,MAAM,KAAK,QAAS,GAAE,QAAQ;AACnC,OAAK,MAAM,SAAS,KAAK;;;;;;;;;;AAW7B,SAAS,aACP,IACA,QACkC;AAClC,KAAI,WAAW,KAAM,QAAO,GAAG,KAAK,OAAU;AAC9C,KAAI,OAAO,GAAI,QAAO,GAAG,KAAK,OAAO,EAAE;AACvC,KAAI,GAAG,MAAO,QAAO,GAAG,MAAM,OAAO,EAAE;AACvC,OAAM,OAAO;;;;;AC/Pf,IAAM,cAAN,MAA8C;CAC5C,AAAQ,QAA6D,EACnE,MAAM,WACP;CACD,AAAQ,UAAoB,EAAE;CAK9B,KAAK,OAAgB;AACnB,MAAI,KAAK,MAAM,SAAS,UAAW;AACnC,OAAK,QAAQ;GAAE,MAAM;GAAW;GAAO;EACvC,MAAM,KAAK,KAAK;AAChB,OAAK,UAAU,EAAE;EACjB,MAAMC,UAAmB;GAAE,IAAI;GAAM,GAAG;GAAO;AAC/C,OAAK,MAAM,KAAK,GAAI,GAAE,QAAQ;;CAGhC,SAAkB;AAChB,SAAO,KAAK,MAAM,SAAS;;CAG7B,eAAwB;AACtB,MAAI,KAAK,MAAM,SAAS,UACtB,OAAM,IAAI,MAAM,uDAAuD;AAEzE,SAAO;GAAE,IAAI;GAAM,GAAG,KAAK,MAAM;GAAO;;CAG1C,gBAAgB,QAAgC;AAC9C,MAAI,KAAK,MAAM,SAAS,UACtB,QAAO;GAAE,IAAI;GAAM,GAAG,KAAK,MAAM;GAAO;AAE1C,OAAK,QAAQ,KAAK,OAAO;AACzB,SAAO;;;AAkBX,SAAgB,cAA6B;CAC3C,MAAM,OAAO,IAAI,aAAgB;AACjC,QAAO;EACL,OAAO,MAKL,IAAU,aAAa;AACrB,QAAK,KAAK,EAAE;IACZ;EACJ,SAAS,WAAc;GAAE,MAAM;GAAS,QAAQ;GAAM,CAAC;EACxD;;;;;AClEH,IAAa,YAAb,MAA+C;CAC7C,AAAiB,yBAA8B,IAAI,KAAK;CACxD,AAAiB,QAA0B,EAAE;CAC7C,AAAiB;CASjB,AAAQ,kBAAmC,IAAI,iBAAiB;;;;;;;;;CAShE,cAAuB;CAEvB,YAAY,KAAmB;AAC7B,OAAK,MAAM;;;;;;;;;;;;;;;;CAiBb,IAAI,cAA2B;AAC7B,SAAO,KAAK,gBAAgB;;CAK9B,UAAU,GAAyB;AACjC,OAAK,MAAM,KAAK,EAAE;;CAGpB,SAAS,GAAyB;AAMhC,OAAK,OAAO,OAAO,EAAE;;CAGvB,YAAe,IAA6B;AAE1C,SAAO,WAAc;GAAE,MAAM;GAAS,QAD5B,KAAK,YAAY,GAAG;GACmB,CAAC;;CAGpD,AAAQ,YAAe,IAA4B;EACjD,MAAM,IAAI,IAAI,MAAS,IAAI,KAAK;AAChC,OAAK,OAAO,IAAI,EAAoB;AACpC,OAAK,MAAM,KAAK,EAAoB;AACpC,SAAO;;CAKT,kBAAqB,SAAkC;AACrD,SAAO,WAAc;GAAE,MAAM;GAAW;GAAS,CAAC;;;;;;;;CASpD,cAAiB,IAA6B;AAC5C,SAAO,KAAK,YAAY,GAAG;;;;;;;CAQ7B,cAA6B;AAC3B,SAAO,aAAgB;;;;;;;;;;;;;CAgBzB,IACE,SACyB;EAIzB,MAAM,KAAK;AACX,MAAI,GAAG,MAAM,gBAAgB,EAAE;GAC7B,MAAM,WAAW,GAAG,KAAK,MAAM,EAAE,eAAe,QAAQ;AACxD,UAAO,KAAK,kBAAkB,KAAK,IAAI,IAAI,SAAS,CAAC;;AAIvD,SAAO,KAAK,cACV,IAAqB,aAAa;GAChC,MAAMC,MAAiB,IAAI,MAAM,GAAG,OAAO;AAC3C,QAAK,IAAI,IAAI,GAAG,IAAI,GAAG,QAAQ,IAE7B,KAAI,KAAK,OAAO,GAAG;AAErB,UAAO;IACP,CACH;;CAGH,KACE,SACiC;EAEjC,MAAM,KAAK;AAEX,SAAO,KAAK,cACV,IAAO,aAAa;GAClB,MAAM,SAAS,OAAO,UAAU,GAAG;AACnC,OAAI,OAAO,QAAQ,GAAI,QAAO,OAAO,QAAQ;AAC7C,SAAM,OAAO,QAAQ;IACrB,CACH;;;;;;;;;;;;;;;;;CAkBH,IACE,SACiC;EAEjC,MAAM,KAAK;AACX,MAAI,GAAG,MAAM,gBAAgB,EAAE;GAC7B,MAAM,WAAW,GAAG,KAAK,MAAM,EAAE,eAAe,QAAQ;AACxD,UAAO,KAAK,kBAAkB,KAAK,IAAI,IAAI,SAAS,CAAC;;AAEvD,SAAO,KAAK,cACV,IAAO,aAAa;GAClB,MAAMC,SAAoB,IAAI,MAAM,GAAG,OAAO;GAC9C,MAAM,4BAAY,IAAI,KAAa;AACnC,QAAK,IAAI,IAAI,GAAG,IAAI,GAAG,QAAQ,IAAK,WAAU,IAAI,EAAE;AACpD,UAAO,UAAU,OAAO,GAAG;IACzB,MAAM,UAAU,MAAM,KAAK,UAAU;IAErC,MAAM,SAAS,OAAO,UADT,QAAQ,KAAK,MAAM,GAAG,GAAI,CACF;IACrC,MAAM,WAAW,QAAQ,OAAO;AAChC,QAAI,OAAO,QAAQ,GAAI,QAAO,OAAO,QAAQ;AAC7C,WAAO,YAAY,OAAO,QAAQ;AAClC,cAAU,OAAO,SAAS;;AAE5B,SAAM,IAAI,eAAe,QAAQ,6BAA6B;IAC9D,CACH;;;;;;;;;;;;;;;CAgBH,WACE,SAGC;EAID,MAAM,KAAK;AACX,MAAI,GAAG,MAAM,gBAAgB,EAAE;GAC7B,MAAM,WAAW,GAAG,KAAK,MAAM,EAAE,eAAe,QAAQ;AACxD,UAAO,KAAK,kBAAkB,KAAK,IAAI,WAAW,SAAS,CAAC;;AAE9D,SAAO,KAAK,cACV,IAAO,aAAa;GAClB,MAAM,MAAM,IAAI,MAAoC,GAAG,OAAO;AAC9D,QAAK,IAAI,IAAI,GAAG,IAAI,GAAG,QAAQ,IAC7B,KAAI;AAEF,QAAI,KAAK;KAAE,QAAQ;KAAa,OADlB,OAAO,GAAG;KACe;YAChC,QAAQ;AACf,QAAI,KAAK;KAAE,QAAQ;KAAY;KAAQ;;AAG3C,UAAO;IACP,CACH;;CAKH,AAAQ,aAAmB;AACzB,SAAO,KAAK,MAAM,SAAS,EAAG,MAAK,MAAM,OAAO,CAAE,SAAS;;;;;;;;CAS7D,MAAM,IAAO,IAA8B;EACzC,MAAM,OAAO,KAAK,YAAY,GAAG;AACjC,OAAK,YAAY;AAEjB,SAAO,KAAK,OAAO,OAAO,GAAG;GAC3B,MAAMC,QAAyB,EAAE;AACjC,QAAK,MAAM,KAAK,KAAK,OACnB,MAAK,MAAM,OAAO,EAAE,eAAe,CAAE,OAAM,KAAK,IAAI;AAEtD,OAAI,MAAM,WAAW,EAInB,OAAM,IAAI,MACR,wEACD;GAGH,MAAM,SAAS,MAAM,KAAK,EAAE,WAAW,QACrC,QAAQ,KAAK,GAAG,MACd,MAAM,SAAY;IAAE;IAAG,IAAI;IAAO;IAAG,GAAG;IAAE;IAAG,IAAI;IAAM;IAAG,CAC3D,CACF;GAkBD,IAAIC;AACJ,OAAI;AACF,iBAAc,MAAM,KAAK,IAAI,KAAK,OAAO;YAClC,GAAG;AACV,QAAI,KAAK,IAAI,eAAe,EAAE,EAAE;AAC9B,UAAK,gBAAgB,MAAM,EAAE;AAC7B,UAAK,kBAAkB,IAAI,iBAAiB;;IAE9C,MAAMC,aAAsB;KAAE,IAAI;KAAO;KAAG;AAC5C,SAAK,MAAM,MAAM,MAAO,IAAG,KAAK,WAAW;AAC3C,SAAK,YAAY;AACjB;;GAGF,MAAM,EAAE,EAAG,GAAG,kBAAkB;GAChC,MAAMC,UAAmB,cAAc,KACnC;IAAE,IAAI;IAAM,GAAG,cAAc;IAAG,GAChC;IAAE,IAAI;IAAO,GAAG,cAAc;IAAG;AACrC,SAAM,GAAI,KAAK,QAAQ;AACvB,QAAK,YAAY;;AAGnB,MAAI,CAAC,KAAK,QAAQ,CAChB,OAAM,IAAI,MAAM,kDAAkD;EAEpE,MAAM,QAAQ,KAAK,cAAc;AACjC,MAAI,MAAM,GAAI,QAAO,MAAM;AAC3B,QAAM,MAAM;;;;;;ACpThB,SAAS,MAAS,GAA4C;AAC5D,QAAO;;;;;;;;;;;;;;;;;;AAmFT,SAAgB,0BACd,UACA,QACkB;AAClB,QAAO,YAAY;AACjB,MAAI;AACF,UAAO,MAAM,OAAO,EAAE,kBAAQ,CAAC;WACxB,GAAG;AACV,OAAIC,SAAO,QACT,OAAM,gBAAgBA,SAAO,OAAO;AAEtC,SAAM;;;;;;;;;;;;;AAcZ,SAAS,eAAkB,QAAsB,MAA2B;CAC1E,MAAM,WAAW,MAAM,MAAM,MAAM;AACnC,KAAI,SAAU,QAAO;CACrB,MAAM,SAAS,OAAO;AACtB,KAAI,OAAQ,QAAO;AACnB,OAAM,IAAI,QAAQ,cAChB,mKAGD;;;AAIH,SAAS,gBAAmB,MAA0C;CACpE,MAAMC,MAA6B,EAAE;AACrC,KAAI,MAAM,UAAU,OAAW,KAAI,QAAQ,KAAK;CAChD,MAAM,IAAI,MAAM;AAChB,KAAI,GAAG;AACL,MAAI,EAAE,gBAAgB,OAAW,KAAI,mBAAmB,EAAE;AAC1D,MAAI,EAAE,gBAAgB,OAAW,KAAI,mBAAmB,EAAE;AAC1D,MAAI,EAAE,oBAAoB,OACxB,KAAI,uBAAuB,EAAE;AAC/B,MAAI,EAAE,gBAAgB,OAAW,KAAI,mBAAmB,EAAE;AAC1D,MAAI,EAAE,mBAAmB,OACvB,KAAI,sBAAsB,EAAE;;AAEhC,QAAO;;AAGT,SAAS,gBAAgB,QAAwC;AAC/D,KAAI,kBAAkB,QAAQ,cAAe,QAAO;AAMpD,QAAO,IAAI,QAAQ,gBAAgB;;AAGrC,IAAa,oBAAb,MAA+B;CAC7B,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAA0B,OAAkB;AACtD,OAAK,MAAM;AACX,OAAK,QAAQ;;CAQf,AAAQ,SAAY,GAAyC;AAC3D,SAAO,KAAK,MAAM,kBAAkB,MAAM,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4C/C,IAAO,QAAsB,MAA8B;EACzD,MAAM,OAAO,eAAe,QAAQ,KAAK;EACzC,MAAM,UAAU,0BAA0B,KAAK,MAAM,aAAa,OAAO;AACzE,SAAO,KAAK,MAAM,kBAChB,MAAM,KAAK,IAAI,IAAI,MAAM,SAAS,gBAAgB,KAAK,CAAC,CAAC,CAC1D;;CAGH,MAAM,UAAqC,MAA6B;AACtE,SAAO,KAAK,MAAM,kBAAkB,MAAM,KAAK,IAAI,MAAM,UAAU,KAAK,CAAC,CAAC;;CAG5E,UAAa,OAA8D;EACzE,MAAM,EAAE,IAAI,YAAY,KAAK,IAAI,UAAU,MAAM;AACjD,SAAO;GAAE;GAAI,SAAS,KAAK,MAAM,kBAAkB,MAAM,QAAQ,CAAC;GAAE;;CAGtE,iBAAoB,IAAY,SAAa,OAA0B;AACrE,OAAK,IAAI,iBAAiB,IAAI,SAAS,MAAM;;CAG/C,gBAAgB,IAAY,QAAwC;AAClE,OAAK,IAAI,gBAAgB,IAAI,OAAO;;CAGtC,OAAU,MAAc,OAAqC;AAC3D,SAAO,KAAK,MAAM,kBAAkB,MAAM,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC,CAAC;;CAG1E,OACE,cACA,OACW;AACX,SAAO,KAAK,MAAM,kBAChB,MAAM,KAAK,IAAI,OAAO,cAAc,MAAM,CAAC,CAC5C;;;;;;;;;CAYH,cACE,KACkD;AAClD,SAAO,WAAW,KAAK,IAAI,cAAiB,IAAI,GAAG,MAAM,KAAK,SAAS,EAAE,CAAC;;;CAI5E,aACE,KACA,KACwD;AACxD,SAAO,WAAW,KAAK,IAAI,aAAgB,KAAK,IAAI,GAAG,MACrD,KAAK,SAAS,EAAE,CACjB;;;CAIH,eACE,KACA,KACmD;AACnD,SAAO,WAAW,KAAK,IAAI,eAAkB,KAAK,IAAI,GAAG,MACvD,KAAK,SAAS,EAAE,CACjB;;CAQH,kBACE,KACwC;AACxC,SAAO,KAAK,IAAI,kBAAqB,IAAI;;CAG3C,iBACE,KACA,KAC8C;AAC9C,SAAO,KAAK,IAAI,iBAAoB,KAAK,IAAI;;CAG/C,mBACE,KACA,KACyC;AACzC,SAAO,KAAK,IAAI,mBAAsB,KAAK,IAAI;;CAUjD,YACE,MACa;AACb,SAAO,KAAK,SAAS,KAAK,IAAI,YAAsB,KAAK,CAAC;;CAG5D,YACE,MAC0B;AAC1B,SAAO,KAAK,IAAI,YAAiB,KAAK;;;;;;;;CAWxC,OAAO,cAA0C;AAC/C,OAAK,IAAI,OAAO,aAAa;;;;;;;;CAW/B,gBACE,MACA,OACyB;EACzB,MAAM,QAAQ,KAAK;AACnB,SAAO,mBAAmB,MAAM,QAAW,MAAM,MAAM,GAAM,MAC3D,KAAK,SAAS,EAA+B,CAC9C;;CAKH,MAAS,IAAwC;AAC/C,SAAOC,MAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;CAyBpB,UAAyB;AACvB,SAAO,KAAK,MAAM,aAAgB;;;;;;;;;;;;;;;;;;;;;CAwBpC,QAAiE;AAC/D,SAAO,UACL,KAAK,KACL,KAAK,OACL,MACD;;;;;;;;;CAUH,cAA6E;AAC3E,SAAO,UACL,KAAK,KACL,KAAK,OACL,MACD;;;;;;;;CAWH,IACE,SACyB;AACzB,SAAO,KAAK,MAAM,IAAI,QAAQ;;;;;;;CAQhC,KACE,SACiC;AACjC,SAAO,KAAK,MAAM,KAAK,QAAQ;;;;;;;;;;CAWjC,IACE,SACiC;AACjC,SAAO,KAAK,MAAM,IAAI,QAAQ;;;;;;;;;;CAWhC,WACE,SAKC;AACD,SAAO,KAAK,MAAM,WAAW,QAAQ;;CAMvC,CAAC,OACC,UAC8C;AAC9C,SAAO,OAAOC,OAAS,SAAS;;;;;;;;;;;;;;;;;;;;;;AA8BpC,eAAsB,QACpB,SACA,IACY;CACZ,MAAM,QAAQ,IAAIC,UAAe,WAAW;AAI5C,OAAM,cAAc,IAAI,kBAAkB,SAAS,MAAM;AACzD,QAAO,MAAM,IAAI,GAAG"}
package/package.json CHANGED
@@ -1,13 +1,63 @@
1
1
  {
2
2
  "name": "@restatedev/restate-sdk-gen",
3
- "version": "0.0.0",
4
- "description": "Placeholder package for @restatedev/restate-sdk-gen",
3
+ "version": "1.14.2",
4
+ "description": "Generator-based DSL for composing Restate workflows",
5
+ "author": "Restate Developers",
6
+ "email": "code@restate.dev",
5
7
  "license": "MIT",
8
+ "homepage": "https://github.com/restatedev/sdk-typescript#readme",
6
9
  "repository": {
7
10
  "type": "git",
8
11
  "url": "git+https://github.com/restatedev/sdk-typescript.git"
9
12
  },
13
+ "bugs": {
14
+ "url": "https://github.com/restatedev/sdk-typescript/issues"
15
+ },
16
+ "type": "module",
17
+ "main": "./dist/index.cjs",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.cts",
20
+ "exports": {
21
+ ".": {
22
+ "import": "./dist/index.js",
23
+ "require": "./dist/index.cjs"
24
+ },
25
+ "./package.json": "./package.json"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md"
30
+ ],
10
31
  "publishConfig": {
11
32
  "access": "public"
33
+ },
34
+ "dependencies": {},
35
+ "devDependencies": {
36
+ "testcontainers": "^11.12.0",
37
+ "@restatedev/restate-sdk": "1.14.2",
38
+ "@restatedev/restate-sdk-clients": "1.14.2",
39
+ "@restatedev/restate-sdk-testcontainers": "1.14.2"
40
+ },
41
+ "peerDependencies": {
42
+ "@restatedev/restate-sdk": "^1.14.2"
43
+ },
44
+ "scripts": {
45
+ "test": "turbo run _test --filter={.}...",
46
+ "_test": "vitest run",
47
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
48
+ "bench": "vitest bench --run",
49
+ "start:tutorial": "tsx examples/tutorial/src/server.ts",
50
+ "start:test-services": "tsx test-services/src/server.ts",
51
+ "build": "turbo run _build --filter={.}...",
52
+ "_build": "tsc --noEmit && tsdown",
53
+ "dev": "tsc --noEmit --watch",
54
+ "clean": "rm -rf dist *.tsbuildinfo .turbo",
55
+ "check:types": "turbo run _check:types --filter={.}...",
56
+ "_check:types": "tsc --noEmit --project tsconfig.build.json",
57
+ "lint": "eslint .",
58
+ "check:exports": "turbo run _check:exports --filter={.}...",
59
+ "_check:exports": "attw --pack .",
60
+ "check:api": "turbo run _check:api --filter={.}...",
61
+ "_check:api": "api-extractor run --local"
12
62
  }
13
- }
63
+ }